我认为浮点精度是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)
答案 0 :(得分:3)
七位小数是一个方便的经验法则,但它并不是真正发生的事情。 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
在实践中,解决方案是你永远不应该使用==
运算符来比较浮点值,总是比较浮点数的精度:
Math.abs(x - y) < epsilon