Formatting for Float/Double Numbers
Have you ever formatted number output in COBOL? As you would have from the CSCI 465/565 class? Because if so,
this next bit is going to look eerily familiar.
C# provides a great deal of control over how we display real numbers in our output. From how many digits
appear before/after the decimal point, to whether we show the decimal point at all, left padding, right
padding, or how negative numbers are represented. Other languages allow us to do this as well, but not many
make it this concise. For example, if I wanted to display a real number, with only two digits after
the decimal point, in a space at least 10 characters wide, and left-aligned within that space, I would do this,
in C++:
cout << fixed << setprecision(2) << setw(10) << left << 3.141519265;
Which would print '3.14 '. But with C#, I can do:
Console.WriteLine(String.Format("{0, -10: 0.00}", 3.14159265));
Like I said: it's concise but might take some getting used to. Let's break this down: first and
foremost, we're utilizing String.Format to provide the, well, format, of this output.
The argument in the above example only prints a single real number, but we could easily modify it to look
more like our other output statements. Such as:
Console.WriteLine(String.Format("Pi: {0, -10: 0.00}", 3.14159265));
The {0} notation is what we're simply expanding on, providing additional instructions
for how that variable will be printed. That's what the first 0 represents, the 0th variable in the
list that follows this format. To provide a minimum length buffer for the output value, you
add either a positive (right-justified) or negative (left-justified) after a comma. For example, if I wanted
to simply print any variable (not just real numbers) to have a certain minimum length buffer,
I would code it as {0, 42}.
The directions after the colon character are what dictate the format the real number will take on when printed.
A "0" character represents a digit that will be printed, no matter what. If no digit fills this space from the
input value, a zero is output. For example:
Console.WriteLine(String.Format("Tau: {0: 00.00}", 6.283185)); // Prints Tau: 06.28
Console.WriteLine(String.Format("{0: 0.00}", 6.283185)); // Prints 6.28
Console.WriteLine(String.Format("{0: 0.00}", 6.2)); // Prints 6.20
If digits after the decimal point get truncated, the number will be rounded up before being
printed. So ("{0: 0.00}", 0.999999) will print as 1.00 (don't be surprised if your
math friends are seizing up at this point in the notes.)
You can also use a "#" character to represent a placeholder for a digit that will be left blank if
not digit from the input value fills it. For example:
Console.WriteLine(String.Format("{0: ##.00}", 0.283185)); // Prints .28
Console.WriteLine(String.Format("{0: #0.00}", 6.283185)); // Prints 6.28
Console.WriteLine(String.Format("{0: 0.##}", 6)); // Prints 6
It's worth noting that multiple # placeholders to the left of the decimal point is redundant, such as the example
up above. If I pass in a value < 10 or some value in the millions, they will be displayed exactly the same as if
I used a single #. If you want to use thousands separators (comma), try:
Console.WriteLine(String.Format("The taxi cab number: {0: 0,0}", 1729)); // Prints 1,729
Console.WriteLine(String.Format("A palindromic prime: {0: 0,0}", 399878993)); // Prints 399,878,993
Here's the fun bit: you can substitute the printing of a negative sign with a word like "minus". Or substitute
zero values to be printed as "zero".
Console.WriteLine(String.Format("{0: 0.00; minus 0.00; zero}", 123.4567)); // Prints 123.46
Console.WriteLine(String.Format("{0: 0.00; minus 0.00; zero}", -123.4567)); // Prints minus 123.46
Console.WriteLine(String.Format("{0: 0.00; minus 0.00; zero}", 0.0)); // Prints zero
Or if you wanted to just get weird:
Console.WriteLine(String.Format("{0: 00whyAmI.doingThis?00}", 123.4567));
// Prints 123whyAmI.doingThis?46
String.Format also includes modifiers for frequently utilized formats: representations
of money (insertion of a floating dollar sign) and percentages.
Console.WriteLine(String.Format("{0: $0.00}", 123.4567)); // Prints $123.46
Console.WriteLine(String.Format("{0: 0.00%}", 0.1415)); // Prints 14.15%