General Stream Manipulation in C++ - Float Formatting
(Page 3 of 4 )
Formatting float numbers is a little more interesting, as you can change the precision of the display, the notation of the display, and even the decimal display for float values that turn out to have some whole part at a level. All of it is condensed in the lines below.
double i = 3.165; //(1)
cout << i << endl; //(2)
cout <<showpoint<< i << endl; //(3)
int old = cout.precision(2); //(4)
cout << i << endl; //(5)
cout << scientific << i << endl; //(6)
cout << uppercase<< i <<endl; //(7)
cout << fixed << setw(8) << right << i << endl; //(8)
cout << setw(8) << internal ; //(9)
cout << setfill('@') << showpos << i << endl; //(10)
cout << setfill('#') << showpos << -i << endl; //(11)
cout.precision(old); //(12)
3.165
3.16500
3.2
3.17e+000
3.17E+000
3.17
+@@@3.17
-3.17
Press any key to continue . . .
In the first line we just print out the number as we should—nothing devilish. In the third row of the code snippet we apply the showpoint manipulator that tells the stream what prints the zeros after the decimal points. The opposite of this is on by default, the noshowpoint manipulator.
We can set the precision of the output with the precision function of the stream. This function will return the old one, so we can restore it in the end (line 12). However, be aware that this will be the count of all numbers that will be printed, even the ones prior to the decimal point.
Here I cannot stress enough that C++ will NOT truncate the number when it converts from a larger precision to a smaller one. Instead, it will round the number, so be aware of this. Line 5 in the code and line 3 in the output demonstrate my point.
Then again there it is the scientific flag. This will display the number in a scientific manner. However, this has some additional effects. This means that the precision functions no longer set the precision for the number. Now only the after-the-decimal-point function will be applied.
Whether or not to apply the scientific mode is resolved automatically by the stream after making an evaluation of the number. If it is very large or small, the scientific view will be better for readability, so it will print it out in that fashion. Nevertheless, you can request the scientific mode with the manipulator mentioned above. If you want your output to be easy to read, better leave it on the default behavior.
If you want to print a char uppercase (also, for hexadecimal values, the X), just apply the uppercase manipulator or the nouppercase if you want the default behavior. The fixed manipulator will get the precision behavior from the scientific mode into the default settings. So just apply that to the numbers after the decimal point.
Then we have the ordering options. You have a right manipulator and a default one, left. This will make sense with the setw function. This will point out to the stream that you want that your output take n position (what you specify as an argument to the setw) on the screen.
The stream will take the output, and if it is smaller than what you specified, align it as required and fill the remaining chars as you want. By default, this character is the space, but you can modify it as I did with the setfill(‘#’) manipulator.
Here we must point out that setw is the exception function that I was talking about earlier. The setw function is special, and only affects the following first output (or input, as I will show in the last section). That is why the last line ended up printing just the number.
Other manipulators used here are the internal one, that will tell the stream to order the sign to the left and the number to the right. Then there is the showpos one, that just forces it to print the positive sign on the screen (or inside a file).
You may ask how we turn off the fixed effects, as I have not mentioned a counterpart. The answer is that we must unset all the settings for the floatfield (all that apply for a float number) with the following method:
cout.unsetf(ostream::floatfield);
// note: or we can write a manipulator to do the same but //that will be explained in a future article
Next: Closing Thoughts >>
More C++ Articles
More By Gabor Bernat