Standard formatting in .NET is sometimes not enough to fill specific requirements. For example, when high-level financial reports from big corporations need to be produced, the numbers dealt-with are generally around hundred of millions. Consider the following report where the scale and the currency (M$) is being displayed in the row header.
Quarter 1
Quarter 2
New York (in M$)
102.76
21.40
Florida (in M$)
32.76
67.40
In order to achieve this formatting, a straightforward solution would be to apply a scaling factor to the numbers beforehand.
Sometimes, it is not appropriate nor possible to scale the numbers. In this situation, number scaling using the “,” custom specifier could be used. Note the use of two commas since the number to be formatted is divided by 1000 for each comma:
[csharp]
decimal valueToFormat = 1345278000.346M;
string.Format(“0:#,#,,”, valueToFormat ); // displays 1,345 with the invariant culture
[/csharp]
Most of the examples found in the MSDN fail to explain how to scale the formatted number and keep the decimals at the same time. The trick is to add the “.” custom specifier after the “,” comma specifiers:
This custom formatting technique, however, has some drawbacks:
It is harder to read than standard formatting such as {0:N} or {0:C}.
The output may not be consistent with the settings of some cultures. For example, forcing to display two decimal digits may not be compatible with the value of CultureInfo.NumberFormat.NumberDecimalDigits.
Finally, custom specifiers do not mix with the >standard numeric specifiers. The currency symbol cannot be therefore displayed side-by-side with the number.
A custom formatter called NumberScalingFormatter has been hence developed to allow scaling the numbers while keeping the underlying settings of the culture. In order to use it, pass the ScalingFactor and the underlying culture. The following output illustrates the behavior of the custom formatter as well as the custom “,” specifier combined with the “.” specifier:
For an introduction to custom formatter, please check out the post from David Hayden. A basic outline of the code follows.