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?
![](../../users/profiles/471164.webp)
- 37,224
- 19
- 144
- 248
![](../../users/profiles/6212.webp)
- 37,168
- 13
- 93
- 118
-
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
-
1@vitaut I don't recommend marking highly popular questions as duplicates of much smaller ones. Your answer will eventually reach the top here. Who knows, in 10 years, there will be an even better method (unlikely in this case). Then what do we do? Close the second and open a third? It would be messy. This one has the Google pagerank, so let's make the right answer go up here. Underlying problem is that SO's answer sorting algorithms are naive, but they just don't care about fixing it. – Ciro Santilli新疆棉花TRUMP BAN BAD Jan 09 '21 at 08:37
-
Actually the other question is more recent (duplicate), so it should be https://stackoverflow.com/questions/19610161/full-precision-display-of-floating-point-numbers-in-c that should be closed and this one (original) that should be reopened. – Antonin GAVREL Feb 27 '21 at 06:50
16 Answers
You can set the precision directly on std::cout
and use the std::fixed
format specifier.
double d = 3.14159265358979;
cout.precision(17);
cout << "Pi: " << fixed << d << endl;
You can #include <limits>
to get the maximum precision of a float or double.
#include <limits>
typedef std::numeric_limits< double > dbl;
double d = 3.14159265358979;
cout.precision(dbl::max_digits10);
cout << "Pi: " << d << endl;
![](../../users/profiles/1288.webp)
- 369,957
- 201
- 546
- 842
-
48Why do you explicitly advise to use `fixed`? With `double h = 6.62606957e-34;`, `fixed` gives me `0.000000000000000` and `scientific` outputs `6.626069570000000e-34`. – Arthur Jan 09 '12 at 17:58
-
36The precision needs to be 17 (or std::numeric_limits
::digits10 + 2) because 2 extra digits are needed when converting from decimal back to the binary representation to ensure the value is rounded to the same original value. Here is a paper with some details: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – Mike Fisher Oct 28 '13 at 09:16 -
9Is the really the right answer? When I manually use a high number, I can print out as many as 51 digits of approximated e, but with `cout.precision(numeric_limits
::digits10 + 2);` I only get 16.... – Assimilater Sep 04 '14 at 22:07 -
6For those looking where it mentions 17 digits in the paper @MikeFisher cited, it's under Theorem 15. – Emile Cormier Jan 11 '15 at 21:23
-
16@MikeFisher You're right, [C++11 introduces `max_digits10`](http://www2.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf) to denote the same. Fixed the answer to reflect this. – legends2k Aug 24 '15 at 07:47
-
2`max_digits10` might be useful for setting the number of figures displayed in scientific notation; for fixed it only works for values with magnitude near 1. – Ben Voigt Nov 15 '15 at 21:24
-
1But what is the reason behind? why cout not print value as it is? – Asif Mushtaq Jan 16 '16 at 16:16
-
@Ben, I agree with you. max_digits10 gives the maximum number of digits before and after the decimal point. set_precision() with fixed specifier sets the number of digits only after the decimal point. – Daniel Laügt Jan 17 '16 at 22:46
-
1@DanielLaügt am I right in thinking then that the currently posted solution should work, since if max_digits10 denotes the total number of digits period then set_precision with that many digits should only be overkill, and no precision should be lost? – Joseph Garvin Apr 13 '17 at 23:45
-
@MikeFisher Disagree about "or std::numeric_limits
::digits10 + 2". Depending on various FP attributes, _in general_, the +2 needs to be as high as +3. Note +3 applies commonly with `float`. – chux - Reinstate Monica Sep 12 '18 at 13:25 -
2@chux indeed, with float we have 6 vs 9 digits. But also with `long double` on x87 (with full precision, e.g. in GCC) we have 18 vs 21 digits, a well as with `float128` (IEEE754 `binary128`): 33 vs 36 digits. So it's the `double` who is outlier with its 15 vs 17 digits min and max. – Ruslan May 27 '19 at 17:33
-
I see people using in our code set_precision(18) for double. Is this really meaning full? Shouldn't we use set_precision(17)? – stephanmg Feb 11 '20 at 00:52
-
1@Assimilater Most of those are just artefacts of the particular negative power of two. Here's a simplified example: Imagine you had a super-low precision type with only three binary places and no exponent, so it could only represent 0, 1/8, 2/8, ..., 7/8. Then converting 0.1 to it and back would give you "0.125" so it looks like 3 decimal places of precision, but really there's only 1 decimal place of actual information. – Arthur Tacca Jun 16 '20 at 08:57
-
@ass No, this is not the correct answer. It confuses two concepts: *"full precision"* and *"no loss of information"*. Displaying `max_digits10` digits guarantees that converting that decimal back to a floating point value will result in the same binary representation, so there is no loss of information. That's far from full precision, though. A floating point value represented in base 10 will always end in a final decimal of either `0` or `5`. The [proposed solution](https://godbolt.org/z/vZCLTq)'s output ends in `9`. – IInspectable Jun 24 '20 at 22:11
Use std::setprecision
:
std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;
![](../../users/profiles/1329340.webp)
- 3,502
- 3
- 30
- 34
![](../../users/profiles/14356.webp)
- 13,460
- 5
- 30
- 67
-
2Is there some kind of MAX_PRECISION macro or enum or something I can pass to std::setPrecision? – Jason Punyon Feb 16 '09 at 18:23
-
3
-
16
-
7Should be `std::setprecision (17)` for double, see comments on @Bill The Lizard's answer. – Alec Jacobson Dec 17 '15 at 14:45
-
11
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.
![](../../users/profiles/14065.webp)
- 234,851
- 74
- 306
- 532
-
14
-
-
2
-
-
5@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 -
1@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
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
![](../../users/profiles/501771.webp)
- 2,289
- 4
- 27
- 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
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;
![](../../users/profiles/364818.webp)
- 18,024
- 5
- 88
- 112
-
variant with union will give you undefined behavior because it attempts to read uninitialized value `x.u64`. – user7860670 Jul 19 '20 at 09:01
In C++20 you'll be able to use std::format
to do this:
std::cout << std::format("{}", M_PI);
Output (assuming IEEE754 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.
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);
Disclaimer: I'm the author of {fmt} and C++20 std::format
.
![](../../users/profiles/471164.webp)
- 37,224
- 19
- 144
- 248
-
2C++20 `std::format` previously mentioned at: https://stackoverflow.com/a/65266570/895245 :-) Thanks for making this. – Ciro Santilli新疆棉花TRUMP BAN BAD Dec 17 '20 at 16:37
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>
![](../../users/profiles/5262677.webp)
- 93
- 1
- 8
![](../../users/profiles/5229914.webp)
- 919
- 1
- 10
- 17
-
5This 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
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.
- 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
- Otherwise:
fixed
orscientific
?
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
- 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
//1234567890123456 17 total digits
![](../../users/profiles/2410359.webp)
- 113,725
- 11
- 107
- 213
-
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
-
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
printf("%.12f", M_PI);
%.12f means floating point, with precision of 12 digits.
![](../../users/profiles/257903.webp)
- 4,712
- 1
- 29
- 32
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 typeT
.
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 double
s1. 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.
![](../../users/profiles/1889329.webp)
- 35,521
- 8
- 69
- 148
-
@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
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.145
The as mentioned at https://stackoverflow.com/a/65329803/895245 not 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:
- Set back default floating point print precision in C++ for how to restore the initial precision in pre-c++20
- std::string formatting like sprintf
- https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification
![](../../users/profiles/895245.webp)
- 256,395
- 72
- 959
- 767
-
I recommend using the default precision instead of passing precision explicitly. – vitaut Dec 17 '20 at 16:56
-
@vitaut thanks! That's what happens when I don't test the code XD – Ciro Santilli新疆棉花TRUMP BAN BAD Dec 17 '20 at 17:19
Most portably...
#include <limits>
using std::numeric_limits;
...
cout.precision(numeric_limits<double>::digits10 + 1);
cout << d;
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}.
![](../../users/profiles/3882652.webp)
- 31
- 5
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
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.
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 ;
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.
![](../../users/profiles/6829195.webp)
- 345
- 3
- 15
-
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
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';
![](../../users/profiles/7008416.webp)
- 6,565
- 1
- 27
- 42
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.
![](../../users/profiles/154256.webp)
- 123
- 5
-
3numeric_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