如何在 Java 8 和 Java 9 中使用无符号整数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25556017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use the unsigned Integer in Java 8 and Java 9?
提问by Pabce
In the Oracle "Primitive data types" page, it mentions that Java 8 adds support for unsigned ints and longs:
在 Oracle "Primitive data types" page 中,它提到 Java 8 添加了对无符号整数和长整数的支持:
int
: By default, theint
data type is a 32-bit signed two's complement integer, which has a minimum value of ?231and a maximum value of 231?1. In Java SE 8 and later, you can use theint
data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 232?1.Use theInteger
class to useint
data type as an unsigned integer. See the section The Number Classes for more information. Static methods likecompareUnsigned
,divideUnsigned
etc have been added to theInteger
class to support the arithmetic operations for unsigned integers.
long
: Thelong
data type is a 64-bit two's complement integer. The signedlong
has a minimum value of ?263and a maximum value of 263?1. In Java SE 8 and later, you can use thelong
data type to represent an unsigned 64-bitlong
, which has a minimum value of 0 and a maximum value of 264?1.Use this data type when you need a range of values wider than those provided by int. TheLong
class also contains methods likecompareUnsigned
,divideUnsigned
etc to support arithmetic operations for unsignedlong
.
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
。
However, I find no way to declare an unsigned long or integer. The following code, for example, gives a compiler error message of "the literal is out of range" (I'm using Java 8, of course), when it should be in range (the value assigned is precisely 264?1):
但是,我找不到声明无符号长整数或整数的方法。例如,以下代码给出了“文字超出范围”的编译器错误消息(当然,我使用的是 Java 8),当它应该在范围内时(分配的值正好是 2 64?1) :
public class Foo {
static long values = 18446744073709551615L;
public static void main(String[] args){
System.out.println(values);
}
}
So, is there any way to declare an unsigned int or long?
那么,有没有办法声明一个 unsigned int 或 long?
采纳答案by Sbodd
Per the documentation you posted, and this blog post- there's no difference when declaring the primitive between an unsigned int/long and a signed one. The "new support" is the addition of the static methods in the Integer and Long classes, e.g. Integer.divideUnsigned. If you're not using those methods, your "unsigned" long above 2^63-1 is just a plain old long with a negative value.
根据您发布的文档和这篇博客文章- 在 unsigned int/long 和有符号整数之间声明原语时没有区别。“新支持”是在 Integer 和 Long 类中添加静态方法,例如Integer.divideUnsigned。如果您不使用这些方法,则高于 2^63-1 的“无符号”long 只是一个带有负值的普通旧 long。
From a quick skim, it doesn't look like there's a way to declare integer constants in the range outside of +/- 2^31-1, or +/- 2^63-1 for longs. You would have to manually compute the negative value corresponding to your out-of-range positive value.
从快速浏览来看,似乎没有办法在 +/- 2^31-1 或 +/- 2^63-1 以外的范围内声明整数常量。您必须手动计算与超出范围的正值相对应的负值。
回答by kajacx
Well, even in Java 8, long
and int
are still signed, only some methods treat them as if they were unsigned. If you want to write unsigned long
literal like that, you can do
好吧,即使在 Java 8 中,long
并且int
仍然是有符号的,只有一些方法将它们视为 unsigned。如果你想写这样的无符号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
}
回答by 1ac0
There is no way how to declarean unsigned long or intin Java 8 or Java 9. But some methods treat them as if they were unsigned, for example:
有没有办法如何来声明一个无符号长或者int在Java中8或Java 9.但有些方法对待他们,好像他们是无符号,例如:
static long values = Long.parseUnsignedLong("123456789012345678");
but this is not declarationof the variable.
但这不是变量的声明。
回答by blueberry0xff
// 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
*/
回答by Lukas Eder
If using a third party library is an option, there is jOOU(a spin off library from jOOQ), which offers wrapper types for unsigned integer numbers in Java. That's not exactly the same thing as having primitive type (and thus byte code) support for unsigned types, but perhaps it's still good enough for your use-case.
如果使用第三方库是一种选择,则有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);
All of these types extend java.lang.Number
and can be converted into higher-order primitive types and BigInteger
.
所有这些类型都扩展java.lang.Number
并可以转换为高阶原始类型和BigInteger
.
(Disclaimer: I work for the company behind these libraries)
(免责声明:我为这些库背后的公司工作)