Gibt es eine Möglichkeit, ein vorzeichenloses int in Java zu deklarieren?
Oder die Frage könnte auch so lauten: Was ist das Java-Äquivalent von unsigned?
Nur um Ihnen den Kontext zu erläutern, in dem ich mir die Implementierung von Java angesehen habe String.hashcode()
. Ich wollte die Möglichkeit einer Kollision testen, wenn die Ganzzahl 32 unsigned int wäre.
>>>
Operator verwenden>>
.Antworten:
Java hat keinen Datentyp für vorzeichenlose Ganzzahlen .
Sie können ein
long
anstelle eines definieren,int
wenn Sie große Werte speichern müssen.Sie können eine vorzeichenbehaftete Ganzzahl auch so verwenden, als wäre sie nicht vorzeichenbehaftet. Der Vorteil der Zweierkomplementdarstellung besteht darin, dass die meisten Operationen (wie Addition, Subtraktion, Multiplikation und Linksverschiebung) auf Binärebene für vorzeichenbehaftete und vorzeichenlose Ganzzahlen identisch sind. Einige Operationen (Division, Rechtsverschiebung, Vergleich und Casting) sind jedoch unterschiedlich. Ab Java SE 8 können Sie mit neuen Methoden in der
Integer
Klasse denint
Datentyp vollständig verwenden , um vorzeichenlose Arithmetik auszuführen :Beachten Sie, dass
int
Variablen beim Deklarieren immer noch signiert sind, aber mit diesen Methoden in derInteger
Klasse jetzt eine Arithmetik ohne Vorzeichen möglich ist .quelle
int
Datentyp verwenden, um eine vorzeichenlose 32-Bit-Ganzzahl darzustellen, die einen Mindestwert von0
und einen Höchstwert von hat2^32-1
. - Siehe docs.oracle.com/javase/tutorial/java/nutsandbolts/… und docs.oracle.com/javase/8/docs/api/java/lang/Integer.htmlint
mit verschiedenen Methoden so zu verwenden, als ob sie vorzeichenlos wäre.In Java 8 gibt es eine API für vorzeichenlose Ganzzahlen und Long!
quelle
Integer
Klasse in Java 8 die Verwendung von int ohne Vorzeichen erlaubt, ist dies der Unterschied zwischen nur Platz und Geschwindigkeit (da sie in C / C ++ primitiv sind, während es in Java ein ganzer Objekt-Wrapper ist)int
, auch wenn diese signiert sind. Es ist C / C ++, bei dem nicht signiertes Rollover ausgeführt wird, signiertes jedoch beim Überlauf „Undefiniertes Verhalten“ verursacht. Wenn "Überrollen" Ihr einziges Anliegen ist, brauchen Sie kein unsigniertes. Ich denke, deshalb funktionieren CRC-Routinen usw. in Java ohne zusätzlichen Aufwand. Aus diesem Grund fügt die neue API nur Parsen, Formatieren, Vergleichen, Teilen und Rest hinzu. Alle anderen Operationen, nämlich alle Bitmanipulationen, aber auch Addition, Subtraktion, Multiplikation usw., machen sowieso das Richtige.Ob ein Wert in einem int vorzeichenbehaftet oder vorzeichenlos ist, hängt davon ab, wie die Bits interpretiert werden. Java interpretiert Bits als vorzeichenbehafteten Wert (es gibt keine vorzeichenlosen Grundelemente).
Wenn Sie ein int haben, das Sie als vorzeichenlosen Wert interpretieren möchten (z. B. wenn Sie ein int aus einem DataInputStream lesen, von dem Sie wissen, dass es einen vorzeichenlosen Wert enthält), können Sie den folgenden Trick ausführen.
Beachten Sie, dass es wichtig ist, dass das Hex-Literal ein langes Literal ist, kein int-Literal - daher das 'l' am Ende.
quelle
0xFFFFFF
das int machen und behalten?Wir benötigten Zahlen ohne Vorzeichen zu modellieren MySQL ohne Vorzeichen
TINYINT
,SMALLINT
,INT
,BIGINT
in jOOQ , weshalb wir geschaffen haben jOOU , ein minimalistisches Bibliothek Angebot Wrapper - Typen für unsigned Integer - Zahlen in Java. Beispiel:Alle diese Typen erstrecken sich
java.lang.Number
und können in primitive Typen höherer Ordnung und konvertiert werdenBigInteger
. Hoffe das hilft.(Haftungsausschluss: Ich arbeite für die Firma hinter diesen Bibliotheken)
quelle
Für vorzeichenlose Nummern können Sie diese Klassen aus der Guava-Bibliothek verwenden :
Sie unterstützen verschiedene Operationen:
Das, was im Moment zu fehlen scheint, sind Byte-Shift-Operatoren. Wenn Sie diese benötigen, können Sie BigInteger von Java aus verwenden.
quelle
Verwendung
char
für 16-Bit-Ganzzahlen ohne Vorzeichen.quelle
Vielleicht hast du das gemeint?
getUnsigned(0)
→ 0getUnsigned(1)
→ 1getUnsigned(Integer.MAX_VALUE)
→ 2147483647getUnsigned(Integer.MIN_VALUE)
→ 2147483648getUnsigned(Integer.MIN_VALUE + 1)
→ 2147483649quelle
2 * (long) Integer.MAX_VALUE + 2
ist leichter zu verstehen als0x1_0000_0000L
? Warum nicht einfachreturn signed & 0xFFFF_FFFFL;
?Es scheint, dass Sie das Signaturproblem lösen können, indem Sie ein "logisches UND" für die Werte ausführen, bevor Sie sie verwenden:
Beispiel (Wert von
byte[]
header[0]
is0x86
):Ergebnis:
quelle
Hier gibt es gute Antworten, aber ich sehe keine Demonstrationen von bitweisen Operationen. Wie Visser (die derzeit akzeptierte Antwort) sagt, signiert Java standardmäßig Ganzzahlen (Java 8 hat Ganzzahlen ohne Vorzeichen, aber ich habe sie nie verwendet). Lass es uns ohne weiteres tun ...
RFC 868 Beispiel
Was passiert, wenn Sie eine vorzeichenlose Ganzzahl in IO schreiben müssen? Ein praktisches Beispiel ist, wenn Sie die Zeit gemäß RFC 868 ausgeben möchten . Dies erfordert eine 32-Bit-Big-Endian-Ganzzahl ohne Vorzeichen, die die Anzahl der Sekunden seit dem 1. Januar 1900 um 00:00 Uhr codiert. Wie würden Sie dies codieren?
Erstellen Sie Ihre eigene vorzeichenlose 32-Bit-Ganzzahl wie folgt:
Deklarieren Sie ein Byte-Array mit 4 Bytes (32 Bit).
Dadurch wird das Array initialisiert, siehe Werden Byte-Arrays in Java auf Null initialisiert? . Jetzt müssen Sie jedes Byte im Array mit Informationen in der Big-Endian-Reihenfolge füllen (oder Little-Endian, wenn Sie Chaos anrichten möchten). Angenommen, Sie haben eine lange Zeit, die die Zeit enthält (lange Ganzzahlen sind in Java 64 Bit lang
secondsSince1900
) Sie können das logische UND verwenden, um Bits daraus zu extrahieren und diese Bits in Positionen (Ziffern) zu verschieben, die beim Zusammenführen in ein Byte und in Big-Endian-Reihenfolge nicht ignoriert werden.Unsere
my32BitUnsignedInteger
entspricht jetzt einer vorzeichenlosen 32-Bit-Big-Endian-Ganzzahl, die dem RCF 868-Standard entspricht. Ja, der lange Datentyp ist signiert, aber wir haben diese Tatsache ignoriert, da wir davon ausgegangen sind, dass der secondSince1900 nur die unteren 32 Bit verwendet hat. Da das Long in ein Byte umgewandelt wird, werden alle Bits, die höher als 2 ^ 7 sind (die ersten beiden Ziffern in Hex), ignoriert.Quelle angegeben: Java Network Programming, 4. Ausgabe.
quelle
Ich habe gerade diesen Code erstellt, der "this.altura" von einer negativen in eine positive Zahl umwandelt. Hoffe das hilft jemandem in Not
quelle
Sie können die Funktion Math.abs (Nummer) verwenden. Es wird eine positive Zahl zurückgegeben.
quelle
MIN_VALUE
0