用作整数的float的行为

Boy*_*nov 1 c floating-point

假设我们必须使用float变量作为计数器 - 例如

float i = 1;
float previ = 0;
do 
{
   previ = i;
}
while (i++);
Run Code Online (Sandbox Code Playgroud)

i(i-previ)与1的值有什么不同?这种差异仍然是一个整数,还是会成为一个理性的非整数?

Eri*_*hil 9

在浮点最常见的实现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.

之所以说16777217是第一不可表示的整数的是,IEEE 754 32位二进制格式使用24个比特尾数(小数部分).(显式存储23位.高位对于正常值隐含一位.)因此,可以用24位表示的所有整数都是可表示的.2 24名义上需要25个整数位(从2 24到2 0).但是,仅使用24个高位不会引入任何错误(它表示为1•2 24),因为丢失的低位将为零.相反,不能表示16,777,217,因为它需要缺少的位为1.