Simple question: How to setup Matlab to calculate more precisely?

조회 수: 2 (최근 30일)
Manuela Gräfe
Manuela Gräfe 2017년 5월 31일
댓글: Walter Roberson 2017년 6월 1일
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

답변 (2개)

Walter Roberson
Walter Roberson 2017년 5월 31일
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.

David Goodmanson
David Goodmanson 2017년 5월 31일
편집: David Goodmanson 2017년 6월 1일
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
David Goodmanson
David Goodmanson 2017년 5월 31일
편집: David Goodmanson 2017년 5월 31일
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
Walter Roberson 2017년 6월 1일
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

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Logical에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by