Question

Format Decimal Values to 2 Decimal Places in C#

csharp.netformatdecimal

Question

How can I display a C# decimal value with exactly two decimal places? Calling .ToString() currently shows many decimal digits, but I am using the value to represent dollars and cents and want output such as 12.50. Is there a suitable variation of .ToString() for this?

Short Answer

You will learn how C# numeric format strings control a decimal value's displayed precision. In particular, you will use "F2" and "0.00" to show two digits after the decimal point, and "C" or "C2" when the value should be displayed as currency.

Concept

decimal.ToString() converts a number into text. With no format string, C# chooses a representation that preserves the number's meaningful digits, which can result in more decimal places than a user-facing screen needs.

A numeric format string tells ToString() how the text should look:

  • "F2" means fixed-point notation with two digits after the decimal separator.
  • "0.00" is a custom format that also requires exactly two digits after the separator.
  • "C2" means currency formatting with two decimal digits, including a culture-specific currency symbol and separators.
decimal price = 12.5m;

Console.WriteLine(price.ToString("F2")); // 12.50
Console.WriteLine(price.ToString("0.00")); // 12.50

Formatting changes the text you display; it does not change the original decimal variable. This distinction matters: calculate with numeric values, then format only at the boundary where you show a value to a person, write a report, or export text.

Mental Model

Think of a decimal as the amount written in an accounting ledger, and ToString("F2") as the print layout for that ledger.

The stored value can contain more precision, but the printed layout reserves exactly two spaces after the decimal separator:

  • 8 becomes 8.00
  • 8.4 becomes 8.40
  • 8.456 is printed as 8.46

The layout affects what readers see, not the underlying ledger entry.

Take Quiz

Syntax and Examples

Use ToString with a standard or custom numeric format string.

decimal amount = 49.987m;

string fixedAmount = amount.ToString("F2");
string customAmount = amount.ToString("0.00");

Console.WriteLine(fixedAmount);  // 49.99
Console.WriteLine(customAmount); // 49.99

Both examples display two decimal places. They also round when the value has more than two decimal places.

For a monetary value shown to a user, currency formatting is often clearer:

using System.Globalization;

decimal amount = 1234.5m;

Console.WriteLine(amount.ToString("C2", CultureInfo.GetCultureInfo("en-US")));
// $1,234.50

Console.WriteLine(amount.ToString("C2", CultureInfo.GetCultureInfo("en-GB")));
// £1,234.50

"C2" uses the supplied culture to choose the currency symbol, decimal separator, and thousands separator. Use a specific culture when output must be consistent regardless of the computer's regional settings.

Step by Step Execution

Consider this code:

decimal subtotal = 19.995m;
string displayedSubtotal = subtotal.ToString("F2");

Console.WriteLine(displayedSubtotal);
  1. subtotal stores the numeric decimal value 19.995.
  2. ToString("F2") asks C# to produce fixed-point text with two fractional digits.
  3. Since three fractional digits exist, the result is rounded for display.
  4. displayedSubtotal contains the string "20.00".
  5. Console.WriteLine prints 20.00.

The original variable is still numeric:

Console.WriteLine(subtotal); // 19.995

If business rules require you to round the value before later calculations, round the decimal explicitly instead of relying only on display formatting:

decimal roundedSubtotal = decimal.Round(subtotal, 2, MidpointRounding.AwayFromZero);

Real World Use Cases

  • Checkout pages: Display an item price as 15.00 rather than 15.
  • Invoices and receipts: Use "C2" to show amounts with a currency symbol and grouping separators.
  • Financial reports: Use "N2" for a two-decimal number with thousands separators but no currency symbol, such as 1,234.50.
  • CSV or text exports: Use "F2" together with an invariant culture when another system requires a period as the decimal separator.
  • API logs and diagnostics: Limit displayed precision so logs remain readable, while retaining the original numeric value for calculations.
Take Quiz

Real Codebase Usage

In production code, formatting usually happens near the presentation layer rather than inside calculation logic.

public string FormatPrice(decimal price, CultureInfo culture)
{
    return price.ToString("C2", culture);
}

For an application whose culture is chosen per request or per user, pass that culture into the formatter. This prevents accidentally displaying a US-style amount to a user who expects another locale.

For machine-readable output, use an explicit culture rather than the current machine culture:

using System.Globalization;

decimal amount = 42.5m;
string valueForExport = amount.ToString("F2", CultureInfo.InvariantCulture);

Console.WriteLine(valueForExport); // 42.50

A common validation pattern is to keep values as decimal until they are displayed or serialized:

if (amount < 0)
{
    throw new ArgumentOutOfRangeException(nameof(amount));
}

return amount.ToString("C2", culture);

This avoids parsing formatted strings back into numbers later.

Common Mistakes

Using double for currency

Binary floating-point types such as double cannot represent many decimal fractions exactly. Prefer decimal for dollar-and-cent calculations.

// Avoid for money calculations.
double price = 0.1 + 0.2;

// Prefer.
decimal price = 0.1m + 0.2m;

The m suffix makes a numeric literal a decimal.

Assuming formatting changes the numeric value

decimal amount = 12.345m;
string text = amount.ToString("F2"); // "12.35"

Console.WriteLine(amount); // Still 12.345

Use decimal.Round if the stored or subsequently calculated value itself must be rounded.

Using "0.##" when exactly two places are required

decimal amount = 12.5m;
Console.WriteLine(amount.ToString("0.##")); // 12.5

# means an optional digit. Use "0.00" or "F2" when trailing zeros must appear.

Hard-coding a currency symbol

string text = "$" + amount.ToString("F2");

This can be wrong for users in another region and misses culture-specific formatting. Prefer amount.ToString("C2", culture).

Relying on the current culture for data interchange

A value formatted on one computer may use 12,50; another may use 12.50. For fixed machine formats, use CultureInfo.InvariantCulture.

Comparisons

FormatExample for 1234.5m in en-USBest use
ToString()1234.5General conversion when a fixed display precision is not needed
ToString("F2")1234.50Exactly two decimal places, without grouping or a currency symbol
ToString("0.00")1234.50Exactly two decimal places using a custom format
ToString("N2")1,234.50Readable numbers with thousands separators
ToString("C2")$1,234.50Currency shown to users
decimal.Round(amount, 2)numeric 1234.50Changing the numeric value used in later calculations

"F2" and "0.00" produce similar results for ordinary positive amounts. "F2" is a standard fixed-point format; "0.00" gives you more control if you later need a custom layout, such as "$0.00" for a fixed literal symbol.

Take Quiz

Cheat Sheet

using System.Globalization;

decimal amount = 12.5m;

amount.ToString("F2");                         // "12.50"
amount.ToString("0.00");                       // "12.50"
amount.ToString("N2", CultureInfo.GetCultureInfo("en-US")); // "12.50" or grouped for larger values
amount.ToString("C2", CultureInfo.GetCultureInfo("en-US")); // "$12.50"
amount.ToString("F2", CultureInfo.InvariantCulture);         // "12.50"
  • Use decimal and the m suffix for monetary values.
  • 0 requires a digit; # makes a digit optional.
  • "F2" and "0.00" display exactly two fractional digits.
  • Formatting returns a string; it does not modify the number.
  • Use decimal.Round when later calculations must use the rounded value.
  • Use an explicit CultureInfo for consistent output or user-specific currency formatting.

FAQ

How do I show exactly two decimal places in C#?

Use amount.ToString("F2") or amount.ToString("0.00").

What is the difference between F2 and 0.00?

Both normally show two decimal places. F2 is a standard fixed-point format, while 0.00 is a custom format that can be extended with your own literals and digit rules.

Does ToString("F2") round a decimal value?

It rounds the textual result to two decimal places. The original decimal value is unchanged.

How do I round the actual decimal value to two places?

Use decimal.Round(amount, 2). Choose a MidpointRounding option explicitly if your business rules require a specific midpoint behavior.

Should I use decimal or double for dollars and cents?

Use decimal for monetary calculations. It is designed for precise base-10 decimal arithmetic.

How do I include a currency symbol?

Use amount.ToString("C2", culture), supplying a suitable CultureInfo, such as CultureInfo.GetCultureInfo("en-US").

Why does my decimal separator appear as a comma?

Numeric formatting follows the active culture. Pass CultureInfo.InvariantCulture for a fixed period decimal separator in machine-readable output.

Take Quiz

Mini Project

Description

Build a small receipt formatter for a checkout workflow. It calculates a subtotal and tax as decimal values, then formats the final output as user-friendly currency without converting values to strings during calculation.

Goal

Create a console receipt that displays prices, tax, subtotal, and total using two decimal places.

Requirements

  1. Store all monetary amounts as decimal values.
  2. Calculate the subtotal from at least two item prices.
  3. Calculate tax from the subtotal using a decimal tax rate.
  4. Display each monetary value with a currency symbol and two decimal places.
  5. Use an explicit en-US culture for consistent output.
Take Quiz

Keep learning

Related questions

View more