c++ - 尽管使用浮点运算,仍从 fmod 或类似的方法获得预期结果

标签 c++ floating-accuracy fmod

背景

考虑三个 double 的验证 low , widthhigh使得以下三个规则成立:

  1. low < high ;
  2. width > 0 ;和
  3. width适合 (high - low) “正好”整数次。

本质上,这三个值应指定一个范围,该范围将被分成一定数量的 bin,每个 bin 的宽度“完全”相等,范围内没有任何部分未计算在内。

例如:

(A) low = -0.5 , width = 0.005high = 0.5

将指定具有有效 bin 宽度的范围,因为可以创建“恰好”200 个完整的 bin,而

(B) low = -0.5 , width = 0.275high = 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/

相关文章:

c++ - 对于类模板定义中由 this-> 限定的类/命名空间名称,是否应该延迟名称查找?

c++ - 在 C++ 中将 float 转换为 int 时丢失数据

c - C 中的整数除法将值向下舍入/结果为零

matlab - 点积 : * Command vs. 循环给出不同的结果

php - 类型转换 float 是否具有破坏性?

c# - FMOD 无缝循环和序列播放

c++ - matlab strel函数参数作为opencv cpp中的八角形

audio - 麦克风输入播放(Fmod studio API)

c++ - borland turbo c++ 4.5 中的 FMOD 错误

c++ - 在回溯中使用 `free()` 解除分配时出现 `delete` 错误