比较浮点数的正确方法
Correct Way to Compare Floating-point Numbers
我正在计算一个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
步骤中。
相关文章:
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 从浮点数中删除小数部分但保留类型的有效方法
- 找到一种使用 C++ 中的条件提取浮点数的方法
- 有没有一种简单的方法可以从嵌入的 GNU ARM C++字符串中解析浮点数?
- 有没有更有效的方法可以原子地添加两个浮点数?
- 在 C/C++ 中以指数形式将浮点数声明为宏的正确方法是什么?
- 这是为浮点数/双精度函数泛型的正确方法吗?
- 从 QByteArray 获取具有 bigendian 格式的浮点数组的有效方法
- 怪异的方法来检查浮点数是否为负
- 在 C/C+ 中从 16 位线性 PCM 音频转换为 32 位浮点数的最佳方法
- 从C 中的字符串中提取浮点数的最简单方法
- 将 cv::Mat 向量复制到浮点数向量的最佳方法是什么?
- 比较浮点数与零的标准方法是什么
- 比较浮点数的正确方法
- 给定二进制随机数生成器生成随机浮点数的正确方法
- 将 uint8 转换为范围为 0-1 的浮点数的最有效方法
- 无需任何库函数即可将浮点数转换为字符串的有效方法
- 将浮点数数组设置为相同值的最快方法
- 有可能的方法可以将两个从无符号 int 铸造的浮点数除以产生负浮点数结果