Reputation: 15837
Suppose we want to calculate (a + b)2 in two different ways, that is
(a + b) * (a + b)
a2 + 2 a b + b2
Now, suppose a = 1.4
and b = -2.7
. If we plug those two numbers in the formulas with format long
we obtain in both cases 1.690000000000001
, that is, if I run the following script:
a = 1.4;
b = -2.7;
format long
r = (a + b) * (a + b)
r2 = a^2 + 2*a*b + b^2
abs_diff = abs(r - r2)
I obtain
r = 1.690000000000001
r2 = 1.690000000000001
abs_diff = 6.661338147750939e-16
What's going on here? I could preview different results for r
or r2
(because Matlab would be executing different floating-point operations), but not for the absolute value of their difference.
I also noticed that the relative error of r
and r2
are different, that is, if I do
rel_err1 = abs(1.69 - r) / 1.69
rel_err2 = abs(1.69 - r2) / 1.69
I obtain
rel_err1 = 3.941620205769786e-16
rel_err2 = 7.883240411539573e-16
This only makes me think that r
are not actually the same r2
. Is there a way to see them completely then, if they are really different? If not, what's happening?
Also, both relative errors are not less than eps / 2
, does this mean that an overflow has happened? If yes, where?
Note: This is a specific case. I understood that we're dealing with floating-point numbers and rounding errors. But I would like a to understand better them by going through this example.
Upvotes: 0
Views: 419
Reputation: 124543
Don't rely on the output of format long
to conclude that two numbers are equal...
a = 1.4;
b = -2.7
r1 = (a + b) * (a + b);
r2 = a^2 + 2*a*b + b^2;
r3 = (a+b)^2;
Instead you can check their hex representation using:
>> num2hex([r1 r2 r3])
ans =
3ffb0a3d70a3d70d
3ffb0a3d70a3d710
3ffb0a3d70a3d70d
or the printf
family of functions:
>> fprintf('%bx\n', r1, r2, r3)
3ffb0a3d70a3d70d
3ffb0a3d70a3d710
3ffb0a3d70a3d70d
or even:
>> format hex
>> disp([r1; r2; r3])
3ffb0a3d70a3d70d
3ffb0a3d70a3d710
3ffb0a3d70a3d70d
Upvotes: 3
Reputation: 35525
Floating point arithmetic is not associative.
While mathematically these two are equal, they are not in floating point maths.
r = (a + b) * (a + b)
r2 = a^2 + 2*a*b + b^2
The order operations are executed in floating point maths is very relevant. That is why when you do floating point maths you need to be very careful of the order of you r multiplications/divisions, specially when working with very big numbers together with really small numbers.
Upvotes: 1