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

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".
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

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)

2)  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,

More information about the core-libs-dev mailing list