What I want to do is storing a 64-bit unsigned integer as a Long
type, preserving its interval binary representation.
For example, I want to save
2^63-1 = 9223372036854775807 as it is (9223372036854775807) (∵ 2^63-1 <= Long.MAX_VALUE)
and
2^63 = 9223372036854775808 = 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000(2) as -9223372036854775808
because 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000(2) is -9223372036854775808's binary representation for the signed 64-bit integer type.
Likewise, I want to save 2^64-1 = 18446744073709551615 as -1
because (unsigned) 18446744073709551615 = 0xFFFFFFFFFFFFFFFF and (signed long) -1 = 0xFFFFFFFFFFFFFFFF
JavaDoc for BigInteger.longValue()
says that
Converts this BigInteger to a long. This conversion is analogous to a narrowing primitive conversion from long to int as defined in section 5.1.3 of The Java™ Language Specification: if this BigInteger is too big to fit in a long, only the low-order 64 bits are returned. Note that this conversion can lose information about the overall magnitude of the BigInteger value as well as return a result with the opposite sign.
However, I am not sure it is guaranteed to work as I intended.
Will BigInteger(string).longValue()
be enough for my purpose where string
is the string representation of the original integer?
Update: I am using JDK 1.7, so Long.parseUnsignedLong()
is not available.
In this case, I would just run the code and see what happens.
println(new BigInteger("2").pow(63).longValue());
println(new BigInteger("2").pow(63).subtract(new BigInteger("1")).longValue());
println(new BigInteger("2").pow(64).longValue());
println(new BigInteger("2").pow(64).subtract(new BigInteger("1")).longValue());
Outputs
-9223372036854775808
9223372036854775807
0
-1
So yes, BigInteger.longValue() does exactly what you think it does (and according to the reading of the docs, this is the guaranteed behavior. AKA, it is converted to a bit array, and only the low 64 bits are kept and used as long value, ignoring the fact that the 64'th bit is actually the sign bit).