重复递增浮点数
发布时间: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时会出现表示错误和操作错误. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |