我认为浮点精度是 7 位小数/数字(包括整数和小数部分) - 这里我的意思是 base10 7 位数字 - 我可以在代码编辑器中的浮点文字中输入这 7 位数字。这意味着如果两个数字中有 7 位有效数字(小数点前后),那么这两个数字将始终不同。
但正如我所看到的,两个具有 7 个有效数字的数字有时不同,有时相同!!!
1)我哪里错了?
2)下面例子的模式和原理是什么?为什么相同的 7 位精度组合有时被视为不同,有时又被视为相同?
float f01 = 90.000_001f;
float f02 = 90.000_002f; // f01 == f02 is TRUE ! (CORRECT RESULT)
float f03 = 90.000_001f;
float f04 = 90.000_003f; // f03 == f04 is TRUE ! (CORRECT RESULT)
float f1 = 90.000_001f;
float f2 = 90.000_004f; // FALSE (INCORRECT RESULT)
float f3 = 90.000_002f;
float f4 = 90.000_009f; // FALSE (INCORRECT RESULT)
float f5 = 90.000_009f;
float f6 = 90.000_000f; // FALSE (INCORRECT RESULT)
float f7 = 90.000_001f;
float f8 = 90.000_009f; // FALSE (INCORRECT RESULT)
最佳答案
小数点后七位是一个方便的经验法则,但事实并非如此。 Java 的 float
是 32-bit binary floating point format, following the IEEE-754 standard 。编码有 1 个符号位,23 位用于尾数,8 位用于指数,因此您的值采用科学记数法表示,采用二进制:
f = +/- mantissa * 2^exponent
将您的值转换为这种格式,您应该能够看到发生了什么:
90.000001 = 0(sign) 10000101(exponent) 01101000000000000000000(mantissa)
90.000003 = 0(sign) 10000101(exponent) 01101000000000000000000(mantissa)
90.000004 = 0(sign) 10000101(exponent) 01101000000000000000001(mantissa)
如果您想进一步探索,这是一个用于比较编码值的便捷工具:https://www.h-schmidt.net/FloatConverter/IEEE754.html
实际上,解决此问题的方法是永远不要使用 ==
运算符来比较浮点值,而应始终将 float 与精度进行比较:
Math.abs(x - y) < epsilon
关于java - 浮点精度在实际例子中到底如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49586191/