c - 用作整数的 float 的行为

标签 c floating-point

假设我们必须使用一个浮点变量作为计数器——例如

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/

相关文章:

python - Cython - 替换 def __init__() 方法,因为 Cython 的 Python 函数和方法无法处理值为 0 的无符号字符数组

c - 父进程和子进程

c - fork 后在子进程中设置 errno - OSX

c++ - 字符串转 float ,C++实现

c++ - 摆脱带符号的零

c++ - 最后 5 个元素的读取访问权限

c - 将函数中声明的局部数组传递给另一个函数

在指数和小数部分具有不同位数的格式之间转换

c# - 我需要在 C# 中编写一个大端单精度 float 到文件

javascript - JavaScript 是否具有 double float ?