Java-Äquivalent von unsigned long long?

106

In C ++ hatte ich gerne Zugriff auf eine 64-Bit-Ganzzahl ohne Vorzeichen, via unsigned long long intoder viauint64_t . In Java sind Longs 64 Bit, ich weiß. Sie sind jedoch signiert.

Gibt es ein vorzeichenloses Long (Long) als Java-Grundelement? Wie benutze ich es?

elf81
quelle
4
HINWEIS Die akzeptierte Antwort ist ab Java 8 und höher veraltet. In der Antwort von GigaStore finden Sie die neue Funktion, mit der Sie Java bitten können, eine Nummer als nicht signiert zu betrachten. Nicht für den täglichen Gebrauch, aber praktisch, wenn Sie es brauchen.
Basil Bourque

Antworten:

55

Ich glaube nicht. Wenn Sie einmal größer als ein signiertes Long werden möchten, ist BigInteger meiner Meinung nach der einzige (sofort einsatzbereite ) Weg.

Sean Bright
quelle
17
Diese Antwort ist etwas veraltet (sie wurde 2009 veröffentlicht). Ab Java 8 (veröffentlicht im März 2014) wird unsigned long unterstützt. Überprüfen Sie ein Beispiel, das ich unten als Antwort gepostet habe.
Amr
140

Ab Java 8 wird vorzeichenloses Long (vorzeichenloses 64-Bit) unterstützt. Sie können es folgendermaßen verwenden:

Long l1 = Long.parseUnsignedLong("17916881237904312345");

Um es zu drucken, können Sie nicht einfach l1 drucken, sondern müssen zuerst:

String l1Str = Long.toUnsignedString(l1)

Dann

System.out.println(l1Str);
Amr
quelle
@ j10, Long ul1 = Long.parseUnsignedLong(objScannerInstance.next("\\d+"));Nicht gerade elegant, da es keine Bereichsprüfung gibt, aber Sie können lange numerische Eingaben eingeben, die andernfalls den Bereich eines vorzeichenbehafteten Longs überschreiten könnten. (Nutzt die Tatsache, dass Scanner::next(...)auch ein Musterobjekt oder ein Zeichenkettenmuster akzeptiert werden kann.)
Spencer D
es ist schwierig.
Alex78191
12

Nein, das gibt es nicht. Sie müssen den primitiven longDatentyp verwenden und sich mit Signaturproblemen befassen oder eine Klasse wie z BigInteger.

Adam Rosenfield
quelle
7

Nein, gibt es nicht. Die Designer von Java geben bekannt, dass sie nicht signierte Ints nicht mochten. Verwenden Sie stattdessen eine BigInteger . Siehe diese Frage für Details.

Paul Tomblin
quelle
22
Ich respektiere Gosling für das, was er getan hat, aber ich denke, seine Verteidigung gegen nicht unterschriebene Ints ist eine der dümmsten Ausreden, die ich je gehört habe. :-) Wir haben in Java mehr wackelige Dinge als nicht signierte Ints ... :-)
Brian Knoblauch
1
Gosling auf JavaPolis 2007 gab ein Beispiel, das verwirrenderweise nicht für vorzeichenlose Ints funktioniert. Josh Bloch wies darauf hin, dass es auch für signierte Ints nicht funktioniert. Ganzzahlen beliebiger Größe ftw!
Tom Hawtin - Tackline
2
@PP.: Ich denke nicht, dass es möglich ist, sinnvolle Regeln zu definieren, die eine freie Interaktion zwischen signierten und nicht signierten Typen ermöglichen, wenn mindestens einer von ihnen das Umbruchverhalten definiert hat. Allerdings hätte ein vorzeichenloses Byte oder ein vorzeichenloser Kurzschluss keine Probleme verursacht , da Bytes ohnehin nicht mit anderen Typen interagieren. Ein größeres Problem besteht darin, das Umhüllungsverhalten für Typen zu definieren, die zur Darstellung von Zahlen verwendet werden , im Gegensatz zu separaten Umhüllungstypen für die seltenen Fälle (wie Hashcode-Berechnungen), in denen das Umhüllungsverhalten tatsächlich nützlich ist.
Supercat
3
@PP.: Ich wünschte, Sprachdesigner würden erkennen, wie wichtig es ist, Zahlen von algebraischen Ringen zu unterscheiden (was "umhüllende Ganzzahl" -Typen sind). Jede Größenzahl sollte implizit in einen Ring mit beliebiger Größe konvertiert werden, aber Ringe sollten nur über eine Funktion oder durch explizite Typumwandlung in dieselbe Größennummer in Zahlen konvertiert werden . Das Verhalten von C, bei dem sich vorzeichenlose Typen im Allgemeinen als algebraische Ringe, manchmal aber auch als Zahlen verhalten, ist wahrscheinlich die schlechteste aller möglichen Welten. Ich kann Gosling nicht vorwerfen, dass er das vermeiden wollte, obwohl er dafür völlig falsch vorgegangen ist.
Supercat
6

Java 8 bietet eine Reihe von vorzeichenlosen Long-Operationen, mit denen Sie diese Long-Variablen direkt als vorzeichenlose Long-Variablen behandeln können. Hier sind einige häufig verwendete:

Additionen, Subtraktionen und Multiplikationen sind für vorzeichenbehaftete und vorzeichenlose Longs gleich.

Kielar
quelle
2
Ein kurzer Blick in den Quellcode zeigt mir, dass ich mit diesen Methoden etwas vorsichtig sein muss. Wenn die Longs tatsächlich negativ sind (dh es gibt einen Unterschied zum vorzeichenbehafteten Fall), wird die BigInteger-Klasse verwendet. Dies bedeutet, dass bis zu 8 neue BigInteger zugewiesen werden. Dies ist eine Menge und definitiv ein Leistungsabfall.
Toonijn
4

Abhängig von den Operationen, die Sie ausführen möchten, ist das Ergebnis ähnlich, signiert oder nicht signiert. Wenn Sie jedoch keine trivialen Operationen verwenden, wird BigInteger verwendet.

Peter Lawrey
quelle
4

Für unsigned long können Sie die UnsignedLong- Klasse aus der Guava-Bibliothek verwenden :

Es unterstützt verschiedene Operationen:

  • Plus
  • Minus
  • mal
  • mod
  • geteilt durch

Das, was im Moment zu fehlen scheint, sind Byte-Shift-Operatoren. Wenn Sie diese benötigen, können Sie BigInteger von Java aus verwenden.

Andrejs
quelle
3

Java hat keine vorzeichenlosen Typen. Erhöhen Sie, wie bereits erwähnt, den Overhead von BigInteger oder verwenden Sie JNI, um auf nativen Code zuzugreifen.

Basszero
quelle
15
char ist ein vorzeichenloser 16-Bit-Wert;)
Peter Lawrey
2

Das Paket org.apache.axis.types enthält a

UnsignedLong-Klasse.

für maven:

<dependency>
    <groupId>org.apache.axis</groupId>
    <artifactId>axis</artifactId>
    <version>1.4</version>
</dependency>
user637338
quelle
0

Es scheint, als ob in Java 8 einige Methoden zu Long hinzugefügt wurden , um altes Gut [signiert] als nicht signiert zu behandeln. Scheint eine Problemumgehung zu sein, kann aber manchmal helfen.

Mikalai Sabel
quelle