简体   繁体   English

C ++舍入问题

[英]C++ rounding issue

I am trying to create a histogram using GSL. 我正在尝试使用GSL创建直方图。 I get a problem when I try to add to the histogram the value of the division 1470/100. 当我尝试将直方图的值除以1470/100时遇到问题。 This results in 14.69999999 and when added to the histogram it gets rounded to the lower bin. 结果为14.69999999,当添加到直方图中时,将四舍五入到较低的bin。 My question is how can i make 1470/100 result in 14.7 and not 14.69999? 我的问题是如何使1470/100的结果变为14.7,而不是14.69999? Thank you 谢谢

Edit: 编辑:

int minRange = 14;
double val;


val = minRange + j*0.05;


gsl_histogram_increment(hist, val);

When val is added to the histogram it is considered to be 14.65 instead of 14.7. 将val添加到直方图中时,它被认为是14.65而不是14.7。 (j is 14 in this case). (在这种情况下,j为14)。

I solved the issue by adding 1e-6 to val. 我通过在val中添加1e-6解决了该问题。 Thank you for the help 感谢您的帮助

This is a floating point precision issue. 这是一个浮点精度问题。 A good way to solve is to set the histrogram points just off the integral values, eg 15 - e where e is of the order 10-6. 一种很好的解决方法是将直方图点设置在积分值附近,例如15 - e ,其中e约为10-6。

Yes, 是,

Adding 1e-6 usually works, but in general you have to be more careful when truncating float. 通常添加1e-6是可行的,但是通常在截断float时必须更加小心。

This blog explain all the problems you can face if you want to round float numbers (and also the pitfalls of naive solutions). 该博客介绍了如果要舍入浮点数会遇到的所有问题(以及幼稚的解决方案的陷阱)。 It also suggest the following more robust implementation of "adding 1e-6" 它还建议使用以下更强大的“添加1e-6”实现

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

You can test that myround(0.49999997) = 0 and myround(0.49999999) = 1 . 您可以测试myround(0.49999997)= 0和myround(0.49999999)= 1。

So I would read this blog first before calling this question completely solved! 因此,在将这个问题完全解决之前,我会先阅读此博客!

Another point is that c++11 has a new function called std::round which returns the nearest integer so you can also implement rounding by comparing std::abs(x - std::round(x)) < epsilon , where epsilon is your target. 另一点是,c ++ 11具有一个称为std :: round的新函数,该函数返回最接近的整数,因此您还可以通过比较std::abs(x - std::round(x)) < epsilon来实现舍入,其中epsilon是您的目标。 Again this is a naive implementation that is not as robust as myround (which you need to adapt to double). 同样,这是一个天真的实现,没有myround健壮(您需要适应double)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM