📜 ⬆️ ⬇️

Java hangs on 2.2250738585072012e-308

Konstantin Preisser recently discovered something very interesting: Java — both runtime and compiler — enters an infinite loop when converting a decimal 2.2250738585072012e-308 to a double. In theory, the number should be converted to 0x1p-1022 , that is, Double.MIN_VALUE . However, Java hangs at 0x0.fffffffffffffp-1022 , the largest denormalized number for double.

Infinite runtime loop

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


Infinite loop at compile time


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

Under the cut of the author's reasoning about the causes of this phenomenon.

What's 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 out this part, there is no longer any hangup in Double.parseDouble(String s) , because Double.parseDouble(String s) , which calls sun.misc.FloatingDecimal.readJavaFormatString(s).doubleValue() is pure java code, nothing native. But it uses artifacts of floating-point numbers, so the matter can be in the compiler settings, which compiled JRE and javac.

Without a 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 convert correctly:
 00000000 00010000 00000000 00000000 00000000 00000000 00000000 00000000 



From translator


I checked and reproduced the problem on 32-bit and 64-bit HotSpot and on 64-bit OpenJDK. In addition, a similar problem exists in PHP . Konstantin Preisser has already sent a bugreport.

Source: https://habr.com/ru/post/112948/


All Articles