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

重复递增浮点数

发布时间:2020-12-16 10:06:44 所属栏目:百科 来源:网络整理
导读:我正在查看一些遗留代码,它们定义了沿轴f的一些网格点. int main(){ double f[9]; int i = 0; for (double a = 0; a = 1; a += 0.125){ f[i++] = a; }} 我担心重复添加1/8到a,并且循环没有正确运行.这是因为我认为你不能像这样添加浮点值,并且当我是8时它依
我正在查看一些遗留代码,它们定义了沿轴f的一些网格点.

int main(){
    double f[9];
    int i = 0;
    for (double a = 0; a <= 1; a += 0.125){
        f[i++] = a;
    }
}

我担心重复添加1/8到a,并且循环没有正确运行.这是因为我认为你不能像这样添加浮点值,并且当我是8时它依赖于它正好是1.

或者这段代码是否正常,我应该停止担心? (代码显然至少已有20年历史,并且从未造成过麻烦 – 尽管在原始版本中,在循环之外声明了double a,我正在阅读为什么会这样.).

解决方法

当使用C编译器编译时,代码很好,C编译器提供精确的IEEE 754语义或它们的近似值(例如,FLT_EVAL_METHOD> 0,或者甚至是子表达式的任意多余精度和任意舍入到标称精度).

你担心的问题是:

>表示错误,其中0.125不完全是1/8,和
>操作错误,其中不完全是数学加法.对于这个特定的程序,这些都不会发生.

0.125要求1位精度在基数2中精确表示.这意味着程序在这些条件下使用的浮点数恰好是预期的1/8.此外,在添加任何近似值之前,它可以添加到自身253次.

这种推理对于其他增量步骤是不正确的.例如,下面的程序的变化留下了一个数组的索引,f [100],至少与我的编译器(实现严格的IEEE 754语义)未初始化:

int main(){
    double f[101];
    int i = 0;
    for (double a = 0; a <= 1; a += 0.01){
        printf("%.16e %dn",a,i);
        f[i++] = a;
    }
}

当我运行它时,我得到最后一行:

...
9.8000000000000065e-01 98
9.9000000000000066e-01 99

f [100]永远不会被写入,因为尝试在二进制浮点中重复添加0.01时会出现表示错误和操作错误.

(编辑:李大同)

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

    推荐文章
      热点阅读