问题
Java 8 is widely reported to have library support for unsigned integers. However, there seem to be no articles explaining how to use it and how much is possible.
Some functions like Integer.CompareUnsigned are easy enough to find and seem to do what one would expect. However, I fail to write even a simple loop that loops over all powers of two within the range of unsigned long.
int i = 0;
for(long l=1; (Long.compareUnsigned(l, Long.MAX_VALUE*2) < 0) && i<100; l+=l) {
System.out.println(l);
i++;
}
produces the output
1
2
4
8
...
1152921504606846976
2305843009213693952
4611686018427387904
-9223372036854775808
0
0
0
...
0
Am I missing something or are external libraries still required for this simple task?
回答1:
If you're referring to
(Long.compareUnsigned(l, Long.MAX_VALUE*2) < 0)
l
reaches
-9223372036854775808
unsigned it is
9223372036854775808
and
Long.MAX_VALUE*2
is
18446744073709551614
So l
is smaller than Long.MAX_VALUE*2
in the unsigned world.
Assuming you're asking about the 0's
0
0
0
...
0
the problem (if you see it that way) is that, for long
(other numerical primitives), the first bit is the sign bit.
so
10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
is
-9223372036854775808
When you do
-9223372036854775808 + -9223372036854775808
you underflow (overflow?) since
10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+ 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
is
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
which is 0. On later loop iterations, 0 + 0
remains 0
.
回答2:
The only problem here is that you're printing l
as a signed integer. You can use Integer.toUnsignedString to get the results you're expecting:
int i = 0;
byte[] tmp = new byte[9];
for(int l=1; (Long.compareUnsigned(l, Long.MAX_VALUE*2) < 0) && i<100; l+=l) {
System.out.println(Integer.toUsignedString(l)); // <== MODIFIED THIS LINE
i++;
}
来源:https://stackoverflow.com/questions/22903669/java8-unsigned-arithmetic