提问者:小点点

在实际示例中,浮点数的精度如何?


我认为浮点精度是7位小数/位(包括整数和小数部分)——这里我的意思是基数10位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)

共1个答案

匿名用户

小数点后七位是一个方便的经验法则,但这不是真正发生的事情。Java的flot是一种32位二进制浮点格式,遵循IEEE-754标准。编码有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