2024-04-29 12:23:16 发布
网友
float a = 0; while (true) { a++; if (a > 16777216) break; // Will never break... a stops at 16777216 }
有谁能解释一下为什么在这段代码中,浮点值不再递增为16777216?
编辑:
或者更简单:
float a = 16777217; // a becomes 16777216
IEEE-754浮点数(32位)的简短汇总:
(sign ? -1 : +1) * 2^exponent * (1.0 + mantissa)
1001 0000 0000 0000 0000 000 = 2^-1 + 2^-4 = .5 + .0625 = .5625
1.5625
现在以你为例:
16777216正好是224,将表示为32位浮点,如下所示:
10010111
0 10010111 00000000000000000000000
(+1) * 2^24 * (1.0 + .0) = 2^24 = 16777216
现在让我们看看数字16777217,或者正好是224+1:
(+1) * 2^24 * (1.0 + 2^-24) = 2^24 + 1 = 16777217
当您在二进制表示中查看该值时,您将看到它是一个1和多个零,即1 0000 0000 0000 0000 0000 0000,或者正好是2^24。这意味着,在16777216,这个数字刚刚增长了一位数。
1 0000 0000 0000 0000 0000 0000
由于它是一个浮点数,这可能意味着它末端的最后一个仍被存储的数字(即在其精度范围内)也会向左移动。
可能,你看到的是,最后一个数字的精度已经移到了一个以上,所以增加一个就不再有什么区别了。
16777217不能用浮点数精确表示。float可以精确表示的下一个最高数字是16777218。
因此,尝试将浮点值16777216增加到16777217,这不能用浮点表示。
IEEE-754浮点数(32位)的简短汇总:
(sign ? -1 : +1) * 2^exponent * (1.0 + mantissa)
1001 0000 0000 0000 0000 000 = 2^-1 + 2^-4 = .5 + .0625 = .5625
,小数分隔符前面的值不存储,而是隐式假设为1(如果指数为255,则假设为0,但这在这里并不重要),因此对于指数为30,例如,此尾数示例表示值1.5625
现在以你为例:
16777216正好是224,将表示为32位浮点,如下所示:
10010111
)0 10010111 00000000000000000000000
(+1) * 2^24 * (1.0 + .0) = 2^24 = 16777216
现在让我们看看数字16777217,或者正好是224+1:
(+1) * 2^24 * (1.0 + 2^-24) = 2^24 + 1 = 16777217
当您在二进制表示中查看该值时,您将看到它是一个1和多个零,即
1 0000 0000 0000 0000 0000 0000
,或者正好是2^24。这意味着,在16777216,这个数字刚刚增长了一位数。由于它是一个浮点数,这可能意味着它末端的最后一个仍被存储的数字(即在其精度范围内)也会向左移动。
可能,你看到的是,最后一个数字的精度已经移到了一个以上,所以增加一个就不再有什么区别了。
IEEE-754浮点数(32位)的简短汇总:
(sign ? -1 : +1) * 2^exponent * (1.0 + mantissa)
1001 0000 0000 0000 0000 000 = 2^-1 + 2^-4 = .5 + .0625 = .5625
,小数分隔符前面的值不存储,而是隐式假设为1(如果指数为255,则假设为0,但这在这里并不重要),因此对于指数为30,例如,这个尾数示例表示值1.5625
现在以你为例:
16777216正好是224,将表示为32位浮点,如下所示:
10010111
)0 10010111 00000000000000000000000
(+1) * 2^24 * (1.0 + .0) = 2^24 = 16777216
现在让我们看看数字16777217,或者正好是224+1:
(+1) * 2^24 * (1.0 + 2^-24) = 2^24 + 1 = 16777217
16777217不能用浮点数精确表示。float可以精确表示的下一个最高数字是16777218。
因此,尝试将浮点值16777216增加到16777217,这不能用浮点表示。
相关问题 更多 >
编程相关推荐