12

Is there a built-in method for it? The .NET framework must have a method to do this!

private decimal RoundDownTo2DecimalPlaces(decimal input)
{
   if (input < 0)
   {
      throw new Exception("not tested with negative numbers");
   }

   // There must be a better way!
   return Math.Truncate(input * 100) / 100;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ian Ringrose
  • 51,220
  • 55
  • 213
  • 317
  • Do you want to round down the decimal itself or a text representation? – H H Sep 26 '10 at 10:13
  • @Henk, I need to output the value as text, but would rather do the rounding before the output. It is likly the value will have to feed into other calcs later. – Ian Ringrose Sep 26 '10 at 10:17
  • 1
    possible duplicate of [Round a double to 2 significant figures after decimal point](http://stackoverflow.com/questions/2808535/round-a-double-to-2-significant-figures-after-decimal-point) – ecatmur Sep 17 '12 at 17:24

5 Answers5

22

If you are rounding down then you need:

Math.Floor(number * 100) / 100;

If you are looking for something called bankers' rounding (probably not if it's for output and not for statistics/summing) then:

Math.Round(number, 2);

Finally, if you want—I am not sure what the correct term is—'normal rounding':

Math.Round(number, 2, MidpointRounding.AwayFromZero);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
FinnNk
  • 3,249
  • 23
  • 25
  • 1
    Look at my response below: MidpointRounding.AwayFromZero or MidpointRounding.ToEven specify how to handle numbers ending with '5': the MidpointRounding.ToEven specify that 1.135 should be round to 1.13, and 1.145 to 1.15 the MidpointRounding.AwayFromZero specify that 1.135 should be round to 1.14, and 1.145 to 1.15 – Andrea Parodi Sep 26 '10 at 10:56
7

Use Math.Floor if you want to round down the value, or Math.Round if you want to get an exact round. Math.Truncate simply removes the decimal part of the number, so you get bad results for negative numbers:

var result = Math.Floor(number * 100) / 100;

Math.Floor always returns the smallest integral value that is lesser (floor) or greater (ceiling) than the specified value. So you don't get a correct rounding. Example:

Math.Floor(1.127 * 100) / 100 == 1.12 // Should be 1.13 for an exact round
Math.Ceiling(1.121 * 100) / 100 == 1.13 // Should be 1.12 for an exact round

Always prefer the version of Math.Round containing the mid-point rounding parameter. This parameter specifies how to handle mid-point values (5) as the last digit.

If you don't specify AwayFromZero as the value for the parameter, you'll get the default behaviour, which is ToEven. For example, using ToEven as the rounding method, you get:

Math.Round(2.025, 2) == 2.02
Math.Round(2.035, 2) == 2.04

Instead, using the MidPoint.AwayFromZero parameter:

Math.Round(2.025, 2, MidpointRounding.AwayFromZero) == 2.03
Math.Round(2.035, 2, MidpointRounding.AwayFromZero) == 2.04

So, for a normal rounding, it's best to use this code:

var value = 2.346;
var result = Math.Round(value, 2, MidpointRounding.AwayFromZero);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Andrea Parodi
  • 5,534
  • 27
  • 46
3
Math.Floor(number * 100) / 100;
Itay Karo
  • 17,924
  • 4
  • 40
  • 58
  • butter then my solution, as Math.Floor give the correct result with negitive numbers. see http://stackoverflow.com/questions/14/whats-the-difference-between-math-floor-and-math-truncate-in-net – Ian Ringrose Sep 26 '10 at 10:27
3

Use .Truncate() to get the exact amount, or .Round() to round off.

decimal dNum = (decimal)165.6598F;
decimal dTruncated = (decimal)(Math.Truncate((double)dNum*100.0) / 100.0); // Will give 165.65
decimal dRounded = (decimal)(Math.Round((double)dNum, 2)); // Will give 165.66

Or you can make an extension method to run it like dNum.ToTwoDecimalPlaces();

public static class Extensions
{
    public static decimal ToTwoDecimalPlaces(this decimal dNum)
    {
        return ((decimal)(Math.Truncate((double)dNum*100.0) / 100.0));
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
KMån
  • 9,896
  • 2
  • 31
  • 41
0

There isn't any built-in method in the .NET framework to do this. Other answers say how to write your own code.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ian Ringrose
  • 51,220
  • 55
  • 213
  • 317