Java 为什么在16_711_711f==16_711_712f,不应';t float只有7位小数精度?

Java 为什么在16_711_711f==16_711_712f,不应';t float只有7位小数精度?,java,floating-point,Java,Floating Point,浮点是32位。指数是8位。因此,有效位为32-8=24位(减号位加一个隐式位) 如果使用24位存储有效(二进制)数字,则只能存储log10(2^24)=7位十进制有效数字-无论这些数字是十进制数字(点后)还是整数部分的数字 为什么在下面的示例中识别第8位小数?我的推理哪里有错误 float f1 = 16_711_711; float f2 = 16_711_712; System.out.println(f1 == f2); // false log10(2^24)约为7.22 你在这里看

浮点是32位。指数是8位。因此,有效位为32-8=24位(减号位加一个隐式位)

如果使用24位存储有效(二进制)数字,则只能存储log10(2^24)=7位十进制有效数字-无论这些数字是十进制数字(点后)还是整数部分的数字

为什么在下面的示例中识别第8位小数?我的推理哪里有错误

float f1 = 16_711_711;
float f2 = 16_711_712;

System.out.println(f1 == f2); // false
log10(2^24)约为7.22

你在这里看到的是.22


它可以完美地保存7位数字,并且能够存储关于8位数字的一些信息,但不能保存全部信息。您碰巧发现了一个例子,其中有足够的信息来区分这两个数。

2^24=16*(2^10)^2=16*(10^6+2*24*10^3+24^2)>16768000
,因此您的两个数仍然位于可表示为
float
“的连续整数段内,然后仅为log10(2^24)=7个十进制有效数字可以存储“->不完全。对于
float
,24位二进制意义到十进制意义的映射从6位到9位摆动。我担心任何小于2^24=16_777_216的数字都不会有问题,这并不能解释0.22技巧。似乎每一个16_777_216下超过7位的数字都是精确的…确实如此。它可以用8位数字正确地表示一些数字,但不是所有数字。这就是非整数位数在本例中的含义。请记住,log10()对于我们这些以10为基数思考的人来说只是一个关键点。事实上,它可以精确地表示24位数字,但这些是二进制数字。对不起,我终于得到了它!16_777_217也有8位数字,但无法精确表示@卡斯达斯:没错。在某些点上,它只能表示两的倍数,然后在另一个更高的点上,它只能表示8的倍数,然后是16,32,等等。因此,一些有效位数超过7位的整数值可以精确表示,但不是全部。它们越大,无法表示的值就越多。