简体   繁体   English

Java中的无符号长

[英]Unsigned long in Java

Currently, I am using signed values, -2^63 to 2^63-1.目前,我使用的是有符号值,-2^63 到 2^63-1。 Now I need the same range (2 * 2^64), but with positive values only.现在我需要相同的范围 (2 * 2^64),但只有正值。 I found the java documentations mentioning unsigned long, which suits this use.我发现 java 文档提到了 unsigned long,它适合这种用途。

I tried to declare 2^64 to a Long wrapper object, but it still loses the data, in other words, it only captures till the Long.MAX_VALUE , so I am clearly missing something.我试图将 2^64 声明为 Long 包装器对象,但它仍然丢失数据,换句话说,它只捕获到Long.MAX_VALUE ,所以我显然错过了一些东西。 Is BigInteger the signed long that Java supports? BigInteger是 Java 支持的有符号长BigInteger吗?

Is there a definition or pointer as to how to declare and use it?是否有关于如何声明和使用它的定义或指针?

In Java 8, unsigned long support was introduced.在 Java 8 中,引入了unsigned long支持。 Still, these are typical longs, but the sign doesn't affect adding and subtracting.尽管如此,这些都是典型的多头,但符号不影响加法和减法。 For dividing and comparing, you have dedicated methods in Long .对于划分和比较,您在Long有专门的方法。 Also, you can do the following:此外,您可以执行以下操作:

long l1 = Long.parseUnsignedLong("12345678901234567890");
String l1Str = Long.toUnsignedString(l1)

BigInteger is a bit different. BigInteger有点不同。 It can keep huge numbers.它可以保留大量数字。 It stores them as int[] and supports arithmetic.它将它们存储为int[]并支持算术。

Although Java has no unsigned long type, you can treat signed 64-bit two's-complement integers (ie long values) as unsigned if you are careful about it.尽管 Java 没有 unsigned long 类型,但如果小心的话,您可以将有符号的 64 位二进制补码整数(即long值)视为无符号。

Many primitive integer operations are sign agnostic for two's-complement representations.许多原始整数运算对于二进制补码表示是符号不可知的。 For example, you can use Java primitive addition, subtraction and multiplication on an unsigned number represented as a long , and get the "right" answer.例如,您可以对表示为long的无符号数使用 Java 原始加法、减法和乘法,并得到“正确”的答案。

For other operations such as division and comparison, the Long class provides method like divideUnsigned and compareUnsigned that will give the correct results for unsigned numbers represented as long values.对于其他操作,例如除法和比较, Long类提供了像divideUnsignedcompareUnsigned这样的方法,它们将为表示为long值的无符号数提供正确的结果。

The Long methods supporting unsigned operations were added in Java 8. Prior to that, you could use 3rd-party libraries to achieve the same effect.支持无符号操作的Long方法是在 Java 8 中添加的。在此之前,您可以使用第 3 方库来实现相同的效果。 For example, the static methods in the Guava UnsignedLongs class.例如,Guava UnsignedLongs类中的静态方法。


Is BigInteger the signed long that Java supports? BigInteger是 Java 支持的有符号长BigInteger吗?

BigInteger would be another way to represent integer values greater that Long.MAX_VALUE . BigInteger是表示大于Long.MAX_VALUE整数值的另一种方式。 But BigInteger is a heavy-weight class.但是BigInteger是一个重量级的类。 It is unnecessary if your numbers all fall within the range 0 to 2 64 - 1 (inclusive).如果您的数字都在 0 到 2 64 - 1(含)范围内,则没有必要。

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.如果使用第三方库是一种选择,则有jOOU (来自jOOQ的衍生库),它为 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.这与为无符号类型提供原始类型(以及字节码)支持并不完全相同,但对于您的用例来说,它可能仍然足够好。

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 In your case, earlier versions of jOOU simply stored the unsigned long value in a BigInteger .在您的情况下,早期版本的 jOOU 只是将 unsigned long 值存储在BigInteger Version 0.9.3 does some cool bit shifting to fit the value in an ordinary long . 0.9.3 版做了一些很酷的位移来适应普通long的值。

(Disclaimer: I work for the company behind these libraries) (免责声明:我为这些图书馆背后的公司工作)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM