13.2. Number Formatting

Table 13.1 lists the format specifiers for number formatting. You can format numeric types using the ToString() method on the data types. The standard format specifier string consists of a special character followed by a sequence of digits specifying precision.

13.2.1. Currency Formatting

Listing 13.1 shows currency formatting. The format specifier to be used is C or c.

Listing 13.1. Currency Formatting (C#)
using System;
using System.Globalization;
using System.IO;

public class NumericFormatting {

  static float NUMBER = 334.456F;

  public static void Main(string[] args) {
    TextWriter tw = Console.Out;
    PlainCurrencyFormatting(tw);
    CurrencyFormattingWithCustomProvider(tw);
    GreatBritainCurrencyFormatting(tw);
  }

  private static void PlainCurrencyFormatting(TextWriter tw) {
    tw.WriteLine(NUMBER.ToString("C"));
    tw.WriteLine(NUMBER.ToString("C6"));
  }

  private static void CurrencyFormattingWithCustomProvider
                                         (TextWriter tw) {
    NumberFormatInfo provider = new NumberFormatInfo();
    provider.CurrencyDecimalDigits = 3;
    provider.CurrencySymbol= "$";
    provider.CurrencyDecimalSeparator= "*";
    tw.WriteLine(NUMBER.ToString("c", provider));
  }

  private static void GreatBritainCurrencyFormatting(TextWriter
    tw) {
    CultureInfo culture =
           CultureInfo.CreateSpecificCulture("en-GB");
    NumberFormatInfo provider = culture.NumberFormat;
    tw.WriteLine(NUMBER.ToString("c", provider));
  }
}

Table 13.1. Format Specifiers for Numerical Formatting in C#
Format CharacterDescription
C,cCurrency
E,eScientific
F,fFixed point
G,gGeneral
N,nNumber
R,rRoundtrip
X,xHexadecimal

The output of the Listing 13.1 is as follows:

$334.46
$334.456000
$334*456
£334.46

When no provider is specified, the number is formatted as $334.46, which uses the CultureInfo en-US (that is the equivalent of Locale.US). The $ symbol is used for the currency, and by default there are two digits after the decimal point, so the last digit (6) was the result of rounding. The third number in the output is a currency from a custom NumberFormatInfo. Note that the currency symbol had to be specified as $; it is not assumed to be $ by default. Because the plain instantiation of NumberFormatInfo is culture invariant, it makes no assumption about the currency symbol.

The next example is that of printing the same currency using the British pound. Note how the appropriate culture is obtained and the default NumberFormatInfo for that culture is used.

13.2.2. Scientific Formatting

The E and e format specifiers can be used to format numbers in the scientific notation m.dddE+xxx. One digit always precedes the decimal point, and the number of decimal places is specified by the precision specifier, with six places used as the default. The format specifier controls whether E or e appears in the output. Listing 13.2 shows an example of scientific formatting.

Listing 13.2. Scientific Formatting (C#)
using System;
using System.Globalization;
using System.IO;
public class ScientificFormatting {

  static double NUMBER = 2345334.456547554D;

  public static void Main(string[] args) {
    TextWriter tw = Console.Out;
    PlainFormatting(tw);
    FormattingWithCustomProvider(tw);
    CultureSpecificFormatting(tw);
  }

  private static void PlainFormatting(TextWriter tw) {
    tw.WriteLine(NUMBER.ToString("E"));
    tw.WriteLine(NUMBER.ToString("E2"));
    tw.WriteLine(NUMBER.ToString("E4"));
  }

  private static void FormattingWithCustomProvider(TextWriter
      tw) {
    NumberFormatInfo provider = new NumberFormatInfo();
    provider.NumberDecimalDigits = 2;
    tw.WriteLine(NUMBER.ToString("E", provider));
  }

  private static void CultureSpecificFormatting(TextWriter tw) {
      CultureInfo culture =
             CultureInfo.CreateSpecificCulture("fr-FR");
    NumberFormatInfo provider = culture.NumberFormat;
    tw.WriteLine(NUMBER.ToString("e", provider));
  }
}

The output of Listing 13.2 is as follows:

2.345334E+006
2.35E+006
2.3453E+006
2.345334E+006
2,345334e+006

In Listing 13.2, the first method, PlainFormatting, merely modifies the number of digits that are put after the decimal point using the format specifier. The second method, FormattingWithCustomProvider, tries to limit the number of decimal digits to 2, but the runtime does not do so because of the E/e format specifier. The last method shows how French scientists would denote a number in exponential form.

13.2.3. Number, Fixed-Point, and General Formatting

The number format specified by the N or n specifier formats a number into a string that has commas. By default, the number is formatted with two digits to the right of the decimal point. You can control this by specifying the number of digits after the format specifier; for example, N4 or n4 would mean four digits after the decimal point.

The fixed-point format is similar to the number format except that it does not put commas into the formatted string. The general format string converts the value to either the fixed-point or the scientific format, whichever is more compact. Listing 13.3 gives examples of the three formats.

Listing 13.3. Number, General, and Fixed-Point Formats (C#)
using System;
using System.Globalization;
using System.IO;
public class ScientificFormatting {

  static float NUMBER = 85.56546F;

  public static void Main(string[] args) {
    TextWriter tw = Console.Out;

    //Using the {N,n} format specifiers
    tw.WriteLine("The number format");
    PlainFormatting (tw, "n2");
    FormattingWithCustomProvider(tw, "n");
    CultureSpecificFormatting(tw, "n");

    //Using the {G,g} format specifiers
    tw.WriteLine("The general format");
    PlainFormatting (tw, "g2");
    FormattingWithCustomProvider(tw, "g");
    CultureSpecificFormatting(tw, "g");

    //Using the fixed-point {F,f} format specifiers
    tw.WriteLine("The fixed-point format");
    PlainFormatting (tw, "f2");
    FormattingWithCustomProvider(tw, "f");
    CultureSpecificFormatting(tw, "f");

    //Using the % format specifiers
    tw.WriteLine("The % format");
    PlainFormatting (tw, "###.##%");
    FormattingWithCustomProvider(tw, "###.##%");
    CultureSpecificFormatting(tw, "###.##%");
  }

  private static void PlainFormatting(TextWriter tw, string
    pattern){
    tw.WriteLine(NUMBER.ToString(pattern));
  }

  private static void FormattingWithCustomProvider(TextWriter
    tw, string pattern) {
    NumberFormatInfo provider = new NumberFormatInfo();
    provider.PercentDecimalDigits = 2;
    provider.PercentSymbol = "&";
    tw.WriteLine(NUMBER.ToString(pattern, provider));
  }
  

  private static void CultureSpecificFormatting(TextWriter tw,
    string pattern) {
    CultureInfo culture =
           CultureInfo.CreateSpecificCulture("fr-FR");
    NumberFormatInfo provider = culture.NumberFormat;
    tw.WriteLine(NUMBER.ToString(pattern, provider));
  }
}

The output of Listing 13.3 is as follows:

The number format
85.57
85.57
85,57
The general format
86
85.56546
85,56546
The fixed-point format
85.57
85.57
85,57
The % format
8556.55%
8556.55&
8556,55%

Note that when you use the French culture, the symbol “.” is replaced with a “,”. Note also that using the % specifier, the % symbol is changed to & in the last example because of the following statement in the code:

provider.PercentSymbol = "&" ;

13.2.4. Percent Formatting

Unlike Java, C# has no special percent formatter. However, the % symbol is used to indicate the percentage. The number is multiplied by 100 before it is displayed as a percentage. In Listing 13.3 the last method call shows percent formatting. Note that we introduced a new character in the format specifier. The next section discusses these custom format specifiers.

13.2.5. Custom Specifiers

In addition to the standard format specifiers we have seen, you can specify custom format specifiers. Custom format specifiers are similar to the ones in Java. The special characters in Table 13.2 are used for specifying custom format strings and have similar meanings to the ones in Java.

In general, the zero character (0) is used as a digit or zero placeholder. If the numeric value has a digit in the position at which the 0 appears in the format string, the digit will appear in the result. If not, a zero appears in that position.

Throughout this chapter we have used the ToString() function to format numbers. However, format specifier strings can also be passed to the Console.WriteLine method to format the output at the time of printing.

Table 13.2. Format Specifiers for Custom Formatting in C#
CharacterResult
0Displays leading zeros if the number has fewer digits than there are zeros in the format.
#Replaces # with digits only for significant digits.
,{comma)Separates number groups such as 1,000. When used after a number, divides by 1,000.
%Displays the % character.
.Displays the decimal point.
;Separates sections.

The format specifiers follow the same syntax as when you specify them in the ToString() method, with a slight modification. Listing 13.4 shows how to use the format specifiers in the Console.WriteLine method. The specifier string is {0:00} here; the 00 after the : is the actual specifier. The 0 before the : indicates that the specifier is to be applied to the first argument of the Console.WriteLine call.

Listing 13.4. Using the 0 Character Placeholder (C#)
using System;
public class ZeroFormatting {

  public static void Main(string[] args) {
    Console.WriteLine("{0:00}", 55);
    Console.WriteLine("{0:00000}", 556);
    Console.WriteLine("{0:00}", 66464);
  }
}

The output of Listing 13.4 is as follows:

55
00556
66464

The # character behaves similarly to the 0 character, except that the # character is omitted if there is no digit in that position. Listing 13.5 shows the use of the # character.

Listing 13.5. Using the # Character Placeholder
using System;

public class HashFormatting {

  public static void Main(string[] args) {
    Console.WriteLine("{0:####}", 55);
    Console.WriteLine("{0:#}", 556);
    Console.WriteLine("{0:##}", 66464);
  }
}

The output of Listing 13.5 is as follows:

55
556
66464

Note that 556 is now not preceded with leading zeros.

The “,” character is used as a group separator. If a comma appears in the middle of a display digit placeholder (0 or #) and to the left of the decimal point, then a group separator will be inserted into the string. Listing 13.6 shows how this works.

Listing 13.6. Using the "," Character Placeholder (C#)
using System;
public class CommaFormatting {

  public static void Main(string[] args) {
    Console.WriteLine("{0:,###}", 55678);
    Console.WriteLine("{0:#,##}", 55678);
    Console.WriteLine("{0:#,#,#}", 55678);
    Console.WriteLine("{0:#,#,#}", 55678857);
    Console.WriteLine("{0:000#,.000}", 55678857);
  }
}

The output of Listing 13.6 is as follows:

55678
55,678
55,678
55,678,857
55678.857

Note that putting one comma first divides the number by 1,000 and places the comma at the appropriate location. Every subsequent comma added divides the number further by 1,000, and the commas are again added to appropriate places. You can scale a number by placing the comma character directly before the decimal point. For each comma present in this location, the number is divided by 1,000 before it is formatted.

13.2.6. Section, Hexadecimal, and Escaping Specifiers

Listing 13.7 shows the section, hexadecimal, and escaping specifiers. The section specifier is used to specify different formatting strings for a number depending on whether it is positive, negative, or zero. Sections are demarcated by a semicolon. If there are three sections (x;y;z), then format x would apply if the number were positive, format y would apply if the number were negative, and format z would apply if the number were zero.

Listing 13.7. Three Kinds of Specifiers (C#)
using System;
using System.Globalization;
using System.IO;

public class ScientificFormatting {

  static float NUMBER = 85.56546F;

  public static void Main(string[] args) {

    //Hexadecimal formatting
    Console.WriteLine("{0:X}", 58);

    //Section formatting
    Console.WriteLine("{0:##;#.000;(##.00)}", 57575.356);
    Console.WriteLine("{0:##,00;00.##;(##.00)}",-57575.356);
    Console.WriteLine("{0:##,00;00.##;(##.00)}", 0);

    //Escaping characters
    Console.WriteLine("{0:###;bs;bs#}", 345);
  }
}

The escaping specifier is in fact not a specifier but a way to escape characters so that they don't get interpreted at the time of formatting.

The output of Listing 13.7 is as follows:

3A
57575
57575.36
(.00)
345#

Notice that when the number is 0, the section specifier chooses the rightmost format for formatting the number.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.184.90