假设我们必须使用一个浮点变量作为计数器——例如
float i = 1;
float previ = 0;
do
{
previ = i;
}
while (i++);
i 的值是多少时 (i-previ) 与 1 不同?这个差值仍然是一个整数,还是会变成一个有理数的非整数?
最佳答案
在最常见的浮点实现 IEEE 754 中,第一个不能用 32 位二进制浮点表示的整数是 224+1 (16,777,217)。此时,224 (16,777,216) 和 224+2 (16,777,218) 是可表示的。
当您将 1 加到 16,777,216 时,精确的数学结果是 16,777,217。由于这不可表示,因此四舍五入为可表示的值。最常见的默认舍入模式是舍入到最接近的。但是,16,777,216 和 16,777,218 与 16,777,217 的距离相等。在平局的情况下,选择具有偶数低位(在浮点有效数中)的值。所以返回 16,777,216。
因此,当一个 float 重复加1时,从0开始,一直计数到16,777,216,然后连续产生16,777,216。
16,777,217 是第一个不可表示的整数的原因是 IEEE 754 32 位二进制格式使用 24 位作为有效数(小数部分)。 (显式存储 23 位。高位隐式表示正常值。)因此,所有可以用 24 位表示的整数都是可表示的。 224 名义上需要 25 个整数位(从 224 到 20)。但是,仅使用 24 个高位不会引入任何错误(表示为 1•224),因为丢失的低位将为零。相反,无法表示 16,777,217,因为它需要缺失的位为一。
关于c - 用作整数的 float 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15094611/