So I know setprecision(int n) should be used when printing a double value with precision n. However, I've run into a problem on a project that I'm working on that is akin to this code:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
double var = 1.0000001;
cout << setprecision(10) << var << endl;
string str = to_string(var);
cout << str << endl;
return 0;
}
Here is the output:
1.0000001
1.000000
In the project I'm working on, I need to save the double value as a string, and it will occasionally need more than six decimal places of precision. Here, precision is clearly lost in the conversion. Any pointers would be greatly appreciated.
Here's a reference for to_string. Note that it produces "As many digits are written as needed to represent the integral part, followed by the decimal-point character and six decimal digits".
The rest of the question is a dupe of lots of SO ansers - see here, for example.
I believe what you are looking for is std::fixed which is described below:
http://www.cplusplus.com/reference/ios/fixed/
Using ostringstream will solve your problem.
#include <sstream>
double var = 1.0000001;
ostringstream os;
os << setprecision(10) << var;
string str = os.str();
cout << str << endl; // this should print 1.0000001
Related
I am trying to convert a string to a double, however when i use stod() the double has lost some of it's decimal places.
Here is the relevant code :
cout << line3 << endl;
float temp = stod(line3);
cout << temp << endl;
For example, when line3 is "4.225308642", temp outputs as 4.22531. What is causing the shortening of the number and how can I fix it?
There are two aspects to consider here.
First, formating on a IOStream by default has a precision of 6 significant digits. That explains your result. You can increase the precision with the manipulator setprecision.
Then, float by itself has a limited precision of about 6 decimal digits as well. Although you can display more, they will be the result of displaying a binary float as decimal, not really an increase of the precision. You can get about 15 decimal digits of precision by using double.
So combining the two, the program
#include <iostream>
#include <string>
#include <iomanip>
int main() {
std::string line3 = "4.225308642";
std::cout << line3 << '\n';
float tempf = stof(line3);
double tempd = stod(line3);
std::cout << "default: float=" << tempf << ", double=" << tempd << '\n';
std::cout << std::setprecision(20);
std::cout << "precision(20): float=" << tempf << ", double=" << tempd << '\n';
}
has for result:
4.225308642
default: float=4.22531, double=4.22531
precision(20): float=4.2253084182739257812, double=4.2253086419999998924
Note again that the last digits result of displaying a binary format. There is a precision after which you can't expect a decimal representation matching the input, and 20 is greater than that. That aspect is explained in more details here.
I need help on keeping the precision of a double. If I assign a literal to a double, the actual value was truncated.
int main() {
double x = 7.40200133400;
std::cout << x << "\n";
}
For the above code snippet, the output was 7.402
Is there a way to prevent this type of truncation? Or is there a way to calculate exactly how many floating points for a double? For example, number_of_decimal(x) would give 11, since the input is unknown at run-time so I can't use setprecision().
I think I should change my question to:
How to convert a double to a string without truncating the floating points. i.e.
#include <iostream>
#include <string>
#include <sstream>
template<typename T>
std::string type_to_string( T data ) {
std::ostringstream o;
o << data;
return o.str();
}
int main() {
double x = 7.40200;
std::cout << type_to_string( x ) << "\n";
}
The expected output should be 7.40200 but the actual result was 7.402. So how can I work around this problem? Any idea?
Due to the fact the float and double are internally stored in binary, the literal 7.40200133400 actually stands for the number 7.40200133400000037653398976544849574565887451171875
...so how much precision do you really want? :-)
#include <iomanip>
int main()
{
double x = 7.40200133400;
std::cout << std::setprecision(51) << x << "\n";
}
And yes, this program really prints 7.40200133400000037653398976544849574565887451171875!
You must use setiosflags(ios::fixed) and setprecision(x).
For example, cout << setiosflags(ios::fixed) << setprecision(4) << myNumber << endl;
Also, don't forget to #include <iomanip.h>.
std::cout << std::setprecision(8) << x;
Note that setprecision is persistent and all next floats you print will be printed with that precision, until you change it to a different value. If that's a problem and you want to work around that, you can use a proxy stringstream object:
std::stringstream s;
s << std::setprecision(8) << x;
std::cout << s.str();
For more info on iostream formatting, check out the Input/output manipulators section in cppreference.
Solution using Boost.Format:
#include <boost/format.hpp>
#include <iostream>
int main() {
double x = 7.40200133400;
std::cout << boost::format("%1$.16f") % x << "\n";
}
This outputs 7.4020013340000004.
Hope this helps!
The only answer to this that I've come up with is that there is no way to do this (as in calculate the decimal places) correctly! THE primary reason for this being that the representation of a number may not be what you expect, for example, 128.82, seems innocuous enough, however it's actual representation is 128.8199999999... how do you calculate the number of decimal places there??
Responding to your answer-edit: There is no way to do that. As soon as you assign a value to a double, any trailing zeroes are lost (to the compiler/computer, 0.402, 0.4020, and 0.40200 are the SAME NUMBER). The only way to retain trailing zeroes as you indicated is to store the values as strings (or do trickery where you keep track of the number of digits you care about and format it to exactly that length).
Let s make an analogous request: after initialising an integer with 001, you would want to print it with the leading zeroes. That formatting info was simply never stored.
For further understanding the double precision floating point storage, look at the IEEE 754 standard.
Doubles don't have decimal places. They have binary places. And binary places and decimal places are incommensurable (because log2(10) isn't an integer).
What you are asking for doesn't exist.
The second part of the question, about how to preserve trailing zeroes in a floating point value from value specification to output result, has no solution. A floating point value doesn't retain the original value specification. It seems this nonsensical part was added by an SO moderator.
Regarding the first and original part of the question, which I interpret as how to present all significant digits of 7.40200133400, i.e. with output like 7.402001334, you can just remove trailing zeroes from an output result that includes only trustworthy digits in the double value:
#include <assert.h> // assert
#include <limits> // std::(numeric_limits)
#include <string> // std::(string)
#include <sstream> // std::(ostringstream)
namespace my{
// Visual C++2017 doesn't support comma-separated list for `using`:
using std::fixed; using std::numeric_limits; using std::string;
using std::ostringstream;
auto max_fractional_digits_for_positive( double value )
-> int
{
int result = numeric_limits<double>::digits10 - 1;
while( value < 1 ) { ++result; value *= 10; }
return result;
}
auto string_from_positive( double const value )
-> string
{
ostringstream stream;
stream << fixed;
stream.precision( max_fractional_digits_for_positive( value ) );
stream << value;
string result = stream.str();
while( result.back() == '0' )
{
result.resize( result.size() - 1 );
}
return result;
}
auto string_from( double const value )
-> string
{
return (0?""
: value == 0? "0"
: value < 0? "-" + string_from_positive( -value )
: string_from_positive( value )
);
}
}
#include<iostream>
auto main()
-> int
{
using std::cout;
cout << my::string_from( 7.40200133400 ) << "\n";
cout << my::string_from( 0.00000000000740200133400 ) << "\n";
cout << my::string_from( 128.82 ) << "\n";
}
Output:
7.402001334
0.000000000007402001334
128.81999999999999
You might consider adding logic for rounding to avoid long sequences of 9's, like in the last result.
The following is my console input/output.
Please enter a real number: -23486.33
Characters checked: 9
Thank you.
The real number you entered is -23486.3
The value I entered is -23486.33, but yet cout prints it as -23486.3.
The relevant code is below:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
// Function prototype (declaration)
string readDouble();
bool isValidDouble(string);
int main()
{
string value;
double number;
value = readDouble();
while (!isValidDouble(value)) {
cout << "The number you entered is not a valid integer." << endl;
value = readDouble();
}
number = atof(value.c_str());
cout << "Thank you." << endl
<< "The real number you entered is " << number << endl;
}
When debugging, I check the value of number right after the method call atof(value.c_str())l;. Number is shown to have a value of -23486.33. So what happens between that and the print out by cout? In no part of my code do I set the precision of cout or make it fixed.
If you have any questions, please let me know.
Have you tried
std::cout << std::setprecision(2) << number;
look at:
http://www.cplusplus.com/reference/iomanip/setprecision/
-23486.3 is displayed because std::cout prints only 6 digits by default.
To print back a number entered from standard input (convertion text → floating number → text), you can use set_precision with digits10 as precision:
double d = -23486.33;
int precision = std::numeric_limits<double>::digits10;
std::cout << std::setprecision(precision) << d << std::endl;
This displays:
-23486.33
To print a number with full precision (usually for convertion floating number → text → floating number), you can use set_precision with max_digits10 as precision:
double d = -23486.33;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::setprecision(precision) << d << std::endl;
This displays:
-23486.330000000002
Here the printed number is not the same because -23486.33 doesn't have an exact representation in IEEE encoding (expressed in base 2 instead of base 10).
For more details with digits10 and max_digits10, you can read:
difference explained by stackoverflow
digits10
max_digits10
Set a precision when you output a double and keep precision explicitly when you compare them.
When you convert a string presentation of a DEC number to a double(float point number presentation), the data in the memory might not be mathematically equal to the string presentation. It's the best approximation by a float point number presentation, and vise versa.
You can set the precision to the maximum limit for double.
The code snippet is here:
#include <iostream>
#include <limits>
#include <iomanip>
using namespace std;
double number = ... // your double value.
cout << setprecision(numeric_limits<double>::digits10) << number << endl;
I have a float number and I want to print one digit after decimal. How can I do this using cout? I have tried the following code but its giving wrong display.
#include <iostream>
using namespace std;
int main()
{
float time = 2.2;
cout.precision(1);
cout << time << endl;
return 0;
}
You need to set tge precision to one and float formatting flags to fixed:
std::cout << std::fixed << std::setprecision(1);
BTW, don't use std::endl. To get a newline use '\n' and if you really mean to flush the stream use std::flush.
I need help on keeping the precision of a double. If I assign a literal to a double, the actual value was truncated.
int main() {
double x = 7.40200133400;
std::cout << x << "\n";
}
For the above code snippet, the output was 7.402
Is there a way to prevent this type of truncation? Or is there a way to calculate exactly how many floating points for a double? For example, number_of_decimal(x) would give 11, since the input is unknown at run-time so I can't use setprecision().
I think I should change my question to:
How to convert a double to a string without truncating the floating points. i.e.
#include <iostream>
#include <string>
#include <sstream>
template<typename T>
std::string type_to_string( T data ) {
std::ostringstream o;
o << data;
return o.str();
}
int main() {
double x = 7.40200;
std::cout << type_to_string( x ) << "\n";
}
The expected output should be 7.40200 but the actual result was 7.402. So how can I work around this problem? Any idea?
Due to the fact the float and double are internally stored in binary, the literal 7.40200133400 actually stands for the number 7.40200133400000037653398976544849574565887451171875
...so how much precision do you really want? :-)
#include <iomanip>
int main()
{
double x = 7.40200133400;
std::cout << std::setprecision(51) << x << "\n";
}
And yes, this program really prints 7.40200133400000037653398976544849574565887451171875!
You must use setiosflags(ios::fixed) and setprecision(x).
For example, cout << setiosflags(ios::fixed) << setprecision(4) << myNumber << endl;
Also, don't forget to #include <iomanip.h>.
std::cout << std::setprecision(8) << x;
Note that setprecision is persistent and all next floats you print will be printed with that precision, until you change it to a different value. If that's a problem and you want to work around that, you can use a proxy stringstream object:
std::stringstream s;
s << std::setprecision(8) << x;
std::cout << s.str();
For more info on iostream formatting, check out the Input/output manipulators section in cppreference.
Solution using Boost.Format:
#include <boost/format.hpp>
#include <iostream>
int main() {
double x = 7.40200133400;
std::cout << boost::format("%1$.16f") % x << "\n";
}
This outputs 7.4020013340000004.
Hope this helps!
The only answer to this that I've come up with is that there is no way to do this (as in calculate the decimal places) correctly! THE primary reason for this being that the representation of a number may not be what you expect, for example, 128.82, seems innocuous enough, however it's actual representation is 128.8199999999... how do you calculate the number of decimal places there??
Responding to your answer-edit: There is no way to do that. As soon as you assign a value to a double, any trailing zeroes are lost (to the compiler/computer, 0.402, 0.4020, and 0.40200 are the SAME NUMBER). The only way to retain trailing zeroes as you indicated is to store the values as strings (or do trickery where you keep track of the number of digits you care about and format it to exactly that length).
Let s make an analogous request: after initialising an integer with 001, you would want to print it with the leading zeroes. That formatting info was simply never stored.
For further understanding the double precision floating point storage, look at the IEEE 754 standard.
Doubles don't have decimal places. They have binary places. And binary places and decimal places are incommensurable (because log2(10) isn't an integer).
What you are asking for doesn't exist.
The second part of the question, about how to preserve trailing zeroes in a floating point value from value specification to output result, has no solution. A floating point value doesn't retain the original value specification. It seems this nonsensical part was added by an SO moderator.
Regarding the first and original part of the question, which I interpret as how to present all significant digits of 7.40200133400, i.e. with output like 7.402001334, you can just remove trailing zeroes from an output result that includes only trustworthy digits in the double value:
#include <assert.h> // assert
#include <limits> // std::(numeric_limits)
#include <string> // std::(string)
#include <sstream> // std::(ostringstream)
namespace my{
// Visual C++2017 doesn't support comma-separated list for `using`:
using std::fixed; using std::numeric_limits; using std::string;
using std::ostringstream;
auto max_fractional_digits_for_positive( double value )
-> int
{
int result = numeric_limits<double>::digits10 - 1;
while( value < 1 ) { ++result; value *= 10; }
return result;
}
auto string_from_positive( double const value )
-> string
{
ostringstream stream;
stream << fixed;
stream.precision( max_fractional_digits_for_positive( value ) );
stream << value;
string result = stream.str();
while( result.back() == '0' )
{
result.resize( result.size() - 1 );
}
return result;
}
auto string_from( double const value )
-> string
{
return (0?""
: value == 0? "0"
: value < 0? "-" + string_from_positive( -value )
: string_from_positive( value )
);
}
}
#include<iostream>
auto main()
-> int
{
using std::cout;
cout << my::string_from( 7.40200133400 ) << "\n";
cout << my::string_from( 0.00000000000740200133400 ) << "\n";
cout << my::string_from( 128.82 ) << "\n";
}
Output:
7.402001334
0.000000000007402001334
128.81999999999999
You might consider adding logic for rounding to avoid long sequences of 9's, like in the last result.