Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rounding to even in C#

Tags:

c#

math

rounding

I'm not seeing the result I expect with Math.Round.

return Math.Round(99.96535789, 2, MidpointRounding.ToEven); // returning 99.97

As I understand MidpointRounding.ToEven, the 5 in the thousandths position should cause the output to be 99.96. Is this not the case?

I even tried this, but it returned 99.97 as well:

return Math.Round(99.96535789 * 100, MidpointRounding.ToEven)/100;

What am I missing

Thanks!

like image 816
Bret Walker Avatar asked Sep 14 '09 18:09

Bret Walker


People also ask

How do you round to the nearest even?

This familiar rule is used by many rounding methods. If the difference between the number and the nearest integer is exactly 0.5, look at the integer part of the number. If the integer part is EVEN, round towards zero. If the integer part of the number is ODD, round away from zero.

What is the even odd rounding rule?

EVEN: If the last retained digit is even, its value is not changed, the 5 and any zeros that follow are dropped. ODD: if the last digit is odd, its value is increased by one. Evens Rule Example 1: Round to one decimal place.

How do you round mantissa?

Rounding up is done by adding 1 to the mantissa in the mantissa's least significant bit position just before G . If the mantissa overflows (its 23 least significant bits that you will store become zeroes), you have to add 1 to the exponent.


1 Answers

You're not actually at the midpoint. MidpointRounding.ToEven indicates that if you had the number 99.965, i.e., 99.96500000[etc.], then you would get 99.96. Since the number you're passing to Math.Round is above this midpoint, it's rounding up.

If you want your number to round down to 99.96, do this:

// this will round 99.965 down to 99.96
return Math.Round(Math.Truncate(99.96535789*1000)/1000, 2, MidpointRounding.ToEven);

And hey, here's a handy little function to do the above for general cases:

// This is meant to be cute;
// I take no responsibility for floating-point errors.
double TruncateThenRound(double value, int digits, MidpointRounding mode) {
    double multiplier = Math.Pow(10.0, digits + 1);
    double truncated = Math.Truncate(value * multiplier) / multiplier;
    return Math.Round(truncated, digits, mode);
}
like image 80
Dan Tao Avatar answered Oct 30 '22 20:10

Dan Tao