Please explain this. I also faced this type of problems before:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include <iostream>
#include <cmath>
usingnamespace std;
int main()
{
double a = 1.1, b = 2.2, c = 3.3;
cout << "a + b = " << a + b << endl;
cout << "c = " << c << endl;
if(a + b == c) cout << "Okay!\n";
else cout << "Surprise!\n"; // this is executed
return 0;
}
1.1 + 2.2 Is equal to 3.3. But From what I understand, and someone will correct me if Im wrong. You can't compare two floats/doubles in c++, because there is rounding problems. I debugged your program (Something you should learn to do) and these are the a b and c values.
Because 1.1, 2.2 and 3.3 in base 10 can't be represented exactly in the base 2 floating point format used by your computer. For this reason, it's never a good idea to compare floating point numbers with ==. Instead of doing a == b, do fabs(a-b) < epsilon where epsilon is some very small number.
ah b/c in computer doing operation on real numbers always cause some rounding.
You may not notice the rounding but computer is in base 2 so 0.1 cannot really be represented perfectly nor 0.2 and 0.3 but 0.25 can be that's because 0.25 is 2^-2. If you want to know more I may explain more just ask.
So comparision is usually done this way
1 2 3 4
#define epsilon 0.0000001
if( fabs( a + b - c ) < epsilon )
Hell yeah 2 people is way quicker than me lolololol this forum is quite crowded today.
If you just want the conclusion skip to the last sentence of this post
so here is how real num is represented in computer according to IEEE754 standard (if you are a cs student you will learn this eventually)
there are 3 parts
sign bit
exponent bit
fraction bit
here is how they are stored perhaps you want to store 0.8 in 8 bit float
1 sign bit
3 exponent bit
4 fraction bit
first transform the decimal to binary decimal like these
0.8 * 2 = 1.6
0.6 * 2 = 1.2
0.2 * 2 = 0.4
0.4 * 2 = 0.8
0.8
take your decimal time it by 2 then see the number before dot what ever it is remove it and then replace it with 0
the resulting binary decimal is
0.11001100....
the you have to transform it to a sort of scientific form
something like the way you write number in physic
0.0000444 is 4.44 * 10^-5
0.11001100 become
1.1001100... * 2^-1
so
the sign is 0 (positive)
the exponent is -1
the fraction is 0.1001100 << i didn't miss the 1 before the dot
0.100110011000 is an infinite loop so some round would be done
become
0.1010
And the bit representation become
0 010 1010
s exp frac
which if translated back become
1.1010 * 2^-1 =
0.11010 = 1*1/2 + 1*1/4 + 0 * 1/8+ 1*1/16 = 13/16 = 0.8125
that's way it's not perfect
there must be part where it seem strange to you but I not explaining them because it would be too long.
My point is you the way computer store real number is the same as how you store scientific number in physic. There will be rounding because memory is limited.
#include <iostream>
#include <iomanip>
#include <cmath>
usingnamespace std;
int main()
{
double a = 1.1, b = 2.2, c = 3.3;
double sum = a + b;
cout << setprecision(18);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "sum = " << sum << endl;
cout << "c = " << c << endl;
cout << "sum - c = " << sum - c << endl;
cout << "c - sum = " << c - sum << endl;
cout << "abs(c - sum) = " << abs(c - sum) << endl;
constdouble epsilon = 0.0000001;
if (abs(c - sum) < epsilon)
cout << "Equal\n";
else
cout << "Not equal\n";
return 0;
}
a = 1.10000000000000009
b = 2.20000000000000018
sum = 3.30000000000000027
c = 3.29999999999999982
sum - c = 4.44089209850062616e-016
c - sum = -4.44089209850062616e-016
abs(c - sum) = 4.44089209850062616e-016
Equal
In C++ the <cmath> function abs() will work. A const is preferred over #define.
Edit:
line 21 should read if (abs(c - sum) < epsilon)
We are used to the idea that some numbers cannot be expressed precisely in decimal notation, e.g.
1/7 = 0.142857142857142857142857142857... or
1/3 = 0.333333333333333333333333333333...
In binary a similar thing happens, but it may take us by surprise because it means decimal values such as 1.1 cannot be represented precisely, but instead have recurring sequence of digits.