2

I am looking for a way to round to the nearest dollar with the following stipulations:
(If wholenumber.50 and above round up to the next whole number)
(If wholenumber.49 and below round down to the current whole number)

I have tried:

Math.Round(wholenumber.xx, MidpointRounding.ToEven);

This doesn't always round how I want for instance 1.5 = 2 and 2.5 = 2 as it rounds to nearest even number.

I have also tried:

Math.Round(wholenumber.xx, MidpointRounding.AwayFromZero);

This always rounds up to the higher whole number.

Is there any built in functionality for what I am trying to do or will I need to write my own custom method to check the number and do floor or ceil depending?

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
Baxter
  • 5,633
  • 24
  • 69
  • 105
  • 5
    Using floating point arithmetics to store currency is never a good idea though.. – Jack Apr 09 '12 at 21:40
  • You can do Math.round without a second parameter I think? That's the default rounding like you described. – MarioDS Apr 09 '12 at 21:41
  • 3
    MidpointRounding.AwayRoundZero is what you describe. It doesn't mean to round up all values, only midpoints (0.5). – dtb Apr 09 '12 at 21:41
  • 4
    @Jack: It is perfectly acceptable to use floating point arithmetic; you should avoid *binary* floating point arithmetic. The `decimal` type is a floating point type, it is just not a *binary* floating point type. As its name indicates, it is a *decimal* floating point type. – Eric Lippert Apr 09 '12 at 21:48
  • You do not say what you want to happen for negative numbers. When you say "round up" on a negative number do you mean round *up in magnitude* -- away from zero -- or round *up in value* -- towards zero? – Eric Lippert Apr 09 '12 at 21:52
  • There will never be negative numbers in this scenario. – Baxter Apr 09 '12 at 21:53

1 Answers1

12

First off, I note that you should always use decimal for this task; never use double. If you are using double, stop what you are doing right now and fix your program so that you stop using a type designed for physics problems and start using a type designed for money problems to solve your money problem.

Second, you are simply wrong when you say

This always rounds up to the higher whole number.

It does not. It rounds to the nearest whole number, and if there is no nearest whole number because you are at a midpoint, then it chooses the whole number that is farther from zero.

Try it, if you don't believe me:

using System;
class P
{
  static void Main()
  {
    decimal buckFifty = 1.50m;
    decimal buckFortyNine = 1.49m;
    Console.WriteLine(Math.Round(buckFortyNine, MidpointRounding.AwayFromZero));
    Console.WriteLine(Math.Round(buckFifty, MidpointRounding.AwayFromZero));
    Console.WriteLine(Math.Round(-buckFortyNine, MidpointRounding.AwayFromZero));
    Console.WriteLine(Math.Round(-buckFifty, MidpointRounding.AwayFromZero));
  }
}

results are

1
2
-1
-2
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • I see what you mean. I was thinking of it in the context of being at the midpoint. It always goes to the higher number when at the midpoint. I am also using Decimal already. – Baxter Apr 09 '12 at 21:51
  • 1
    @Baxter: *"It always goes to the higher number when at the midpoint."* - According to your question, that's exactly what you want... – BlueRaja - Danny Pflughoeft Apr 09 '12 at 21:52
  • 1
    Thanks, that set me straight. – John H Apr 09 '12 at 21:53
  • 2
    @Baxter: **No**. When *at the midpoint* it always goes to the number *farther away from zero*. That's why the enum value is called **MidpointRounding.AwayFromZero**. If it always went to the *higher* number then it would be **MidpointRounding.ToHigherNumber**. -2 is *further from zero* than -1, but -1 is *higher* than -2. – Eric Lippert Apr 09 '12 at 21:55