Float formatting in C++
Asked Answered
W

6

25

How do you format a float in C++ to output to two decimal places rounded up? I'm having no luck with setw and setprecision as my compiler just tells me they are not defined.

cout << "Total : " << setw(2) << total << endl;

total outputs: Total : 12.3961

I'd like it to be: 12.40 or 12.39 if it's too much work to round up.

Whew answered 21/1, 2013 at 3:19 Comment(1)
My bad, forgot it and edited it in.Whew
E
19

You need to include <iomanip> and provide namespace scope to setw and setprecision

#include <iomanip>
std::setw(2)
std::setprecision(5)

try:

cout.precision(5);
cout << "Total : " << setw(4)   << floor(total*100)/100 << endl;

or

 cout << "Total : " << setw(4)   << ceil(total*10)/10 << endl;

iostream provides precision function, but to use setw, you may need to include extra header file.

Ellis answered 21/1, 2013 at 3:23 Comment(4)
Are there no other ways to format it without including other libraries? I ask this because my professor is super strict, and I'm assuming he doesn't want us to explore more libraries than the ones we learned in class aka iostream and cstring.Whew
setprecision(2) displays 12 not 12.39. How to display decimals?Whew
@Whew <iomanip> is part of the C++ standard library. A good professor should not forbid you to explore the internet about good solutions. If you can explain why you included another file of the standard library (it's not another library), it should be perfectly fine.Headwaters
@Whew This (12 instead of 12.39) is because setprecision defines (per default) the number of significant digits, not the ones after the decimal point. Note that for large values, it will use the exponential form. If you always want to have 2 digits after the decimal point, as it seems to be the case for me, you have to use the fixed number format (also write std::fixed to std::cout); see my answer with an online view.Headwaters
M
21

Use cout << fixed or cout.setf(ios::fixed), and std::cout.precision(<# of decimal digits>) as in the following (using the Clang-503.0.40 compiler included with OSX Mavericks):

#include <iostream>

int main()
{
   using namespace std;

   float loge = 2.718;
   double fake = 1234567.818;
   cout << fixed;
   cout.precision(2);
   cout << "loge(2) = " << loge << endl;
   cout << "fake(2) = " << fake << endl;
   cout.precision(3);
   cout << "loge(3) = " << loge << endl;
   cout << "fake(3) = " << fake << endl;
}

The output from this is (note the rounding):

loge(2) = 2.72
fake(2) = 1234567.82
loge(3) = 2.718
fake(3) = 1234567.818

This is the simple version. In lieu of using cout << fixed;, you can use cout.setf(ios::fixed); (for displaying scientific notation, replace fixed with scientific; both will set the number of digits to the right of the decimal point). Note the cout.precision() is also used to set the number of digits displayed in total on either side of the decimal point if the format flags do not include fixed or scientific. There are tutorials for this on the Internet.

Maffa answered 5/8, 2014 at 22:58 Comment(0)
E
19

You need to include <iomanip> and provide namespace scope to setw and setprecision

#include <iomanip>
std::setw(2)
std::setprecision(5)

try:

cout.precision(5);
cout << "Total : " << setw(4)   << floor(total*100)/100 << endl;

or

 cout << "Total : " << setw(4)   << ceil(total*10)/10 << endl;

iostream provides precision function, but to use setw, you may need to include extra header file.

Ellis answered 21/1, 2013 at 3:23 Comment(4)
Are there no other ways to format it without including other libraries? I ask this because my professor is super strict, and I'm assuming he doesn't want us to explore more libraries than the ones we learned in class aka iostream and cstring.Whew
setprecision(2) displays 12 not 12.39. How to display decimals?Whew
@Whew <iomanip> is part of the C++ standard library. A good professor should not forbid you to explore the internet about good solutions. If you can explain why you included another file of the standard library (it's not another library), it should be perfectly fine.Headwaters
@Whew This (12 instead of 12.39) is because setprecision defines (per default) the number of significant digits, not the ones after the decimal point. Note that for large values, it will use the exponential form. If you always want to have 2 digits after the decimal point, as it seems to be the case for me, you have to use the fixed number format (also write std::fixed to std::cout); see my answer with an online view.Headwaters
H
13

To also include the trailing zero, it isn't sufficient to set the precision. You also have to change the floating point format to fixed format, which uses the number of digits as told by setprecision as the number of digits after the decimal point:

std::cout << std::fixed << std::setprecision(2) << v;

Working online example code

Headwaters answered 21/1, 2013 at 4:11 Comment(1)
For this to work you need to add this to your includes: #include <iomanip>Klockau
H
9

If you want the trailing zero from rounding, you can use the C function printf.

#include <iostream>
#include <cstdio>

int main() {
    float v = 12.3961;
    std::printf("%.2f",v); //prints 12.40
}

Compared to:

#include <iostream>
#include <iomanip>

int main() {
    float v = 12.3961;
    std::cout << std::setprecision(4) << v; //prints 12.4
}
Herman answered 21/1, 2013 at 3:29 Comment(7)
This doesn't answer the question, does it?Headwaters
@Headwaters he's asking how to get formatted precision output. Isn't he? At least that's what I read.Herman
Hmm... I think this was my mistake. Your answer is correct. However, I don't like that you want to fall back to a C function like printf. And your C++ solution doesn't print the correct output as he wanted it to be (with the trailing 0). [By the way: you said leading instead of trailing]Headwaters
@Headwaters Yeah, I don't like using C functions either but for formatted float input it's much better than std::setprecision in my opinion.Herman
@Herman that's the opinion I was looking for, I agree with you. Weird how C++ don't have a better way than our older C buddy.Poteat
@eusoubrasileiro Since this was written, there is now {fmt} and std::format in C++20 so this is out of date actually.Herman
@Herman wow almost identical to str.format in python 3+ thanks!Poteat
G
7

You can do it with C++20 std::format:

std::cout << std::format("Total     : {:.2f}\n", total);

or the fmt::format function from the {fmt} library, std::format is based on. {fmt} also provides the print function that integrates formatting and output making it even easier and more efficient (godbolt):

#include <fmt/core.h>

int main() {
  fmt::print("Total     : {:.2f}\n", 12.3961);
}

Output:

Total     : 12.40

This uses the IEEE754 default rounding mode (round to nearest even) so you'll have to round up yourself (How do I round up/down a decimal place of a float value? C++).

Gunpoint answered 27/5, 2021 at 16:12 Comment(0)
Y
3

This is a little dirty...

template <typename T>
string sFormat(const char *f, T value)
{
    char buffer[64];
    snprintf(buffer, sizeof(buffer), f, value);
    return string(buffer);
}

And do things like this :

cout << "Result :" << sFormat(" %5.2f", 3.14) << sFormat(" %5d", 2300) << endl;
Yogi answered 13/9, 2020 at 21:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.