How to Convert a Number with Comma to Decimal in C#

Need to convert number with comma to decimal in C#? Call decimal.Parse with NumberStyles.Number and an explicit culture, so the comma is read as a thousands separator:

using System.Globalization;

var us = CultureInfo.GetCultureInfo("en-US");
CultureInfo.CurrentCulture = us;
decimal sales = decimal.Parse("1,234,567.89", NumberStyles.Number, us);

Console.WriteLine(sales);        // 1234567.89
Console.WriteLine(sales + 0.11m); // 1234568.00

That turns “1,234,567.89” into a real decimal you can do math with. I ran every snippet below on .NET 10 with 2026 sales numbers, including the bad input and European formats that break this.

decimal.Parse with NumberStyles.Number: Convert a Comma Number to Decimal

decimal.Parse(string, NumberStyles, IFormatProvider) is the method you want. The style says which symbols may appear; the culture says what the comma and dot mean.

My running sample is a 2026 sales report from Front Range Outfitters, a made-up outdoor store in Denver. Here are four amounts the way the report prints them:

using System.Globalization;

var us = CultureInfo.GetCultureInfo("en-US");
CultureInfo.CurrentCulture = us;   // print in en-US too
// Front Range Outfitters, Denver: 2026 sales report values
string[] amounts = { "1,234,567.89", "48,250", "-2,150.75", "  980.10 " };

foreach (string text in amounts)
{
    decimal value = decimal.Parse(text, NumberStyles.Number, us);
    Console.WriteLine($"{text,-14} -> {value}");
}

var flags = NumberStyles.AllowThousands | NumberStyles.AllowDecimalPoint;
Console.WriteLine(decimal.Parse("48,250.50", flags, us));

Output:

1,234,567.89   -> 1234567.89
48,250         -> 48250
-2,150.75      -> -2150.75
  980.10       -> 980.10
48250.50
VS Code running ParseComma.cs: C# decimal.Parse with NumberStyles.Number and en-US converts 1,234,567.89 to 1234567.89 and -2,150.75 to -2150.75
NumberStyles.Number handles thousands commas, a minus sign and extra spaces

All four parse, including the minus sign and the padded ” 980.10 “. NumberStyles.Number allows thousands separators, a decimal point, a sign and white space.

The last line uses AllowThousands | AllowDecimalPoint instead. It also works (48250.50), but it rejects a minus sign and spaces, so I’d rather use NumberStyles.Number.

I use decimal rather than double for money because it keeps exact base-10 digits; the C# data types guide compares them. Going the other way, from a value back to “1,234,567.89”, is covered in format a number with commas and decimals in C#.

Which NumberStyles Value Accepts a Comma?

Plain decimal.Parse(text) already uses NumberStyles.Number, but with the PC’s current culture. These are the styles you’ll actually pick from (flags from Microsoft Learn’s NumberStyles table):

NumberStylesThousands commaDecimal point$ sign(45.00) as negative
NumberYesYesNoNo
AllowThousands | AllowDecimalPointYesYesNoNo
CurrencyYesYesYesYes
FloatNoYesNoNo
IntegerNoNoNoNo

So Float and Integer fail on “48,250”. That’s also why int.Parse chokes on a comma, which you can work around as shown in convert a string to int without int.Parse.

Use decimal.TryParse for User Input with Commas

decimal.Parse throws FormatException on bad text. For anything a person types, decimal.TryParse returns false instead. Same en-US culture, six inputs a cashier could enter:

using System.Globalization;

var us = CultureInfo.GetCultureInfo("en-US");
CultureInfo.CurrentCulture = us;
string?[] inputs = { "1,250.00", "abc", "", null, "12,50", "1,2,3" };

foreach (string? input in inputs)
{
    if (decimal.TryParse(input, NumberStyles.Number, us, out decimal amount))
        Console.WriteLine($"{input ?? "null",-10} -> {amount}");
    else
        Console.WriteLine($"{input ?? "null",-10} -> not a valid amount");
}

Output:

1,250.00   -> 1250.00
abc        -> not a valid amount
           -> not a valid amount
null       -> not a valid amount
12,50      -> 1250
1,2,3      -> 123
VS Code running TryParseComma.cs: C# decimal.TryParse returns false for abc, an empty string and null, but reads 12,50 as 1250 and 1,2,3 as 123
TryParse rejects junk, but it doesn’t check where the commas sit

“abc”, the empty string and null all print “not a valid amount” with no exception. That’s the main reason to prefer it over wrapping Parse in a try-catch block in C#.

Important: look at the last two lines. “12,50” became 1250 and “1,2,3” became 123, because .NET doesn’t check the group size around a comma. If a typo like that matters, validate the pattern before you parse.

The null case is the same idea as in convert null to int in C#: TryParse hands you a false and a 0, so pick your own default.

Parse Currency Strings with a Dollar Sign (NumberStyles.Currency)

Spreadsheet exports often keep the $ sign and use parentheses for refunds. NumberStyles.Number refuses the $, so switch to NumberStyles.Currency:

using System.Globalization;

var us = CultureInfo.GetCultureInfo("en-US");
CultureInfo.CurrentCulture = us;
string[] cells = { "$1,234.56", "($45.00)", "-$12.30", "$ 2,500" };

foreach (string cell in cells)
{
    decimal value = decimal.Parse(cell, NumberStyles.Currency, us);
    Console.WriteLine($"{cell,-10} -> {value}");
}

bool ok = decimal.TryParse("$1,234.56", NumberStyles.Number, us, out _);
Console.WriteLine($"Number style with $: {ok}");

Output:

$1,234.56  -> 1234.56
($45.00)   -> -45.00
-$12.30    -> -12.30
$ 2,500    -> 2500
Number style with $: False
VS Code running CurrencyParse.cs: C# decimal.Parse with NumberStyles.Currency reads $1,234.56 as 1234.56 and ($45.00) as -45.00
Currency style accepts the $ sign and treats parentheses as a negative amount

“$1,234.56” gives 1234.56, and the refund “($45.00)” comes back as -45.00. The last line confirms that NumberStyles.Number returns False for the same $ string.

How Do You Convert a European Number Like 1.234,56 to Decimal?

In Germany, France and much of Europe, the comma IS the decimal separator and the dot groups thousands. A Berlin supplier’s invoice total of “1.234,56” needs the de-DE culture:

using System.Globalization;

var de = CultureInfo.GetCultureInfo("de-DE");
var us = CultureInfo.GetCultureInfo("en-US");
CultureInfo.CurrentCulture = us;
string fromBerlin = "1.234,56";

decimal value = decimal.Parse(fromBerlin, NumberStyles.Number, de);
Console.WriteLine($"de-DE: {value}");

bool ok = decimal.TryParse(fromBerlin, NumberStyles.Number, us, out decimal wrong);
Console.WriteLine($"en-US: {ok} {wrong}");

Console.WriteLine($"de-DE \"12,50\": {decimal.Parse("12,50", de)}");
Console.WriteLine($"en-US \"12,50\": {decimal.Parse("12,50", us)}");

Output:

de-DE: 1234.56
en-US: False 0
de-DE "12,50": 12.50
en-US "12,50": 1250
VS Code running EuropeanComma.cs: C# decimal.Parse with de-DE culture converts 1.234,56 to 1234.56, while en-US TryParse returns False
Same text, two cultures: de-DE reads the comma as the decimal point

With de-DE you get 1234.56. With en-US, TryParse returns False because a dot followed by a comma makes no sense there.

The scary pair is “12,50”: de-DE reads it as 12.50 and en-US as 1250. Neither throws, so you must know where the data came from.

The same culture rules apply to double.Parse; see convert a string to double in C# for the floating-point side.

Why Replace(“,”, “”) Is a Risky Way to Remove Commas

A lot of old code strips the commas and parses what’s left. It works on US text and quietly breaks on everything else:

using System.Globalization;

var inv = CultureInfo.InvariantCulture;
CultureInfo.CurrentCulture = inv;
string[] samples = { "1,234.56", "1.234,56", "12,50" };

foreach (string s in samples)
{
    string stripped = s.Replace(",", "");
    decimal value = decimal.Parse(stripped, inv);
    Console.WriteLine($"{s,-9} -> \"{stripped}\" -> {value}");
}

Output:

1,234.56  -> "1234.56" -> 1234.56
1.234,56  -> "1.23456" -> 1.23456
12,50     -> "1250" -> 1250

“1,234.56” is fine. But the European “1.234,56” turns into 1.23456 and “12,50” into 1250, and nothing throws.

A culture-aware Parse either fails or reads the value right. If you need to round the result afterwards, show a number with 2 decimal places covers that part.

Always Pass a Culture to decimal.Parse: InvariantCulture vs Server Culture

Calls without a culture use CultureInfo.CurrentCulture, which comes from the machine. My own dev PC isn’t set to en-US, and a cloud server in Frankfurt won’t be either. Here’s “1,234.56” under three cultures:

using System.Globalization;

string text = "1,234.56";
var cultures = new[] { CultureInfo.InvariantCulture,
    CultureInfo.GetCultureInfo("en-US"), CultureInfo.GetCultureInfo("de-DE") };

foreach (var culture in cultures)
{
    CultureInfo.CurrentCulture = culture;     // what the server is set to
    bool ok = decimal.TryParse(text, out decimal value);
    string name = culture.Name == "" ? "Invariant" : culture.Name;
    Console.WriteLine($"{name,-10} {ok,-5} {value}");
}

Output:

Invariant  True  1234.56
en-US      True  1234.56
de-DE      False 0

CultureInfo.InvariantCulture and en-US read 1234.56; de-DE returns False. The code didn’t change, only the machine setting did.

My rule: pass CultureInfo.InvariantCulture for files, APIs and config you control, pass the user’s culture for what people type, and never rely on the default. decimal.Parse(text, CultureInfo.InvariantCulture) already implies NumberStyles.Number.

Once the amount is a decimal, these are the next stops:

Frequently Asked Questions

How do I convert “1,234.56” to decimal in C#?

Use decimal.Parse("1,234.56", NumberStyles.Number, CultureInfo.GetCultureInfo("en-US")). It returns 1234.56. Use decimal.TryParse with the same arguments when the text comes from a user.

Why does decimal.Parse throw FormatException on a comma?

The style or culture doesn’t allow it. NumberStyles.Float and Integer reject thousands separators, and a de-DE machine reads the comma as the decimal point. Pass NumberStyles.Number and the culture the text was written in.

How do I convert a string with a comma as the decimal separator?

Parse it with a culture that uses a comma decimal, such as de-DE: decimal.Parse("1.234,56", CultureInfo.GetCultureInfo("de-DE")) returns 1234.56.

Can I parse a string with a $ sign to decimal?

Yes, with NumberStyles.Currency and en-US. “$1,234.56” becomes 1234.56, and “($45.00)” becomes -45.00. NumberStyles.Number returns false for the $ sign.

Where are the NumberStyles flags documented?

The NumberStyles enum on Microsoft Learn lists every flag and which composite styles (Number, Currency, Float) include it.