The hexadecimal number "FBD626CC4961A4FC"
, converted to decimal, is exactly 18146734407382312188
. That number is indeed larger than the maximum possible long
, defined as Long.MAX_VALUE
and which is equal to 263-1, or 9223372036854775807
:
System.out.println(new BigInteger("FBD626CC4961A4FC", 16)); // 18146734407382312188
System.out.println(Long.MAX_VALUE); // 9223372036854775807
As such, it's normal that you get back a negative number.
You do not have an exception, as it is exactly the purpose of those new *Unsigned*
methods added in Java 8, to give the ability to handle unsigned longs (like compareUnsigned
or divideUnsigned
). Since the type long
in Java is still unsigned, those methods work by understanding negative values as values greater than MAX_VALUE
: it simulates an unsigned long. parseUnsignedLong
says:
An unsigned integer maps the values usually associated with negative numbers to positive numbers larger than MAX_VALUE
.
If you print a long
that was the result of parseUnsignedLong
, and it is negative, all it means is that the value is greater than the max long value as defined by the language, but that methods taking unsigned longs as parameter will correctly interpret those values, as if they were greater than the max value. As such, instead of printing it directly, if you pass that number to toUnsignedString
, you'll get the right output, like shown in this other answer. Not all of these methods are new to Java 8, for example toHexString
also interprets the given long
as an unsigned long in base 16, and printing Long.toHexString(Long.parseUnsignedLong("FBD626CC4961A4FC", 16))
will give you back the right hex String.
parseUnsignedLong
will throw an exception only when the value cannot be represented as an unsigned long, i.e. not a number at all, or greater than 264-1 (and not 263-1 which is the maximum value for a signed long).