【问题标题】:C++ rounding issueC ++舍入问题
【发布时间】:2013-06-25 12:16:19
【问题描述】:

我正在尝试使用 GSL 创建直方图。当我尝试将除法 1470/100 的值添加到直方图中时遇到问题。 这导致 14.69999999 并且当添加到直方图中时,它会四舍五入到较低的 bin。 我的问题是如何使 1470/100 结果为 14.7 而不是 14.69999? 谢谢

编辑:

int minRange = 14;
double val;


val = minRange + j*0.05;


gsl_histogram_increment(hist, val);

当 val 添加到直方图中时,它被认为是 14.65 而不是 14.7。 (在这种情况下,j 是 14)。

我通过将 1e-6 添加到 val 解决了这个问题。谢谢你的帮助

【问题讨论】:

  • 也许我在这里错了,但如果你想把所有直方图点四舍五入,你不能做类似 round(number*100)/10.0 的事情吗?请问可以提取代码吗?不确定您使用的是什么数据类型。
  • 仅供参考:14.7 IEEE 754 浮点表示:32-bit float64-bit double
  • 感谢您的解释。现在我明白了

标签: c++ histogram gsl


【解决方案1】:

这是一个浮点精度问题。解决的一个好方法是设置直方图点刚好离开积分值,例如15 - e 其中e 的顺序为 10-6。

【讨论】:

    【解决方案2】:

    是的,

    添加 1e-6 通常有效,但通常在截断浮点数时必须更加小心。

    This blog 解释如果你想对浮点数进行四舍五入会遇到的所有问题(以及幼稚解决方案的陷阱)。它还建议以下更健壮的“添加1e-6”实现

     float myround(float f)
     {
          if (f >= 0x1.0p23) return f;
          return (float) (unsigned int) (f + 0.49999997f);
     }
    

    您可以测试 myround(0.49999997) = 0 和 myround(0.49999999) = 1。

    所以我会在完全解决这个问题之前先阅读这篇博客!

    另外一点是,c++11 有一个名为 std::round 的新函数,它返回最接近的整数,因此您还可以通过比较 std::abs(x - std::round(x)) < epsilon 来实现舍入,其中 epsilon 是您的目标。同样,这是一个幼稚的实现,不如 myround 健壮(您需要适应 double)。

    【讨论】:

      猜你喜欢
      • 2013-04-12
      • 2011-08-23
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多