This is a snippet of my code. I need some help in removing the error shown below.
#include <iostream>
#include <string>
#include <sstream>
int main()
{
char doubleStr[] = "5.2";
double d = 0.0;
std::stringstream stream (doubleStr);
stream >> d;
std::cout << d << std::endl;
std::cout << (d <= 5.2);
return 0;
}
This gives output:
5.200000000002
0
How to remove this precision error? Can I use std::setprecision() to solve the issue?
numeric_limits<double>::digits10 can be used to find the number of digits that are uniquely representable by a double.
I see you've tagged your question with Visual Studio. You can test this code on http://webcompiler.cloudapp.net/ to get Visual Studio's number of uniquely representable digits for a double:
#include <iostream>
#include <limits>
int main() { std::cout << std::numeric_limits<double>::digits10 << std::endl; }
This code will not output 2 it will output:
15
Which means that any double up to 14 decimal places will survive the round trip through a stringstream and still be equal to itself.
The above means that there is something you are not including in your example that is causing the round trip failure, or you are using non-standard source files that are not IEEE compliant. (For example I can do a live example on gcc that gives a contrary output to yours, and running the same code on Visual Studio disagrees with your output.)
Either way, for any uniquely representable double (like 5.2), you can ensure that round trip success through a stringstream by setting the precision. Precision is a sticky modifier, so you'll only need to set it once after stream construction. In your example you use stringstream stream so before you work with stream you'd need to set this modifier:
stream.precision(numeric_limits<double>::digits10 - 1);
You can use it like this in order to show the double number in the right way:
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <limits>
int main()
{
char doubleStr[] = "5.2";
double d = 0.0;
std::stringstream stream (doubleStr);
stream >> d;
std::cout << std::setprecision(2)<< d << std::endl;
return 0;
}
http://cpp.sh/9lub
about comparing float point numbers you may look at this What is the most effective way for float and double comparison?
Related
how would I make it so when i enter 2.785 for the input question the output will display the variable question as 2.79?
I tried using setprecision but for some reason it is not working unless i am doing it wrong
here is the user input question and what it should be:
Enter positive daily growth % (.1 must be entered as 10):
user enters "2.785"
output -> 0.02785
My desired output should look like:
desired output-> 2.79%
Any help is appreciated. I know it may seem simple to others but I have already tried looking online and everything I find just isn't making sense or doesn't work and I dont know what I am doing wrong.
Floating point arithmetic
The reason why it is challenging is that floating point cannot be represented accurately when you perform operations on them. See wikipedia article
It is a very intesting topic, if you have a bit of time, take a look at explanations about floating point and how its representation inside the computer.
If you are looking for the display only (only works for small decimals)
If you are just looking to display a small value you can use below code:
#include <cmath>
#include <iostream>
#include <iomanip>
#include <limits>
#include <sstream>
using namespace std;
string truncateAsString(double n, int precision) {
stringstream ss;
double remainder = static_cast<double>((int)floor((n - floor(n)) * precision) % precision);
ss << setprecision(numeric_limits<double> ::max_digits10 + __builtin_ctz(precision))<< floor(n);
if (remainder)
ss << "." << remainder;
cout << ss.str() << "%" << endl;
return ss.str();
}
int main(void) {
double a = 0.02785;
int precision = 100; // as many digits as you add zeroes. 3 zeroes means precision of 3.
string s = truncateAsString(a*100 + 0.5 / 100, precision);
return 0;
}
Looking for the true value?
Maybe you are looking for true value for your floating point, you can use boost multiprecision library
The Boost.Multiprecision library can be used for computations requiring precision exceeding that of standard built-in types such as float, double and long double. For extended-precision calculations, Boost.Multiprecision supplies a template data type called cpp_dec_float. The number of decimal digits of precision is fixed at compile-time via template parameter.
You need to use a custom library like boost/multiprecision because of the lack of precision for floating points, see my code below:
#include <boost/math/constants/constants.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
#include <limits>
#include <cmath>
#include <iomanip>
using namespace std;
using boost::multiprecision::cpp_dec_float_50;
cpp_dec_float_50 truncate(cpp_dec_float_50 n, int precision) {
cpp_dec_float_50 remainder = static_cast<cpp_dec_float_50>((int)floor((n - floor(n)) * precision) % precision) / static_cast<cpp_dec_float_50>(precision);
return floor(n) + remainder;
}
int main(void) {
int precision = 100; // as many digits as you add zeroes. 5 zeroes means precision of 5.
cpp_dec_float_50 n = 0.02785 * 100;
n = truncate(n + 0.5/precision, precision); // first part is remainder, floor(n) is int value truncated.
cout << setprecision(numeric_limits<cpp_dec_float_50> ::max_digits10 + __builtin_ctz(precision)) << n << "%" << endl; // __builtin_ctz(precision) will equal the number of trailing 0, exactly the precision we need!
return 0;
}
Output (both cases)
2.79%
NB: I add 0.5 / precision to the truncate function to force it to act like a rounding.
Have googled a lot about avoiding rounding errors but none of them are solving my case. Need to round off 9.99999975e-05 upto 8 or more precision.
Have tried using stringstream along with setprecision which is pretty much the standard way according to other answers on this site.
#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;
int main(void){
double val = 9.99999975e-05;
stringstream tmp;
tmp << setprecision(8) << fixed << val;
cout << tmp.str();
return 0;
}
Ideally I would like the result to be 0.00009999
But I am getting 0.00010000 , which I believe is occurring due to rounding off from farthest to most significant '9'.
Any idea how can I stop rounding at 8th precision ?
Need to round off 9.99999975e-05 upto 8 or more precision. (...)
I would like the result to be 0.00009999
Without other test cases I can only guess the OP's intent. So why not truncating the string resulting from the maximum output precision possible?
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <limits>
int main()
{
double val = 9.99999975e-05;
std::stringstream tmp;
tmp << std::setprecision(std::numeric_limits<double>::digits10 + 1)
<< std::fixed << val;
auto repr = tmp.str();
// Truncate the string
repr = repr.erase(repr.find('.') + 9);
std::cout << repr << '\n'; // --> 0.00009999
}
I'll also assume that the OP are already aware of What Every Computer Scientist Should Know About Floating-Point Arithmetic.
Which platform are you using ? You can try using fesetround api in linux and _controlfp in windows.
I get Value 0.000099999998 on linux when rounding set to zero.
However, i will always recommend using a floating point library for such codes.
For the sake of completeness after going through How to truncate a floating point number after a certain number of decimal places (no rounding)? mentioned by #Arne above in comments, here's the changes that I made to above piece of code;
double val = 9.99999975e-05;
cout << setprecision(8) << fixed << trunc(100000000 * val) / 100000000;
return 0;
I am trying to separate whole number and decimal number
two int variable
#include <iostream>
#include <iomanip>
#include<math.h>
using namespace std;
int main()
{
double initialAmount = 42800.13;
double fractionalPart = initialAmount - floor(initialAmount);
cout<<int(initialAmount)<<"\n"<<fractionalPart<<"\n";
}
Present output is
42800
0.13
expected output
42800
13
It can be more than two decimal places .
any easy way to do that
Maybe not the best solution, but at least it is simple :)
Store your double initialAmount in a int - which will truncate the decimal part. Then you have the number before the decimal point. Then subtract that from the initial value and you'll be left with just the part after the decimal point. Multiply that by however many powers of 10 that you deem significant and then again store that in a int and you'll have your two values.
As suggested in the comments, it could help to convert the number into a string. Here's one possibility:
#include <sstream>
#include <iostream>
#include <vector>
#include <string>
int main() {
double d = 42800.13;
std::vector<std::string> numbers_s;
std::string s;
std::istringstream numberAsString(std::to_string( d ));
while (getline(numberAsString, s, '.')) {
numbers_s.push_back(s);
}
std::cout << "whole number:" << numbers_s[0] << std::endl;
//[ remove trailing zeros from fractional part:
numbers_s[1].erase(numbers_s[1].find_last_not_of('0') + 1, std::string::npos);
//]
std::cout << "fractional part:" << std::stoi(numbers_s[1]) << std::endl;
}
Error checks should be added to capture cases when the number does not contain a decimal point.
I need a way to convert this string into its exact number representation. I've tried quite a few things and, from what I know, this should work (famous last words). I'm trying to stay away from installing libraries and I have A LOT of these numbers to convert.
I understand that it is difficult to represent long decimal numbers in binary, but I need a solution.
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
string data = "138.6470184568";
cout << atof(data.c_str()) << endl;
return 0;
}
Output
138.647
Turns out that it is converting correctly, but, when asked to cout the number, it only gives 3-4 decimal places. Anyone know why?
#include <iostream>
#include <stdlib.h>
#include <iomanip>
using namespace std;
int main()
{
string data1 = "138.6470184568";
string data2 = "138.6470184568";
double data3 = atof(data1.c_str()) + atof(data2.c_str());
cout << data3 << endl;
cout << setprecision(15) << data3;
return 0;
}
Gives
277.294
277.2940369136
I am having a application in which I have to process very large numbers. Application API gives me number then I had to convert it into the string and send to further processing.
Code receives number as - 1535625179.1619387
Then for conversion I have used -
char buffer[255];
sprintf(buffer, "%e", OverallVolume); //OverallVolume has the above value.
Now here buffer variable return 1.535625e+009 which is normalized as 1535625000.00
BUT my application shows value as 1.5356252e+09 which is normalized as 1535625200.00
So I want to ask what method I should be using to covert Double to String so that my resultant value will match to the value shown by application.
If I understand your question correctly, you want 7 digits to appear after the decimal point. To do that specify a precision as follows:
sprintf(buffer, "%.7e", OverallVolume); // buffer contains 1.5356252e+09
Live demo
Also, since this is tagged C++, here's a version using IO streams that prints the same result.
#include <ios>
#include <iomanip>
#include <iostream>
#include <sstream>
int main()
{
double OverallVolume = 1535625179.1619387;
std::ostringstream ss;
ss << std::scientific << std::setprecision(7) << OverallVolume;
std::cout << ss.str() << '\n'; // prints 1.5356252e+09
}
Live demo