Why is MATLAB messing up this very simple calculation.
Ältere Kommentare anzeigen
I was trying to tutor MATLAB to one of the underclassman I tutor. I came across an error that I initially could not fix. I eventually found the error but it isn't my error. MATLAB calculated the wrong number! -2.9982*5=-14.991 not -2.9982*5=-14.991000000000001. I can avoid using this calculation in the code but I just want to know what is causing this silly error so I can avoid it again.
3 Kommentare
Viet Ha Tran
am 13 Aug. 2020
I have found a similar issue but I would like to raise a question:
In my program, I have to compare:
11.2/1.6x1.07 with 7.49
Matlab answered that the former is lower than the later. and:
>> 11.2/1.6*1.07 - 7.49
ans =
-8.8818e-16
However, both Windows Calculator and Excel give zero difference. Using logical comparisions (equal, greater, smaller) reveal the same results: Matlab says the former is smaller than the later. Excel says they are the same.
I would like to know why, thanks!
@Viet Ha Tran: MATLAB does the calculation following the IEEE 754 standard. You can compare this against other tools that also follow IEEE 754 and get the same answer.
Windows Calculator uses an abritrary-precision arithmetic library (see https://en.wikipedia.org/wiki/Windows_Calculator), I could not find any relevant documentation online in the short time I spent searching. Possibly it uses some decimal number format, or just a really high precision binary format for storing those values.
Windows Office Excel certainly stores numbers in memory as double (i.e. binary floating point) but as far as I am aware does not document how they use these in calculations. Excel has an option to change the calculation precision based on the display format (search for "Precision as displayed"), truncates digits beyond 15 significiant figures to 0, and its development team is known to have written their own C compiler, all of which indicate that they do some of their own magic and probably also use some arbitrary precision arithmetic library.
Summary: Windows applications do not openly document how they work. MATLAB follows an international standard for binary floating point numbers.
Viet Ha Tran
am 14 Aug. 2020
Bearbeitet: Viet Ha Tran
am 14 Aug. 2020
Thank you for your quick and clear answer. I have that problem when running my script which will decide what to do depending on the comparision above. My idea now is to set, say, 10e-12 difference as zero. I see some good discussions on google search, will figure it out. Thanks again.
Akzeptierte Antwort
Weitere Antworten (1)
Micha E
am 4 Apr. 2019
I have some problems with "wrong" calculations in Matlab too. I like to use some calculations to create idices, pretty simple and I always get positive integer by calculating it with hand.
example in Matlab:
>> 203/200*1000
ans =
1.0150e+03
by using it as index brings an error
>> 203/200*1000-203*1000/200
ans =
-1.1369e-13
shows why.
h=(1:1:1000)';
for i=1:1000
h(i)=h(i)/200*200-h(i)*200/200;
end
The code shows were I have problems: i=7,14,28,29....
Is it a problem of my PC or Matlab ?... very strange. An answer would be great!
Thanks, Michael
1 Kommentar
John D'Errico
am 4 Apr. 2019
Bearbeitet: John D'Errico
am 4 Apr. 2019
Please don't answer a question with another question. Worse, had you bothered to read the answers to the question you attached this too, you would learn something about floating point numbers.
What is 203/200? Is it an integer? Is it exactly representable as a floating point number, using a binary storage form? (Hint: no. Read the answer.) While you might think that 203/200 is 1.015, that is not what was computed.
sprintf('%0.55f',203/200)
ans =
'1.0149999999999999023003738329862244427204132080078125000'
The number 1.015 cannot be stored exactly as a number using binary. READ THE ABOVE ANSWER. So, instead, the intermediate result is created as the mess above, an approximation to 1.015, but not in fact 1.015. In binary form, we would see the expansion of 1.015 as the infinite binary number
1.0000001111010111000010100011110101110000101000111101...
This is a repeating, non-terminating binary number, with a repeating part that appears to be: "11110101110000101000".
Then when you multiply it by 1000, is there any reason to expect the result to be an exact integer? Again, no, because MATLAB could not represent the previous computation exactly. Some information was lost in the intermediate computation. And information, once lost, is not easily recovered, often not at all.
sprintf('%0.55f',203/200*1000)
ans =
'1014.9999999999998863131622783839702606201171875000000000000'
If it is not an integer, then it is not a valid index.
Why is there a difference when you do the operation in a different order? Thus, what is this intermediate result?
203*1000
Is that an integer? Yes. Is it less than 2^53? Yes. Is it evenly divisible by 200, still as an integer? Again, clearly yes. So MATLAB has no problem with the computation 203*1000/200. The result in that order will in fact be a positive integer, and thus potentially a valid index.
Remember that intermediate results are computed. The order in which you perform a computation DOES matter. Computer programming is NOT mathematics, only an approximation thereof. While it is often a good approximation, it is only an APPROXIMATION. And you need to understand when it is only approximate, because for SOME computations you are able to work with integers without approximation. All of this means that while you assume the commutative law should apply on computations like this, it need not in fact apply exactly.
So read the answer you apparently ignored. And when you have a question, don't hijack another question with a non-answer. Post a question.
Kategorien
Mehr zu Programming finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!