How to use NumberFormatInfo

56 Views Asked by At

I want to be able to format any decimal number as I want. Specifically I want to be able to control:

  1. the number of decimals
  2. the decimal separator
  3. the thousand separator

I have tried to do that

var nfi = new NumberFormatInfo();
nfi.NumberDecimalDigits= 4;       <----- for point 1
nfi.NumberDecimalSeparator = "@"; <----- for point 2
nfi.NumberGroupSeparator = "^";   <----- for point 3? or
nfi.PerMilleSymbol= "#";          <----- for point 3?

and then I have applied it:

enter image description here

but for some reasons I can't get to have what I expect.

If I look here it seems that it applies to integers?

And also this answer is not helping.

1

There are 1 best solutions below

0
dbc On BEST ANSWER

The formatting properties NumberDecimalDigits, NumberDecimalSeparator, NumberGroupSeparator and PerMilleSymbol do not apply to all format strings. To determine their applicability you need to check the docs:

  • NumberDecimalDigits: The NumberDecimalDigits property is used with the "F" and "N" standard format strings without a precision specifier in numeric formatting operations.

  • NumberDecimalSeparator: The NumberDecimalSeparator property is used with the "E", "F", "G", "N", and "R" standard format strings to define the symbol that separates integral from fractional digits.

    It also used by the "." custom specifier.

  • NumberGroupSeparator: The NumberGroupSeparator property is used with the "N" standard format string to define the symbol that separates groups of integral digits.

    It is also used by the "," custom specifier.

  • PerMilleSymbol: The string assigned to the PerMilleSymbol property is included in the result string when a numeric value is formatted with a format string that includes the "‰" .

Since, as noted in the doc remarks for ToString(IFormatProvider):

The ToString(IFormatProvider) method formats a Double value in the default ("G", or general) format of a specified culture.

Only NumberDecimalSeparator applies in this format. You need to pass formats for which you the other options are implemented to see their effect. For instance:

double aaa = -123456.789;
foreach (var formatString in new [] { "G", "N", "F", "P", "#0.## " + '\u2030'})
{
    string str = aaa.ToString(formatString, nfi);
    Console.WriteLine("aaa.ToString(\"{0}\", nfi) = {1}", formatString, str);
}

Results in:

aaa.ToString("G", nfi) = -123456@789
aaa.ToString("N", nfi) = -123^456@7890
aaa.ToString("F", nfi) = -123456@7890
aaa.ToString("P", nfi) = -12,345,678.90 %
aaa.ToString("#0.## ‰", nfi) = -123456789 #

Demo fiddle here: https://dotnetfiddle.net/81HXz9