3

Intuitively I would think that long doubles have more decimal places than doubles and doubles have more decimal places than floats, however, if so why does std::cout print out floats, doubles, and long doubles at the same decimal precision, even when they have overloads for all primitive data types?

C++ source code:

#include <iostream>

#define PI 3.1415926535897932384626433832;

int main()
{
    float f = PI;
    double d = PI;
    long double ld = PI;

    std::cout << f << std::endl;
    std::cout << d << std::endl;
    std::cout << ld << std::endl;

    return 0;
}

output:

3.14159
3.14159
3.14159
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
MaximV
  • 155
  • 11
  • 1
    There is just one setting for all types of floats. You can't have different precision for float, double and long double. – Thomas Sablik Jun 23 '20 at 14:46
  • 3
    @ThomasSablik That's not quite a motivation for *why* the standards commitee chose to do it that way. – Arthur Tacca Jun 23 '20 at 14:47
  • Reason is simple standard doesn't strictly define precision of each of that types. On each platform precision of `double` can be different (even on same platform different compilers use different precision). So there is no reasonable choice for number of significant digits when printing a value. – Marek R Jun 23 '20 at 14:51
  • 2
    Related: https://stackoverflow.com/a/50970282/4641116 – Eljay Jun 23 '20 at 14:53
  • 1
    @MarekR The standard could easily have specified something like "enough to make the representation unambiguous in that precision". That means the library would need to know implementation-specific details, but that's already the case e.g. in `std::numeric_limits`. In fact such a hypothetical implementation could even *use* `std::numeric_limits`! – Arthur Tacca Jun 23 '20 at 15:09
  • @ArthurTacca nope since in such case same program on different platform would produce significantly different result. – Marek R Jun 23 '20 at 15:11
  • 1
    @MarekR Only if the floating point type being used has a different precision on those two platforms, in which case there is already a different result on those two platforms. – Arthur Tacca Jun 23 '20 at 15:13
  • 1
    @MaximV Are you actually interested in why it does this? That's what you asked, but given the answer you accepted, it seems like what you're really interested in is how to change the behaviour. – Arthur Tacca Jun 23 '20 at 15:41
  • @ArthurTacca I was interested in why it did it and how to resolve it – MaximV Jun 23 '20 at 15:43
  • @MaximV At that question that was linked to ("How do I print a double value...") I just posted an answer that shows a wrapper function that also works for `float` and lets you use a fairly simple wrapper function with the stream (like `std::cout << printIt(d)`). – Arthur Tacca Jun 23 '20 at 16:12

2 Answers2

3

Values have a fixed precision depending on the type and you can't change it. It's implementation defined. You can only change the precision of the output and there is just one setting for all types of floats. You can't have different output precision for float, double and long double. The default output precision for all types of float is 6.

It's technically not possible to set a different output precision for e.g. float than e.g. double.

There are no overloads for std::setprecision. Each std::basic_ostream can hold only one value for precision.

Thomas Sablik
  • 16,127
  • 7
  • 34
  • 62
  • How come [cout](http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/) provides overloads for all decimal types? – MaximV Jun 23 '20 at 14:51
  • I have also noted that std::to_string does the same, is there any way around this? – MaximV Jun 23 '20 at 14:52
  • @MaximV There are no overloads for `std::setprecision`. Each `std::basic_ostream` can hold only one value for precision. You can write your own wrapper. – Thomas Sablik Jun 23 '20 at 15:08
0

You may want to take a look at the setprecision function from <iomanip> library. This will solve your problem. By calling this function, you'll be able to set a decimal for your printed output. Check the example below:

#include <iostream>
#include <iomanip>
#include <limits>

using namespace std;

int main() {
    float a,b;
    cin>>a>>b;
    float c=a+b;
    cout<<fixed<<setprecision(1)<<c;// to print the decimal point scaled to 1

    return 0;
}

Update me if you still have a question.

Liana
  • 314
  • 5
  • 15
  • Why is `setprecision` being applied before c in a string stream? shouldn't it be a function being applied directly to c returning a string? – MaximV Jun 23 '20 at 15:30
  • 2
    @MaximV Are you looking for a "why" answer, or do you just want to know how to print more digits? This answer doesn't explain why there's a single setting for all three, but your accepting it indicates it's good enough. – John Kugelman Jun 23 '20 at 15:35
  • 2
    @MaximV `setprecision` sets the precision of the stream not of the value. You can't change the precision of a value. _"Why is setprecision being applied before c in a string stream?"_ There is no string stream. – Thomas Sablik Jun 23 '20 at 15:36
  • @ThomasSablik what if there were multiple decimals with different precisions in the same stream? – MaximV Jun 23 '20 at 15:39
  • 1
    @MaximV They will be printed with the same precision. You can't change the precision of a value and each stream can hold only one precision. `cout< – Thomas Sablik Jun 23 '20 at 15:39
  • 1
    @MaximV looking for it on forums or more sources may help you. That's how it's used. [link] (https://www.cplusplus.com/reference/iomanip/setprecision/). – Liana Jun 23 '20 at 15:40