与一些程序员进行了有关浮点不精确度的简短讨论之后,我们发现Java的某些行为对我们来说很奇怪。
System.out.println(0.1 + 0.2); // 0.30000000000000004
System.out.println((float) 0.1 + (float) 0.2); // 0.3
由于某种原因,当您将变量强制转换为浮点数时,不正确的信息会消失吗?我们试图研究一些解释,但找不到任何解释。
有没有人知道Java为什么这样表现?
注意:我知道什么是浮点不精确度,而不是为什么当我转换为浮点数时它会消失。我知道这里的精度问题有所不同。
答案 0 :(得分:1)
Java’s default formatting仅产生足够的十进制数字,以唯一地区分浮点数与相邻的浮点数。
当源文本0.3
转换为double
时,结果是最接近的double
值,即0.299999999999999988897769753748434595763683319091796875。当打印此字时,“ 0.3”就足以唯一标识它,因为0.299999999999999988897769753748434595763683319091796875当然是最接近的值,因为这是我们首先从0.3
获得它的方式。
源文本0.1
和0.2
产生0.1000000000000000055511151231257827021181583404541015625和
0.200000000000000011102230246251565404236316680908203125。以double
格式添加时,结果为0.3000000000000000444089209850062616169452667236328125。请注意,这与上面的数字不同。因此,在打印时,“ 0.3”不足以将其与相邻的值0.299999999999999988897769753748434595763683319091796875区别开。必须产生“ 0.30000000000000004”以表明它是不同的。
将值转换为float
时,将使用float
的格式,而不是double
的格式。格式化float
时,只有float
中可表示的值才是邻居的候选值。 float
中可表示的最接近0.3的值为0.300000011920928955078125。这也是(float) 0.1 + (float) 0.2
的结果,并且仅打印“ 0.3”即可与相邻的float
值(0.2999999821186065673828125和0.3000000417232513427734375)充分区分开。