Issue while rounding decimal fileds in C++ using setprecision [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Does setprecision in c++ round? If so why am I seeing this?
Here is the function I'm using
char* round(double value, int decimal_places)
{
decimal_places = decimal_places+1;
std::stringstream s2;
s2 << std::setprecision(decimal_places) << std::setiosflags(std::ios_base::fixed) << value;
std::string st = s2.str();
return st;
}
My input value is 0.89425 and the number of decimal palaces is 4
My output is 0.8942 but i want 0.8943 i.e., if next digit after my required decimal places is >= 5 then the output should be rounded to the next value.

0.89425 is not representable exactly in binary floating point; the nearest exactly representable value is 0.894249999999999989341858963598497211933135986328125, which is correctly rounded to decimal 0.8942.
If you want to see decimal rounding behaviour, use fixed-point or decimal floating point.

Related

c++11 double precision [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 9 months ago.
Doing the following calculation:
double result = 58/10;
Will result: 5.7999999999999998
I know c++ will round it on further calculations or printing, but I need to compare output with where rounding doesn't occur so I can't have rounding happen because that may just lead to differences in other places in the output.
Is there any way to improve the precision of such calculations and having 58/10 result 5.8?
5.8 cannot be exactly represented in floating point. If you are working with 2 digits precision after the decimal point, for example if you need to store monetary values, store it as "580" (e.g., 580 cents) and do your own formatting when printing.
printf("%d.%02d", n / 100, n % 100);
Alternatively store the decimal as a fraction:
struct Fraction {
int numerator;
int denominator;
};
int main() {
Fraction f(29, 5);
}

Why is the difference between 2 double values wrongly calculated? [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 2 years ago.
I need to calculate the difference value between 2 string numbers by only taking only the first precision. I have to convert to double first then calculate the difference as below
#include <iostream>
#include <math.h>
#include <string>
using namespace std;
int main()
{
string v1 = "1568678435.244555";
string v2 = "1568678435.300111";
double s1 = atof(v1.substr(0,12).c_str()); // take upto first precision and convert to double
double s2 = atof(v2.substr(0,12).c_str()); // take upto first precision and convert to double
std::cout<<s1<<" "<<s2<<" "<<s2-s1<<endl;
if (s2-s1 >= 0.1)
cout<<"bigger";
else
cout<<"smaller";
return 0;
}
I expect the calculation would be 1568678435.3 - 1568678435.2 = 0.1 . But this program returns this value :
1.56868e+09 1.56868e+09 0.0999999
smaller
Why is that and how to get the value that I want properly?
Floating point format has limited precision. Not all values are representable. For example, the number 1568678435.2 is not representable (in IEEE-754 binary64 format). The closest representable value is:
1568678435.2000000476837158203125
1568678435.3 is also not a representable value. The closest reprecentable value is:
1568678435.2999999523162841796875
Given that the floating point values that you start with are not precise, it should be hardly surprising that the result of the calculation is also not precise. The floating point result of subtracting these numbers is:
0.099999904632568359375
Which very close to 0.1, but not quite. The error of the calculation was:
0.000000095367431640625
Also note that 0.1 is itself not a representable number, so there is no way to get that as the result of a floating point operation no matter what your inputs are.
how to get the value that I want properly?
To print the value 0.1, simply round the output to a sufficiently coarse precision:
std::cout << std::fixed << std::setprecision(1) << s2-s1;
This works as long as the error of the calculation doesn't exceed half of the desired precision.
If you don't want to deal with any accuracy error in your calculation, then you mustn't use floating point numbers.
You should round the difference between the values.
if (round((s2-s1) * 10) >= 1)
cout<<"bigger";
else
cout<<"smaller";

C++ Avoid Rounding Number

I know we can use setprecision to prevent a number to be rounded but what if I don't want to round all of my numbers in the list with the same decimal places? In other words, I want to keep my numbers the same as calculated and each number has its own decimal places.
For example: if we use setprecision(7) then it will give the output up to 7 decimal places for all numbers in my list. What if I have a list of different numbers with different decimal places such as 8 or 10 decimal places? Do I need to do setprecision for each of them? Is there any way to keep my numbers the same as the output after calculated? Ex:0.1234567, 0.123456789, 0.12345678910
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<double> myVec{0.1234567, 0.123456789, 0.12345678, 0.12345678910};
for(int i = 0; i < myVec.size(); i++)
{
cout << myVec[i] << " ";
}
return 0;
}
Is there any way to keep my numbers the same as the output after calculated?
Not with floating point types such as double.
These are binary floating points, not decimal. Many exact finite decimal fractions will convert to infinite binary fraction, and rounding would happen. So after you do dobule d = 0.1234567, the variable d will not contain exactly 0.1234567, it is rather something close to 0.1234567 representable as double.
A way to deal with this is to have custom data types that are decimal fractions, with fixed or floating point, so that 0.1234567 could be represented exactly.

I don't understand why. problems with double [duplicate]

This question already has answers here:
How do I print a double value with full precision using cout?
(17 answers)
Closed 3 years ago.
Why doubles round themselves? How can i prevent it?
If i insert 45000.98 i expect 45000.98, but the number is rounded.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double a;
cin >> a; //if i insert 45000.98
cout << a; //output is 45001
cout << endl << setprecision(2) << a; //output is 4.5e+04
}
Double type has 11 bits for exponent and 52 bits for the fractional part, more than enough to give you enough precision to represent 45000.98, but setprecision argument, as far as i recall, receives a characters limit, not the number of digits after decimal point. Use setprecision(8) and you should see 45000.98 as you probably expect.
The double did not round itself; the streaming operation rounded the value — first by default, and later according to your instructions. You requested that your value be rounded to 2 digits of precision, and that's what you got (just the first two digits: 4.5e+04). You are getting scientific notation because you have not requested enough digits to reach the decimal point.
If you want to see all 7 digits of 45000.98 then request at least 7 digits of precision. (You may want to stay under 17 digits though, since that's where you start seeing the artifacts of the floating point representation.)

Rounding to the second decimal spot [duplicate]

This question already has answers here:
Round a float to a regular grid of predefined points
(11 answers)
Closed 5 years ago.
how do i round to the second decimal point in C++.
thanks for your help.
You can multiply by 100 and then round to an integer. Then put the decimal point after the first 2 digits.
For example:
void round(double x)
{
double y = 100 * x;
int rounded = (int)(y + 0.5);
printf("%lf rounded = %d.%02d\n", x, rounded / 100, rounded % 100);
}
When printing doubles you can specify the precision:
f,F
The double argument is rounded and converted to decimal notation in the style [-]ddd.ddd, where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is taken as 6; if the precision is explicitly zero, no decimal-point character appears. If a decimal point appears, at least one digit appears before it.
Try:
printf("%f rounded = %.2f\n", x, x);
The same thing in C++
std::cout << x << " rounded = " << std::setprecision(2) << x << "\n";
If you're expecting an exact result in a double or float, it may be impossible. Many numbers that can be exactly represented in two decimal digits can't be represented in the base 2 floating point numbers at all, and all you'll get is the nearest equivalent. For example you might find that 1.10 is stuck at 1.1000000000000001 no matter how many times you try to round it.
You didn't specify which kind of rounding you need.
Assuming rounding to the nearest integer:
#include <math.h>
#include <stdio.h>
double round(double x) { return floor(x * 100 + 0.5) / 100; }
int main()
{
printf("%g\n", round(12.345));
}
It prints 12.35.
Or if you just want to print a number rounded to two digits after decimal point:
printf("%.2f\n", x);
Check out round() for float in C++ which talks about rounding floats although not to 2 places. The same basic techniques should work.