Bug in Long.parseUnsignedLong

Paul Sandoz paul.sandoz at oracle.com
Thu Dec 19 17:36:12 UTC 2013


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 <lowasser at 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 <lowasser at 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



More information about the core-libs-dev mailing list