比较浮点数的正确方法

时间:2014-12-24 12:12:28

标签: c++ c floating-point floating-accuracy

我正在计算N + fraction形式的实数数值。比方说,例如,N + fraction = 7.10987623,然后是N = 7fraction = 0.10987623接下来,我需要检查fraction是否大于或等于比率23269/25920

以下,在C / C ++中,似乎给出了正确的结果;但是,我不确定这是否是进行比较的正确方法:

// EPSILON is defined to be the error tolerance
// and `ratio' is defined as 23269.0/25920.0 
if(fabs(fraction - ratio) > EPSILON)
 // `fraction' is greater or equal to `ratio'

我也尝试过另一种方式,但似乎结果不正确。

if(fabs(fraction - ratio) < EPSILON)

3 个答案:

答案 0 :(得分:4)

您有正确的方法来比较平等:

fabs(fraction - ratio) < EPSILON

在宽度ratio的{​​{1}}附近建立相等带。任何以上那个乐队,都严格来说更高。因此,EPSILON检查是:

>

由于我们需要fraction > ratio + EPSILON ,我们只需要将这两个部分结合起来:

>=

答案 1 :(得分:0)

不是指定EPSILON,而是需要根据N的大小而变化,而是将N添加到ratio,然后将其添加到fractionx <= floor(x) + ratio 将产生相同的四舍五入:

{{1}}

答案 2 :(得分:0)

通过modf()将数字分成整数和小数部分 有了一个好的FP库,预计不会有精度损失。

#include <math.h>
int foo(double N_plus_fraction) {
  double ipart;
  double fraction = modf(N_plus_fraction, &ipart);
  fraction = fabs(fraction);  // lets use the absolution fraction.

将阈值分解为分子/分母部分并缩放分数。

  double f = fraction*25920.0;
  return f >= 23269.0;
}

由于产品f可能不是fraction25920.0的精确数学乘积,而是最接近的舍入值,代码可能会使用f稍大一点(或{更小}与nextafter()取决于想要偏向结果的方式。

  double f = fraction*25920.0;
  f = nextafter(f, 2*f);  // make f the next greater FP value.
  return f >= 23269.0;
}

预期 不准确性发生在fraction*25920.0步骤中。