Показаны сообщения с ярлыком тип int в Golang. Показать все сообщения
Показаны сообщения с ярлыком тип int в Golang. Показать все сообщения

среда, 20 мая 2020 г.

Константа переполняет int

Почему этот код не компилируется?

const n = 9876543210 * 9876543210
fmt.Println(n)

../main.go:2:13: constant 97546105778997104100 overflows int

Ответ

Нетипизированная константа n должна быть преобразована в тип, прежде чем ее можно будет присвоить параметру interface{} в вызове fmt.Println.

fmt.Println(a ...interface{})

Когда тип не может быть выведен из контекста, нетипизированная константа преобразуется в bool, int, float64, complex128, string или rune в зависимости от формата константы.

В этом случае константа является целым числом, но n больше максимального значения типа int.

Тем не менее, n может быть представлен как float64.

const n = 9876543210 * 9876543210
fmt.Println(float64(n))

9.75461057789971e+19

Для точного представления больших чисел пакет math/big реализует арифметику произвольной точности (длинная арифметика). Он поддерживает целые числа со знаком, рациональные числа и числа с плавающей точкой.


Читайте также:


среда, 13 мая 2020 г.

Выбрать правильный тип: int против int64

Используйте int для индексации

Индекс, длина или емкость обычно должны быть int. Тип int имеет 32 или 64 бита и всегда достаточно большой, чтобы вместить максимально возможную длину массива.

Используйте int64 и друзей для данных

Типы int8, int16, int32 и int64 (и их беззнаковые (unsigned) аналоги) лучше всего подходят для данных. Int64 - типичный выбор, когда память не является проблемой.

В частности, вы можете использовать byte, который является псевдонимом для uint8, для большей ясности в ваших намерениях. Точно так же вы можете использовать rune, которая является псевдонимом для int32, чтобы подчеркнуть, что целое число представляет кодовую точку.

Иногда, если вы используете 32- или 64-битные данные, это не имеет большого значения или вообще ничего не меняет, и тогда достаточно просто использовать int. Однако предпочтительно быть явным. Это заставляет вас задуматься о выборе, а также делает код более понятным.

Примеры

В этом коде элементы среза и переменная max имеют тип int64, а индекс и длина среза имеют тип int.

func Max(a []int64) int64 {
    max := a[0]
    for i := 1; i < len(a); i++ {
        if max < a[i] {
            max = a[i]
        }
    }
    return max
}

Реализация time.Duration - типичный пример из стандартной библиотеки, где для хранения данных используется int64:

type Duration int64

Duration представляет время между двумя моментами в виде числа наносекунд. Это ограничивает максимально возможную продолжительность около 290 лет.

В посте Максимальное значение int показано, как вычислить размер и предельные значения типа int в виде нетипизированных констант.


Читайте также:


вторник, 5 мая 2020 г.

Округление числа с плавающей точкой до целочисленного значения в Golang

Округление от нуля

Используйте math.Round, чтобы вернуть ближайшее целое число, как float64, округляя связи от нуля.

fmt.Println(math.Round(-0.6)) // -1
fmt.Println(math.Round(-0.4)) // -0
fmt.Println(math.Round(0.4))  // 0
fmt.Println(math.Round(0.6))  // 1

Обратите внимание на особые случаи.

Round(±0) = ±0
Round(±Inf) = ±Inf
Round(NaN) = NaN

Округлить до четного числа

Используйте math.RoundToEven, чтобы вернуть ближайшее целое число, как float64, округляя связи до четного числа.

fmt.Println(math.RoundToEven(0.5)) // 0
fmt.Println(math.RoundToEven(1.5)) // 2

Преобразовать в тип int

Обратите внимание, что при преобразовании числа с плавающей точкой в ​​тип int дробь отбрасывается (усечение до нуля).

fmt.Println(int64(1.9))  //  1
fmt.Println(int64(-1.9)) // -1

Предупреждение: если тип результата не может представлять значение, преобразование завершается успешно, но результат зависит от реализации.

До версии Go 1.10

Следующие реализации эквивалентны math.Round и math.RoundToEven, но менее эффективны.

// Round возвращает ближайшее целое число, 
// округляя связи от нуля.
func Round(x float64) float64 {
    t := math.Trunc(x)
    if math.Abs(x-t) >= 0.5 {
        return t + math.Copysign(1, x)
    }
    return t
}

// RoundToEven возвращает ближайшее целое число, 
// округляя связи до четного числа.
func RoundToEven(x float64) float64 {
    t := math.Trunc(x)
    odd := math.Remainder(t, 2) != 0
    if d := math.Abs(x - t); d > 0.5 || (d == 0.5 && odd) {
        return t + math.Copysign(1, x)
    }
    return t
}


Читайте также:


купить игрушку gopher

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

Go имеет два предварительно объявленных целочисленных типа с размерами, зависящими от реализации:

  • uint (целое число без знака) имеет 32 или 64 бита,
  • int (целое число со знаком) имеет тот же размер, что и uint.

Этот код вычисляет предельные значения как нетипизированные константы.

const UintSize = 32 << (^uint(0) >> 32 & 1) // 32 или 64

const (
    MaxInt       = 1<<(UintSize-1) - 1 // 1<<31 - 1 или 1<<63 - 1
    MinInt       = -MaxInt - 1         // -1 << 31 или -1 << 63
    MaxUint uint = 1<<UintSize - 1     // 1<<32 - 1 или 1<<64 - 1
)

fmt.Println(UintSize)
fmt.Println(MaxInt)
fmt.Println(MinInt)
fmt.Println(MaxUint)

Вывод:

64                    // UintSize
9223372036854775807   // MaxInt
-9223372036854775808  // MinInt
18446744073709551615  // MaxUint

Константа UintSize также доступна в пакете math/bits.


Читайте также: