背景
考虑三个 doubles 的验证low
,width
并且high
使得以下三个规则成立:
low < high
;width > 0
; 和width
完全符合(high - low)
“完全”的次数。
本质上,这三个值应该指定一个范围,该范围将被分成一定数量的箱,每个箱的宽度“完全”相等,范围的任何部分都没有下落不明。
例如:
(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 不覆盖该范围的一部分。
问题
考虑到双精度数的浮点性质,处理第三个验证规则的最佳方法是什么?
我的第一次天真的尝试包括:
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;
}
注意公差默认值的完全和绝对任意性......