Math.Round() behaviour in .NET 4 [duplicate]

2020-04-26 13:01发布

问题:

This question already has answers here:
Closed 9 years ago.

Possible Duplicates:
In C#: Math.Round(2.5) result is 2 (instead of 3)! Are you kidding me?
.Net Round Bug

I have a halfway value (number.5) and I need to specify how this will be rounded (upper or lower value.)

I understand the behaviour of Math.Round with the MidPointRounding parameter but that does not solve my problem:

// To Even
Console.WriteLine(Math.Round(4.4)); // 4
Console.WriteLine(Math.Round(4.5)); // 4
Console.WriteLine(Math.Round(4.6)); // 5
Console.WriteLine(Math.Round(5.5)); // 6

// AwayFromZero
Console.WriteLine(Math.Round(4.4)); // 4
Console.WriteLine(Math.Round(4.5)); // 5
Console.WriteLine(Math.Round(4.6)); // 5
Console.WriteLine(Math.Round(5.5)); // 6

// in one case I need 
Console.WriteLine(Math.Round(4.4)); // 4
Console.WriteLine(Math.Round(4.5)); // 4
Console.WriteLine(Math.Round(4.6)); // 5
Console.WriteLine(Math.Round(5.5)); // 5

// another case I need
Console.WriteLine(Math.Round(4.4)); // 4
Console.WriteLine(Math.Round(4.5)); // 5
Console.WriteLine(Math.Round(4.6)); // 5
Console.WriteLine(Math.Round(5.5)); // 6

回答1:

You have a overload to Math.Round that take a enum value from MidpointRounding.

This has two options:

  • ToEven (default) Also called bankers rounding. Will round to the nearest pair. So 2.5 becomes 2, while 3.5 becomes 4.
  • AwayFromZero: Always round X.5 up to X+1; So 2.5 for example becomes 3.


回答2:

It seems like what you want is a non-existant MidpointRounding value of TowardsZero or TowardsNegativeInfinity. The only option is to code the rounding yourself.

perhaps something like this: (not tested, and probably doesn't deal well with inf/nan etc)

double RoundTowardNegInfinity(double val)
{
  var frac = val - Math.Truncate(val);
  if (frac == 0.5 || frac == -0.5)
  {
    return Math.Floor(val);
  }
  return Math.Round(val);
}

double RoundTowardZero(double val)
{
  var frac = val - Math.Truncate(val);
  if (frac == 0.5 || frac == -0.5)
  {
    return Math.Truncate(val);
  }
  return Math.Round(val);
}


回答3:

The Round method has two different ways of rounding that you can specify:

value = Math.Round(value, MidpointRounding.ToEven);

and:

value = Math.Round(value, MidpointRounding.AwayFromZero);

(If you don't specify a MidpointRounding value, ToEven is used.)

If you want to want to round up, you use the Ceiling method instead:

value = Math.Ceiling(value);

If you want to round down, you use the Floor method:

value = Math.Floor(value);


回答4:

You can use Math.Round(), Math.Ceiling() or Math.Floor() depending on your needs.



回答5:

Have a look at http://msdn.microsoft.com/en-us/library/ms131274.aspx, you can use the Math.Round(Decimal, MidpointRounding) for this.



回答6:

Take a look at the Math.Round() call that takes a MidpointRounding argument. With it, you can specify ToEven (rounded towards the nearest even number) or AwayFromZero (rounded to the nearest number in the direction away from zero) to alter the rounding behaviour.