Подтвердить что ты не робот

Максимальное значение для типа int в Go

Как определить максимальное значение, представимое для целого типа unsigned?

Я хотел бы знать, как инициализировать min в цикле ниже, который итеративно вычисляет минимальную и максимальную длины из некоторых структур.

var minLen uint = ???
var maxLen uint = 0
for _, thing := range sliceOfThings {
  if minLen > thing.n { minLen = thing.n }
  if maxLen < thing.n { maxLen = thing.n }
}
if minLen > maxLen {
  // If there are no values, clamp min at 0 so that min <= max.
  minLen = 0
}

так что в первый раз при сравнении minLen >= n.

4b9b3361

Ответ 1

https://groups.google.com/group/golang-nuts/msg/71c307e4d73024ce?pli=1

Германская часть:

Поскольку целые типы используют две арифметические дополнения, вы можете сделать вывод о том, min/max для int и uint. Например,

const MaxUint = ^uint(0) 
const MinUint = 0 
const MaxInt = int(MaxUint >> 1) 
const MinInt = -MaxInt - 1

В соответствии с комментарием @CarelZA:

uint8  : 0 to 255 
uint16 : 0 to 65535 
uint32 : 0 to 4294967295 
uint64 : 0 to 18446744073709551615 
int8   : -128 to 127 
int16  : -32768 to 32767 
int32  : -2147483648 to 2147483647 
int64  : -9223372036854775808 to 9223372036854775807

Ответ 2

https://golang.org/ref/spec#Numeric_types для ограничений физического типа.

Максимальные значения определены в математическом пакете, поэтому в вашем случае: math.MaxUint32

Следите за тем, чтобы не было переполнения - увеличение значения за макс приводит к переносу.

Ответ 3

Я бы использовал пакет math для получения максимального значения и минимального значения:

func printMinMaxValue() {
    // integer max
    fmt.Printf("max int64 = %+v\n", math.MaxInt64)
    fmt.Printf("max int32 = %+v\n", math.MaxInt32)
    fmt.Printf("max int16 = %+v\n", math.MaxInt16)

    // integer min
    fmt.Printf("min int64 = %+v\n", math.MinInt64)
    fmt.Printf("min int32 = %+v\n", math.MinInt32)

    fmt.Printf("max flloat64= %+v\n", math.MaxFloat64)
    fmt.Printf("max float32= %+v\n", math.MaxFloat32)

    // etc you can see more int the `math`package
}

Вывод:

max int64 = 9223372036854775807
max int32 = 2147483647
max int16 = 32767
min int64 = -9223372036854775808
min int32 = -2147483648
max flloat64= 1.7976931348623157e+308
max float32= 3.4028234663852886e+38

Ответ 4

Я изначально использовал код, взятый из потока обсуждения, который @nmichaels использовал в своем ответе. Теперь я использую несколько иной расчет. Я включил некоторые комментарии в случае, если у кого-то еще есть тот же запрос, что и @Arijoon

const (
    MinUint uint = 0                 // binary: all zeroes

    // Perform a bitwise NOT to change every bit from 0 to 1
    MaxUint      = ^MinUint          // binary: all ones

    // Shift the binary number to the right (i.e. divide by two)
    // to change the high bit to 0
    MaxInt       = int(MaxUint >> 1) // binary: all ones except high bit

    // Perform another bitwise NOT to change the high bit to 1 and
    // all other bits to 0
    MinInt       = ^MaxInt           // binary: all zeroes except high bit
)

Последние два шага работают из-за того, как положительные и отрицательные числа представлены в двух арифметических дополнениях. Раздел спецификации языка Go на Числовые типы ссылаются на читателя на статью Википедии. Я этого не читал, но я узнал о двух дополнениях из книги Code by Charles Petzold, которая является очень доступным вступлением в основы компьютеров и кодирования.

Я помещаю код выше (минус большинство комментариев) в маленький целочисленный математический пакет.

Ответ 5

Одним из способов решения этой проблемы является получение исходных точек из самих значений:

var minLen, maxLen uint
if len(sliceOfThings) > 0 {
  minLen = sliceOfThings[0].minLen
  maxLen = sliceOfThings[0].maxLen
  for _, thing := range sliceOfThings[1:] {
    if minLen > thing.minLen { minLen = thing.minLen }
    if maxLen < thing.maxLen { maxLen = thing.maxLen }
  }
}

Ответ 6

Краткое резюме:

import "math/bits"
const (
    MaxUint uint = (1 << bits.UintSize) - 1
    MaxInt int = (1 << bits.UintSize) / 2 - 1
    MinInt int = (1 << bits.UintSize) / -2
)

Фон:

Как я полагаю, вы знаете, тип uint имеет тот же размер, что и uint32 или uint64, в зависимости от платформы, на которой вы находитесь. Обычно их можно использовать только в том случае, если нет риска приблизиться к максимальному значению, поскольку версия без спецификации размера может использовать "родной" тип, в зависимости от платформы, что, как правило, быстрее.

Обратите внимание, что это имеет тенденцию быть "быстрее", потому что использование не собственного типа иногда требует, чтобы процессор выполнял дополнительную проверку математики и границ, чтобы эмулировать большее или меньшее целое число. Имея это в виду, следует помнить, что производительность процессора (или кода, оптимизированного для компилятора) почти всегда будет лучше, чем добавление собственного кода проверки границ, поэтому, если существует какой-либо риск его появления, он может имеет смысл просто использовать версию фиксированного размера и позволить оптимизированной эмуляции справиться с любыми последствиями.

С учетом вышесказанного все еще существуют ситуации, когда полезно знать, с чем вы работаете.

Пакет " математика/биты " содержит размер uint в битах. Чтобы определить максимальное значение, сдвиньте 1 на столько битов, минус 1. т.е.: (1 << bits.UintSize) - 1

Обратите внимание, что при вычислении максимального значения uint вам, как правило, нужно явно uint его в переменной uint (или большей), иначе компилятор может потерпеть неудачу, так как он по умолчанию попытается присвоить это вычисление целому числу со int (где, как должно быть очевидно, это не подходит), поэтому:

const MaxUint uint = (1 << bits.UintSize) - 1

Это прямой ответ на ваш вопрос, но есть также несколько связанных расчетов, которые могут вас заинтересовать.

Согласно спецификации, uint и int всегда имеют одинаковый размер.

uint или 32 или 64 бит

int такого же размера, как uint

Таким образом, мы также можем использовать эту константу для определения максимального значения int, взяв тот же ответ и разделив на 2 затем вычтя 1. то есть: (1 << bits.UintSize)/2 - 1

И минимальное значение int путем сдвига 1 на столько битов и деления результата на -2. то есть: (1 << bits.UintSize) / -2

В итоге:

MaxUint: (1 << bits.UintSize) - 1

MaxInt: (1 << bits.UintSize)/2 - 1

MinInt: (1 << bits.UintSize) / -2

полный пример (должен быть таким же, как показано ниже)

package main

import "fmt"
import "math"
import "math/bits"

func main() {
    var mi32 int64 = math.MinInt32
    var mi64 int64 = math.MinInt64

    var i32 uint64 = math.MaxInt32
    var ui32 uint64 = math.MaxUint32
    var i64 uint64 = math.MaxInt64
    var ui64 uint64 = math.MaxUint64
    var ui uint64 = (1 << bits.UintSize) - 1
    var i uint64 = (1 << bits.UintSize) / 2 - 1
    var mi int64 = (1 << bits.UintSize) / -2

    fmt.Printf(" MinInt32: %d\n", mi32)
    fmt.Printf(" MaxInt32:  %d\n", i32)
    fmt.Printf("MaxUint32:  %d\n", ui32)
    fmt.Printf(" MinInt64: %d\n", mi64)
    fmt.Printf(" MaxInt64:  %d\n", i64)
    fmt.Printf("MaxUint64:  %d\n", ui64)
    fmt.Printf("  MaxUint:  %d\n", ui)
    fmt.Printf("   MinInt: %d\n", mi)
    fmt.Printf("   MaxInt:  %d\n", i)
}