背景
考虑三个 double 的验证 low
, width
和 high
使得以下三个规则成立:
-
low < high
; -
width > 0
;和 -
width
适合(high - low)
“正好”整数次。
本质上,这三个值应指定一个范围,该范围将被分成一定数量的 bin,每个 bin 的宽度“完全”相等,范围内没有任何部分未计算在内。
例如:
(A) low = -0.5
, width = 0.005
和 high = 0.5
将指定具有有效 bin 宽度的范围,因为可以创建“恰好”200 个完整的 bin,而
(B) low = -0.5
, width = 0.275
和 high = 0.5
将指定一个具有无效 bin 宽度的范围,因为可以创建 3 个完整的 bin,但部分范围未被这些 bin 覆盖。
问题
考虑到 double 的浮点性质,接近第三条验证规则的最佳方法是什么?
我第一次天真的尝试包括:
fmod( high - low, width ) == 0.0
但不幸的是,fmod 返回 0.005,例如 (A) - 我的调试器告诉我 0.005 的双倍值实际上包含 0.0050000000000000001
的值.
我应该自己编写解决方案以包含公差,还是有更优雅的解决方案来解决这个问题?
这是我目前拥有的:
bool valid(double range, double width, double tolerance = 0.000000001)
{
assert(width > 0 && range > 0);
while( range > 0 && range > tolerance )
{
range -= width;
}
return abs(range) <= tolerance;
}
请注意公差默认值的完全任意性......
最佳答案
您使用容差进行双重比较的方法是一种合理的方法。您现在唯一需要做的就是进行其余的需求分析,以确定您真正需要达到的准确程度:)
如果您知道最大精度,则乘以整数值进行比较。
关于c++ - 尽管使用浮点运算,仍从 fmod 或类似的方法获得预期结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11099265/