Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6910473

java.math.BigInteger.bitLength() may return negative "int" on large numbers

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P3
    • 8
    • 6u16
    • core-libs
    • b115
    • x86
    • solaris_nevada
    • Verified

    Description

      FULL PRODUCT VERSION :
      java version "1.6.0_16"
      Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
      Java HotSpot(TM) Server VM (build 14.2-b01, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      SunOS opteron 5.11 snv_125 i86pc i386 i86pc


      A DESCRIPTION OF THE PROBLEM :
      It is possible to create BigInteger so large that its bit length larger than Integer.MAX_VALUE. In these case bitLength() method returns negative "int" value and toByteArray() method crashes.

      IMHO, the range of possible BigInteger values should be limited either to a range
      [-2^Integer.MAX_VALUE,2^Integer.MAX_VALUE-1] with bit length <= Integer.MAX_VALUE
      or to a symmetrical range
      [-2^Integer.MAX_VALUE+1,2^Integer.MAX_VALUE-1].

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1) Save "Source code for an executable test case" as TestLargeBigInteger.java
      2) javac TestLargeBigInteger.java
      3) java TestLargeBigInteger

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I expect ArithmeticExceptionon when the result of shiftLeft() method is out of suggested BigInteger range.
      --------------------
      Exception in thread "main" java.lang.ArithmeticException: BigInteger overflow
              at java_math.BigInteger.<init>(BigInteger.java:949)
              at java_math.BigInteger.shiftLeft(BigInteger.java:2129)
              at TestLargeBigInteger.main(TestLargeBigInteger.java:6)

      ACTUAL -
      The bitLength() method returns negative result and toByteArray method throws an exception.
      -------------------------
      bitLength=-2147483648
      java.lang.NegativeArraySizeException
      at java.math.BigInteger.toByteArray(BigInteger.java:2667)
      at TestLargeBigInteger.main(TestLargeBigInteger.java:9)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.math.BigInteger;

      public class TestLargeBigInteger {
          public static void main(String[] args) {

              BigInteger x = BigInteger.ONE.shiftLeft(Integer.MAX_VALUE); // x = 2^Integer.MAX_VALUE;
              System.out.println("bitLength="+x.bitLength());
              try {
                  byte[] bytes = x.toByteArray();
              } catch (Exception e) {
                  e.printStackTrace(System.out);
              }
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      I am preparing a fix and a test for this bug:

      http://kenai.com/projects/rigorousnum/sources/java_math/content/trunk/java_math/src/java_math/BigInteger.java?rev=17
      http://kenai.com/projects/rigorousnum/sources/java_math/content/trunk/BigIntegerTests/src/HugeValues.java?rev=17
      http://kenai.com/projects/rigorousnum/sources/java_math/content/trunk/BigIntegerTests/src/ExtremeShiftingTests.java?rev=17

      However I'm going to test more before I submit a WebRev.

      Attachments

        Issue Links

          Activity

            People

              bpb Brian Burkhalter
              ndcosta Nelson Dcosta (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: