Czy istnieje sposób na zadeklarowanie niepodpisanej int w Javie?
Albo pytanie może zostać sformułowane w ten sposób: Co to jest odpowiednik Java bez znaku?
Żeby powiedzieć kontekst, w którym patrzyłem na implementację Javy String.hashcode()
. Chciałem przetestować możliwość kolizji, gdyby liczba całkowita wynosiła 32 bez znaku int.
>>>
operatora zamiast>>
.Odpowiedzi:
Java nie ma typu danych dla liczb całkowitych bez znaku .
Możesz zdefiniować
long
zamiast,int
jeśli chcesz przechowywać duże wartości.Możesz także użyć podpisanej liczby całkowitej, tak jakby była niepodpisana. Zaletą reprezentacji uzupełnienia dwóch jest to, że większość operacji (takich jak dodawanie, odejmowanie, mnożenie i przesunięcie w lewo) jest identyczna na poziomie binarnym dla liczb całkowitych ze znakiem i bez znaku. Kilka operacji (podział, przesunięcie w prawo, porównanie i rzutowanie) są jednak różne. Począwszy od Java SE 8, nowe metody w
Integer
klasie pozwalają w pełni wykorzystaćint
typ danych do wykonania arytmetyki bez znaku :Zauważ, że
int
zmienne są nadal podpisywane, gdy są deklarowane, ale arytmetyka bez znaku jest teraz możliwa przy użyciu tych metod wInteger
klasie.źródło
int
typu danych do reprezentowania 32-bitowej liczby całkowitej bez znaku, która ma minimalną wartość0
i maksymalną wartość2^32-1
. - patrz docs.oracle.com/javase/tutorial/java/nutsandbolts/… i docs.oracle.com/javase/8/docs/api/java/lang/Integer.htmlint
tak, jakby były niepodpisane przy użyciu różnych metod.W Javie 8 jest API dla niepodpisanych liczb całkowitych i długich!
źródło
Integer
klasa w Javie 8 pozwala na użycie unsigned int, jest różnica między samą przestrzenią a szybkością (ponieważ w C / C ++ są one prymitywne, podczas gdy w Javie jest to opakowanie na cały obiekt)int
, nawet jeśli są podpisane. Jest to C / C ++, w którym niepodpisany przechodzi, ale podpis powoduje „Niezdefiniowane zachowanie” przy przepełnieniu. Jeśli „przewracanie” jest Twoim jedynym zmartwieniem, nie potrzebujesz niepodpisanego. Myślę, że dlatego procedury CRC itp. Działają w Javie bez dodatkowych wysiłków. I dlatego nowy interfejs API dodaje tylko parsowanie, formatowanie, porównania, dzielenie i resztę. Wszystkie inne operacje, a mianowicie manipulacje bitami, ale także dodawanie, odejmowanie, mnożenie itd. I tak robią właściwą rzecz.To, czy wartość w int jest podpisana, czy niepodpisana, zależy od sposobu interpretacji bitów - Java interpretuje bity jako wartość podpisaną (nie ma prymitywów bez znaku).
Jeśli masz liczbę całkowitą, którą chcesz interpretować jako wartość bez znaku (np. Czytasz liczbę całkowitą z DataInputStream, o której wiesz, że zawiera wartość bez znaku), możesz wykonać następującą sztuczkę.
Zauważ, że ważne jest, aby literał szesnastkowy był długim literałem, a nie literałem int - stąd „l” na końcu.
źródło
0xFFFFFF
i zachować int?Potrzebowaliśmy numery niepodpisane modelować MySQL niepodpisane
TINYINT
,SMALLINT
,INT
,BIGINT
w jOOQ , dlatego stworzyliśmy jOOU , minimalistyczny oferty biblioteki otoki typów dla niepodpisanych liczb całkowitych w Javie. Przykład:Wszystkie te typy rozszerzają się
java.lang.Number
i można je przekształcić w typy pierwotne wyższego rzędu iBigInteger
. Mam nadzieję że to pomoże.(Zastrzeżenie: Pracuję dla firmy stojącej za tymi bibliotekami)
źródło
W przypadku liczb bez znaku możesz użyć tych klas z biblioteki Guava :
Obsługują różne operacje:
W tej chwili wydaje się, że brakuje operatorów zmiany bajtów. Jeśli potrzebujesz, możesz użyć BigInteger z Java.
źródło
Użyj
char
dla 16-bitowych liczb całkowitych bez znaku.źródło
Być może o to ci chodziło?
getUnsigned(0)
→ 0getUnsigned(1)
→ 1getUnsigned(Integer.MAX_VALUE)
→ 2147483647getUnsigned(Integer.MIN_VALUE)
→ 2147483648getUnsigned(Integer.MIN_VALUE + 1)
→ 2147483649źródło
2 * (long) Integer.MAX_VALUE + 2
łatwiej to zrozumieć niż0x1_0000_0000L
? W związku z tym, dlaczego nie po prostureturn signed & 0xFFFF_FFFFL;
?Wygląda na to, że możesz poradzić sobie z problemem podpisywania, wykonując „logiczne AND” na wartościach przed ich użyciem:
Przykład (wartość
byte[]
header[0]
is0x86
):Wynik:
źródło
Tutaj są dobre odpowiedzi, ale nie widzę żadnych demonstracji operacji bitowych. Jak mówi Visser (obecnie akceptowana odpowiedź), Java domyślnie podpisuje liczby całkowite (Java 8 ma liczby całkowite bez znaku, ale nigdy ich nie używałem). Bez zbędnych ceregieli, zróbmy to ...
Przykład RFC 868
Co się stanie, jeśli będziesz musiał zapisać liczbę całkowitą bez znaku w IO? Praktycznym przykładem jest, gdy chcesz wyprowadzić czas zgodnie z RFC 868 . Wymaga to 32-bitowej, dużej liczby całkowitej bez znaku, która koduje liczbę sekund od 00:00 1 stycznia 1900 roku. Jak byś to zakodował?
Stwórz własną 32-bitową liczbę całkowitą bez znaku:
Deklaracja tablicy bajtów 4 bajtów (32 bity)
To inicjuje tablicę, patrz Czy tablice bajtów są inicjowane na zero w Javie? . Teraz musisz wypełnić każdy bajt w tablicy informacjami w kolejności big-endian (lub little-endian, jeśli chcesz zniszczyć spustoszenie). Zakładając, że masz długi zawierający czas (długie liczby całkowite w Javie mają 64 bity)
secondsSince1900
(który wykorzystuje tylko pierwsze 32 bity, a ty poradziłeś sobie z faktem, że data odnosi się do godziny 12:00 1 stycznia 1970), to możesz użyć logicznego AND do wydobycia z niego bitów i przesunięcia tych bitów na pozycje (cyfry), które nie zostaną zignorowane, gdy zostaną wprowadzone w Bajt, w kolejności big-endian.Nasz
my32BitUnsignedInteger
jest teraz równoważny z niepodpisaną 32-bitową liczbą całkowitą big-endian, która jest zgodna ze standardem RCF 868. Tak, długi typ danych jest podpisany, ale zignorowaliśmy ten fakt, ponieważ założyliśmy, że secondSince1900 używał tylko niższych 32 bitów). Z powodu przekształcenia długiego w bajt wszystkie bity większe niż 2 ^ 7 (pierwsze dwie cyfry w kodzie szesnastkowym) zostaną zignorowane.Źródło odniesienia: Java Network Programming, 4th Edition.
źródło
Właśnie utworzyłem ten fragment kodu, który konwertuje „this.altura” z liczby ujemnej na dodatnią. Mam nadzieję, że to pomaga komuś w potrzebie
źródło
Możesz użyć funkcji Math.abs (liczba). Zwraca liczbę dodatnią.
źródło
MIN_VALUE
0