[PATCH] Sunbug 7131192: Optimize BigInteger.doubleValue(), floatValue() (original) (raw)

Dmitry Nadezhin dmitry.nadezhin at gmail.com
Mon Feb 25 09:14:31 UTC 2013


Hi Louis,

I looked at your fix of sunbug=6358355 "Fix Float.parseFloat to round correctly and preserve monotonicity". https://bugs.openjdk.java.net/show_bug.cgi?id=100208 I like how you separate String->double and String->float conversions. They both become more clear. However I found two issues.

  1. The line in floatValue() method fValue = (float) doubleValue();

fValue can become Float.POSITIVE_INFINITY. It causes incorrect result on input like this String s = "340282356779733661637539395458142568447"; // 2^128 - 2^103 - 1 floatValue() returns Float.POSITIVE_INFINITY, the correct result is Float.MAX_VALUE .

fValue can also become 0. It causes assertion error on input like this String s = "7.00649232162408535461864791644958065640130970938257885878534141944895541342930300743319094181060791015625E-46"; // 2^(-150)

It can be fixed in such a way fValue = Math.max(Float.MIN_VALUE, Math.min(Float.MAX_VALUE, (float) doubleValue()));

  1. The line in floatValue() method. // difference is exactly half an ULP // round to some other value maybe, then finish fValue += 0.5f*ulp( fValue, overvalue );

When fValue is subnormal, the right-hand sign evaluates to 0, fValue remains unchanged. This is similar to the bug 4396272 - Parsing doubles fails to follow IEEE for largest decimal that should yield 0. The result of String s = "7.00649232162408535461864791644958065640130970938257885878534141944895541342930300743319094181060791015625E-46"; // 2^(-150) is Float.MIN_VALUE, the correct result is 0.

It can be fixed in such a way fValue = (float) (fValue + 0.5*ulp(fValue, overvalue)); Constant 0.5 instead of 0.5f causes double evaluation of right-hand side, so it doesn'nt underflow.

Best Regards, -Dima



More information about the core-libs-dev mailing list