round() for float in C++

后端 未结 22 1224
时光取名叫无心
时光取名叫无心 2020-11-22 03:01

I need a simple floating point rounding function, thus:

double round(double);

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

I can find

22条回答
  •  太阳男子
    2020-11-22 03:34

    Beware of floor(x+0.5). Here is what can happen for odd numbers in range [2^52,2^53]:

    -bash-3.2$ cat >test-round.c <
    #include 
    
    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
    

    This is http://bugs.squeak.org/view.php?id=7134. Use a solution like the one of @konik.

    My own robust version would be something like:

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

    Another reason to avoid floor(x+0.5) is given here.

提交回复
热议问题