这是IEEE 754标准问题。我不完全理解它背后的机制。
public class Gray {
public static void main(String[] args){
System.out.println( (float) (2000000000) == (float) (2000000000 + 50));
}
}
答案 0 :(得分:29)
因为float
只能容纳大约7到8位有效数字。也就是说,它没有足够的位来准确表示数字2000000050,因此它被舍入到2000000000。
具体而言,float
由三部分组成:
您可以将浮点视为计算机进行科学记数法的方式,而不是二进制。
精度等于log(2 ^ number of significand bits)
。这意味着float
可以保留log(2 ^ 24) = 7.225
个有效数字。
数字2,000,000,050有9位有效数字。上面的计算告诉我们24位有效数字不能保存那么多有效数字。之所以2,000,000,000是有效的,因为只有1个有效数字,所以它适用于有效数字。
要解决这个问题,你可以使用double
,因为它有一个52位有效数字,这足以代表每个可能的32位数字。
答案 1 :(得分:3)
简单地说 - 当浮点值为20亿时,50是舍入误差。
答案 2 :(得分:3)
你可能会发现这个技巧可以找到下一个有意义的值。
float f = 2000000000;
int binaryValue = Float.floatToRawIntBits(f);
int nextBinaryValue = binaryValue+1;
float nextFloat = Float.intBitsToFloat(nextBinaryValue);
System.out.printf("The next float value after %.0f is %.0f%n", f, nextFloat);
double d = 2000000000;
long binaryValue2 = Double.doubleToRawLongBits(d);
long nextBinaryValue2 = binaryValue2+1;
double nextDouble = Double.longBitsToDouble(nextBinaryValue2);
System.out.printf("The next double value after %.7f is %.7f%n", d, nextDouble);
打印
The next float value after 2000000000 is 2000000128
The next double value after 2000000000.0000000 is 2000000000.0000002
答案 3 :(得分:2)
如果你考虑下面的程序(C ++),它可能会帮助你理解这种情况。它显示了四舍五入到相同浮点值的连续整数组:
#include <iostream>
#include <iomanip>
int main()
{
float prev = 0;
int count = 0;
double from;
for (double to = 2000000000 - 150; count < 10; to += 1.0)
{
float now = to;
if (now != prev)
{
if (count)
std::cout << std::setprecision(20) << from << ".." << to - 1 << " ==> " << prev << '\n';
prev = now;
from = to;
++count;
}
}
}
输出:
1999999850..1999999935 ==> 1999999872
1999999936..2000000064 ==> 2000000000
2000000065..2000000191 ==> 2000000128
2000000192..2000000320 ==> 2000000256
2000000321..2000000447 ==> 2000000384
2000000448..2000000576 ==> 2000000512
2000000577..2000000703 ==> 2000000640
2000000704..2000000832 ==> 2000000768
2000000833..2000000959 ==> 2000000896
这表明浮点只能精确到表示1999999850到1999999935之间的所有整数,错误地将它们的值记录为1999999872.因此,对于其他值。这是上述有限存储空间的实际结果。