简体   繁体   中英

Rounding error in C++ Visual Studio Express 2012

I am encountering a very weird functionality while trying to write my own rounding function in C++.

Both of the following functions produce 0.000 as an output.

double round ( double x, int y)
{
    double value = 0;

    value = floor(x*pow(10, y) + x>=0?0.5:-0.5)/pow(10, y);

    return value;
}

double round3(double x)
{
    double value = 0;

    value = floor(x * 1000 + x>=0?0.5:-0.5) / 1000;

    return value;
}

However this function produces correct output, rounding to 3 decimal places.

double round(double x)
{
    double value = 0;

    if (x >= 0){
        value = floor( x*1000 + 0.5 )/1000;
    }
    else{
        value = floor( x*1000 - 0.5 )/1000;
    }
    return value;
}

Can anyone enlighten me as to why this is happening?

The ternary operator ?: has a rather low priority, this

x * 1000 + x>=0?0.5:-0.5

is equivalent to:

(x * 1000 + x>=0)?0.5 :-0.5

which results as either 0.5 or -0.5 .

The first two have operator precendence errors, eg (x * 1000 + x>=0?0.5:-0.5) / 1000 is evaluated as (((x * 1000 + x) >= 0) ? 0.5 : -0.5) / 1000 , so is 0.0005 when x is positive, and -0.0005 when x is negative.

Do keep in mind too that "rounding" of doubles is a tricky business... there can generally be errors around the 15th or 16th digit, whether because the "mathematically perfect" result of the operations you've performed can't be represented exactly in a double variable, or because of approximations in intermediate values or maths functions like pow , so you may find values you think of as being "n.5" are sometimes rounded up and sometimes down. If confused by this, perhaps read What Every Computer Scientist Should Know About Floating-Point Arithmetic .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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