Daniel Laügt
Daniel Laügt

Reputation: 1147

std::cout with floating number

I'm using visual studio 2015 to print two floating numbers:

double d1 = 1.5;
double d2 = 123456.789;

std::cout << "value1: " << d1 << std::endl;
std::cout << "value2: " << d2 << std::endl;

std::cout << "maximum number of significant decimal digits (value1): " << -std::log10(std::nextafter(d1, std::numeric_limits<double>::max()) - d1) << std::endl;
std::cout << "maximum number of significant decimal digits (value2): " << -std::log10(std::nextafter(d2, std::numeric_limits<double>::max()) - d2) << std::endl;

This prints the following:

value1: 1.5
value2: 123457
maximum number of significant decimal digits (value1): 15.6536
maximum number of significant decimal digits (value2): 10.8371

Why 123457 is printed out for the value 123456.789? Does ANSI C++ specification allow to display anything for floating numbers when std::cout is used without std::setprecision()?

Upvotes: 19

Views: 70211

Answers (3)

incomplet_
incomplet_

Reputation: 328

The rounding off happens because of the C++ standard which can be seen by writing std::cout<<std::cout.precision();

The output screen will show 6 which tells that the default number of significant digits which will be printed by the std::cout statement is 6. That is why it automatically rounds off the floating number to 6 digits.

Upvotes: 12

Ankit Acharya
Ankit Acharya

Reputation: 3121

What you have have pointed out is actually one of those many things that the standardization committee should consider regarding the standard iostream in C++. Such things work well when you write :-

printf ("%f\n", d2);

But not with std::cout where you need to use std::setprecision because it's formatting is similar to the use of %g instead of %f in printf. So you need to write :-

std::cout << std::setprecision(10) << "value2: " << d2 << std::endl;

But if you dont like this method & are using C++11 (& onwards) then you can also write :-

std::cout << "value2: " << std::to_string(d2) << std::endl;

This will give you the same result as printf ("%f\n", d2);.

A much better method is to cancel the rounding that occurs in std::cout by using std::fixed :-

#include <iostream>
#include <iomanip>
int main()
{
    std::cout << std::fixed;
    double d = 123456.789;
    std::cout << d;
    return 0;
}

Output :-

123456.789000

So I guess your problem is solved !!

Upvotes: 13

Mats Petersson
Mats Petersson

Reputation: 129524

I think the problem here is that the C++ standard is not written to be easy to read, it is written to be precise and not repeat itself. So if you look up the operator<<(double), it doesn't say anything other than "it uses num_put - because that is how the cout << some_float_value is implemented.

The default behaviour is what print("%g", value); does [table 88 in n3337 version of the C++ standard explains what the equivalence of printf and c++ formatting]. So if you want to do %.16g you need to change the precision by calling setprecision(16).

Upvotes: 3

Related Questions