486

I want to do this using the Math.Round function

Rex M
  • 142,167
  • 33
  • 283
  • 313

16 Answers16

799

Here's some examples:

decimal a = 1.994444M;

Math.Round(a, 2); //returns 1.99

decimal b = 1.995555M;

Math.Round(b, 2); //returns 2.00

You might also want to look at bankers rounding / round-to-even with the following overload:

Math.Round(a, 2, MidpointRounding.ToEven);

There's more information on it here.

radbyx
  • 9,352
  • 21
  • 84
  • 127
Eoin Campbell
  • 43,500
  • 17
  • 101
  • 157
  • 67
    You should clarify that MidPointRounding.ToEven IS the default. If you wanted AwayFromZero you would have to use the overload – Brian Vander Plaats Feb 23 '09 at 18:25
  • 7
    If you wanted to **round up** to 2 decimal places, add `0.005` to the number before rounding. Likewise to **round down**, subtract `0.005` before passing to `Math.Round` function. – orad Aug 19 '15 at 22:04
  • 7
    The reason that .NET defaults to `MidPointRounding.ToEven` (aka "Bankers Rounding") is because the we all learned to round in school where .5 rounds up causes too much rounding up. This is a problem when dealing with money, tax calculations, etc. – asporter Nov 11 '16 at 19:36
124

Try this:

twoDec = Math.Round(val, 2)
Pure.Krome
  • 84,693
  • 113
  • 396
  • 647
John Boker
  • 82,559
  • 17
  • 97
  • 130
44

If you'd like a string

> (1.7289).ToString("#.##")
"1.73"

Or a decimal

> Math.Round((Decimal)x, 2)
1.73m

But remember! Rounding is not distributive, ie. round(x*y) != round(x) * round(y). So don't do any rounding until the very end of a calculation, else you'll lose accuracy.

Colonel Panic
  • 132,665
  • 89
  • 401
  • 465
36

Personally I never round anything. Keep it as resolute as possible, since rounding is a bit of a red herring in CS anyway. But you do want to format data for your users, and to that end, I find that string.Format("{0:0.00}", number) is a good approach.

Gleno
  • 16,621
  • 12
  • 64
  • 85
16

Wikipedia has a nice page on rounding in general.

All .NET (managed) languages can use any of the common language run time's (the CLR) rounding mechanisms. For example, the Math.Round() (as mentioned above) method allows the developer to specify the type of rounding (Round-to-even or Away-from-zero). The Convert.ToInt32() method and its variations use round-to-even. The Ceiling() and Floor() methods are related.

You can round with custom numeric formatting as well.

Note that Decimal.Round() uses a different method than Math.Round();

Here is a useful post on the banker's rounding algorithm. See one of Raymond's humorous posts here about rounding...

Foredecker
  • 7,395
  • 4
  • 29
  • 30
  • Can you expand on "Decimal.Round()" uses a different method than Math.Round()"? As of 14 years (!) after you posted this, it doesn't look like there's any difference. – Josh Gallagher Jul 05 '22 at 17:03
16

// convert upto two decimal places

String.Format("{0:0.00}", 140.6767554);        // "140.67"
String.Format("{0:0.00}", 140.1);             // "140.10"
String.Format("{0:0.00}", 140);              // "140.00"

Double d = 140.6767554;
Double dc = Math.Round((Double)d, 2);       //  140.67

decimal d = 140.6767554M;
decimal dc = Math.Round(d, 2);             //  140.67

=========

// just two decimal places
String.Format("{0:0.##}", 123.4567);      // "123.46"
String.Format("{0:0.##}", 123.4);         // "123.4"
String.Format("{0:0.##}", 123.0);         // "123"

can also combine "0" with "#".

String.Format("{0:0.0#}", 123.4567)       // "123.46"
String.Format("{0:0.0#}", 123.4)          // "123.4"
String.Format("{0:0.0#}", 123.0)          // "123.0"
Rae Lee
  • 1,321
  • 10
  • 11
  • 2
    String.Format("{0:0.00}", 140.6767554); != "140.67" It actually renders as "140.68" - rounding up – AndyT Apr 07 '17 at 13:21
10

If you want to round a number, you can obtain different results depending on: how you use the Math.Round() function (if for a round-up or round-down), you're working with doubles and/or floats numbers, and you apply the midpoint rounding. Especially, when using with operations inside of it or the variable to round comes from an operation. Let's say, you want to multiply these two numbers: 0.75 * 0.95 = 0.7125. Right? Not in C#

Let's see what happens if you want to round to the 3rd decimal:

double result = 0.75d * 0.95d; // result = 0.71249999999999991
double result = 0.75f * 0.95f; // result = 0.71249997615814209

result = Math.Round(result, 3, MidpointRounding.ToEven); // result = 0.712. Ok
result = Math.Round(result, 3, MidpointRounding.AwayFromZero); // result = 0.712. Should be 0.713

As you see, the first Round() is correct if you want to round down the midpoint. But the second Round() it's wrong if you want to round up.

This applies to negative numbers:

double result = -0.75 * 0.95;  //result = -0.71249999999999991
result = Math.Round(result, 3, MidpointRounding.ToEven); // result = -0.712. Ok
result = Math.Round(result, 3, MidpointRounding.AwayFromZero); // result = -0.712. Should be -0.713

So, IMHO, you should create your own wrap function for Math.Round() that fit your requirements. I created a function in which, the parameter 'roundUp=true' means to round to next greater number. That is: 0.7125 rounds to 0.713 and -0.7125 rounds to -0.712 (because -0.712 > -0.713). This is the function I created and works for any number of decimals:

double Redondea(double value, int precision, bool roundUp = true)
{
    if ((decimal)value == 0.0m)
        return 0.0;

    double corrector = 1 / Math.Pow(10, precision + 2);

    if ((decimal)value < 0.0m)
    {
        if (roundUp)
            return Math.Round(value, precision, MidpointRounding.ToEven);
        else
            return Math.Round(value - corrector, precision, MidpointRounding.AwayFromZero);
    }
    else
    {
        if (roundUp)
            return Math.Round(value + corrector, precision, MidpointRounding.AwayFromZero);
        else
            return Math.Round(value, precision, MidpointRounding.ToEven);
    }
}

The variable 'corrector' is for fixing the inaccuracy of operating with floating or double numbers.

fedesanp
  • 309
  • 3
  • 4
9

This is for rounding to 2 decimal places in C#:

label8.Text = valor_cuota .ToString("N2") ;

In VB.NET:

 Imports System.Math
 round(label8.text,2)
Kate Gregory
  • 18,808
  • 8
  • 56
  • 85
sadim
  • 91
  • 1
  • 1
7

I know its an old question but please note for the following differences between Math round and String format round:

decimal d1 = (decimal)1.125;
Math.Round(d1, 2).Dump();   // returns 1.12
d1.ToString("#.##").Dump(); // returns "1.13"

decimal d2 = (decimal)1.1251;
Math.Round(d2, 2).Dump();   // returns 1.13
d2.ToString("#.##").Dump(); // returns "1.13"
Guy P
  • 1,395
  • 17
  • 33
7

Had a weird situation where I had a decimal variable, when serializing 55.50 it always sets default value mathematically as 55.5. But whereas, our client system is seriously expecting 55.50 for some reason and they definitely expected decimal. Thats when I had write the below helper, which always converts any decimal value padded to 2 digits with zeros instead of sending a string.

public static class DecimalExtensions
{
    public static decimal WithTwoDecimalPoints(this decimal val)
    {
        return decimal.Parse(val.ToString("0.00"));
    }
}

Usage should be

var sampleDecimalValueV1 = 2.5m;
Console.WriteLine(sampleDecimalValueV1.WithTwoDecimalPoints());

decimal sampleDecimalValueV1 = 2;
Console.WriteLine(sampleDecimalValueV1.WithTwoDecimalPoints());

Output:

2.50
2.00
Riyaz Hameed
  • 1,087
  • 12
  • 10
4

One thing you may want to check is the Rounding Mechanism of Math.Round:

http://msdn.microsoft.com/en-us/library/system.midpointrounding.aspx

Other than that, I recommend the Math.Round(inputNumer, numberOfPlaces) approach over the *100/100 one because it's cleaner.

Michael Stum
  • 177,530
  • 117
  • 400
  • 535
3

You should be able to specify the number of digits you want to round to using Math.Round(YourNumber, 2)

You can read more here.

2

Math.Floor(123456.646 * 100) / 100 Would return 123456.64

user3405179
  • 184
  • 11
2

Simply Math.Round() solves this problem and fits the situation by passing a precision parameter and MidpointRounding parameter to the method.

By default Math.Round uses MidpointRounding.ToEven which is actually bankers rounding meaning that the halfway numbers round to the nearest even number:

1.5 => 2
2.5 => 2
3.5 => 4
4.5 => 4

Let me make it clear. Actually, there are 5 strategies of MidpointRounding you could take to get what you expect from Math.Round():

  1. ToEven (default) When a number is halfway between two others, it is rounded toward the nearest even number.

  2. AwayFromZero (mathematical rounding) When a number is halfway between two others, it is rounded toward the nearest number away from zero. (Aka, round up)

  3. ToZero rounds down the number based on specified precision

  4. ToNegativeInfinity (floor) rounds down the number based on specified precision

  5. ToPositiveInfinity (ceiling) rounds up the number based on specified precision.

Here is the code to see exactly how they work:

var num1 = 1.5;
var num2 = 2.5;
var num3 = 3.5;
var num4 = 2.51;
var num5 = 2.48;

Console.WriteLine("----------------Round with MidpointRounding.ToEven (default) ---------------------");
Console.WriteLine($"{num1} => {Math.Round(num1, MidpointRounding.ToEven)}");
Console.WriteLine($"{num2} => {Math.Round(num2, MidpointRounding.ToEven)}");
Console.WriteLine($"{num3} => {Math.Round(num3, MidpointRounding.ToEven)}");
Console.WriteLine($"{num4} => {Math.Round(num4, MidpointRounding.ToEven)}");
Console.WriteLine($"{num5} => {Math.Round(num5, MidpointRounding.ToEven)}");

Console.WriteLine("----------------Round with MidpointRounding.AwayFromZero (mathematical rounding) ---------------------");
Console.WriteLine($"{num1} => {Math.Round(num1, MidpointRounding.AwayFromZero)}");
Console.WriteLine($"{num2} => {Math.Round(num2, MidpointRounding.AwayFromZero)}");
Console.WriteLine($"{num3} => {Math.Round(num3, MidpointRounding.AwayFromZero)}");
Console.WriteLine($"{num4} => {Math.Round(num4, MidpointRounding.AwayFromZero)}");
Console.WriteLine($"{num5} => {Math.Round(num5, MidpointRounding.AwayFromZero)}");

Console.WriteLine("----------------Round with MidpointRounding.ToZero ---------------------");
Console.WriteLine($"{num1} => {Math.Round(num1, MidpointRounding.ToZero)}");
Console.WriteLine($"{num2} => {Math.Round(num2, MidpointRounding.ToZero)}");
Console.WriteLine($"{num3} => {Math.Round(num3, MidpointRounding.ToZero)}");
Console.WriteLine($"{num4} => {Math.Round(num4, MidpointRounding.ToZero)}");
Console.WriteLine($"{num5} => {Math.Round(num5, MidpointRounding.ToZero)}");

Console.WriteLine("----------------Round with MidpointRounding.ToNegativeInfinity (floor) ---------------------");
Console.WriteLine($"{num1} => {Math.Round(num1, MidpointRounding.ToNegativeInfinity)}");
Console.WriteLine($"{num2} => {Math.Round(num2, MidpointRounding.ToNegativeInfinity)}");
Console.WriteLine($"{num3} => {Math.Round(num3, MidpointRounding.ToNegativeInfinity)}");
Console.WriteLine($"{num4} => {Math.Round(num4, MidpointRounding.ToNegativeInfinity)}");
Console.WriteLine($"{num5} => {Math.Round(num5, MidpointRounding.ToNegativeInfinity)}");

Console.WriteLine("----------------Round with MidpointRounding.ToPositiveInfinity (ceiling) ---------------------");
Console.WriteLine($"{num1} => {Math.Round(num1, MidpointRounding.ToPositiveInfinity)}");
Console.WriteLine($"{num2} => {Math.Round(num2, MidpointRounding.ToPositiveInfinity)}");
Console.WriteLine($"{num3} => {Math.Round(num3, MidpointRounding.ToPositiveInfinity)}");
Console.WriteLine($"{num4} => {Math.Round(num4, MidpointRounding.ToPositiveInfinity)}");
Console.WriteLine($"{num5} => {Math.Round(num5, MidpointRounding.ToPositiveInfinity)}");

the result:

----------------Round with MidpointRounding.ToEven (default) ---------------------
1.5 => 2
2.5 => 2
3.5 => 4
2.51 => 3
2.48 => 2
----------------Round with MidpointRounding.AwayFromZero (mathematical rounding) ---------------------
1.5 => 2
2.5 => 3
3.5 => 4
2.51 => 3
2.48 => 2
----------------Round with MidpointRounding.ToZero ---------------------
1.5 => 1
2.5 => 2
3.5 => 3
2.51 => 2
2.48 => 2
----------------Round with MidpointRounding.ToNegativeInfinity ---------------------
1.5 => 1
2.5 => 2
3.5 => 3
2.51 => 2
2.48 => 2
----------------Round with MidpointRounding.ToPositiveInfinity ---------------------
1.5 => 2
2.5 => 3
3.5 => 4
2.51 => 3
2.48 => 3
mahdi yousefi
  • 807
  • 1
  • 9
  • 15
  • don't copy and paste answers. customize the answer to the question. you have a bunch of useless noise here – starball Aug 07 '23 at 02:10
  • when someone gets here from a Google search there should be a complete explanation of how things work exactly, to fully understand the usage, and I clearly explained for everyone who reaches this page to get the answer to their problem – mahdi yousefi Aug 07 '23 at 09:15
  • take the [tour]. one of the whole points of this platform is to avoid noise. – starball Aug 07 '23 at 09:18
  • So how could others find the whole explanation of a topic or a problem? – mahdi yousefi Aug 07 '23 at 09:21
  • find a question that actually asks this info and then write this as an answer there. – starball Aug 07 '23 at 09:36
  • I deleted my other answer to that similar question, and put the link to this answer there! thank you for your feedback. – mahdi yousefi Aug 07 '23 at 09:41
1

string a = "10.65678";

decimal d = Math.Round(Convert.ToDouble(a.ToString()),2)

Abhishek Jaiswal
  • 1,161
  • 12
  • 6
0
  public double RoundDown(double number, int decimalPlaces)
        {
            return Math.Floor(number * Math.Pow(10, decimalPlaces)) / Math.Pow(10, decimalPlaces);
        }
Ruan
  • 3,969
  • 10
  • 60
  • 87