Wie gibt man den Maximalwert an, der für einen unsigned
Integer-Typ darstellbar ist?
Ich möchte wissen, wie man min
in der folgenden Schleife initialisiert , die iterativ die minimalen und maximalen Längen einiger Strukturen berechnet.
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
}
damit das erste mal durch den vergleich , minLen >= n
.
int(^uint(0) >> 1) // largest int
das aus golang.org/doc/effective_go.html#printingAntworten:
https://groups.google.com/group/golang-nuts/msg/71c307e4d73024ce?pli=1
Der deutsche Teil:
Gemäß dem Kommentar von @ CarelZA:
quelle
math
: golang.org/pkg/math/#pkg-constants , würden Sie wollen ,math.MaxInt32
am wahrscheinlichsten.int
Typ ist auf einem 32-Bit-System 32 Bit lang und auf einem 64-Bit-System 64 Bit lang. Siehe hier .https://golang.org/ref/spec#Numeric_types für physikalische Typbeschränkungen.
Die Maximalwerte werden im Mathematikpaket definiert, also in Ihrem Fall: math.MaxUint32
Achten Sie darauf, dass kein Überlauf auftritt. Wenn Sie das Maximum überschreiten, wird dies umgangen.
quelle
uint
nichtuint32
. Dielen
undcap
Verwendungint
nichtint32
so möchte ich nutzen , um etwas, das die Größe von denen auf allen Architekturen übereinstimmt.math/const.go
definiert eine Reihe von,Max<type>
aber keine für entwederuint
oder `int.uint(len(...)) < thing.minLen
aber ich weiß nicht, obuint64(int)
definiertes Verhalten ist und bleiben wird.Ich würde das
math
Paket verwenden, um den Maximalwert und den Minimalwert zu erhalten:Ausgabe:
quelle
int64
Überlauf der beiden int, was passiert, wenn Sie Konstanten vor der String-Interpolation nicht explizit eingeben. Verwenden Sieint64(math.MaxInt64)
stattdessen, siehe stackoverflow.com/questions/16474594/…Ich habe ursprünglich den Code aus dem Diskussionsthread verwendet, den @nmichaels in seiner Antwort verwendet hat. Ich benutze jetzt eine etwas andere Berechnung. Ich habe einige Kommentare eingefügt, falls jemand die gleiche Abfrage wie @Arijoon hat
Die letzten beiden Schritte funktionieren aufgrund der Darstellung positiver und negativer Zahlen in der Zweierkomplementarithmetik. Der Abschnitt zur Go-Sprachspezifikation für numerische Typen verweist den Leser auf den entsprechenden Wikipedia-Artikel . Ich habe das nicht gelesen, aber ich habe aus dem Buch Code von Charles Petzold , das eine sehr leicht zugängliche Einführung in die Grundlagen von Computern und Codierung darstellt, etwas über die Ergänzung von zwei gelernt .
Ich habe den obigen Code (abzüglich der meisten Kommentare) in ein kleines ganzzahliges Mathematikpaket eingefügt .
quelle
Kurze Zusammenfassung:
Hintergrund:
Wie Sie wahrscheinlich wissen, hat der
uint
Typ die gleiche Größe wie entwederuint32
oderuint64
, abhängig von der Plattform, auf der Sie sich befinden. Normalerweise würde man die nicht dimensionierte Version davon nur verwenden, wenn kein Risiko besteht, sich dem Maximalwert anzunähern, da die Version ohne Größenangabe je nach Plattform den "nativen" Typ verwenden kann, der tendenziell schneller ist.Beachten Sie, dass es tendenziell "schneller" ist, da die Verwendung eines nicht nativen Typs manchmal zusätzliche Berechnungen und Grenzüberprüfungen durch den Prozessor erfordert, um die größere oder kleinere Ganzzahl zu emulieren. Beachten Sie vor diesem Hintergrund, dass die Leistung des Prozessors (oder des optimierten Codes des Compilers) fast immer besser ist als das Hinzufügen eines eigenen Codes zur Überprüfung der Grenzen. Wenn also das Risiko besteht, dass dieser ins Spiel kommt, kann dies zu einer Beeinträchtigung führen Es ist sinnvoll, einfach die Version mit fester Größe zu verwenden und die optimierte Emulation alle daraus resultierenden Folgen bewältigen zu lassen.
Nachdem dies gesagt wurde, gibt es immer noch Situationen, in denen es nützlich ist zu wissen, mit was Sie arbeiten.
Das Paket " math / bits " enthält die Größe von
uint
in Bits. Um den Maximalwert zu bestimmen, verschieben Sie1
um so viele Bits minus 1. Das heißt:(1 << bits.UintSize) - 1
Beachten Sie, dass Sie bei der Berechnung des Maximalwerts von im
uint
Allgemeinen explizit in eineuint
(oder eine größere) Variable einfügen müssen, da der Compiler sonst möglicherweise fehlschlägt, da standardmäßig versucht wird, diese Berechnung einer signiertenint
(wo, wie sollte) zuzuweisen offensichtlich sein, es würde nicht passen), also:Das ist die direkte Antwort auf Ihre Frage, aber es gibt auch einige verwandte Berechnungen, an denen Sie interessiert sein könnten.
Gemäß der Spezifikation ,
uint
undint
sind immer gleich groß.Wir können diese Konstante also auch verwenden, um den Maximalwert von zu bestimmen
int
, indem wir dieselbe Antwort nehmen und durch2
Subtrahieren dividieren1
. dh:(1 << bits.UintSize) / 2 - 1
Und der Minimalwert von
int
durch Verschieben1
um so viele Bits und Teilen des Ergebnisses durch-2
. dh:(1 << bits.UintSize) / -2
Zusammenfassend:
MaxUint:
(1 << bits.UintSize) - 1
MaxInt:
(1 << bits.UintSize) / 2 - 1
MinInt:
(1 << bits.UintSize) / -2
vollständiges Beispiel (sollte das gleiche sein wie unten)
quelle
/2
Teil ist das, was dieses Bit bei der Berechnung der Größe von min / max für int64 aus der Betrachtung entfernt.)Aus der Mathematikbibliothek: https://github.com/golang/go/blob/master/src/math/const.go#L39
quelle
Eine Möglichkeit, dieses Problem zu lösen, besteht darin, die Ausgangspunkte aus den Werten selbst zu ermitteln:
quelle
Ein leichtes Paket enthält sie (sowie andere Grenzwerte für Int-Typen und einige weit verbreitete Ganzzahlfunktionen):
quelle
quelle