目前,我使用的是有符号值,-2 ^ 63到2 ^ 63-1。现在我需要相同的范围(2 * 2 ^ 64),但只有正值。我发现java文档提到了unsigned long,它适合这种用法。
我试图将2 ^ 64声明为一个Long包装器对象,但它仍然丢失数据,换句话说,它只捕获到Long.MAX_VALUE
,所以我显然遗漏了一些东西。 BigInteger
是Java支持的签名长吗?
是否有关于如何声明和使用它的定义或指针?
Java没有unsigned long类型,但是如果你小心的话,可以将带符号的64位二进制补码整数(即long
)视为无符号。
许多原始整数运算是“符号不可知的”;例如你可以使用Java原语加法,减法和乘法,并获得使用long
表示的无符号数的“正确”答案。
对于除法和比较之类的其他操作,Long
类提供了类似divideUnsigned
和compareUnsigned
的方法,它将为表示为long
值的无符号数给出正确的结果。
(这些操作是在Java 8中添加的。在此之前,您可以使用第三方库,例如Guava;例如com.google.common.primitives.UnsignedLongs
中的静态方法。)
在Java 8中,引入了unsigned long
支持。尽管如此,这些都是典型的多头,但这个标志不会影响加减。对于划分和比较,您在Long
中有专门的方法。此外,您可以执行以下操作:
long l1 = Long.parseUnsignedLong("12345678901234567890");
String l1Str = Long.toUnsignedString(l1)
BigInteger
有点不同。它可以保持庞大的数字。它将它们存储为int[]
并支持算术。
如果使用第三方库是一个选项,则有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
。在您的情况下,早期版本的jOOU只是将unsigned long值存储在BigInteger
中。版本0.9.3做了一些很酷的位移,以适应普通的long
中的值。
(免责声明:我为这些图书馆背后的公司工作)