当前位置:  开发笔记 > 编程语言 > 正文

如何处理浮点计算中的过度精度?

如何解决《如何处理浮点计算中的过度精度?》经验,为你挑选了1个好方法。

在我的数值模拟中,我的代码类似于以下代码段

double x;
do {
  x = /* some computation */;
} while (x <= 0.0);
/* some algorithm that requires x to be (precisely) larger than 0 */

对于某些平台上的某些编译器(例如gcc)(例如linux,x87 math),有可能x以高于双精度("具有过度精度")的方式计算.(更新:当我在这里谈到精度时,我的意思是精度/和/范围.)在这种情况下,可以想象,x <= 0即使下一次x向下舍入到双精度,它也会变为0,而compare()返回false.(和无法保证x不会在任意时间点向下舍入.)

有没有办法进行这种比较

便携,

适用于内联的代码,

没有性能影响

不排除某些任意范围(0,eps)?

我尝试使用(x < std::numeric_limits::denorm_min())但是在使用SSE2数学时,这似乎显着减慢了循环.(我知道非正规可以减慢计算速度,但我没想到它们只是移动并比较慢.)

更新: 另一种方法是在比较之前使用volatile强制x进入内存,例如通过写入

} while (*((volatile double*)&x) <= 0.0);

但是,根据应用程序和编译器应用的优化,此解决方案也会引入明显的开销.

更新: 任何容忍的问题是它是非常随意的,即它取决于具体的应用程序或上下文.我更愿意在没有过多精度的情况下进行比较,这样我就不必做任何额外的假设或在我的库函数的文档中引入一些任意的epsilons.



1> Christoph..:

正如Arkadiy在评论中指出的那样,一个明确的演员((double)x) <= 0.0 应该有效 - 至少根据标准.

C99:TC3,5.2.4.2.2§8:

除了赋值和强制转换(删除所有额外的范围和精度)之外,具有浮动操作数的操作值和受常规算术转换和浮动常量限制的值将被评估为其范围和精度可能大于类型.[...]


如果在x86上使用GCC,则可以使用标志-mpc32,-mpc64并将-mpc80浮点运算的精度设置为单精度,双精度和双精度.

推荐阅读
虎仔球妈_459
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有