Handling Currency in C#

The recommended built-in type in C# is decimal as apposed to float or double. Use of float or double will have precision problems when handling large amounts. For example running the following unit test yields different numbers for the same amount:

[Test]
public void FloatVsDecimalPrecisionForCurrency()
{
    const decimal currencyInDecimal = 123456.78m;
    const float currencyInFloat = 123456.78f;
    Console.WriteLine("Decimal Currency: {0}, Float Currency: {1}",
        currencyInDecimal.ToString("c"), currencyInFloat.ToString("c"));
}

The returned result is Decimal Currency: £123,456.78, Float Currency: £123,456.80

Martin Fowler recommends the use of a Money/Quantity class to encapsulate the Unit and Amount as well as currency specific operations.

NUnit makes it very easy to test Currency operations for various Locales, see example below:

[Test]
[SetCulture("fr-FR")]
public void CurrencyStringRepresentationForFranceHasTheEuroSuffix()
{
    const decimal currencyInDecimal = 123456.78m;

    // convert breaking spaces to a normal spaces
    var formatedCurrency = Regex.Replace(
        currencyInDecimal.ToString("C"), @"\u00A0", " ");

    Assert.That(formatedCurrency, Is.EqualTo("123 456,78 €"));
}

Note: currencyInDecimal.ToString("C") returns a string containing breaking whitespaces which are not equal to the white spaces in the string literal we are comparing against. For this reason we have a Regex.Replace.

Advertisements