鉴于我们对浮点精度的了解,为什么这个代码:
float a = 0.1f;
System.out.println(a);
打印0.1
而非0.100000001
?
答案 0 :(得分:7)
0.100000001
也不准确。如果Java打印完全没有基础的浮动,it would print
0.100000001490116119384765625
对大多数浮点用例来说都是无用的。
要么根本不圆,你得到0.100000001490116119384765625
,要么轮回,你需要一个舍入策略。 The rounding strategy they picked是在小数点后打印足够的数字,以区分浮点数与任何其他浮点值,至少有一位数。 不必须足以区分浮动与任何其他 double 值。
答案 1 :(得分:6)
println(a)
来电最终致电Float.toString(a)
,其中说:
m 或 a 的小数部分必须打印多少位数?必须至少有一个数字来表示小数部分,并且除此之外必须有多个,但只有多少,更多的数字才能唯一地将参数值与类型
float
的相邻值区分开来。也就是说,假设 x 是由此方法为有限非零参数 f 生成的十进制表示所表示的精确数学值。那么 f 必须是最接近 x 的float
值;或者,如果两个float
值同样接近 x ,则 f 必须是其中之一,并且 f的有效位的最低有效位必须为0
。
或者说另一种方式,因为IEEE 754 single-precision floating-point值只有6到9 significant decimal digits精度,它不包括最终1
,因为它超过了精度储值。
以下是显示数字的代码:
System.out.println(Math.nextDown(0.1f)); // prints: 0.099999994
System.out.println(0.1f); // prints: 0.1
System.out.printf("%.15f%n", 0.1f); // prints: 0.100000001490116
System.out.println(Math.nextUp(0.1f)); // prints: 0.10000001