加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 如何在一个区间内循环遍历双精度的每个值?

发布时间:2020-12-16 10:26:01 所属栏目:百科 来源:网络整理
导读:我读了 here并得出结论,double的最小值(绝对值)是1.7e-308,但我的代码永远循环: for (double d(-1.0); d = 1.0; d+=1.7e-308){} 编辑:我想以尽可能小的增量从-1.0循环到1.0. 解决方法 TL;DR: the gap between the numbers that a computer is able to stor
我读了 here并得出结论,double的最小值(绝对值)是1.7e-308,但我的代码永远循环:

for (double d(-1.0); d <= 1.0; d+=1.7e-308)
{
}

编辑:我想以尽可能小的增量从-1.0循环到1.0.

解决方法

TL;DR: the gap between the numbers that a computer is able to store in floating point numbers gets larger as the number gets larger. Your minimum number is only valid when the number is zero. At some point,trying to add such a small number does nothing as it can’t represent such a small change in number.

这是因为每个可表示的浮点数之间的差距随着数量的增加而增大.

1和最接近的可表示小于1之间的差异约为1.11×10-16,远大于您尝试添加的值.

会发生的是,double用一组位存储用于数字符号,另一位用于表示数字本身(作为无符号整数)和乘数作为指数2.

当你接近零时,指数非常小,使得实际数量的一个变化存储得比你的指数大得多.

例如,(4 – 3)×299显然会大于(4 – 3)×2-99,这是基本上发生的事情.

当你开始添加时,你会发现最终,添加1.7×10-308没有任何作用,因为你的当前值是加法的最接近的可表示值,它继续在无限循环中继续.

请注意,这仅在将舍入模式设置为roundTiesToEven或roundTiesToAway时,它们将舍入到最接近的可表示值,除非它们同样接近.

如果您通过事先使用FE_UPWARD(as Marc Glisse noted)调用std::fesetround手动将舍入模式设置为roundTowardPositive,如果添加任何正数(除零),它将继续增加.我认为roundTowardNegative和roundTowardZero是不言自明的.

顺便说一句,即使你用1.11×10-16替换它,你仍然需要在完成之前通过18 014 398 509 481 984(18千万亿)迭代.如果你实际循环遍历-1和1之间的每个值,那就是9 223 372 036 854 775 809(9 quintillion)迭代.祝好运.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读