Hi, I think the logic for overflow when using the compareUnsigned is incorrect in Long:
long first = parseLong(s.substring(0, len - 1), radix); int second = Character.digit(s.charAt(len - 1), radix); if (second < 0) { throw new NumberFormatException("Bad digit at end of " + s); } long result = first * radix + second; if (compareUnsigned(result, first) < 0) { Take for example a string representation consisting of 17 digits "12000000000000000" The long that will be parsed is one char less "1200000000000000": first = 0x1200_0000_0000_0000 second = 0; result = 0x2000_0000_0000_0000 // first << 4, result > first i.e. overflow of the overflow if you consider 16 additions, rather than a multiply. My brain is too clogged up with cold at the moment to propose a fix :-( Paul. On Dec 19, 2013, at 12:52 AM, Louis Wasserman <lowas...@google.com> wrote: > Derp. Here is the test case: > > import java.math.BigInteger; > > public class UnsignedLongBug { > public static void main(String[] args) { > try { > String input = "1234567890abcdef1"; > System.out.println(Long.parseUnsignedLong(input, 16)); > BigInteger maxUnsignedLong = > BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE); > BigInteger inputValue = new BigInteger(input, 16); > System.out.println(maxUnsignedLong.compareTo(inputValue)); > throw new AssertionError(); > } catch (NumberFormatException expected) { > System.out.println("Correct"); > } > } > } > > > On Wed, Dec 18, 2013 at 3:51 PM, Louis Wasserman <lowas...@google.com>wrote: > >> The Javadoc of Long.parseUnsignedLong specifies that it should throw a >> NumberFormatException if "the value represented by the string is larger >> than the largest unsigned long, 2^64-1." >> >> This does not appear to be happening: >> >> -- >> Louis Wasserman >> > > > > -- > Louis Wasserman