Bug in matlab R2012b version
Ältere Kommentare anzeigen
Hello,
I use the MATLAB R2012b version and when I try this:
0.5:0.1:0.8 the answer is:
ans =
Columns 1 through 3
5.000000000000000e-01 6.000000000000000e-01 7.000000000000001e-01
Column 4
8.000000000000000e-01
Why the third term is not strictly equal to 0.7? Furthermore when I try 0.5:0.1:0.9 the bug disappears!
Do you have an answer? Note: (as a reminder go to "HOME", "Preferences" and select "long e")
Thanks in advance
Akzeptierte Antwort
Weitere Antworten (8)
James Tursa
am 22 Jul. 2014
Bearbeitet: James Tursa
am 23 Jul. 2014
Others have already adequately answered your question. But to help you gain a better understanding of this I will point you to an FEX submission, NUM2STREXACT, which prints the exact floating point binary to decimal conversion for any number. Bottom line is that the majority of numbers you are working with cannot be represented exactly in IEEE double (as others have already written). To see what the exact decimal conversions are for your examples:
>> x = num2strexact(0.5:0.1:0.8)
x =
'0.5' [1x55 char] [1x55 char] [1x54 char]
>> x{1}
ans =
0.5
>> x{2}
ans =
0.59999999999999997779553950749686919152736663818359375
>> x{3}
ans =
0.70000000000000006661338147750939242541790008544921875
>> x{4}
ans =
0.8000000000000000444089209850062616169452667236328125
And here is your second example:
>> x = num2strexact(0.5:0.1:0.9)
x =
'0.5' [1x55 char] [1x54 char] [1x54 char] [1x55 char]
>> x{1}
ans =
0.5
>> x{2}
ans =
0.59999999999999997779553950749686919152736663818359375
>> x{3}
ans =
0.6999999999999999555910790149937383830547332763671875
>> x{4}
ans =
0.8000000000000000444089209850062616169452667236328125
>> x{5}
ans =
0.90000000000000002220446049250313080847263336181640625
Note that the underlying algorithm used by the COLON operator does not guarantee that individual element results will necessarily match up even when the starting element and the delta are the same (this is due to methods used for minimizing accumulated errors, see the COLON doc for more details)
You can find NUM2STREXACT here:
EDIT
For completeness I will add these results as well:
>> x = num2strexact([0.5 0.5+0.1 0.5+2*0.1 0.5+3*0.1 0.5+4*0.1])
x =
'0.5' [1x55 char] [1x54 char] [1x54 char] [1x55 char]
>> x{2}
ans =
0.59999999999999997779553950749686919152736663818359375
>> x{3}
ans =
0.6999999999999999555910790149937383830547332763671875
>> x{4}
ans =
0.8000000000000000444089209850062616169452667236328125
>> x{5}
ans =
0.90000000000000002220446049250313080847263336181640625
>> x = num2strexact(linspace(0.5,0.8,4))
x =
'0.5' [1x55 char] [1x55 char] [1x54 char]
>> x{2}
ans =
0.59999999999999997779553950749686919152736663818359375
>> x{3}
ans =
0.70000000000000006661338147750939242541790008544921875
>> x{4}
ans =
0.8000000000000000444089209850062616169452667236328125
>> x = num2strexact(linspace(0.5,0.9,5))
x =
'0.5' [1x55 char] [1x54 char] [1x54 char] [1x55 char]
>> x{2}
ans =
0.59999999999999997779553950749686919152736663818359375
>> x{3}
ans =
0.6999999999999999555910790149937383830547332763671875
>> x{4}
ans =
0.8000000000000000444089209850062616169452667236328125
>> x{5}
ans =
0.90000000000000002220446049250313080847263336181640625
>> num2strexact(0.7)
ans =
0.6999999999999999555910790149937383830547332763671875
5 Kommentare
David Young
am 22 Jul. 2014
James - I can't see anything in the colon doc that mentions minimizing accumulated errors. (Doing "doc colon" from the command line in ver 2013b.) Am I looking in the wrong place? The doc actually only specifies the behaviour "for integer values"; the help information doesn't include this qualification and does seem to be to say that the upper limit should affect only the length of the vector, not its values:
J:D:K is the same as [J, J+D, ..., J+m*D] where m = fix((K-J)/D).
Image Analyst
am 23 Jul. 2014
Neither did I. The online documentation doesn't say anything about adjusting the increment to reduce accumulated errors either. http://www.mathworks.com/help/matlab/ref/colon.html. Wayne and Mischa work for the Mathworks so perhaps they can reveal the secrets of this oddity.
James Tursa
am 23 Jul. 2014
Neither did I ... now I have to remember where exactly I read this ...
Image Analyst
am 25 Jul. 2014
James: Here is where you saw it: http://www.mathworks.com/matlabcentral/answers/143255-how-does-the-colon-operator-work#answer_146337
James Tursa
am 25 Jul. 2014
Thanks. I knew I read this somewhere but just couldn't find it.
the cyclist
am 22 Jul. 2014
2 Stimmen
It's not a bug. It's a reality of floating point arithmetic. See this page as one possible starting point to increase your understanding.
Roger Stafford
am 22 Jul. 2014
Bearbeitet: Roger Stafford
am 22 Jul. 2014
2 Stimmen
The reality, Scarzo, is that because matlab's 'double' uses a binary number representation, it can never represent any of the fractions 0.6, 0.7, 0.8, or 0.9 exactly, though it can achieve 0.5 precisely. It is analogous to trying to represent 1/3 exactly as a decimal fraction, which is impossible.
However, it is also true that with most formats the displays of stored 'double' numbers are also not exact. The net result is that some numbers may appear to be represented exactly when in fact they aren't, such as is the case with 6.000000000000000e-01 or 8.000000000000000e-01 in your example. If you were to make a careful study of the corresponding numbers actually in the computer, they are not, and cannot be, exactly 6/10 and 8/10, even though the display indicates that they are. Even when the computer claims that the logical proposition A(3)==.7 is true, it is really only saying that both slightly erroneous representations of 0.7 are the same.
In all such cases, however, the difference between the exact fraction and the machine value differ by an error which is something like half the value of the least binary bit or less. Since in 'double' there are 53 significand bits, this is a very small amount relative to the size of the number. It is the best the machine can do. In all fairness, this cannot be considered as a "bug", any more than a decimal calculator can be considered as having a bug when it gives 0.3333333333 as the answer to 1 divided by 3. It's the best it can do.
5 Kommentare
David Young
am 22 Jul. 2014
Bearbeitet: David Young
am 22 Jul. 2014
Indeed, but I think Scarzo has pointed to something which is strange - at least I don't understand it, and I don't think anyone has offered an explanation. It's this:
a = 0.5 : 0.1 : 0.8;
b = 0.5 : 0.1 : 0.9;
a(3) - b(3)
which prints 1.1102e-16
I'd have expected both a(3) and b(3) to be computed identically, and probably to be equal to the result of
(0.5 + 0.1) + 0.1
- but although b(3) is equal to this result, a(3) has the same value as the result of
0.5 + 2*((0.8-0.5)/3)
I agree with Scarzo that that's curious - the colon operator must be implemented in some way that means the upper limit affects the increment!
[Edit: added expression that gives same value as a(3) and following sentence.]
Daniel Shub
am 23 Jul. 2014
@David, been there, done that. In summary, MATLAB works in from both ends to minimize error accumulation.
David Young
am 23 Jul. 2014
Thanks Daniel - but I see the link that would reveal all (from Matt Fig's answer to your previous post) is now broken.
Daniel Shub
am 24 Jul. 2014
@David I have put in a service request to get access to the technical solution. Will see what happens.
Image Analyst
am 25 Jul. 2014
The answer has already been posted here: http://www.mathworks.com/matlabcentral/answers/143255-how-does-the-colon-operator-work#answer_146337
Mischa Kim
am 22 Jul. 2014
Bearbeitet: Mischa Kim
am 22 Jul. 2014
1 Stimme
Wayne King
am 22 Jul. 2014
In R2012b with win7 and a 64-bit machine I get the following:
A = 0.5:0.1:.8;
abs(A(3)-0.7)
ans =
1.1102e-16
eps(.7)
ans =
1.1102e-16
Note that:
abs(A(3)-0.7)
is equal to
eps(0.7) %see the help for eps()
So you do obtain the closest floating point number of 0.7 as the 3rd element as expected.
scarzo
am 22 Jul. 2014
0 Stimmen
2 Kommentare
Image Analyst
am 22 Jul. 2014
For clarity, here is your code:
clc;
A = 0.5:0.1:.8
abs(A(3)-0.7)
A = 0.5:0.1:.9
abs(A(3)-0.7)
and here is the results:
A =
0.5000 0.6000 0.7000 0.8000
ans =
1.1102e-16
A =
0.5000 0.6000 0.7000 0.8000 0.9000
ans =
0
1 Kommentar
Image Analyst
am 25 Jul. 2014
This explains it perfectly: http://www.mathworks.com/matlabcentral/answers/143255-how-does-the-colon-operator-work#answer_146337
Daniel Shub
am 24 Jul. 2014
0 Stimmen
The colon operator in MATLAB with non-integers is a tricky beast. Not only do you need to worry about round off errors associated with working with floating point numbers, but you need to think about how those errors accumulate. Since the COLON function is closed source, you cannot see how it solves this problem. The MathWorks used to have a nice technical solution, now only available on the way back machine, on the issue and made MATLAB code available. The documentation on COLON changed between r2013a and r2013b, so the source code may no longer be an accurate representation of the COLON function anymore.
Kategorien
Mehr zu Creating and Concatenating Matrices 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!