Unsigned long in Java

蓝咒 提交于 2021-01-26 03:06:20

问题


Currently, I am using signed values, -2^63 to 2^63-1. Now I need the same range (2 * 2^64), but with positive values only. I found the java documentations mentioning unsigned long, which suits this use.

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. Is BigInteger the signed long that Java supports?

Is there a definition or pointer as to how to declare and use it?


回答1:


In Java 8, unsigned long support was introduced. Still, these are typical longs, but the sign doesn't affect adding and subtracting. For dividing and comparing, you have dedicated methods in Long. Also, you can do the following:

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

BigInteger is a bit different. It can keep huge numbers. It stores them as int[] and supports arithmetic.




回答2:


Although Java has no unsigned long type, you can treat signed 64-bit two's-complement integers (i.e. long values) as unsigned if you are careful about it.

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.

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.

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. For example, the static methods in the Guava UnsignedLongs class.


Is BigInteger the signed long that Java supports?

BigInteger would be another way to represent integer values greater that Long.MAX_VALUE. But BigInteger is a heavy-weight class. It is unnecessary if your numbers all fall within the range 0 to 264 - 1 (inclusive).




回答3:


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.

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. In your case, earlier versions of jOOU simply stored the unsigned long value in a BigInteger. Version 0.9.3 does some cool bit shifting to fit the value in an ordinary long.

(Disclaimer: I work for the company behind these libraries)



来源:https://stackoverflow.com/questions/44413304/unsigned-long-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!