Unsigned int in Java
Java does not have unsigned data types. Your options are:
- Use a
long
- Use an
UnsignedInteger
from Guava - Use an
int
and interpret the bits as unsigned (described below)
An unsigned int
An int
is always signed in Java, but nothing prevents you from viewing an int
simply as 32 bits and interpret those bits as a value between 0 and 264.
Java int value | Bits | Interpreted as unsigned |
---|---|---|
0 | 00000000…00000000 |
0 |
1 | 00000000…00000001 |
1 |
⋮ | ⋮ | ⋮ |
2,147,483,647 | 01111111…11111111 |
2,147,483,647 |
−2,147,483,648 | 10000000…00000000 |
2,147,483,648 |
⋮ | ⋮ | ⋮ |
−2 | 11111111…11111110 |
4,294,967,294 |
−1 | 11111111…11111111 |
4,294,967,295 |
Keep in mind that there’s nothing you can do to force your interpretation upon someone else’s method. If a method accepts a int
, then that method accepts a value between −231 and 231 − 1 unless explicitly stated otherwise.
Here are a couple of useful conversions / manipulations.
Printing an unsigned int
System.out.println("Value of my unsigned int: " + Integer.toUnsignedString(uint));
Converting from long
to unsigned int
Casting to int
throws away all but the lowest 32 bits.
long lng = 2200000000L; // 00000000 ... 00000000 10000011 00100001 01010110 00000000
int i = (int) lng; // 10000011 00100001 01010110 00000000
System.out.println(i); // -2094967296
System.out.println(Integer.toUnsignedString(i)); // 2200000000
Converting from unsigned int
to long
Use Integer.toUnsignedLong
to avoid sign extension.
int i = 0b10000011001000010101011000000000; // -2094967296 or 2200000000
long signed = i; // -2094967296 (with sign extension)
long unsigned = Integer.toUnsignedLong(i); // 2200000000 (without sign extension)
Or, equivalently:
long unsigned = i & 0xffffffffL;
Comparing unsigned int
s
int cmp = Integer.compareUnsigned(i1, i2);
// cmp = -1 => i1 < i2
// cmp = 0 => i1 = i2
// cmp = 1 => 11 > i2
Parsing an unsigned int
int i = Integer.parseUnsignedInt("2200000000");
System.out.println(Integer.toUnsignedString(i)); // 2200000000
Note: Integer.parseInt
would throw a NumberFormatException
for the above input.
Arithmetics
As it happens, the 2-complement representation “just works” for addition, subtraction and multiplication.
// two unsigned ints
int i1 = (int) 2200000000L;
int i2 = 55555;
int sum = i1 + i2; // 2200055555
int diff = i1 - i2; // 2199944445
int prod = i2 * i2; // 3086358025
For division and remainder, use Integer.divideUnsigned
and Integer.remainderUnsigned
:
int q = Integer.divideUnsigned(i1, i2); // 39600
int r = Integer.remainderUnsigned(i1, i2); // 22000