Why Is Colon Operator Not Equivalent To linspace Command?
35 ビュー (過去 30 日間)
古いコメントを表示
Why does q not equal zero in the following?
q = isequal(0:.08:50000,linspace(0,50000,625001))
1 件のコメント
Voss
2024 年 11 月 14 日 20:21
A = 0:0.08:50000;
B = linspace(0,50000,625001);
C = (0:50000*12.5)/12.5;
isequal(A,B)
isequal(A,C)
isequal(B,C)
回答 (3 件)
James Tursa
2024 年 11 月 14 日 18:00
編集済み: James Tursa
2024 年 11 月 14 日 18:12
The short answer is that the algorithms are different. In the first place, 0.08 cannot be represented exactly in IEEE double precision floating point, so using that as the delta does result in some binary floating point calculation inaccuracies compared to what you might expect looking at the decimal version. E.g., if you read the doc for colon, it doesn't even guarantee that you get the requested end point if the delta is not an integer. On the other hand, the linspace algorithm always gives you the end points. Also, the intermediate points might not match up exactly either, again because of floating point effects based on the different algorithms. E.g.,
a = 0:.08:50000;
b = linspace(0,50000,625001);
numel(a) == numel(b)
max(abs(a-b))
In your case, you happened to get the same number of elements with both methods, but the points generated are not exactly the same because of floating point effects of the different algorithms.
k = find(a ~= b,1,'last')
eps(a(k))
num2hex(a(k))
num2hex(b(k))
And above you can see the max difference is on the order of eps of the largest element that had a difference. I.e., the very last bit of the floating point value. Generally I would prefer linspace over colon in cases like yours so that you have control over the end points being generated.
0 件のコメント
Torsten
2024 年 11 月 14 日 18:04
Both arrays seem to be generated differently such that floating point issues come into play:
z1 = 0:.08:50000;
z2 = linspace(0,50000,625001);
[~,idx] = find(z1~=z2);
format long
z1(idx)-z2(idx)
0 件のコメント
Walter Roberson
2024 年 11 月 14 日 22:04
The colon operator is defined to use repeated addition. When the increment does not happen to be an integer multiple of a power of 2, there are round-off error problems. For example, 0.08 is not represented by the rational fraction 8 / 100
fprintf('%.999g\n', 0.08)
those ....1665<etc> accumulate under repeated addition.
The colon operator is not defined as (0:NumberOfValues-1)*Increment+BaseNumber . If it were defined that way, then
for K = 1:inf
would have to generate a vector 1, 2, 3, ... 9223372036854775806 ahead of time and use the elements from that vector. But 9223372036854775806 is 2^63 and it is not possible to generate vectors longer than 2^47-1 even if memory was available.
Of course, potentially MATLAB could have defined that the colon operator in
K=1:1.1:2^40
worked differently than the colon operator in
for K=1:1.1:2^40
but it chose to define them the same way: using repeated addition both ways.
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Logical についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!