442

In my earlier question I was printing a double using cout that got rounded when I wasn't expecting it. How can I make cout print a double using full precision?

vitaut
  • 49,672
  • 25
  • 199
  • 336
Restore the Data Dumps
  • 38,967
  • 12
  • 96
  • 122
  • 2
    Sadly most of the answers below are incorrect. I recommend checking out https://stackoverflow.com/questions/19610161/full-precision-display-of-floating-point-numbers-in-c instead. – vitaut Dec 17 '20 at 19:23
  • 2
    Note that there isn't really such a thing as "full" precision. – Mooing Duck Jul 19 '21 at 21:40
  • 1
    @MooingDuck Actually, if you print the double as a an integer, then you can be sure you save all the bits... (`cout << *reinterpret_cast(&my_double);`) This is useful to save your data and reload it later with the exact same value, bit for bit. But in most cases that's not what the user wants. – Alexis Wilke Dec 16 '21 at 18:32
  • @AlexisWilke: `std::hexfloat` is better than casting, but yes – Mooing Duck Dec 20 '21 at 19:07
  • @AlexisWilke Be **very** careful with that! Type-punning is, unfortunately, horribly broken in C++! – Niko O Feb 10 '22 at 13:06
  • @NikoO [Type punning](https://en.wikipedia.org/wiki/Type_punning) works just fine, at least as long as you don't go across many different processor types. It has worked since day one. I use it in my [libaddr](https://github.com/m2osw/libaddr) project where I deal with IPv4 and IPv6 addresses. See the Socket Example on the Wikipedia page referenced. – Alexis Wilke Feb 10 '22 at 14:00
  • 2
    @AlexisWilke I would argue that "it might just randomly not work in subtle ways with your compiler and there is no 'good' way of doing it" qualifies as "horribly broken". In any case, it is sub-optimal to just post a snippet that "works on my machine" and not even hint at the fact that something wonky is going on. – Niko O Feb 10 '22 at 14:30
  • 4
    FWIW: this question got some attention on a blogpost: https://www.zverovich.net/2023/06/04/printing-double.html – kebs Jun 05 '23 at 14:30

16 Answers16

96

In C++20 you can use std::format to do this:

std::cout << std::format("{}", std::numbers::pi_v<double>);

Output (assuming IEEE 754 double):

3.141592653589793

The default floating-point format is the shortest decimal representation with a round-trip guarantee. The advantage of this method compared to the setprecision I/O manipulator is that it doesn't print unnecessary digits and is not affected by global state (see this blog post for more details).

In the meantime you can use the {fmt} library, std::format is based on. {fmt} also provides the print function that makes this even easier and more efficient (godbolt):

fmt::print("{}", M_PI);

The question doesn’t actually define what it means by "full precision". Normally it is understood as the precision enough for a round trip through decimal but there is another possible but unlikely interpretation of the maximum number of (significant) decimal digits. For IEEE 754 double the latter is 767 digits.

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

vitaut
  • 49,672
  • 25
  • 199
  • 336
  • 1
    Too bad that even GCC 11.2 does not seem to implement `std::format`. – Philipp Ludwig Apr 17 '22 at 07:52
  • 5
    {fmt} works with gcc 4.4 and later – vitaut Jun 04 '23 at 19:41
  • Note: to archive IEEE-754 compliance, the number of significant decimal digits correctly printed does not need to be so great. IIRC, it would be 3 more than the round-trip need. 17 + 3 for common `double`. After that, it might be many zeros. – chux - Reinstate Monica Jun 05 '23 at 14:07
  • 1
    That part is not talking about IEEE-754 compliance but about mathematical representation of the binary number in decimal. – vitaut Jun 05 '23 at 14:12
  • 6
    Saw your rad blog post. Green check transferred <3 – Restore the Data Dumps Jun 06 '23 at 17:18
  • 2
    @PhilippLudwig It would be implemented by the library, not by the compiler. – Keith Thompson Jun 06 '23 at 22:35
  • @KeithThompson true, but wouldn’t this be the job of libstdc++ that ships with GCC? – Philipp Ludwig Jun 07 '23 at 07:08
  • @PhilippLudwig I don't know the details of libstdc++; I'm more familiar with the C side. There's a GNU C standard library that's separate from gcc; other C compilers use glibc, and gcc uses other C libraries on some systems. libstdc++ does appear to be more tightly integrated with gcc/g++, so yes, the gcc release version would be relevant. – Keith Thompson Jun 07 '23 at 18:39
85

Use std::setprecision:

#include <iomanip>
std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;
Joachim W
  • 7,290
  • 5
  • 31
  • 59
Paul Beckingham
  • 14,495
  • 5
  • 33
  • 67
27

Here is what I would use:

std::cout << std::setprecision (std::numeric_limits<double>::digits10 + 1)
          << 3.14159265358979
          << std::endl;

Basically the limits package has traits for all the build in types.
One of the traits for floating point numbers (float/double/long double) is the digits10 attribute. This defines the accuracy (I forget the exact terminology) of a floating point number in base 10.

See: http://www.cplusplus.com/reference/std/limits/numeric_limits.html
For details about other attributes.

Martin York
  • 257,169
  • 86
  • 333
  • 562
  • 14
    This header is needed to use `std::setprecision()`: `#include ` – Martin Berger Aug 19 '11 at 15:26
  • it should be `std::numeric_limits` instead of `numberic_limits` – niklasfi Apr 15 '14 at 14:00
  • 2
    Why do you add `1` to `std::numeric_limits::digits10`? – Alessandro Jacopson Oct 03 '14 at 11:40
  • @uvts_cvs: Because of rounding errors when printing. – Martin York Oct 03 '14 at 11:55
  • 6
    @LokiAstari You can use C+11's `max_digits10` instead. See [this](http://stackoverflow.com/questions/554063/how-do-i-print-a-double-value-with-full-precision-using-cout/554134#comment52239614_554134). – legends2k Aug 25 '15 at 09:04
  • Should be `std::setprecision (std::numeric_limits::digits10 + 2)` , see comments on @Bill The Lizard's answer. – Alec Jacobson Dec 17 '15 at 14:46
  • 4
    @AlecJacobson It should rather be `max_digits10`, not some arbitrary `digits10+2`. Otherwise, in the case of `float`, `long double`, `boost::multiprecision::float128` this will fail, since there you'd need `+3` instead of `+2`. – Ruslan May 27 '19 at 17:41
  • @MartinBerger in that case `` is also needed for numeric_limits but finding the right header is trivial if you have cppreference so its no big deal :) – simplename Feb 25 '22 at 07:06
24

How do I print a double value with full precision using cout?

Use hexfloat or
use scientific and set the precision

std::cout.precision(std::numeric_limits<double>::max_digits10 - 1);
std::cout << std::scientific <<  1.0/7.0 << '\n';

// C++11 Typical output
1.4285714285714285e-01

Too many answers address only one of 1) base 2) fixed/scientific layout or 3) precision. Too many answers with precision do not provide the proper value needed. Hence this answer to a old question.

  1. What base?

A double is certainly encoded using base 2. A direct approach with C++11 is to print using std::hexfloat.
If a non-decimal output is acceptable, we are done.

std::cout << "hexfloat: " << std::hexfloat << exp (-100) << '\n';
std::cout << "hexfloat: " << std::hexfloat << exp (+100) << '\n';
// output
hexfloat: 0x1.a8c1f14e2af5dp-145
hexfloat: 0x1.3494a9b171bf5p+144

  1. Otherwise: fixed or scientific?

A double is a floating point type, not fixed point.

Do not use std::fixed as that fails to print small double as anything but 0.000...000. For large double, it prints many digits, perhaps hundreds of questionable informativeness.

std::cout << "std::fixed: " << std::fixed << exp (-100) << '\n';
std::cout << "std::fixed: " << std::fixed << exp (+100) << '\n';
// output
std::fixed: 0.000000
std::fixed: 26881171418161356094253400435962903554686976.000000 

To print with full precision, first use std::scientific which will "write floating-point values in scientific notation". Notice the default of 6 digits after the decimal point, an insufficient amount, is handled in the next point.

std::cout << "std::scientific: " << std::scientific << exp (-100) << '\n';  
std::cout << "std::scientific: " << std::scientific << exp (+100) << '\n';
// output
std::scientific: 3.720076e-44
std::scientific: 2.688117e+43

  1. How much precision (how many total digits)?

A double encoded using the binary base 2 encodes the same precision between various powers of 2. This is often 53 bits.

[1.0...2.0) there are 253 different double,
[2.0...4.0) there are 253 different double,
[4.0...8.0) there are 253 different double,
[8.0...10.0) there are 2/8 * 253 different double.

Yet if code prints in decimal with N significant digits, the number of combinations [1.0...10.0) is 9/10 * 10N.

Whatever N (precision) is chosen, there will not be a one-to-one mapping between double and decimal text. If a fixed N is chosen, sometimes it will be slightly more or less than truly needed for certain double values. We could error on too few (a) below) or too many (b) below).

3 candidate N:

a) Use an N so when converting from text-double-text we arrive at the same text for all double.

std::cout << dbl::digits10 << '\n';
// Typical output
15

b) Use an N so when converting from double-text-double we arrive at the same double for all double.

// C++11
std::cout << dbl::max_digits10 << '\n';
// Typical output
17

When max_digits10 is not available, note that due to base 2 and base 10 attributes, digits10 + 2 <= max_digits10 <= digits10 + 3, we can use digits10 + 3 to insure enough decimal digits are printed.

c) Use an N that varies with the value.

This can be useful when code wants to display minimal text (N == 1) or the exact value of a double (N == 1000-ish in the case of denorm_min). Yet since this is "work" and not likely OP's goal, it will be set aside.


It is usually b) that is used to "print a double value with full precision". Some applications may prefer a) to error on not providing too much information.

With .scientific, .precision() sets the number of digits to print after the decimal point, so 1 + .precision() digits are printed. Code needs max_digits10 total digits so .precision() is called with a max_digits10 - 1.

typedef std::numeric_limits< double > dbl;
std::cout.precision(dbl::max_digits10 - 1);
std::cout << std::scientific <<  exp (-100) << '\n';
std::cout << std::scientific <<  exp (+100) << '\n';
// Typical output
3.7200759760208361e-44
2.6881171418161356e+43
//2345678901234567  17 total digits

Similar C question

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 3
    Great answer! A few remarks though: You're right that `precision()` sets the number of decimal places for scientific mode. Without specifying `scientific`, it sets the total number of digits, excluding the exponent. You might still end up with scientific output, depending on your number value, but then you might also get less digits than you specified. Example: `cout.precision(3); cout << 1.7976931348623158e+308; // "1.8e+308"` Results for `printf` may be different. Confusing stuff one should be aware off. – Simpleton Mar 04 '20 at 08:46
  • 1
    For posterity, here's the required buffer length for guaranteed exact string representation of all double numbers in scientific mode using printf: `char buf[DBL_DECIMAL_DIG + 3 + 5]; sprintf(buf, "%.*g", DBL_DECIMAL_DIG, d);` The extra characters are for: sign, decimal point, trailing zero, e[+|-], 3 digits for the exponent (DBL_MAX_10_EXP = 308). Hence the total number of required characters is 25. – Simpleton Mar 04 '20 at 08:56
  • Can't edit my first comment, so here we go again: Another issue with scientific mode is that it might decide to not use exponential output, it even might decide to not use floating point output at all. That is, it will output 1.0 as "1", which might be a problem in a serialization/deserialization context. You can force it to output a decimal point by using "%#.*g", but this has the drawback that it adds a number of trailing zeros, which it doesn't without the #... – Simpleton Mar 05 '20 at 10:13
  • *"Whatever N (precision) is chosen, there will not be a one-to-one mapping between double and decimal text."* - That's incorrect. **Any** floating point value has an exact, finite representation in decimal. The opposite isn't true, though. There is no finite representation for the decimal value `0.1` as a floating point value, for example. – IInspectable Jun 23 '20 at 22:01
  • 1
    @IInspectable True that [all finite FP can be converted to decimal text](https://codereview.stackexchange.com/q/212490/29485), yet not certainly with `std::cout <<`. Only rare implementations will do so for all `std::cout.precision(n)`. IEEE 754 only requires about at least dbl::max_digits10 + 3. As "one-to-one mapping between double and decimal text" refers to both conversion directions, we agree one direction possible maps yet the other does not. – chux - Reinstate Monica Oct 07 '21 at 12:43
  • 1
    Fair enough, *"mapping between X and Y"* does suggest a bijective relationship, which apparently escaped me back when I left the comment. – IInspectable Oct 07 '21 at 18:26
  • @Ruslan regarding [It should rather be max_digits10](https://stackoverflow.com/questions/554063/how-do-i-print-a-double-value-with-full-precision-using-cout/52299693?noredirect=1#comment99267839_554780): --> yes, for the total number of _significant_ decimal digits. With `std::scientific`, `1 + setprecision` is the number of significant digits printed. Recommend this answer's `std::scientific` and `cout.precision(dbl::max_digits10 - 1);` – chux - Reinstate Monica Oct 07 '21 at 18:58
14

The iostreams way is kind of clunky. I prefer using boost::lexical_cast because it calculates the right precision for me. And it's fast, too.

#include <string>
#include <boost/lexical_cast.hpp>

using boost::lexical_cast;
using std::string;

double d = 3.14159265358979;
cout << "Pi: " << lexical_cast<string>(d) << endl;

Output:

Pi: 3.14159265358979

Timothy003
  • 2,348
  • 5
  • 28
  • 33
  • The boost documentation says "For numerics that have a corresponding specialization of std::numeric_limits, the current version now chooses a precision to match". This seems like the easiest way to get the max precision. (http://www.boost.org/doc/libs/1_58_0/doc/html/boost_lexical_cast/changes.html) – JDiMatteo May 15 '15 at 21:34
  • Link with boost::lexical_cast (http://www.boost.org/doc/libs/release/libs/conversion/lexical_cast.htm) is dead. – chux - Reinstate Monica Oct 07 '21 at 18:38
  • Note that printing a `double` with only 15 digits as with "Pi: 3.14159265358979" might not convert back to the same `double`. To always do that requires more like [max_digits10](https://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10) significant digits. – chux - Reinstate Monica Oct 07 '21 at 18:41
11

By full precision, I assume mean enough precision to show the best approximation to the intended value, but it should be pointed out that double is stored using base 2 representation and base 2 can't represent something as trivial as 1.1 exactly. The only way to get the full-full precision of the actual double (with NO ROUND OFF ERROR) is to print out the binary bits (or hex nybbles).

One way of doing that is using a union to type-pun the double to a integer and then printing the integer, since integers do not suffer from truncation or round-off issues. (Type punning like this is not supported by the C++ standard, but it is supported in C. However, most C++ compilers will probably print out the correct value anyways. I think g++ supports this.)

union {
    double d;
    uint64_t u64;
} x;
x.d = 1.1;
std::cout << std::hex << x.u64;

This will give you the 100% accurate precision of the double... and be utterly unreadable because humans can't read IEEE double format ! Wikipedia has a good write up on how to interpret the binary bits.

In newer C++, you can do

std::cout << std::hexfloat << 1.1;
Mark Lakata
  • 19,989
  • 5
  • 106
  • 123
11

Here is how to display a double with full precision:

double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::setprecision(precision) << d << std::endl;

This displays:

100.0000000000005


max_digits10 is the number of digits that are necessary to uniquely represent all distinct double values. max_digits10 represents the number of digits before and after the decimal point.


Don't use set_precision(max_digits10) with std::fixed.
On fixed notation, set_precision() sets the number of digits only after the decimal point. This is incorrect as max_digits10 represents the number of digits before and after the decimal point.

double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::fixed << std::setprecision(precision) << d << std::endl;

This displays incorrect result:

100.00000000000049738

Note: Header files required

#include <iomanip>
#include <limits>
habla2019
  • 93
  • 1
  • 9
Daniel Laügt
  • 1,097
  • 1
  • 12
  • 17
  • 5
    This happens because `100.0000000000005` isn't being represented exactly as a `double`. (It might seem like it should, but it doesn't, because it gets [normalised](https://en.wikipedia.org/wiki/IEEE_754-1985), i.e. its binary representation). To see this, try: `100.0000000000005 - 100`. We get `4.973799150320701e-13`. – Evgeni Sergeev Sep 08 '17 at 12:12
6

C++20 std::format

This great new C++ library feature has the advantage of not affecting the state of std::cout as std::setprecision does:

#include <format>
#include <string>

int main() {
    std::cout << std::format("{:.2} {:.3}\n", 3.1415, 3.1415);
}

Expected output:

3.14 3.142

As mentioned at https://stackoverflow.com/a/65329803/895245 if you don't pass the precision explicitly it prints the shortest decimal representation with a round-trip guarantee. TODO understand in more detail how it compares to: dbl::max_digits10 as shown at https://stackoverflow.com/a/554134/895245 with {:.{}}:

#include <format>
#include <limits>
#include <string>

int main() {
    std::cout << std::format("{:.{}}\n",
        3.1415926535897932384626433, dbl::max_digits10);
}

See also:

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
4

IEEE 754 floating point values are stored using base 2 representation. Any base 2 number can be represented as a decimal (base 10) to full precision. None of the proposed answers, however, do. They all truncate the decimal value.

This seems to be due to a misinterpretation of what std::numeric_limits<T>::max_digits10 represents:

The value of std::numeric_limits<T>::max_digits10 is the number of base-10 digits that are necessary to uniquely represent all distinct values of the type T.

In other words: It's the (worst-case) number of digits required to output if you want to roundtrip from binary to decimal to binary, without losing any information. If you output at least max_digits10 decimals and reconstruct a floating point value, you are guaranteed to get the exact same binary representation you started with.

What's important: max_digits10 in general neither yields the shortest decimal, nor is it sufficient to represent the full precision. I'm not aware of a constant in the C++ Standard Library that encodes the maximum number of decimal digits required to contain the full precision of a floating point value. I believe it's something like 767 for doubles1. One way to output a floating point value with full precision would be to use a sufficiently large value for the precision, like so2, and have the library strip any trailing zeros:

#include <iostream>

int main() {
    double d = 0.1;
    std::cout.precision(767);
    std::cout << "d = " << d << std::endl;
}

This produces the following output, that contains the full precision:

d = 0.1000000000000000055511151231257827021181583404541015625

Note that this has significantly more decimals than max_digits10 would suggest.


While that answers the question that was asked, a far more common goal would be to get the shortest decimal representation of any given floating point value, that retains all information. Again, I'm not aware of any way to instruct the Standard I/O library to output that value. Starting with C++17 the possibility to do that conversion has finally arrived in C++ in the form of std::to_chars. By default, it produces the shortest decimal representation of any given floating point value that retains the entire information.

Its interface is a bit clunky, and you'd probably want to wrap this up into a function template that returns something you can output to std::cout (like a std::string), e.g.

#include <charconv>
#include <array>
#include <string>
#include <system_error>

#include <iostream>
#include <cmath>

template<typename T>
std::string to_string(T value)
{
    // 24 characters is the longest decimal representation of any double value
    std::array<char, 24> buffer {};
    auto const res { std::to_chars(buffer.data(), buffer.data() + buffer.size(), value) };
    if (res.ec == std::errc {})
    {
        // Success
        return std::string(buffer.data(), res.ptr);
    }

    // Error
    return { "FAILED!" };
}

int main()
{
    auto value { 0.1f };
    std::cout << to_string(value) << std::endl;
    value = std::nextafter(value, INFINITY);
    std::cout << to_string(value) << std::endl;
    value = std::nextafter(value, INFINITY);
    std::cout << to_string(value) << std::endl;
}

This would print out (using Microsoft's C++ Standard Library):

0.1
0.10000001
0.10000002

1 From Stephan T. Lavavej's CppCon 2019 talk titled Floating-Point <charconv>: Making Your Code 10x Faster With C++17's Final Boss. (The entire talk is worth watching.)

2 This would also require using a combination of scientific and fixed, whichever is shorter. I'm not aware of a way to set this mode using the C++ Standard I/O library.

IInspectable
  • 46,945
  • 8
  • 85
  • 181
  • @chu That assumes that the smallest representable value is also the one with the longest sequence of digits in decimal. That sounds plausible, but plausibility is not quite where floating point values are at home. Have you tried to use [nextafter](https://en.cppreference.com/w/c/numeric/math/nextafter) to see, if the lengths increase in the vicinity of `DBL_TRUE_MIN`? – IInspectable Jun 23 '20 at 21:25
  • @chu Ah, true, `DBL_TRUE_MIN` only has its least significant bit set in the mantissa. Hadn't thought of that. Still, I'd need to see a mathematical proof to understand, why that would result in the longest decimal sequence. – IInspectable Jun 23 '20 at 21:37
  • Note: "One way to output a floating point value with full precision would be to use a sufficiently large value for the precision," --> A library compliant to IEEE 754 need only print the correctly rounded value to `long double::max_digits10` + 3 significant digits. We might not get full precision. – chux - Reinstate Monica Jun 23 '20 at 21:37
  • "I'd need to see a mathematical proof to understand" --> sounds like a good question on some site - and a bit of work to fulfill - too much for a quick comment. – chux - Reinstate Monica Jun 23 '20 at 21:39
  • Yes `DBL_MIN - DBL_TRUE_MIN` took 767 significant digits. – chux - Reinstate Monica Jun 23 '20 at 23:10
  • @chu *"A library compliant to IEEE 754 need only print the correctly rounded value to `long double::max_digits10` + 3 significant digits."* - I wasn't able to find this requirement in the C++ Standard text. Is this incorporated from C, and if so, do you happen to know where I can find that? – IInspectable Jun 25 '20 at 13:38
  • IInspectable, the spec is a IEEE 754 one (sec 5.12), not a C++ one. C++ may follow IEEE754 to various degrees of compliance. [limit, H, shall be such that H ≥ M+3](https://stackoverflow.com/a/11087221/2410359) – chux - Reinstate Monica Jun 25 '20 at 16:06
2
printf("%.12f", M_PI);

%.12f means floating point, with precision of 12 digits.

Maister
  • 4,978
  • 1
  • 31
  • 34
1

In this question there is a description on how to convert a double to string losselessly (in Octave, but it can be easily reproduced in C++). De idea is to have a short human readable description of the float and a losseless description in hexa form, for instance: pi -> 3.14{54442d18400921fb}.

1

The best option is to use std::setprecision, and the solution works like this:

# include <iostream>
# include <iomanip>

int main()
{
    double a = 34.34322;
    std::cout<<std::fixed<<a<<std::setprecision(0)<<std::endl;
    return 0;
}

Note: you do not need to use cout.setprecision to do it and I fill up 0 at std::setprecision because it must have a argument.

  • With this answer, for `double pi = 3.141592653589793` it prints `3.141593` with Apple clang version 13.1.6 . – ChrisZZ Jun 08 '23 at 13:56
0

Here is a function that works for any floating-point type, not just double, and also puts the stream back the way it was found afterwards. Unfortunately it won't interact well with threads, but that's the nature of iostreams. You'll need these includes at the start of your file:

#include <limits>
#include <iostream>

Here's the function, you could it in a header file if you use it a lot:

template <class T>
void printVal(std::ostream& os, T val)
{
    auto oldFlags = os.flags();
    auto oldPrecision = os.precision();

    os.flags(oldFlags & ~std::ios_base::floatfield);
    os.precision(std::numeric_limits<T>::digits10);
    os << val;
    
    os.flags(oldFlags);
    os.precision(oldPrecision);
}

Use it like this:

double d = foo();
float f = bar();
printVal(std::cout, d);
printVal(std::cout, f);

If you want to be able to use the normal insertion << operator, you can use this extra wrapper code:

template <class T>
struct PrintValWrapper { T val; };
template <class T>
std::ostream& operator<<(std::ostream& os, PrintValWrapper<T> pvw) {
    printVal(os, pvw.val);
    return os;
}
template <class T>
PrintValWrapper<T> printIt(T val) {
    return PrintValWrapper<T>{val};
}

Now you can use it like this:

double d = foo();
float f = bar();
std::cout << "The values are: " << printIt(d) << ", " << printIt(f) << '\n';
Arthur Tacca
  • 8,833
  • 2
  • 31
  • 49
-1

This will show the value up to two decimal places after the dot.

#include <iostream>
#include <iomanip>

double d = 2.0;
int n = 2;
cout << fixed << setprecision(n) << d;

See here: Fixed-point notation

std::fixed

Use fixed floating-point notation Sets the floatfield format flag for the str stream to fixed.

When floatfield is set to fixed, floating-point values are written using fixed-point notation: the value is represented with exactly as many digits in the decimal part as specified by the precision field (precision) and with no exponent part.

std::setprecision

Set decimal precision Sets the decimal precision to be used to format floating-point values on output operations.

If you're familiar with the IEEE standard for representing the floating-points, you would know that it is impossible to show floating-points with full-precision out of the scope of the standard, that is to say, it will always result in a rounding of the real value.

You need to first check whether the value is within the scope, if yes, then use:

cout << defaultfloat << d ;

std::defaultfloat

Use default floating-point notation Sets the floatfield format flag for the str stream to defaultfloat.

When floatfield is set to defaultfloat, floating-point values are written using the default notation: the representation uses as many meaningful digits as needed up to the stream's decimal precision (precision), counting both the digits before and after the decimal point (if any).

That is also the default behavior of cout, which means you don't use it explicitly.

Yushan ZHANG
  • 523
  • 5
  • 18
  • It should be setprecision and not setprecison. Note: the edition proposal is blocked because it contains less than 6 characters! – Vincent Vidal Nov 26 '20 at 09:10
-2

With ostream::precision(int)

cout.precision( numeric_limits<double>::digits10 + 1);
cout << M_PI << ", " << M_E << endl;

will yield

3.141592653589793, 2.718281828459045

Why you have to say "+1" I have no clue, but the extra digit you get out of it is correct.

Jann
  • 121
  • 5
  • 3
    numeric_limits::digits10 equals to 2. Because it can contain any decimal number of two digits 0..99. It can also contain 255.. but not 256, 257... 300 etc. this is why digits10 is not 3! I think "+1" is added to overcome something like this. – Dmitriy Yurchenko Apr 24 '13 at 23:42
-2

Most portably...

#include <limits>

using std::numeric_limits;

    ...
    cout.precision(numeric_limits<double>::digits10 + 1);
    cout << d;