为什么Java将这个浮点数四舍五入

imr*_*ole 1 java floating-point

鉴于我们对浮点精度的了解,为什么这个代码:

float a = 0.1f;
System.out.println(a);
Run Code Online (Sandbox Code Playgroud)

打印0.1而不是0.100000001

use*_*ica 7

0.100000001也不准确.如果Java打印这个浮子完全没有接地,它会打印出来

0.100000001490116119384765625
Run Code Online (Sandbox Code Playgroud)

这对于大多数浮点用例来说是无用的.

要么它根本不圆,你得到0.100000001490116119384765625,或者轮到,你需要一个舍入策略.他们选择的舍入策略是在小数点后打印足够的数字,以区分浮点数与任何其他浮点值,最少一位数.这是不是一定够的花车从任何其他区别双重价值.


And*_*eas 6

println(a)调用最终调用Float.toString(a),它说:

ma的小数部分必须打印多少位?必须至少有一个数字来表示小数部分,并且除此之外必须有多个,但只有多少个,更多的数字才能唯一地将参数值与相邻的类型值区分开来float.也就是说,假设x是由此方法为有限非零参数f生成的十进制表示所表示的精确数学值.那么f必须是float最接近x的值; 或者,如果两个float值是同样接近X,然后˚F必须是它们中的一个和的有效数的至少显著位˚F必须0.

或者换句话说,由于IEEE 754 单精度浮点值仅具有6到9个有效十进制数字精度,因此它不会包含该最终值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
Run Code Online (Sandbox Code Playgroud)