Java hangs on 2.2250738585072012e-308

Original author: Rick Regan
  • Transfer
Praysser Constantine ( Konstantin Preisser ) recently discovered something very interesting: Java - and the runtime and compiler - enters an infinite loop when converting decimal 2.2250738585072012e-308to double. In theory, the number should be converted to 0x1p-1022, that is Double.MIN_VALUE. However, Java hangs on 0x0.fffffffffffffp-1022, the largest denormalized number for double.

Endless loop in runtime

class RuntimeHang {
    public static void main(String[] args) {
        System.out.println("Test:");
        double d = Double.parseDouble("2.2250738585072012e-308");
        System.out.println("Value: " + d);
    }
}


Endless loop at compile time


( If you want to try it out in Eclipse, do not forget to save everything first, otherwise you won’t be able to come to your senses with its shadow compilation - approx.
class CompilationHang {
    public static void main(String[] args) {
        double d = 2.2250738585072012e-308;
        System.out.println("Value: " + d);
    }
}

Under the cat, the author’s reasoning about the causes of this phenomenon.

What is the matter?


Konstantin found out that at least in runtime the problem lies in the “correction cycle” in FloatingDecimal.java . He's writing:

If you comment on this part, there is no longer any hangup in the runtime, since the code in pure java Double.parseDouble(String s)that causes it sun.misc.FloatingDecimal.readJavaFormatString(s).doubleValue()is nothing native. But it uses floating point arithmetic, so it could be the compiler settings in which JRE and javac were compiled.

Without correction cycle, such bits (big endian) are output:
00000000 00001111 11111111 11111111 11111111 11111111 11111111 11111111

That is, the number is converted to the largest denormalized floating-point number, since the exponent is zero. Without a correction cycle, the same thing happens with 2.2250738585072013e-308, however, if you uncomment the cycle, it will be converted correctly:
00000000 00010000 00000000 00000000 00000000 00000000 00000000 00000000



From translator


I tested and reproduced the problem on 32- and 64-bit HotSpot and on 64-bit OpenJDK. In addition, there is a similar problem in PHP . Konstantin Preisser has already sent a bug report.

Also popular now: