El valor máximo para un tipo int en Go

Resuelto Mike Samuel asked hace 13 años • 13 respuestas

¿Cómo se especifica el valor máximo representable para un unsignedtipo entero?

Me gustaría saber cómo inicializar minel siguiente bucle que calcula de forma iterativa las longitudes mínima y máxima de algunas estructuras.

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
}

para que la primera vez a través de la comparación minLen >= n,.

Mike Samuel avatar Jul 30 '11 03:07 Mike Samuel
Aceptado

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

La parte pertinente:

Dado que los tipos de números enteros utilizan aritmética en complemento a dos, puede inferir los valores constantes mínimo/máximo para inty uint. Por ejemplo,

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

Según el comentario de @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
nmichaels avatar Jul 29 '2011 20:07 nmichaels

https://golang.org/ref/spec#Numeric_types para conocer los límites de tipo físico.

Los valores máximos se definen en el paquete matemático, por lo que en su caso: math.MaxUint32

Tenga cuidado, ya que no hay desbordamiento: incrementar más allá del máximo provoca un ajuste.

Deleted avatar Jul 29 '2011 20:07 Deleted

Usaría mathel paquete para obtener los valores máximos y mínimos de números enteros:

package main

import (
    "fmt"
    "math"
)

func main() {
    // 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 float64 = %+v\n", math.MaxFloat64)
    fmt.Printf("max float32 = %+v\n", math.MaxFloat32)

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

Producción:

max int64   = 9223372036854775807
max int32   = 2147483647
max int16   = 32767
min int64   = -9223372036854775808
min int32   = -2147483648
max float64 = 1.7976931348623157e+308
max float32 = 3.4028234663852886e+38
Gujarat Santana avatar Dec 02 '2017 03:12 Gujarat Santana

nota: esta respuesta queda reemplazada a partir de go 1.17 , que incluía e8eb1d8 ; es decir: el mathpaquete ahora incluye constantes para math.MaxUint, math.MaxInty math.MinInt.

Sumario rápido:

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

Fondo:

Como supongo que sabes, el uinttipo es del mismo tamaño que uint32o uint64, dependiendo de la plataforma en la que te encuentres. Por lo general, se usaría la versión sin tamaño de estos solo cuando no haya riesgo de acercarse al valor máximo, ya que la versión sin una especificación de tamaño puede usar el tipo "nativo", dependiendo de la plataforma, que tiende a ser más rápido.

Tenga en cuenta que tiende a ser "más rápido" porque el uso de un tipo no nativo a veces requiere que el procesador realice operaciones matemáticas y de verificación de límites adicionales para emular el entero más grande o más pequeño. Con esto en mente, tenga en cuenta que el rendimiento del procesador (o del código optimizado del compilador) casi siempre será mejor que agregar su propio código de verificación de límites, por lo que si existe algún riesgo de que entre en juego, puede hacer que Tiene sentido simplemente usar la versión de tamaño fijo y dejar que la emulación optimizada maneje cualquier consecuencia de eso.

Dicho esto, todavía hay algunas situaciones en las que es útil saber con qué estás trabajando.

El paquete " math/bits " contiene el tamaño de uint, en bits. Para determinar el valor máximo, cambie 1esa cantidad de bits, menos 1, es decir:(1 << bits.UintSize) - 1

Tenga en cuenta que al calcular el valor máximo de uint, generalmente necesitará ponerlo explícitamente en una uintvariable (o mayor); de lo contrario, el compilador puede fallar, ya que de forma predeterminada intentará asignar ese cálculo en una variable firmada int(donde, como debería sería obvio, no encajaría), entonces:

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

Esa es la respuesta directa a su pregunta, pero también hay un par de cálculos relacionados que pueden interesarle.

Según las especificaciones , uintsiempre intson del mismo tamaño.

uint ya sea 32 o 64 bits

int mismo tamaño queuint

Entonces también podemos usar esta constante para determinar el valor máximo de int, tomando esa misma respuesta y dividiéndola por 2luego restando 1. es decir:(1 << bits.UintSize) / 2 - 1

Y el valor mínimo de int, desplazando 1esa cantidad de bits y dividiendo el resultado por -2. es decir:(1 << bits.UintSize) / -2

En resumen:

MáxUint: (1 << bits.UintSize) - 1

MáxInt: (1 << bits.UintSize) / 2 - 1

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

ejemplo completo (debe ser el mismo que se muestra a continuación)

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)
}
Will Palmer avatar Jan 29 '2019 12:01 Will Palmer