gpt4 book ai didi

c++ - Gotw 67 中的一个例子

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:11:51 27 4
gpt4 key购买 nike

http://www.gotw.ca/gotw/067.htm中有一个例子

int main()
{
double x = 1e8;
//float x = 1e8;
while( x > 0 )
{
--x;
}
}

当你把double改成float时,在VS2008中就是一个无限循环。根据 Gotw 的解释:

What if float can't exactly represent all integer values from 0 to 1e8? Then the modified program will start counting down, but will eventually reach a value N which can't be represented and for which N-1 == N (due to insufficient floating-point precision)... and then the loop will stay stuck on that value until the machine on which the program is running runs out of power.

据我所知,IEEE754 float 是单精度(32 位), float 的范围应该是 +/- 3.4e +/- 38,并且它应该有 7 位有效数字。

但我仍然不明白这到底是怎么发生的:“最终达到一个无法表示的值 N,并且 N-1 == N(由于浮点精度不足)。”有人可以尝试解释这一点吗?

一些额外信息:当我使用 double x = 1e8 时,它在大约 1 秒内完成,当我将其更改为float x = 1e8,它运行的时间更长(5 分钟后仍在运行),如果我将它更改为 float x = 1e7;,它会在大约 1 秒内完成。

我的测试环境是VS2008。

顺便说一句,我询问基本的 IEEE 754 格式解释,因为我已经理解了。

谢谢

最佳答案

好吧,为了论证,假设我们有一个处理器,它表示一个具有 7 位有效小数位的 float ,以及一个具有 2 位小数位的尾数。所以现在数字 1e8 将存储为

1.000 000 e 08

(其中“.”和“e”不需要实际存储。)

现在您要计算“1e8 - 1”。 1表示为

1.000 000 e 00

现在,为了进行减法,我们首先进行无限精度的减法,然后归一化,以便“.”之前的第一个数字。介于 1 和 9 之间,最后四舍五入到最接近的可表示值(例如,盈亏平衡)。 "1e8 - 1"的无限精度结果是

0.99 999 999 e 08

或归一化

9.9 999 999 e 07

可以看出,无限精度结果需要比我们的架构实际提供的多一位有效数字;因此我们需要将无限精确的结果四舍五入(并重新归一化)到 7 位有效数字,从而得到

1.000 000 e 08

因此你以“1e8 - 1 == 1e8”结束并且你的循环永远不会终止。

现在,实际上您使用的是 IEEE 754 二进制 float ,它们有点不同,但原理大致相同。

关于c++ - Gotw 67 中的一个例子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6995950/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com