tags:

views:

150

answers:

3

Hi All,

I am running this code:

decimal d = 1.45M;

Console.WriteLine((System.Math.Round(d,0,MidpointRounding.AwayFromZero).ToString()));

Here I expect the output to be 2 because 1.45 when rounded to 1st decimal place will be 1.5 which when next rounded to 0 decimal places should be 2.

However, I am getting the answer as 1.

Is my assumption correct? If so, is this a bug with Math.Round?

+5  A: 

No, it's not a bug. Your logic talks about rounding twice - but you've only got a single call to Round. 1.45 is less than the midpoint between 1 and 2 (1.5) so it's rounded down to 1.

If you want the code to follow your logic, you can do this:

using System;

class Test
{
    static void Main()
    {
        decimal d = 1.45m;
        d = Math.Round(d, 1, MidpointRounding.AwayFromZero); // 1.5
        d = Math.Round(d, 0, MidpointRounding.AwayFromZero); // 2

        Console.WriteLine(d);
    }
}

Unless you specify that you want two phases of rounding though (as above) .NET will just do the one.

Jon Skeet
Please run this
PrateekSaluja
d = Math.Round(d, 0, MidpointRounding.AwayFromZero);output will be 1 not 2.
PrateekSaluja
@prateeksaluja20: I ran it. The result was 2. Bear in mind that `d` is 1.5m when the second call to Math.Round is run... note the assignment to `d` with the results of the first call.
Jon Skeet
Yep i checked if i assigned a value so output will like that.
PrateekSaluja
Thanks Jon. Its just the notion I had that .net will start rounding the value from the rightmost digit and show only up to the number of decimals specified.
Jeevan
A: 

You can't do 'round' action one digit by one digit! Here you say:

1.45 rounded to 1 decimal place:1.5
1.5 rounded to 0 decimal place:2

It's not correct, here 1.45 rounded to 0 digits, you need to check .4 only.

Danny Chen
A: 

Your understanding is incorrect.

You have specified a decimals value of 0 therefore the value supplied will be rounded to an integer value.

From MSDN "If the value of the first digit in d to the right of the decimal position represented by the decimals parameter is 5, the digit in the decimals position is rounded up if it is odd or left alone if it is even"

As the first value to the right of the decimal point is 4 and not five then the value returned is 1.

If the decimal value had been 1.55 then the answer would have been 2.

If the decimal value had been 2.55 then the answer would have been 2 as well!

As you are specifying the midpoint rounding behaviour then this will be altered, but you as you are asking the round to work with decimals=0 it will only check the first digit after the decimal point.

Infact if you specified decimals=1 as in

Math.Round(1.45,1)

Then your answer would be 1.4 as it checks the second digit after the decimal point for rounding of the first.

ChrisBD