Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formatting floats: returning to default

I am running into a formatting issue on floating-point values, in the sense of returning to "default formatting". Say I have 2 floats:

float f1 = 3.0f, f2 = 1.5f;
std::cout << f1 << " - " << f2 << "\n";

will show these as: 3 - 1.5

Now, for some reason, I need to set precision on std::cout (for other printing):

cout << std::precision(2);

If I print again my two floats, this will lead to: 3.00 - 1.50

Now I want to get back to default formatting. Until C++11 this seems to be difficult (or was it ?). But, thanks, I now got this new flag: std::defaultfloat. Lets try:

std::cout << std::defaultfloat << f1 << " - " << f2;

will print: 3 - 1.50. Fine.

Oh, but wait. Say I have instead:

float f1 = 444.0f, f2 = 444.5f;

Default printing will show: 444 - 444.5

Setting precision (and "fixed"):

cout << std::precision(2) << std::fixed;

will show: 444.00 - 444.50

But returning to "default":

std::cout << std::defaultfloat << f1 << " - " << f2;

will print: 4.4e+02 - 4.4e+02 (automatic switching to scientific format). And, in case you wonder, appending the "fixed" flag will keep the previously assigned precision, thus not returning back to original setting.

Question: How do I get back to the default mode ?

FWIW, live code is here.

Edit: this question has been tagged as a dupe but the linked answer does not provide an answer to the question, it only mentions how to get the current precision.

Edit 2: upon request, here is the full code demonstrating the issue:

int main()
{
    float f1 = 444.5f, f2=443.0f;
    std::cout << f1 << " - " << f2 << "\n";
    std::cout << std::fixed << std::setprecision(2);
    std::cout << f1 << " - " << f2 << "\n";
    std::cout << std::defaultfloat;
    std::cout << f1 << " - " << f2 << "\n";
}

And the result:

444.5 - 443
444.50 - 443.00
4.4e+02 - 4.4e+02
like image 456
kebs Avatar asked Oct 28 '18 11:10

kebs


People also ask

What is float formatting?

Single-precision floating-point format (sometimes called FP32 or float32) is a computer number format, usually occupying 32 bits in computer memory; it represents a wide dynamic range of numeric values by using a floating radix point.

How do you display floating-point numbers in C++?

In order to force C++ to display our floating-point numbers in the scientific format regardless of the size of the number, we use the format specifier scientific inside of cout .


2 Answers

std::defaultfloat doesn't reset the precision. (Don't ask me why). You could reset that to the default which is defined as 6:

std::cout << std::defaultfloat << std::setprecision(6) << f1 << " - " << f2;

Alternatively you could save the entire stream state before the operation and restore it after; see this thread for that.

like image 40
M.M Avatar answered Sep 22 '22 11:09

M.M


In C++20 you can use std::format which is a stateless API. In particular, specifying the precision in one call won't affect the other:

float f1 = 444.0f, f2 = 444.5f;
std::cout << std::format("{} - {}\n", f1, f2);
// Output: 444 - 444.5
std::cout << std::format("{:.2f} - {:.2f}\n", f1, f2);
// Output: 444.00 - 444.50
std::cout << std::format("{} - {}\n", f1, f2);
// Output: 444 - 444.5

std::format is not widely available yet but you can use the {fmt} library, std::format is based on, in the meantime. It also provides a print function that combines formatting and I/O:

float f1 = 444.0f, f2 = 444.5f;
fmt::print("{} - {}\n", f1, f2);
// Output: 444 - 444.5
fmt::print("{:.2f} - {:.2f}\n", f1, f2);
// Output: 444.00 - 444.50
fmt::print("{} - {}\n", f1, f2);
// Output: 444 - 444.5

Disclaimer: I'm the author of {fmt} and C++20 std::format.

like image 64
vitaut Avatar answered Sep 21 '22 11:09

vitaut