0

I am trying to round up decimal numbers towards positive infinity in C# .Net Standard 2.1 library using Math.Round() function with MidpointRounding.ToPositiveInfinity enum as its mode parameter but I don't know why it doesn't exist in the MidpointRounding enum. the same enum value (ToPositiveInfinity) exists when the project is using .net 5. Code

Math.Round(2.336, 2, MidpointRounding.ToPositiveInfinity);

Does anyone know how I can fix this?

enter image description here

Fouad
  • 131
  • 1
  • 11
  • 6
    The [`MidpointRounding` enum in .NET Standard 2.1](https://learn.microsoft.com/en-us/dotnet/api/system.midpointrounding?view=netstandard-2.1) only has `AwayFromZero` and `ToEven`. The other modes, such as `ToPositiveInfinity`, were added later, in .NET Core 3.0. You can't use functionality which doesn't exist (in the runtime you're targetting), unless you implement it yourself. – canton7 Jan 04 '22 at 14:21
  • @canton7 Do you have any idea that how I can implement it? – Fouad Jan 04 '22 at 15:44
  • @Fouad `Math.Floor(x+0.5)` – D Stanley Jan 04 '22 at 16:02
  • @DStanley, it returns an integral value. I need a upward rounded decimal value with two decimal places. Ex: 1.232 => 1.24 | 1.261 => 1.27 | 1.251 => 126 | 1.350 => 1.350 – Fouad Jan 04 '22 at 17:10
  • @Fouad If all of your inputs are positive, just use `.AwayFromZero`. `.ToPositiveInfinity` and `.AwayFromZero` only differ if the input is negative – canton7 Jan 04 '22 at 17:11
  • @Fouad `Math.Floor(x * Math.Pow(10,decimals) + 0.5) / Math.Pow(10,decimals))` – D Stanley Jan 04 '22 at 17:31
  • @canton7 Can't negative inputs be handled by changing sign before and after rounding `.AwayFromZero`? `public static double RoundToPositiveInfinity(double num, int decimals) => (num < 0) ? -Math.Round(-num, decimals, MidpointRounding.AwayFromZero) : Math.Round(num, decimals, MidpointRounding.AwayFromZero); ` – NetMage Jan 04 '22 at 20:09
  • @NetMage I would have thought so – canton7 Jan 04 '22 at 20:39
  • Thanks @NetMage but your solution is not rounding to positive infinity. – Fouad Jan 05 '22 at 10:25
  • @canton7 thanks yes inputs are positive numbers but AwayFromZero and ToPositiveInfinity are different. If you test these two approaches on my examples in the fourth comment fr top you will notice the difference. – Fouad Jan 05 '22 at 10:30
  • Ah, `ToPositiveInfinity` and `ToNegativeInfinity` and `ToZero` aren't actually *midpoint* rounding strategies, despite the enum name. They don't control how we round at the midpoint (e.g. 2.5), they control whether we ceiling or floor the value. That's very confusing. Ignore what I said earlier. – canton7 Jan 05 '22 at 10:56
  • 2
    In that case, `ToPositiveInfinity` is the same as `Math.Ceiling`. So `Math.Ceiling(2.336 * 100) / 100` or so? – canton7 Jan 05 '22 at 10:57

1 Answers1

1

The MidpointRounding enum in .NET Standard 2.1 only has AwayFromZero and ToEven. The other modes, such as ToPositiveInfinity, were added later, in .NET Core 3.0. You can't use functionality which doesn't exist (in the runtime you're targetting), unless you implement it yourself.

However, ToPositiveInfinity does the same thing as Math.Ceiling, so you can use that. Math.Ceiling however doesn't support specifying the number of decimal places to round to, but you can overcome that with a little multiplication:

Math.Ceiling(2.336 * 100) / 100;
canton7
  • 37,633
  • 3
  • 64
  • 77
  • I would speculate that for some precisions there could be a different answer between `ToPositiveInfinity` and `Math.Ceiling`, but not at two places. – NetMage Jan 05 '22 at 20:01
  • @NetMage Would you provide an example? – Fouad Jan 08 '22 at 17:08
  • In addition to @canton7's answer following extension method will support all decimal places, --- public static decimal ToPositiveInfinity(this decimal value, int decimals) { var decimalPlaces = Convert.ToDecimal(Math.Pow(10, decimals)); return Math.Ceiling(value * decimalPlaces) / decimalPlaces; } – Fouad Jan 08 '22 at 17:12