Java odpowiednik unsigned long long?

106

W C ++ lubiłem mieć dostęp do 64-bitowej liczby całkowitej bez znaku, via unsigned long long intlub via uint64_t. Wiem, że w Javie długie są 64 bity. Jednak są podpisane.

Czy jest dostępny długi (długi) bez znaku jako prymityw Java? Jak tego używam?

jedenaście81
źródło
4
UWAGA Zaakceptowana odpowiedź jest nieaktualna w wersji Java 8 i nowszych. Zobacz odpowiedź GigaStore, aby poznać nową funkcję, w której możesz poprosić Javę, aby traktowała numer jako niepodpisany. Nie do codziennego użytku, ale poręczny, gdy go potrzebujesz.
Basil Bourque,

Odpowiedzi:

55

Nie wierzę w to. Jeśli chcesz osiągnąć więcej niż długi ze znakiem , myślę, że BigInteger jest jedynym (po wyjęciu z pudełka) sposobem.

Sean Bright
źródło
17
Ta odpowiedź jest trochę nieaktualna (została opublikowana w 2009 roku). Począwszy od Java 8 (wydanej w marcu 2014 r.), Dostępna jest obsługa długości bez znaku. Sprawdź przykład, który zamieściłem poniżej jako odpowiedź.
Amr
140

Począwszy od Javy 8, dostępna jest obsługa długości bez znaku (64 bity bez znaku). Sposób, w jaki możesz go używać, to:

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

Aby go wydrukować, nie możesz po prostu wydrukować l1, ale musisz najpierw:

String l1Str = Long.toUnsignedString(l1)

Następnie

System.out.println(l1Str);
Amr
źródło
@ j10, Long ul1 = Long.parseUnsignedLong(objScannerInstance.next("\\d+"));Niezupełnie eleganckie, ponieważ nie ma sprawdzania zakresu, ale pozwoliłoby ci wciągnąć długie wejścia numeryczne, które w przeciwnym razie mogłyby przekroczyć zakres ze znakiem długości. (Wykorzystuje fakt, że Scanner::next(...)może również akceptować obiekt Pattern lub wzór String.)
Spencer D
to jest trudne.
Alex78191
12

Nie, nie ma. Będziesz musiał użyć pierwotnego longtypu danych i zająć się problemami z podpisami lub użyć klasy, takiej jak BigInteger.

Adam Rosenfield
źródło
7

Nie, nie ma. Projektanci Javy twierdzą, że nie lubią niepodpisanych intów. Zamiast tego użyj BigInteger . Zobacz to pytanie, aby uzyskać szczegółowe informacje.

Paul Tomblin
źródło
22
Szanuję Goslinga za to, co zrobił, ale myślę, że jego obrona przed niepodpisanymi intami jest jedną z najgłupszych wymówek, jakie kiedykolwiek słyszałem. :-) Mamy więcej dziwnych rzeczy w Javie niż bez znaku ... :-)
Brian Knoblauch
1
Gosling na JavaPolis 2007 podał przykład, że w mylący sposób nie działa dla niepodpisanych int. Josh Bloch zwrócił uwagę, że to nie działa również w przypadku podpisanych int. Liczby całkowite o dowolnej wielkości ftw!
Tom Hawtin - tackline
2
@PP .: Nie sądzę, aby można było zdefiniować rozsądne reguły, które pozwalają na swobodną interakcję między typami podpisanymi i niepodpisanymi, gdy przynajmniej jeden z nich ma zdefiniowane zachowanie zawijania. Biorąc to zostało powiedziane, unsigned byte lub unsigned short spowodowałby zerowy kłopoty ponieważ bajty nie oddziałują z innymi rodzajami i tak. Większym problemem jest zdefiniowanie zachowania zawijania dla typów, które są używane do reprezentowania liczb , w odróżnieniu od posiadania oddzielnych typów zawijania w tych rzadkich przypadkach (takich jak obliczenia hashcode), gdy zachowanie zawijania jest w rzeczywistości przydatne.
supercat
3
@PP .: Chciałbym, żeby projektanci języka dostrzegli znaczenie rozróżniania liczb od pierścieni algebraicznych (czym są typy „zawijające liczby całkowite”). Każdy numer rozmiaru powinien być niejawnie konwertowany na pierścień dowolnego rozmiaru, ale pierścienie powinny być konwertowane na liczby tylko za pomocą funkcji lub przez jawne rzutowanie typu na ten sam numer rozmiaru . Zachowanie C, gdzie typy bez znaku ogólnie zachowują się jak pierścienie algebraiczne, ale czasami zachowują się jak liczby, jest prawdopodobnie najgorszym ze wszystkich możliwych światów; Nie mogę winić Goslinga, że ​​chciał tego uniknąć, chociaż przyjął to całkowicie niewłaściwe podejście.
supercat,
6

Java 8 udostępnia zestaw długich operacji bez znaku, które pozwalają bezpośrednio traktować te zmienne typu Long jako długie bez znaku. Oto kilka najczęściej używanych:

A dodawanie, odejmowanie i mnożenie jest takie samo dla longów ze znakiem i bez znaku.

keelar
źródło
2
Szybki rzut oka na kod źródłowy podpowiada mi, że przy tych metodach należy zachować ostrożność. Gdy długie są rzeczywiście ujemne (tj. Istnieje różnica w stosunku do przypadku ze znakiem), zostanie użyta klasa BigInteger. Oznacza to, że zostanie przydzielonych do 8 nowych BigIntegers, to całkiem sporo i zdecydowanie spadek wydajności.
Toonijn
4

W zależności od operacji, które zamierzasz wykonać, wynik jest bardzo podobny, podpisany lub niepodpisany. Jednak jeśli nie używasz trywialnych operacji, skończysz na BigInteger.

Peter Lawrey
źródło
4

Przez długi czas bez znaku możesz użyć klasy UnsignedLong z biblioteki Guava :

Obsługuje różne operacje:

  • plus
  • minus
  • czasy
  • mod
  • podzielony przez

W tej chwili wydaje się, że brakuje operatorów przesuwających bajty. Jeśli ich potrzebujesz, możesz użyć BigInteger w Javie.

Andrejs
źródło
3

Java nie ma typów bez znaku. Jak już wspomniano, zwiększ obciążenie BigInteger lub użyj JNI, aby uzyskać dostęp do kodu natywnego.

basszero
źródło
15
char to 16-bitowa wartość bez znaku;)
Peter Lawrey
2

Pakiet org.apache.axis.types ma rozszerzenie

Klasa UnsignedLong.

dla maven:

<dependency>
    <groupId>org.apache.axis</groupId>
    <artifactId>axis</artifactId>
    <version>1.4</version>
</dependency>
user637338
źródło
0

Wygląda na to, że w Javie 8 niektóre metody są dodawane do Long, aby traktować stare dobre [podpisane] jako niepodpisane. Wydaje się, że można obejść ten problem, ale czasami może pomóc.

Mikalai Sabel
źródło