Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unsigned long in Java

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?

like image 382
Annapoorni D Avatar asked Jun 07 '17 12:06

Annapoorni D


People also ask

What are unsigned longs?

Unsigned long is a numeric field type that represents an unsigned 64-bit integer with a minimum value of 0 and a maximum value of 264-1 (from 0 to 18446744073709551615 inclusive).

How do you make a long unsigned?

unsigned provides a few methods to convert a long value to an unsigned value. One of the methods is the valueOf() method that takes a long value. In the program, we create a BigInteger and then in the ULong. valueOf() method, we pass the long value using bigInteger.

What is unsigned in Java?

An unsigned integer can hold a larger positive value, and no negative value like (0 to 255) . Unlike C++ there is no unsigned integer in Java.


3 Answers

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.

like image 170
xenteros Avatar answered Oct 17 '22 18:10

xenteros


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).

like image 22
Stephen C Avatar answered Oct 17 '22 18:10

Stephen C


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)

like image 4
Lukas Eder Avatar answered Oct 17 '22 20:10

Lukas Eder