1

I'm interested how to round up double variable to 2 decimal places in some a little bit specific way. What exactly do I mean? Math.Round ( number, 2) works fine but... I have for example number like 17.0449999...

Math.Round(17.044999, 2) // 17.04

But in that case i'd like to get 17.05. I found a way how to do this, for example:

Math.Round(17.044999, 3) // returns 17.045
Math.Round(17.045, 2) // returns 17.05

What I would like to ask is there some other/better/more simple way to do that?

[EDIT]:

I think i found that's kinda strange problem. From the beginning:

We talk about specific number. I have to count 5% from a prize and in that case prize is 340,9. When i do calculations in windows calculator 340,9 * 0.05 the result is 17,045. Same result i get when i do calculations in Excel. But when i do same calculations in C# i get something like 17,04499999998. Which is obviously so close to 17.045 that we could easily round it up. But the point is that i can't round up to 3 decimal places every result, because that might change other results.

Seems that is special case or C# calculations are "too accurate".

Stasiak
  • 51
  • 1
  • 1
  • 4
  • 6
    So... you wan't to round it wrong? You should probably stick to what you are doing already then, because you won't find a built in round function that is designed to produce incorrect results – musefan Aug 10 '16 at 11:08
  • 3
    Can you describe when you want to round up, rather than down? – doctorlove Aug 10 '16 at 11:12
  • @musefan Actually, if the number is 17.0449999 repeated, then the number [is equal to 17.045](https://en.wikipedia.org/wiki/0.999...) – PC Luddite Aug 10 '16 at 11:14
  • 1
    Yes i know that is wrong and i tottaly agree with that. But that is a requirement of my project i have to met - that's stronger than me :) – Stasiak Aug 10 '16 at 11:14
  • @PCLuddite: That's far more than I intend to read... but it seems specific only to 0.999 (recurring) being equal to 1 – musefan Aug 10 '16 at 11:21
  • @musefan I don't think it's specific to just 1. Given (1/9) = 0.1111.... and (1/9) * 9 = 0.9999... = 1, then you could say ((1/9) * 9)/1000 + 17.044 = 17.0449999... = 17.045. – PC Luddite Aug 10 '16 at 13:57
  • @PCLuddite: I don't think it's meant to be a general rule, and it seems it's not a widely agreed standard anyway. Beside in rounding, it doesn't factor. Even with infinite 9's... .0449999 is closer to .04 than it is to .05 – musefan Aug 10 '16 at 14:10
  • @musefan True, you would round .044 to .04, but you would round .045 to .05, and if it's 0.044999... then it's equal to 0.045. Wouldn't you round it the same way? (and it *is* a general rule, widely agreed upon by mathematicians. The example it gives in the second paragraph of that article is that 8.32 = 8.31999…) – PC Luddite Aug 10 '16 at 15:00

2 Answers2

10

You can use:

System.Math.Ceiling (n * 100) / 100;

As explained here:

Difference between Math.Floor() and Math.Truncate()

Example:

System.Math.Ceiling (17.044999 * 100) / 100; // Returns 17.05
Community
  • 1
  • 1
Rian Mostert
  • 714
  • 1
  • 7
  • 19
4
public decimal RoundDown(decimal i, double decimalPlaces)
{
   var power = Math.Pow(10, decimalPlaces);
   return Math.Floor(i * power) / power;
}

public decimal RoundUp(decimal i, double decimalPlaces)
{
   var power = Math.Pow(10, decimalPlaces);
   return Math.Ceiling(i * power) / power;
}

RoundDown(17.045, 2);  // 17.04
RoundUp(17.045, 2);    // 17.05
Nick Bull
  • 9,518
  • 6
  • 36
  • 58
  • 1
    This surely is a "other" way, but I'm not convinced that it's a "better/more simple" way :) – René Vogt Aug 10 '16 at 11:10
  • @RenéVogt It offers some insight about what's going on behind the scenes algorithmically - hopefully he can use that more his "efficiency" purposes... must be doing a lot of rounding! – Nick Bull Aug 10 '16 at 11:14
  • Retrospectively a couple years on since writing this, I'd heavily recommend the accepted answer - you're going to overflow a lot quicker using the method in this answer – Nick Bull Jan 31 '22 at 11:05