浮点的精度如何在实际示例中正常工作



我认为浮点精度是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是遵循IEEE-754标准的32位二进制浮点格式。编码有1个符号位,曼蒂萨(Mantissa(有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

最新更新