Como se especifica o valor máximo representável para um unsigned
tipo inteiro?
Gostaria de saber como inicializar min
no loop abaixo que iterativamente calcula os comprimentos mínimo e máximo de algumas estruturas.
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 a primeira vez através da comparação minLen >= n
,.
int(^uint(0) >> 1) // largest int
extraído de golang.org/doc/effective_go.html#printing #Respostas:
https://groups.google.com/group/golang-nuts/msg/71c307e4d73024ce?pli=1
A parte pertinente:
De acordo com o comentário de @ CarelZA:
fonte
math
: golang.org/pkg/math/#pkg-constants , você provavelmente desejariamath.MaxInt32
.int
tipo tem 32 bits de comprimento em um sistema de 32 bits e 64 bits de comprimento em um sistema de 64 bits. Veja aqui .https://golang.org/ref/spec#Numeric_types para limites de tipo físico.
Os valores máximos são definidos no pacote matemático, portanto, no seu caso: math.MaxUint32
Cuidado, pois não há transbordamento - o incremento de um número máximo máximo de passado causa um desvio.
fonte
uint
, estou usando , nãouint32
. Olen
ecap
useint
não,int32
então eu quero usar algo que corresponda ao tamanho daqueles em todas as arquiteturas.math/const.go
define um monte deMax<type>
mas nenhum para umuint
ou para `int.uint(len(...)) < thing.minLen
mas não sei seuint64(int)
é e continuará sendo um comportamento definido.Eu usaria o
math
pacote para obter o valor máximo e o mínimo:Ouput:
fonte
int64
overflow dos dois int, que é o que acontece se você não digitar explicitamente constantes antes da interpolação de string. Emint64(math.MaxInt64)
vez disso, use stackoverflow.com/questions/16474594/…Originalmente, usei o código retirado do tópico de discussão que @nmichaels usou em sua resposta. Agora eu uso um cálculo ligeiramente diferente. Incluí alguns comentários caso alguém tenha a mesma consulta que @Arijoon
Os dois últimos passos funcionam devido à forma como os números positivos e negativos são representados na aritmética do complemento de dois. A seção de especificação de idioma Go em Tipos numéricos refere o leitor ao artigo relevante da Wikipedia . Não li isso, mas aprendi sobre o complemento de dois no livro Code, de Charles Petzold , que é uma introdução muito acessível aos fundamentos dos computadores e da codificação.
Coloquei o código acima (menos a maioria dos comentários) em um pequeno pacote inteiro de matemática .
fonte
Resumo rápido:
Fundo:
Como presumo que você saiba, o
uint
tipo é do mesmo tamanho que umuint32
ou outrouint64
, dependendo da plataforma em que você está. Normalmente, a versão sem tamanho seria usada apenas quando não há risco de se aproximar do valor máximo, pois a versão sem especificação de tamanho pode usar o tipo "nativo", dependendo da plataforma, que tende a ser mais rápida.Observe que ele tende a ser "mais rápido" porque o uso de um tipo não-nativo às vezes exige que seja feita uma verificação matemática e de limites adicional pelo processador, a fim de emular o número inteiro maior ou menor. Com isso em mente, esteja ciente de que o desempenho do processador (ou código otimizado do compilador) quase sempre será melhor do que adicionar seu próprio código de verificação de limites; portanto, se houver algum risco de entrar em jogo, isso poderá prejudicar É bom usar simplesmente a versão de tamanho fixo e deixar a emulação otimizada lidar com qualquer problema disso.
Com isso dito, ainda existem algumas situações em que é útil saber com o que você está trabalhando.
O pacote " math / bits " contém o tamanho de
uint
, em bits. Para determinar o valor máximo, altere1
o número de bits menos 1. ie:(1 << bits.UintSize) - 1
Observe que, ao calcular o valor máximo de
uint
, geralmente você precisará colocá-lo explicitamente em umauint
variável (ou maior); caso contrário, o compilador poderá falhar, pois o padrão será tentar atribuir esse cálculo a um sinal assinadoint
(onde, como deveria seja óbvio, não caberia), então:Essa é a resposta direta à sua pergunta, mas também existem alguns cálculos relacionados nos quais você pode estar interessado.
De acordo com as especificações ,
uint
eint
são sempre do mesmo tamanho.Portanto, também podemos usar essa constante para determinar o valor máximo de
int
, pegando a mesma resposta e dividindo2
e subtraindo1
. ou seja:(1 << bits.UintSize) / 2 - 1
E o valor mínimo de
int
, deslocando-se1
por tantos bits e dividindo o resultado por-2
. ou seja:(1 << bits.UintSize) / -2
Em suma:
MaxUint:
(1 << bits.UintSize) - 1
MaxInt:
(1 << bits.UintSize) / 2 - 1
MinInt:
(1 << bits.UintSize) / -2
exemplo completo (deve ser o mesmo que abaixo)
fonte
/2
parte é o que remove esse bit de consideração ao calcular o tamanho de min / max para int64)Na lib de matemática: https://github.com/golang/go/blob/master/src/math/const.go#L39
fonte
Uma maneira de resolver esse problema é obter os pontos de partida dos próprios valores:
fonte
Um pacote leve os contém (assim como outros limites de tipos int e algumas funções inteiras amplamente usadas):
fonte
fonte