• Neil Fuller's avatar
    Rewrite tests and add tests that demonstrate a bug · 4e92b626
    Neil Fuller authored
    The bug:
    DecimalFormat.format() behavior is slightly
    lossy around 15 decimal digits even without any
    digit constraints.
    
    This change isolates the test failures that result from
    this bug to 2 test cases:
    
    test_formatDouble_bug17656132
    test_formatDouble_roundingProblemCases
    
    Example of the bug:
    
    Double: 999999999999999.9 is represented as an IEEE 754
    value which is exactly decimal 999999999999999.875
    
    When format(999999999999999.9) is called on a DecimalFormat
    with large MaxIntegerDigit and MaxFractionDigit....
    
    Correct answer: "999999999999999.9"
    Actual answer: "1000000000000000"
    
    By contrast Double.toString() prints 9.999999999999999E14
    for Android and the RI (correctly).
    
    The DecimalFormat is printing to 16 decimal digits: The
    inclusion of the 16th digit implies slightly more precision
    than IEEE 754 provides (~15.9 decimal digits for most of the
    representable range).
    However, the use of 16 decimal digits for outputting IEEE 754
    appears consistent with Double.toString() and elsewhere.
    
    Before printing, DecimalFormat appears to be rounding to
    15 decimal digits internally (or something similar).
    
    Parsing "1000000000000000" produces a different double
    representation than the original double
    (one that is closer to 1000000000000000 than
    999999999999999.9). This is the bug - we just lost information.
    We should be able to round-trip a double if there is no rounding
    since every double is representable with decimal and we have
    sufficient digits available to represent it (close enough) in
    decimal.
    
    Additional tests have been added to demonstrate the bug
    and also demonstrate the (correct) formatting behavior when the
    formatter is rounding.
    
    test_formatDouble_maxFractionDigits: rounding at 1, 10, 14 digits
    after the dp.
    test_formatDouble_roundingTo15Digits: rounding at 15 total digits
    overall
    test_formatDouble_bug17656132: Demonstrates the bug concisely.
    
    The test changes:
    
    test_formatDouble_wideRange():
    implicitly assumed that the any loss of accuracy
    when a decimal string was turned into a double
    would be undone when format() was called, and it would
    always arrive back at the original string. The test
    has been re-written here to use BigDecimal rather than
    Double.parseDouble(), and to compare two doubles rather
    than original string with the output from format().
    
    The test was previously failing with the RI for 1E23:
    the closest representable double to 1E23 is exactly
    99999999999999991611392.
    The value produces "99999999999999990000000" when formatted
    with the RI and not "100000000000000000000000". On Android
    it was passing for 1E23 because of bug 17656132 rounding
    back to the original decimal value.
    
    This test was previously failing on Android with 1E-309 because
    below 1E-308 IEEE 754 starts losing precision and the closest
    representable value is not close to the original string. The
    test now isn't affected if the double being tested is not close
    to the original decimal; it passes providing the can be round
    tripped.
    
    test_formatDouble_roundingProblemCases: Re-written like the
    _wideRange test but continues to demonstrate the bug due to
    the test values (intentionally) chosen.
    
    Bug: 17656132
    Change-Id: I7d81e38bd1f9dbfd1e1b2caa60a6bb16b871b925
    4e92b626
knownfailures.txt 83.8 KB