我正在计算一个N + fraction
形式的实数值。比如说,比如N + fraction = 7.10987623
,然后N = 7
fraction = 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)
你有正确的方法来比较相等性:
fabs(fraction - ratio) < EPSILON
在宽度EPSILON
的ratio
周围建立一个等式带。任何高于该波段的东西,都是严格意义上的更大。因此,>
检查是:
fraction > ratio + EPSILON
由于我们想要>=
,我们只取这两个部分的并集:
fraction > ratio - EPSILON
与其指定一个EPSILON
,它需要根据N
的大小而变化,另一种方法是将N
添加到ratio
,因为这样它和fraction
将产生相同的舍入:
x <= floor(x) + ratio
通过 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
可能不是fraction
和25920.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
步骤中。