假设我们必须使用float变量作为计数器 - 例如
float i = 1;
float previ = 0;
do
{
previ = i;
}
while (i++);
我将(i-previ)的值与1不同?这种差异仍然是一个整数,还是会成为一个理性的非整数?
答案 0 :(得分:8)
在最常见的浮点实现中,IEEE 754,第一个不能用32位二进制浮点表示的整数是2 24 +1(16,777,217)。此时,2 24 (16,777,216)和2 24 +2(16,777,218)是可表示的。
当您将1添加到16,777,216时,确切的数学结果为16,777,217。由于这不可表示,因此将其四舍五入为可表示的值。最常见的默认舍入模式是舍入到最接近的。但是,16,777,216和16,777,218都与16,777,217相同。在绑定的情况下,选择具有偶数低位(在浮点有效位数中)的值。所以返回了16,777,216。
因此,当一个重复添加到浮点值时,从零开始,继续计数直到达到16,777,216,然后连续产生16,777,216。
16,777,217是第一个不可表示的整数的原因是IEEE 754 32位二进制格式使用24位作为有效数(小数部分)。 (显式存储23位。高位对于正常值隐含一位。)因此,可以用24位表示的所有整数都是可表示的。 2 24 名义上需要25个整数位(从2 24 到2 0 )。但是,仅使用24个高位不会引入任何错误(它表示为1•2 24 ),因为丢失的低位将为零。相反,16,777,217无法表示,因为它需要缺少的位为1。