Question

When displaying the value of a decimal currently with .ToString(), it's accurate to like 15 decimal places, and since I'm using it to represent dollars and cents, I only want the output to be 2 decimal places.

Do I use a variation of .ToString() for this?

Was it helpful?

Solution

decimalVar.ToString ("#.##"); // returns "" when decimalVar == 0

or

decimalVar.ToString ("0.##"); // returns "0"  when decimalVar == 0

OTHER TIPS

I know this is an old question, but I was surprised to see that no one seemed to post an answer that;

  1. Didn't use bankers rounding
  2. Didn't keep the value as a decimal.

This is what I would use:

decimal.Round(yourValue, 2, MidpointRounding.AwayFromZero);

http://msdn.microsoft.com/en-us/library/9s0xa85y.aspx

decimalVar.ToString("F");

This will:

  • Round off to 2 decimal places eg. 23.456 => 23.46
  • Ensure that there are always 2 decimal places eg. 23 => 23.00, 12.5 => 12.50

Ideal for currency and displaying monetary amounts.

For documentation on ToString("F"): http://msdn.microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx#FFormatString (with thanks to Jon Schneider)

If you just need this for display use string.Format

String.Format("{0:0.00}", 123.4567m);      // "123.46"

http://www.csharp-examples.net/string-format-double/

The "m" is a decimal suffix. About the decimal suffix:

http://msdn.microsoft.com/en-us/library/364x0z75.aspx

Given decimal d=12.345; the expressions d.ToString("C") or String.Format("{0:C}", d) yield $12.35 - note that the current culture's currency settings including the symbol are used.

Note that "C" uses number of digits from current culture. You can always override default to force necessary precision with C{Precision specifier} like String.Format("{0:C2}", 5.123d).

If you want it formatted with commas as well as a decimal point (but no currency symbol), such as 3,456,789.12...

decimalVar.ToString("n2");

There's already two high scoring answers that refer to Decimal.Round(...) but I think a little more explanation is needed - because there's an unexpected important property of Decimal that isn't obvious.

A decimal 'knows' how many decimal places it has based upon where it came from.

For instance the following may be unexpected :

Decimal.Parse("25").ToString()          =>   "25"
Decimal.Parse("25.").ToString()         =>   "25"
Decimal.Parse("25.0").ToString()        =>   "25.0"
Decimal.Parse("25.0000").ToString()     =>   "25.0000"

25m.ToString()                          =>   "25"
25.000m.ToString()                      =>   "25.000"

Doing the same operations with Double will give no decimal places ("25") for each of the above.

When you want a decimal to 2 decimal places theres about a 95% chance it's because it's currency in which case this is probably fine for 95% of the time:

Decimal.Parse("25.0").ToString("c")     =>   "$25.00"

Or in XAML you just use {Binding Price, StringFormat=c}

One case I ran into where I needed a decimal AS a decimal was when sending XML to Amazon's webservice. The service was complaining because a Decimal value (originally from SQL Server) was being sent as 25.1200 and rejected, (25.12 was the expected format).

All I needed to do was Decimal.Round(...) with 2 decimal places to fix the problem.

 // This is an XML message - with generated code by XSD.exe
 StandardPrice = new OverrideCurrencyAmount()
 {
       TypedValue = Decimal.Round(product.StandardPrice, 2),
       currency = "USD"
 }

TypedValue is of type Decimal so I couldn't just do ToString("N2") and needed to round it and keep it as a decimal.

Here is a little Linqpad program to show different formats:

void Main()
{
    FormatDecimal(2345.94742M);
    FormatDecimal(43M);
    FormatDecimal(0M);
    FormatDecimal(0.007M);
}

public void FormatDecimal(decimal val)
{
    Console.WriteLine("ToString: {0}", val);
    Console.WriteLine("c: {0:c}", val);
    Console.WriteLine("0.00: {0:0.00}", val);
    Console.WriteLine("0.##: {0:0.##}", val);
    Console.WriteLine("===================");
}

Here are the results:

ToString: 2345.94742
c: $2,345.95
0.00: 2345.95
0.##: 2345.95
===================
ToString: 43
c: $43.00
0.00: 43.00
0.##: 43
===================
ToString: 0
c: $0.00
0.00: 0.00
0.##: 0
===================
ToString: 0.007
c: $0.01
0.00: 0.01
0.##: 0.01
===================

None of these did exactly what I needed, to force 2 d.p. and round up as 0.005 -> 0.01

Forcing 2 d.p. requires increasing the precision by 2 d.p. to ensure we have at least 2 d.p.

then rounding to ensure we do not have more than 2 d.p.

Math.Round(exactResult * 1.00m, 2, MidpointRounding.AwayFromZero)

6.665m.ToString() -> "6.67"

6.6m.ToString() -> "6.60"

Very rarely would you want an empty string if the value is 0.

decimal test = 5.00;
test.ToString("0.00");  //"5.00"
decimal? test2 = 5.05;
test2.ToString("0.00");  //"5.05"
decimal? test3 = 0;
test3.ToString("0.00");  //"0.00"

The top rated answer is incorrect and has wasted 10 minutes of (most) people's time.

The top-rated answer describes a method for formatting the string representation of the decimal value, and it works.

However, if you actually want to change the precision saved to the actual value, you need to write something like the following:

public static class PrecisionHelper
{
    public static decimal TwoDecimalPlaces(this decimal value)
    {
        // These first lines eliminate all digits past two places.
        var timesHundred = (int) (value * 100);
        var removeZeroes = timesHundred / 100m;

        // In this implementation, I don't want to alter the underlying
        // value.  As such, if it needs greater precision to stay unaltered,
        // I return it.
        if (removeZeroes != value)
            return value;

        // Addition and subtraction can reliably change precision.  
        // For two decimal values A and B, (A + B) will have at least as 
        // many digits past the decimal point as A or B.
        return removeZeroes + 0.01m - 0.01m;
    }
}

An example unit test:

[Test]
public void PrecisionExampleUnitTest()
{
    decimal a = 500m;
    decimal b = 99.99m;
    decimal c = 123.4m;
    decimal d = 10101.1000000m;
    decimal e = 908.7650m

    Assert.That(a.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("500.00"));

    Assert.That(b.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("99.99"));

    Assert.That(c.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("123.40"));

    Assert.That(d.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("10101.10"));

    // In this particular implementation, values that can't be expressed in
    // two decimal places are unaltered, so this remains as-is.
    Assert.That(e.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("908.7650"));
}

You can use system.globalization to format a number in any required format.

For example:

system.globalization.cultureinfo ci = new system.globalization.cultureinfo("en-ca");

If you have a decimal d = 1.2300000 and you need to trim it to 2 decimal places then it can be printed like this d.Tostring("F2",ci); where F2 is string formating to 2 decimal places and ci is the locale or cultureinfo.

for more info check this link
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx

Mike M.'s answer was perfect for me on .NET, but .NET Core doesn't have a decimal.Round method at the time of writing.

In .NET Core, I had to use:

decimal roundedValue = Math.Round(rawNumber, 2, MidpointRounding.AwayFromZero);

A hacky method, including conversion to string, is:

public string FormatTo2Dp(decimal myNumber)
{
    // Use schoolboy rounding, not bankers.
    myNumber = Math.Round(myNumber, 2, MidpointRounding.AwayFromZero);

    return string.Format("{0:0.00}", myNumber);
}

https://msdn.microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx

This link explains in detail how you can handle your problem and what you can do if you want to learn more. For simplicity purposes, what you want to do is

double whateverYouWantToChange = whateverYouWantToChange.ToString("F2");

if you want this for a currency, you can make it easier by typing "C2" instead of "F2"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top