class Rextester
{
public static void main(String args[])
{
double b = 1.13f * 100;
System.out.println(b);
}
}
在上述代码中,当未将f附加到1.13时,输出为112.99999999999999,但是当将f附加到1.13时,值us113。为什么会这样?
答案 0 :(得分:4)
后缀f
告诉Java,该数字是单精度浮点数,而不是双浮点数。
浮点数通常存在的问题是某些数字无法精确表示。内部表示形式的尾数的每一位代表分母的2的幂,因此1 / 2、1 / 4、1 / 8、1 / 16等。然后计算机将选择最接近的数字来表示您想要的号码。
您的情况是,当您省略f
时,它将使用全双精度位,并获得与其最接近的数字(112.9999999999)。当您执行f
时,您正在告诉程序将其四舍五入到最接近的单精度浮点,因此不适合的前9个将被四舍五入并传播到113的值。
这个特定数字有点巧合。不要以为使用单精度浮点数总是可以得到 expected 结果。浮点算法在计算中总是有些混乱。
答案 1 :(得分:1)
在小数点后加上f
会使它成为float
常数,其精度只有大约6位数字。这使得表示错误的可能性更大并且更大。
当您放弃使用f
时,十进制是一个双精度精度为0.5万亿倍的双精度型。这样可以使表示错误小得多,并且当打印为double
时,看到的可能性就较小。
当打印double
时,库期望出现一些表示错误,并会向您显示最简单/最短的数字,该数字与双精度数字具有相同的表示。 (实际上是映射到相同表示形式的无数个数字)
但是,此隐式舍入将仅校正很小的量,并且不太可能校正float
的表示错误。注意:如果您使用float
而不是double
进行打印,则将进行更大的舍入,从而隐藏了错误。