W Oracle „prymitywnych typów danych” strony , to mówi, że Java 8 dodaje wsparcie dla unsigned int i wyroby długie:
int
: Domyślnieint
typ danych jest 32-bitową uzupełnienie dwójkowe liczbę całkowitą, która ma wartość minimalną -2 31 i wartość maksymalnej ilości 2 31 -1. W Java SE 8, a następnie, można użyćint
typu danych reprezentuje nieoznaczoną 32-bitową liczbę całkowitą, która ma wartość co najmniej 0 i wartości maksimum 2 32 -1. UżyjInteger
klasy, aby użyćint
typu danych jako liczby całkowitej bez znaku. Aby uzyskać więcej informacji, zobacz sekcję Klasy liczbowe. Do klasy dodano metody statyczne, takie jak itp.compareUnsigned
, Aby obsługiwać operacje arytmetyczne na liczbach całkowitych bez znaku.divideUnsigned
Integer
long
: Typlong
danych to 64-bitowa liczba całkowita z uzupełnieniem do dwóch. Podpisanylong
ma wartość minimalną -2 63 i wartość maksymalnej ilości 2 63 -1. W Java SE 8, a następnie, można użyćlong
typu danych reprezentuje nieoznaczoną 64-bitowylong
, który ma minimalną wartość 0, a wartość maksymalna z 2 64 -1. Użyj tego typu danych, gdy potrzebujesz zakresu wartości szerszego niż te podane przez int.Long
Klasa zawiera również metody podobacompareUnsigned
,divideUnsigned
etc w celu wsparcia operacji arytmetycznych na niepodpisanelong
.
Jednak nie znajduję sposobu, aby zadeklarować długość bez znaku lub liczbę całkowitą. Na przykład poniższy kod wyświetla komunikat o błędzie kompilatora „literał jest poza zakresem” (używam oczywiście Java 8), kiedy powinien znajdować się w zakresie (przypisana wartość to dokładnie 2 64 −1) :
public class Foo {
static long values = 18446744073709551615L;
public static void main(String[] args){
System.out.println(values);
}
}
Czy jest więc sposób na zadeklarowanie unsigned int lub long?
Odpowiedzi:
Zgodnie z dokumentacją, którą opublikowałeś, i tym postem na blogu - nie ma różnicy, kiedy deklarujesz prymityw między bez znaku int / long a podpisanym. „Nowa obsługa” to dodanie metod statycznych w klasach Integer i Long, np . Integer.divideUnsigned . Jeśli nie używasz tych metod, twój „unsigned” długo powyżej 2 ^ 63-1 jest zwykłym starym długim z wartością ujemną.
Z szybkiego przeglądu wynika, że nie ma sposobu na zadeklarowanie stałych całkowitych z zakresu poza +/- 2 ^ 31-1 lub +/- 2 ^ 63-1 dla długości. Trzeba by ręcznie obliczyć wartość ujemną odpowiadającą dodatniej wartości spoza zakresu.
źródło
Cóż, nawet w Javie 8
long
iint
nadal są podpisane, tylko niektóre metody traktują je tak, jakby były niepodpisane . Jeśli chcesz pisać bez znakulong
dosłownie w ten sposób, możesz to zrobićstatic long values = Long.parseUnsignedLong("18446744073709551615"); public static void main(String[] args) { System.out.println(values); // -1 System.out.println(Long.toUnsignedString(values)); // 18446744073709551615 }
źródło
// Java 8 int vInt = Integer.parseUnsignedInt("4294967295"); System.out.println(vInt); // -1 String sInt = Integer.toUnsignedString(vInt); System.out.println(sInt); // 4294967295 long vLong = Long.parseUnsignedLong("18446744073709551615"); System.out.println(vLong); // -1 String sLong = Long.toUnsignedString(vLong); System.out.println(sLong); // 18446744073709551615 // Guava 18.0 int vIntGu = UnsignedInts.parseUnsignedInt(UnsignedInteger.MAX_VALUE.toString()); System.out.println(vIntGu); // -1 String sIntGu = UnsignedInts.toString(vIntGu); System.out.println(sIntGu); // 4294967295 long vLongGu = UnsignedLongs.parseUnsignedLong("18446744073709551615"); System.out.println(vLongGu); // -1 String sLongGu = UnsignedLongs.toString(vLongGu); System.out.println(sLongGu); // 18446744073709551615 /** Integer - Max range Signed: From −2,147,483,648 to 2,147,483,647, from −(2^31) to 2^31 – 1 Unsigned: From 0 to 4,294,967,295 which equals 2^32 − 1 Long - Max range Signed: From −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, from −(2^63) to 2^63 − 1 Unsigned: From 0 to 18,446,744,073,709,551,615 which equals 2^64 – 1 */
źródło
Nie ma sposobu, w jaki sposób zadeklarować unsigned long int lub w Java 8 lub Java 9. Ale niektóre sposoby ich traktować tak, jakby były niepodpisany, na przykład:
static long values = Long.parseUnsignedLong("123456789012345678");
ale to nie jest deklaracja zmiennej.
źródło
Jeśli korzystanie z biblioteki innej firmy jest opcją, istnieje jOOU (biblioteka wydzielona z jOOQ ), która oferuje typy opakowań dla liczb całkowitych bez znaku w Javie. To nie jest dokładnie to samo, co posiadanie obsługi typów pierwotnych (a tym samym kodu bajtowego) dla typów bez znaku, ale być może nadal jest wystarczająco dobre dla twojego przypadku użycia.
import static org.joou.Unsigned.*; // and then... UByte b = ubyte(1); UShort s = ushort(1); UInteger i = uint(1); ULong l = ulong(1);
Wszystkie te typy rozszerzają się
java.lang.Number
i można je przekształcić w typy pierwotne wyższego rzędu iBigInteger
.(Zastrzeżenie: pracuję dla firmy stojącej za tymi bibliotekami)
źródło