Comment spécifier la valeur maximale représentable pour un unsigned
type entier?
Je voudrais savoir comment initialiser min
dans la boucle ci-dessous qui calcule de manière itérative les longueurs min et max de certaines structures.
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
}
de sorte que la première fois grâce à la comparaison, minLen >= n
.
int(^uint(0) >> 1) // largest int
extrait de golang.org/doc/effective_go.html#printingRéponses:
https://groups.google.com/group/golang-nuts/msg/71c307e4d73024ce?pli=1
La partie pertinente:
Selon le commentaire de @ CarelZA:
la source
math
: golang.org/pkg/math/#pkg-constants , vous voudrezmath.MaxInt32
probablement.int
type est de 32 bits sur un système 32 bits et de 64 bits sur un système 64 bits. Regardez ici .https://golang.org/ref/spec#Numeric_types pour les limites de type physique.
Les valeurs max sont définies dans le package math, donc dans votre cas: math.MaxUint32
Attention, il n'y a pas de débordement - l'incrémentation au-delà du max provoque un bouclage.
la source
uint
, nonuint32
. Lelen
et ne l'cap
utilisezint
pas,int32
donc je veux utiliser quelque chose qui correspond à la taille de ceux sur toutes les architectures.math/const.go
définit un tas deMax<type>
mais aucun pour l'unuint
ou l' autre ou `int.uint(len(...)) < thing.minLen
mais je ne sais pas siuint64(int)
c'est et restera un comportement défini.J'utiliserais
math
package pour obtenir la valeur maximale et la valeur minimale:Sortie:
la source
int64
débordent int, ce qui se produit si vous ne tapez pas explicitement les constantes avant l'interpolation de chaîne. Utilisez à laint64(math.MaxInt64)
place, voir stackoverflow.com/questions/16474594/…J'ai utilisé à l'origine le code tiré du fil de discussion que @nmichaels a utilisé dans sa réponse. J'utilise maintenant un calcul légèrement différent. J'ai inclus quelques commentaires au cas où quelqu'un d'autre aurait la même requête que @Arijoon
Les deux dernières étapes fonctionnent en raison de la façon dont les nombres positifs et négatifs sont représentés dans l'arithmétique du complément à deux. La section de spécification du langage Go sur les types numériques renvoie le lecteur à l'article Wikipédia pertinent . Je n'ai pas lu cela, mais j'ai appris le complément à deux dans le livre Code de Charles Petzold , qui est une introduction très accessible aux principes fondamentaux de l'informatique et du codage.
J'ai mis le code ci-dessus (moins la plupart des commentaires) dans un petit package mathématique entier .
la source
Résumé rapide:
Contexte:
Comme je suppose que vous le savez, le
uint
type est de la même taille que l'unuint32
ou l' autreuint64
, selon la plate-forme sur laquelle vous vous trouvez. Habituellement, on n'utiliserait la version non dimensionnée de ceux-ci que lorsqu'il n'y a pas de risque de se rapprocher de la valeur maximale, car la version sans spécification de taille peut utiliser le type "natif", selon la plate-forme, qui a tendance à être plus rapide.Notez qu'il a tendance à être "plus rapide" car l'utilisation d'un type non natif nécessite parfois des calculs supplémentaires et une vérification des limites à effectuer par le processeur, afin d'émuler le plus grand ou le plus petit entier. Dans cet esprit, sachez que les performances du processeur (ou du code optimisé du compilateur) seront presque toujours meilleures que l'ajout de votre propre code de vérification des limites, donc s'il y a un risque qu'il entre en jeu, cela peut faire sens d'utiliser simplement la version de taille fixe et de laisser l'émulation optimisée gérer toutes les conséquences de cela.
Cela dit, il existe encore des situations dans lesquelles il est utile de savoir avec quoi vous travaillez.
Le package " math / bits " contient la taille de
uint
, en bits. Pour déterminer la valeur maximale, décalez1
de ce nombre de bits, moins 1, c'est-à-dire:(1 << bits.UintSize) - 1
Notez que lors du calcul de la valeur maximale de
uint
, vous devrez généralement la placer explicitement dans uneuint
variable (ou plus grande), sinon le compilateur peut échouer, car il tentera par défaut d'assigner ce calcul dans un signeint
(où, comme il se doit être évident, cela ne rentrerait pas), donc:C'est la réponse directe à votre question, mais il y a aussi quelques calculs connexes qui pourraient vous intéresser.
Selon les spécifications ,
uint
etint
sont toujours de la même taille.Nous pouvons donc également utiliser cette constante pour déterminer la valeur maximale de
int
, en prenant cette même réponse et en divisant2
puis en soustrayant1
. c'est à dire:(1 << bits.UintSize) / 2 - 1
Et la valeur minimale de
int
, en décalant1
de autant de bits et en divisant le résultat par-2
. c'est à dire:(1 << bits.UintSize) / -2
En résumé:
MaxUint:
(1 << bits.UintSize) - 1
MaxInt:
(1 << bits.UintSize) / 2 - 1
MinInt:
(1 << bits.UintSize) / -2
exemple complet (devrait être le même que ci-dessous)
la source
/2
partie est ce qui supprime ce bit de considération lors du calcul de la taille de min / max pour int64)À partir de la bibliothèque mathématique: https://github.com/golang/go/blob/master/src/math/const.go#L39
la source
Une façon de résoudre ce problème consiste à obtenir les points de départ des valeurs elles-mêmes:
la source
Un package léger les contient (ainsi que d'autres limites de types int et certaines fonctions entières largement utilisées):
la source
la source