在Oracle" Primitive数据类型" page,它提到Java 8增加了对无符号整数和长整数的支持:
int
:默认情况下,int
数据类型是32位带符号的二进制补码整数,其最小值为-2 31 最大值为2 31 -1。 在Java SE 8及更高版本中,您可以使用int
数据类型来表示无符号的32位整数,其最小值为0,最大值为2 32 -1。使用Integer
类将int
数据类型用作无符号整数。有关更多信息,请参阅数字类一节。compareUnsigned
类中添加了divideUnsigned
,Integer
等静态方法,以支持无符号整数的算术运算。
long
:long
数据类型是64位二进制补码整数。带符号long
的最小值为-2 63 ,最大值为2 63 -1。 在Java SE 8及更高版本中,您可以使用long
数据类型来表示无符号的64位long
,其最小值为0,最大值为2 64 -1。当您需要的值范围比int提供的值更宽时,请使用此数据类型。Long
类还包含compareUnsigned
,divideUnsigned
等方法,以支持无符号long
的算术运算。
但是,我发现无法声明无符号长整数或整数。例如,下面的代码给出了编译器错误消息"文字超出了范围" (我当然使用Java 8),当它应该在范围内时(指定的值恰好为2 64 -1):
public class Foo {
static long values = 18446744073709551615L;
public static void main(String[] args){
System.out.println(values);
}
}
那么,有没有办法声明unsigned int或long?
答案 0 :(得分:81)
好吧,即使在Java 8中,long
和int
仍然是签名的,只有一些方法将它们视为未签名。如果你想写这样的无符号long
字面,你可以做
static long values = Long.parseUnsignedLong("18446744073709551615");
public static void main(String[] args) {
System.out.println(values); // -1
System.out.println(Long.toUnsignedString(values)); // 18446744073709551615
}
答案 1 :(得分:46)
根据您发布的文档和this blog post - 在声明unsigned int / long和signed符号之间的原语时没有区别。 “新支持”是在Integer和Long类中添加静态方法,例如Integer.divideUnsigned。如果你没有使用这些方法,那么长于2 ^ 63-1的“无符号”只是一个带有负值的普通旧长度。
从快速浏览,看起来似乎没有办法在+/- 2 ^ 31-1或+/- 2 ^ 63-1之外的范围内声明整数常量。您必须手动计算与超出范围正值相对应的负值。
答案 2 :(得分:23)
// 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
*/
答案 3 :(得分:17)
如何在Java 8或Java 9中声明 unsigned long or int。但有些方法将它们视为无符号,例如:
static long values = Long.parseUnsignedLong("123456789012345678");
但这不是变量的declaration。
答案 4 :(得分:3)
如果使用第三方库是一个选项,则有jOOU(来自jOOQ的衍生库),它为Java中的无符号整数提供包装类型。这与原始类型(以及字节代码)支持无符号类型并不完全相同,但对于您的用例而言它可能仍然足够好。
import static org.joou.Unsigned.*;
// and then...
UByte b = ubyte(1);
UShort s = ushort(1);
UInteger i = uint(1);
ULong l = ulong(1);
所有这些类型都扩展为java.lang.Number
,可以转换为更高阶的基元类型和BigInteger
。
(免责声明:我为这些图书馆背后的公司工作)