JDK-8021203 : BigInteger.doubleValue/floatValue returns 0.0 instead of Infinity
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.math
  • Affected Version: 8
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux_ubuntu
  • Submitted: 2013-07-23
  • Updated: 2014-01-06
  • Resolved: 2013-10-31
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8 b115Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version  " 1.8.0-ea " 
Java(TM) SE Runtime Environment (build 1.8.0-ea-b99)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b41, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux kisa 3.8.0-26-generic #38-Ubuntu SMP Mon Jun 17 21:43:33 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
Now it easy to create a BigInteger object so large that its methods work incorrectly.
This bug report is about methods BigInteger.doubleValue() and BigInteger.floatValue().
They may return <0.0> on such an object,
I expect that either they return <Infinity> or construction of such an object throws ArithemticException.

This bug is related to
JDK-8011942 : BigInteger returns an int for bitLength()
JDK-6910473 : java.math.BigInteger.bitLength() may return negative  " int "  on large numbers


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile attached test code and run it.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
ArithmeticException in shiftLeft method

or

bi.floatValue() = Infinity
bi.doubleValue() = Infinity

ACTUAL -
bi.floatValue() = 0.0
bi.doubleValue() = 0.0


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class DoubleValueTest {
    
    public static void main(String[] args) {
        BigInteger bi = BigInteger.valueOf(2).shiftLeft(Integer.MAX_VALUE);
        System.out.println( " bi.floatValue() =  "  + bi.floatValue());
        System.out.println( " bi.doubleValue() =  "  + bi.doubleValue());
    }
    
}

---------- END SOURCE ----------
Comments
This error is the proximate result of overflow in calculating the int-valued exponent in floatValue() and doubleValue(). Promoting the calculation to use a long solves this particular limitation.
24-07-2013

There is a definite finite value so large in magnitude that all greater values will round to infinity if the value is converted to double. Offhand, is is numerically equal to something like Double.MAX_VALUE + 0.5*Math.ulp(Double.MAX_VALUE). (Note that this sum is done is exact arithmetic rather than double floating-point arithmetic.) In any case, given such a bound, any greater value can have a fast-track to rounding to infinity.
23-07-2013