如何在Java 8和Java 9中使用无符号的Integer?
在Oracle的“Primitive data types” 页面中 ,它提到了Java 8增加了对unsigned int和long的支持:
int
:默认情况下,int
数据types是一个32位有符号的二进制补码整数,其最小值为-2 31 ,最大值为2 31 -1。 在Java SE 8和更高版本中,可以使用int
数据types来表示一个无符号的32位整数,它的最小值为0,最大值为2 32 -1。 使用Integer
类将int
数据types用作无符号整数。 有关更多信息,请参见数字类部分。 像compareUnsigned
,divideUnsigned
等静态方法已被添加到Integer
类来支持无符号整数的算术运算。
long
:long
数据types是一个64位的二进制补码整数。 有符号long
的最小值为-2 63 ,最大值为2 63 -1。 在Java SE 8和更高版本中,可以使用long
数据types来表示无符号的64位long
,其最小值为0,最大值为2 64 -1。 当你需要一个比int提供的值更宽的范围时,使用这个数据types。Long
类还包含像compareUnsigned
,divideUnsigned
等方法来支持无符号long
算术运算。
但是,我发现无法声明一个无符号的long或integer。 例如,下面的代码给出了一个编译器的错误信息:“字面超出范围”(当然我使用的是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吗?
根据你发布的文档和这个博客post ,在unsigned int / long和signed之间声明原语没什么区别。 “新支持”是在Integer和Long类中添加了静态方法,例如Integer.divideUnsigned 。 如果你不使用这些方法,那么长于2 ^ 63-1的“无符号”只是一个普通的长整数,具有负值。
从快速浏览看,似乎没有办法在+/- 2 ^ 31-1或+/- 2 ^ 63-1以外的范围内声明整型常量长时间。 您将不得不手动计算与超出范围正值相对应的负值。
那么,即使在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 }
// 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 */
在Java 8或Java 9中,如何声明 unsigned long或int是没有办法的。但是有些方法把它们看作是无符号的,例如:
static long values = Long.parseUnsignedLong("123456789012345678");
但是这不是variables的声明 。