In this article, we will look at the different standard and custom numeric format strings in .NET. Additionally, we will look at the support for the numeric format strings.

To download the source code for this article, you can visit our GitHub repository.

Formatting is the process of converting certain data types into a string representation. The data can be an object or a primitive type. Moreover, formatting aims to produce a human-readable string or to deserialize the data and restore it to its original form.

Let’s start.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

Standard Numeric Format Strings

They help us format numeric values using a format specifier and precision specifier. The general format structure is first writing the format specifier and then the precision specifier. However, we can also use only the format specifier. In the next section, we will look at the components of standard numeric format strings.

Format Specifier

Format specifiers define the output string format. Moreover, a format specifier is one alphabetic character.

For example, C for currency, D for integral types, E for exponential, etc. Next, we will look at an example and try to understand some of the format specifiers in detail.

Let’s start by creating a StandardFormatStrings class:

public static class StandardFormatStrings
{
    public static string CurrencyFormat(double value) => value.ToString("C");
    public static string EuroCurrency(double value) => value.ToString("C", new CultureInfo("fr-FR"));
    public static string DecimalFormat(int value) => value.ToString("D");
    public static string FixedPointFormat(double value) => value.ToString("F");
}

We use the C format specifier to format a number as a currency, we can also specify the currency sign by passing a CultureInfo object to the ToString() method as we did in the EuroCurrency() method. Depending on the currency type, the C format specifier positions the currency symbol either before or after the numeric value.

For example, for the currency EUR, the sign € comes after the numeric value, whereas for USD, the $ sign comes before the numeric value. Moreover, the CultureInfo object informs if the monetary amount separator should be . or ,. For example, for USD the separator is ., for EUR on the other hand, the separator is ,.

In the DecimalFormat() method, we use the D format specifier to define the number of digits for an integer. The D format specifier only works with integral values. Finally, we use the F format specifier to set the number of digits after a decimal point.

Next, let’s call these methods:

Console.WriteLine($"Currency: {StandardFormatStrings.CurrencyFormat(1652.5899)}");
Console.WriteLine($"Euro Currency: {StandardFormatStrings.EuroCurrency(1652.5899)}");
Console.WriteLine($"Decimal: {StandardFormatStrings.DecimalFormat(6546)}");
Console.WriteLine($"Fixed Point: {StandardFormatStrings.FixedPointFormat(1652.5899)}");

And inspect the output:

Currency: $1,652.59
Euro Currency: 1 652,59 €
Decimal: 6546
Fixed Point: 1652.59

We must note that we can use the format specifiers independently or combined with precision specifiers.

Precision Specifier

The second part of standard numeric format strings is precision specifiers, which define the number of digits to display in the resulting string. Precision specifiers behave differently when we use them with integers and floating-point numbers. In the case of integers, the number is neither rounded up nor down.

On the other hand, floating-point numbers are rounded to the nearest value. For example, if we use the F0 precision specifier on 1.5, it will result in 2, but if we use the same specifier with 1.4, the result will be 1. Notably, unlike format specifiers, precision specifiers are optional.

Let’s look at an example:

public static string DecimalPrecision(int value) => value.ToString("D5");
public static string FloatingPointPrecision(double value) => value.ToString("F2");

The D5 specifies the number of digits for an integer to be 5. D is the format specifier and 5 specifies the precision.

The same applies to F2. F is the floating-point format specifier, and 2 specifies the precision. If there are more decimal digits, the formatted string is rounded up or down using MidpointRounding.AwayFromZero, which means that it will be rounded to the nearest number away from zero.

Next, let’s call these methods:

Console.WriteLine($"Decimal Precision: {StandardFormatStrings.DecimalPrecision(6546)}");
Console.WriteLine($"Floating Point Precision: {StandardFormatStrings.FloatingPointPrecision(1652.5899)}");

After that, we can check the output:

Decimal Precision: 06546
Floating Point Precision: 1652.59

The full list of available standard numeric format strings can be found in the Microsoft documentation.

Format Strings Support

In .NET, standard numeric format strings are supported in different places, and this includes the commonly used methods such as ToString(), TryFormat(), and interpolated strings. In the previous example, we saw how to use standard numeric formats with the ToString() method.

Next, let’s look at how we can use them with interpolated strings:

public static string Percentage(double value) => $"{value:P2}";

We use the P2 standard format to format a number as a percentage with two decimal places.

At this point, we can call the method:

Console.WriteLine($"Percentage: {StandardFormatStrings.Percentage(0.54)}");

After we run the app, we can check the output:

Percentage: 54.00%

Custom Numeric Format Strings

Several standard numeric format strings come out of the box in .NET. However, that may not address our use case. In this scenario, we can use a custom format string. Certainly, any format string that is not a standard numeric format string is considered custom.

There are several different types of custom numeric format strings. Let’s look at some of them:

public static class CustomFormatStrings
{
    public static string Decimal(double number) => number.ToString("00000");
    public static string FloatingPoint(double number) => number.ToString("0000.00");
    public static string Percentage(double number) => number.ToString("0.00%");
    public static string DigitSeparator(double number) => number.ToString("#,###.00");
}

The 0 custom format specifier specifies the number of digits in the resulting string. In our example, that is five digits. The . custom format specifier lets us define the number of digits before and after the decimal point. We use the # custom format specifier as a placeholder for a digit and , as a separator, and the % custom format specifier multiplies the number by 100 and creates a formatted percentage.

The list of custom numeric format strings is quite long. To learn more about them, be sure to check out the Microsoft documentation.

Format Strings Support

Similar to standard numeric format strings, we can use custom ones in different ways, including the ToString() method, interpolated strings, the String.Format() method, etc.

Let’s look at an example:

public static string Phone(long value) => String.Format("{0:(###) ###-####}", value);
public static string PhoneInterpolated(long value) => $"{value:(###) ###-####}";

These two methods will yield the same result. The # symbol serves as a placeholder for a digit, and when we pass the value:

Console.WriteLine($"Phone: {CustomFormatStrings.Phone(55665228871)}");
Console.WriteLine($"Phone: {CustomFormatStrings.PhoneInterpolated(55665228871)}");

It returns a nicely formatted phone number:

Phone: (5566) 522-8871
Phone: (5566) 522-8871

Conclusion

In this article, we looked at the different standard and custom numeric format strings in .NET. Furthermore, we looked at the support for these format strings. 

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!