Simple question: How to setup Matlab to calculate more precisely?
2 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hello,
please check the following example:
A=400;
B=220;
C=1.5;
D=(B/A)*C;
E=(B*C)/A;
F=D-E %%%%=1.110223024625157e-16
In my opinion F must be zero?
Has anyone an explanation for this?
Thanks
1 commentaire
Stephen23
le 31 Mai 2017
"Has anyone an explanation for this?"
Because that is how floating-point arithmetic works. Small differences in the floating-point values means that you should not expect an output equivalent to some mathematical operation/s. Floating-point numbers have been explained a thousand times on this forum:
etc, etc, etc
Réponses (2)
Walter Roberson
le 31 Mai 2017
If you have the symbolic toolbox:
A = sym(400);
B = sym(220);
C = sym(1.5);
D = (B/A)*C;
E = (B*C)/A;
F = D-E
However, if you use this, you need to be aware of how sym converts floating point numbers. Read about the conversion flags at https://www.mathworks.com/help/symbolic/sym.html#input_argument_d0e141952 and read the examples at https://www.mathworks.com/help/symbolic/sym.html#bu1rs8g-1
And remember that the problem occurs in any finite number base. For example in 3 digit decimal,
v = 1/3
1 * v -> 0.333
2 * v -> 0.666
3 * v -> 0.999
1 - 3 * v -> 0.001
Calculations in any finite representation are not the same as algebraic calculations on rationals: order matters.
0 commentaires
David Goodmanson
le 31 Mai 2017
Modifié(e) : David Goodmanson
le 1 Juin 2017
Hi Manuela, you have just discovered one of the features of floating point arithmetic. Matlab uses 64 memory bits for a floating point number, which corresponds to about 15 decimal digits worth of precision. When you multiply and divide quantities in different orders, there can be variations in what happens to the last bit. So you can get perfectly normal disagreement, on the order of 1e-16, in the answers.
With the symbolic toolbox it is possible to obtain precision to many, many more digits but that is much slower and mostly not necessary, once you know what floating point numbers are up to.
Matlab can represent integers exactly in the range of approximately +-9e15
3 commentaires
David Goodmanson
le 31 Mai 2017
Modifié(e) : David Goodmanson
le 31 Mai 2017
the most common situation is when you calculate two numbers x and y that some of the time 'should' be equal, and want to do the following:
if x==y
(do something)
else
(do something else)
end
If x and y differ by 1e-16 or some such, then the first part of the if statement mysteriously never happens. You can guard against that in various ways. If you know that x and y are supposed to come out as integers you can use x = round(x) etc. first. The most common approach is to replace the first line with
if abs(x-y) < 1e-10
or whatever tolerance you think is appropriate.
Other situations are not a problem. For example
for j = 1:1000
for k = 1:1000
if j==k
(do something)
end
end
end
This always works since you are creating integers and comparing them.
Walter Roberson
le 1 Juin 2017
I like to point out that if you calculate the same expression in two different ways, then the result might be different. Even ((A+B)+C) compared to (A+(B+C)) can give you different results.
Therefore the only time it is safe to compare floating point numbers for equality is if they are extracted from the same source. For example it is safe to test
A == min(A)
because the min(A) will be a bitwise-identical copy of some element of A
Voir également
Catégories
En savoir plus sur Logical dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!