Print double value with full precision in C++ [7 methods]

Do not miss this exclusive book on Binary Tree Problems. Get it now for free.

In this article, we have presented several methods to print double or float values with desired precision in C++ using cout.

Table of contents:

  1. Problem printing in low precision in C++
  2. Approach 1: cout.precision
  3. Approach 2: std::setprecision
  4. Approach 3: std::scientific
  5. Approach 4: std::fixed
  6. Approach 5: std::hexfloat
  7. Approach 6: std::format
  8. Approach 7: lexical_cast

Problem printing in low precision in C++

This code is printing a double value e (Euler's constant) with 15 digits of precision.

#include<iostream>

int main() {
    double e = 2.718281828459045;
    std::cout << "e value: " << e << std::endl;
    return 0;
}

Output:

e value: 2.71828

See that the output is printing only 6 digits of precision. This is the problem with printing double or float values as the values are truncated while printing.

We will explore different methods to print values in full precision.

Approach 1: cout.precision

In this approach, using the presion method of cout, we can set the maximum precision required to print a variable of float or double datatype.

double e = 2.71828182845904;
std::cout.precision(17);
std::cout << "e value: " << std::fixed << e << std::endl;

Note there are 15 digits in e but we have added the precision as 17 (15+2) because 2 extra precision is required to ensure there is no loss while conversion between decimal and binary presentation.

If the precision is not known beforehand, we can use std::numeric_limits to get the precision of any variable of datatype float or double.

typedef std::numeric_limits< double > dbl;

double e = 2.718281828459045;
std::cout.precision(dbl::max_digits10 + 2);
std::cout << "e value: " << std::fixed << e << std::endl;

Following is the complete C++ code using cout.precision:

#include<iostream>
#include <limits>
typedef std::numeric_limits< double > dbl;

int main() {
    double e = 2.718281828459045;
    std::cout.precision(dbl::max_digits10 + 2);
    std::cout << "e value: " << std::fixed << e << std::endl;
    return 0;
}

Output:

e value: 2.7182818284590450908

Note some extra precision has been printed which is due to conversion.

Approach 2: std::setprecision

One can use the method setprecision from iomanip library to control the precision of numeric values getting printed.

#include <iomanip>
std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;

To generalize this, use the following:

std::setprecision(std::numeric_limits<double>::digits10 + 2)

Following is the complete C++ code using std::setprecision:

#include<iostream>
#include <limits>
#include <iomanip>
typedef std::numeric_limits< double > dbl;

int main() {
    double e = 2.718281828459045;
    std::cout << std::setprecision(std::numeric_limits<double>::digits10 + 2) << e << std::endl;
    return 0;
}

Output:

2.7182818284590451

Note the output is slightly different from the previous approach though the original number is preserved in both cases.

Approach 3: std::scientific

This is approach we will use through examples how using std::scientific and above precision control approaches help deal with very large and very small values. Note, std::scientific is available in iomanip header file.

std::cout << "std::scientific: " << exp (-100) << std::endl;
std::cout << "std::scientific: " << exp (+100) << std::endl;

Output will be:

std::scientific: 3.72008e-44
std::scientific: 2.68812e+43
std::cout << "std::scientific: " << std::scientific << exp (-100) << std::endl;  
std::cout << "std::scientific: " << std::scientific << exp (+100) << std::endl;

Output will be:

std::scientific: 3.720076e-44
std::scientific: 2.688117e+43
std::cout << std::setprecision(50) << "std::scientific: " << std::scientific << exp (-100) << std::endl;
std::cout << std::setprecision(50) << "std::scientific: " << std::scientific << exp (+100) << std::endl;

Output will be:

std::scientific: 3.72007597602083612000994488118320160434148924400269e-44
std::scientific: 2.68811714181613560942534004359629035546869760000000e+43

Following is the complete C++ code using std::scientific:

#include<iostream>
#include <limits>
#include <cmath>
#include <iomanip>
typedef std::numeric_limits< double > dbl;

int main() {
    double e = 2.718281828459045;
    std::cout << std::setprecision(50) << "std::scientific: " << std::scientific << exp (-100) << std::endl;  
    std::cout << std::setprecision(50) << "std::scientific: " << std::scientific << exp (+100) << std::endl;
    return 0;
}

Output:

std::scientific: 3.72007597602083612000994488118320160434148924400269e-44
std::scientific: 2.68811714181613560942534004359629035546869760000000e+43

Hence, you can get the scientific notation with your desired precision.

Approach 4: std::fixed

In this approach, we use std::fixed instead of std::scientific. In this, the value of precision is critical. Note, std::fixed is available in iomanip header file.

Consider this code snippet using std::fixed:

std::cout << "std::fixed: " << std::fixed << exp (-100) << std::endl;
std::cout << "std::fixed: " << std::fixed << exp (+100) << std::endl;

Output:

std::fixed: 0.000000
std::fixed: 26881171418161356094253400435962903554686976.000000

The difference from scientific notation must be clear now. It is wise to use scientific notation for critical applications.

Let us set the precision value to 50 and check:

std::cout << std::setprecision(50) << "std::fixed: " << std::fixed << exp (-100) << std::endl;
    std::cout << std::setprecision(50) << "std::fixed: " << std::fixed << exp (+100) << std::endl;
std::fixed: 0.00000000000000000000000000000000000000000003720076
std::fixed: 26881171418161356094253400435962903554686976.00000000000000000000000000000000000000000000000000

Now, you can see std::fixed returns the correct value provided the precision is correct.

Following is the complete C++ code using std::fixed:

#include<iostream>
#include <limits>
#include <cmath>
#include <iomanip>
typedef std::numeric_limits< double > dbl;

int main() {
    double e = 2.718281828459045;
    std::cout << std::setprecision(50) << "std::fixed: " << std::fixed << exp (-100) << std::endl;
    std::cout << std::setprecision(50) << "std::fixed: " << std::fixed << exp (+100) << std::endl;
    return 0;
}

Output:

std::fixed: 0.00000000000000000000000000000000000000000003720076
std::fixed: 26881171418161356094253400435962903554686976.00000000000000000000000000000000000000000000000000

Approach 5: std::hexfloat

In previous approaches, we printed the output in base 10. If you need the output in hexadecimal format, you can use std::hexfloat.

std::cout << "hexfloat: " << std::hexfloat << exp (-100) << std::endl;
std::cout << "hexfloat: " << std::hexfloat << exp (+100) << std::endl;

Output:

hexfloat: 0x1.a8c1f14e2af5dp-145
hexfloat: 0x1.3494a9b171bf5p+144

Following is the complete C++ code using std::hexfloat:

#include<iostream>
#include <limits>
#include <cmath>
#include <iomanip>
typedef std::numeric_limits< double > dbl;

int main() {
    std::cout << "hexfloat: " << std::hexfloat << exp (-100) << std::endl;
    std::cout << "hexfloat: " << std::hexfloat << exp (+100) << std::endl;
    return 0;
}

Output:

hexfloat: 0x1.a8c1f14e2af5dp-145
hexfloat: 0x1.3494a9b171bf5p+144

Approach 6: std::format

In this approach, the numeric value is treated as a string and printed and hence, there is no loss in precision. std::format is available in C++20 and beyond.

std::cout << std::format("{}", e);

Following is the complete C++ code using std::format:

#include<iostream>
int main() {
    double e = 2.718281828459045;
    std::cout << std::format("{}", e);
    return 0;
}

Output:

2.718281828459045

Approach 7: lexical_cast

Similar to the previous approach, in this, we use lexical_cast to convert the numeric value to a string and then, print the value to the exact precision. This utilizes the lexical_cast from boost library in C++.

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

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

double e = 2.718281828459045;
std::cout << "e: " << lexical_cast<string>(e) << std::endl;

Following is the complete C++ code using lexical_cast:

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

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

int main() {
    double e = 2.718281828459045;
    std::cout << "e: " << lexical_cast<string>(e) << std::endl;
    return 0;
}

Output:

e: 2.718281828459045

With this article at OpenGenus, you must have the complete idea of how to print a double or float value with desired precision in C++ using cout.

Sign up for FREE 3 months of Amazon Music. YOU MUST NOT MISS.