2017-02-28 70 views
1

我想圆双打到特定的精度,但是下面的功能给我不同的结果:奇怪的舍入行为

版本1:

static double RoundPrecision(double& val) 
{ 
    val = floor(val * 1000 + 0.5) * 0.001; 
    return val; 
} 

版本2:

static double RoundPrecision(double& val) 
{ 
    val = floor(val * 1000 + 0.5)/1000; 
    return val; 
} 

四舍五入300.9时的输出示例:

  • 版本1:300.90000000000003
  • 版本2:300.89999999999998

两个版本有时给出相同的结果,但对于特定输入端的结果不同。将数字等同于程序中的其他变量时,必须有一致的行为。

编辑:

我所知道的浮点精确度,而这正是我试图通过四舍五入来避免此问题。我需要一个一致的方法来精确到小数点后3位。

+0

舍入的要点是避免这些内置的精度错误,这只是我需要一致的结果 –

+0

计算机的精度有限。您可以接受'double'或'float'中的可用精度,或者您寻找能够给出足够精度但性能更差的其他库。实际上,你无法在计算机上获得确切的实数,你甚至不需要它。 'double'给你10^-16的相对精度,然后尝试'long double'。如果这还不够,那么寻找可以为你做到这一点的外部库。下面是一个任意精度库的例子:https://gmplib.org/ –

+0

我需要精确到3个小数点,这就是为什么我有这些功能。我的问题是,以这种精度舍入的两种方式都会产生不同的结果,而且我需要知道使用哪一种。 –

回答

1

电脑的精度有限。您要么接受双精度或浮点精度的可用精度,要么寻找其他能够提供足够精度但性能更差的库。实际上,你无法在计算机上获得确切的实数,你甚至不需要它。双倍给你10^-16的相对精度,然后尝试两倍。如果这还不够,那么寻找可以为你做到这一点的外部库。 Here's an example of an arbitrary precision library

从评论我看到,你需要3位小数精度。如果你读到这个数字最多3个小数点,那么两个结果都是一样的。我认为你感到困惑的原因是你不知道如何比较花车。 Here's how you do it