x = 0:0.1:10... What's going on, really?

조회 수: 1,005 (최근 30일)
John Doe
John Doe 2014년 5월 1일
댓글: Image Analyst 2023년 7월 9일
Please have a look at the following example:
A = 0:0.1:0.4;
find(A == 0.3)
ans =
Empty matrix: 1-by-0
find(A == 0.1+0.1+0.1)
ans =
4
This is in my opinion expected behavior, as 0.1 can't be represented accurately with floating point numbers. What's bugging me is the following:
A = 5.8:0.1:6
A =
5.8000 5.9000 6.0000
find(A == 5.9)
ans =
2
%%Found it!
A = 5.8:0.1:6.1
A =
5.8000 5.9000 6.0000 6.1000
find(A == 5.9)
ans =
Empty matrix: 1-by-0
%%Didn't find it!
find(A == 5.8+0.1)
ans =
2
%%Found it again!
For the record, linspace results in the same results.
A = linspace(5.8, 6.0, 3)
A =
5.8000 5.9000 6.0000
find(A == 5.9)
ans =
2
A = linspace(5.8, 6.1, 4)
A =
5.8000 5.9000 6.0000 6.1000
find(A == 5.9)
ans =
Empty matrix: 1-by-0
find(A == 5.8+0.1)
ans =
2
Notice that the only difference is that the vectors are going to 6.1 instead of 6.0. So, what's going on? Are the following two actually the same: x = [a:b:c] and y = linspace(a,c,(c-a)/b+1)?
A = 5.8:0.1:6.1
A =
5.8000 5.9000 6.0000 6.1000
B = linspace(5.8,6.1,4)
B =
5.8000 5.9000 6.0000 6.1000
A == B
ans =
1 1 1 1
It might appear that way... But the answer is of course no, they're not the same!
x = -0.1:0.1:0.3
x =
-0.1000 0 0.1000 0.2000 0.3000
y = linspace(-0.1,0.3,5)
y =
-0.1000 0 0.1000 0.2000 0.3000
x == y
ans =
1 1 0 0 1
So, what happens when you do A = 5.8:0.1:6? How are the numbers created? And how can the following be explained?
A = 5.8:0.1:6;
B = 5.8:0.1:6.1;
A(2)-B(2)
ans =
8.8818e-016
eps(5.9)
ans =
8.8818e-016

채택된 답변

José-Luis
José-Luis 2014년 5월 1일
편집: José-Luis 2014년 5월 1일
Well, just look at how linspace is implemented:
edit linspace
It might explain some of the behavior you see. On an additional note, comparing double value is risky business. Not only the way you perform a computation (as you so thoroughly illustrate) but the order in which you perform the operations will matter.
Even different compilers might give different results, since they might order operations differently. This means that you can potentially get different results in Matlab if you use different platforms.
EDIT:
As for the colon, here is how it is implemented according to the documentation:
j:i:k is the same as [ j,j+i,j+2i, ...,j+m*i ], where m = fix((k-j)/i), for integer values. For information on the definition of j:i:k with floating-point values, see Technical Solution 1-4FLI96. This syntax returns an empty matrix when i == 0, i > 0 and j > k, or i < 0 and j < k.
  댓글 수: 2
Jeffrey
Jeffrey 2014년 7월 25일
The technical solution 1-4FLI96 referenced in the above comment is no longer available. The solution was republished to MATLAB Central Answers here:
John Doe
John Doe 2014년 8월 28일
The answer in the link provided by Jeffrey is what I'm looking for. I didn't find that question before posting mine. Thanks both =)

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

추가 답변 (2개)

Image Analyst
Image Analyst 2014년 5월 1일
What's going on is explained in the FAQ , along with some workarounds for comparing floating point numbers. http://matlab.wikia.com/wiki/FAQ?title=FAQ&cb=7710#Why_is_0.3_-_0.2_-_0.1_.28or_similar.29_not_equal_to_zero.3F
  댓글 수: 1
John Doe
John Doe 2014년 8월 28일
편집: John Doe 2014년 8월 28일
I apologize for the late reply. My question was not really about floating point arithmetic and how to compare numbers (and is not explained in the FAQ as far as I can see), but rather about why there was a difference between the second element in these two (and similar examples):
A = 5.8:0.1:6;
B = 5.8:0.1:6.1;
The reason is apparently that the first and second half of the vector is created separately (increments from the first number, and decrements from the last, meeting at the middle). Thus, if the vector is longer, the nth element may be created in a different way.
For the record, the FAQ is wrong! Quote from the FAQ: "The difference is that 0:0.1:0.4 increments by a number very close to but not exactly 0.1", which is not the case, as the 0.3 is actually calculated 0.4-0.1, and not 0+0.1+0.1+0.1. This is in order to minimize accumulated errors.

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


Ayesha iqbal
Ayesha iqbal 2023년 7월 9일
If v= 1:3:12 is a vector then v(3)=....?
  댓글 수: 1
Image Analyst
Image Analyst 2023년 7월 9일
This does not look like an answer to @John Doe so it seems like you asking this simple question for yourself. You should know that you can do
v = 1:3:12
v = 1×4
1 4 7 10
element3 = v(3)
element3 = 7
but since you don't, you can learn such fundamental concepts by investing 2 hours of your time here:

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

카테고리

Help CenterFile Exchange에서 Introduction to Installation and Licensing에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by