Do-s和DO-for浮点运算?

对于浮点运算(IEEE754,如果存在混淆)有什么好的做法和不做什么,以确保良好的数值稳定性和结果的高精度?

我知道有些人不喜欢减去相似幅度的数量,但我很好奇其他有什么好的规则。

首先,输入浮点数不一定遵循与实数相同的规则的概念……一旦你接受了这个,你就会理解大部分的陷阱。

以下是我一直遵循的一些规则/提示:

  • 永远不要将浮点数与零或其他任何东西进行比较(IE不要这样做: if (myFloat == 0)
  • 关联属性不适用于浮点…意思是(a + b) + c != a + (b + c)
  • 请记住,总有四舍五入
  • 浮点数不一定具有唯一的倒数
  • 没有带浮点数的闭包……永远不要假设浮点运算的结果导致有效的浮点数。
  • 分配财产不成立
  • 尽量避免使用浮点比较……因为舍入错误会导致意外结果

带浮点数的#1“不”规则是:

不要使用整数就足够的浮点数。

要了解浮点的行为方式。

不要相信简单的规则足以正确使用它们。

例如,至少有两个答案提出应该禁止比较浮点的平等。 首先,有些情况下需要比较它们的平等性。 然后,当进行范围检查是需要的时候,你还需要意识到它有它的缺陷,例如它不是传递性的,这是大多数人将为相等性测试所假设的属性。

请记住,由于错误的浮点运算, 人们死亡,并发生了数十亿美元的损失 。

从不尝试做一个等于比较

double da,db;

if(da == db)然后是什么。

记住C默认使用double,所以如果你想做单精度,请明确它

float fa,fb;

fa = fb + 1.0;

将fb转换为double进行双重添加然后转换为单个并执行单个相等

代替

fa = fb + 1.0F。

所有单身。

如果您要使用像1.0这样的整数,请不要在代码中使用小数。 如果可以最小化ascii数字,您可以从编译器/工具中获得更高的可靠性。 所以

fa = fb + 1;

或者代替

fa = fb + 0.3333333F;

做这样的事情(如果对准确性感兴趣)。

fc = 1; fc = fc / 3; fa = fb + fc;

很多很多其他人,浮点数是痛苦的,编译器和库不是那么好,fpus有错误,IEEE非常痛苦并导致更多错误。 不幸的是,这是我们在大多数平台上生活的世界。

我避免浮点陷阱的“主要武器”是牢牢掌握它们的工作方式。 我认为Chris Hecker很好地解释了基础知识。

搜索,下载和阅读“每个计算机科学家应该了解的有关浮点运算的知识”