我需要一个简单的浮点舍入函数,这样:

double round(double);

round(0.1) = 0
round(-0.1) = 0
round(-0.9) = -1

我可以在math.h中找到ceil()和floor() -但没有round()。

它是否以另一个名字出现在标准c++库中,或者它是否丢失了??


当前回答

我在asm的x86架构和MS VS特定的c++中使用round的以下实现:

__forceinline int Round(const double v)
{
    int r;
    __asm
    {
        FLD     v
        FISTP   r
        FWAIT
    };
    return r;
}

UPD:返回双值

__forceinline double dround(const double v)
{
    double r;
    __asm
    {
        FLD     v
        FRNDINT
        FSTP    r
        FWAIT
    };
    return r;
}

输出:

dround(0.1): 0.000000000000000
dround(-0.1): -0.000000000000000
dround(0.9): 1.000000000000000
dround(-0.9): -1.000000000000000
dround(1.1): 1.000000000000000
dround(-1.1): -1.000000000000000
dround(0.49999999999999994): 0.000000000000000
dround(-0.49999999999999994): -0.000000000000000
dround(0.5): 0.000000000000000
dround(-0.5): -0.000000000000000

其他回答

你可以四舍五入到n位精度:

double round( double x )
{
const double sd = 1000; //for accuracy to 3 decimal places
return int(x*sd + (x<0? -0.5 : 0.5))/sd;
}

小心地板(x+0.5)。下面是在[2^52,2^53]范围内奇数的情况:

-bash-3.2$ cat >test-round.c <<END

#include <math.h>
#include <stdio.h>

int main() {
    double x=5000000000000001.0;
    double y=round(x);
    double z=floor(x+0.5);
    printf("      x     =%f\n",x);
    printf("round(x)    =%f\n",y);
    printf("floor(x+0.5)=%f\n",z);
    return 0;
}
END

-bash-3.2$ gcc test-round.c
-bash-3.2$ ./a.out
      x     =5000000000000001.000000
round(x)    =5000000000000001.000000
floor(x+0.5)=5000000000000002.000000

这里是http://bugs.squeak.org/view.php?id=7134。使用@konik这样的解决方案。

我自己的健壮版本是这样的:

double round(double x)
{
    double truncated,roundedFraction;
    double fraction = modf(x, &truncated);
    modf(2.0*fraction, &roundedFraction);
    return truncated + roundedFraction;
}

这里给出了避免下限(x+0.5)的另一个原因。

编者注:下面的答案提供了一个简单的解决方案,其中包含几个实现缺陷(参见Shafik Yaghmour的答案以获得完整的解释)。注意,c++ 11已经将std::round、std::lround和std::llround作为内置程序。

c++ 98标准库中没有round()。不过你可以自己写。下面是round-half-up的实现:

double round(double d)
{
  return floor(d + 0.5);
}

c++ 98标准库中没有循环函数的可能原因是它实际上可以以不同的方式实现。以上是一种常见的方法,但还有其他的方法,如四舍五入到偶数,如果你要做很多四舍五入,这种方法的偏差更小,通常更好;不过实现起来有点复杂。

它通常实现为下限(值+ 0.5)。

编辑:它可能不叫四舍五入,因为我知道至少有三种四舍五入算法:四舍五入到零,四舍五入到最接近的整数,以及银行家的四舍五入。你要求的是最接近的整数。

Boost提供了一组简单的舍入函数。

#include <boost/math/special_functions/round.hpp>

double a = boost::math::round(1.5); // Yields 2.0
int b = boost::math::iround(1.5); // Yields 2 as an integer

有关更多信息,请参阅Boost文档。

编辑:从c++ 11开始,有std::round, std::lround和std::llround。