Why doesn't 'find' function work properly?

14 views (last 30 days)
Hello everyone, 0.6 and 0.4 must exist in the array. However, I can't find it. Could anyone give some hint? Any help will be appreciated.

Accepted Answer

Star Strider
Star Strider on 14 Dec 2021
Include a tolerance:
wavelength = 0.35 : 0.001 : 0.8;
idx{1} = find(abs(wavelength-0.6)<0.0001);
idx{2} = find(abs(wavelength-0.4)<0.0001);
idx
idx = 1×2 cell array
{[251]} {[51]}
format long g
wavelength([idx{:}])
ans = 1×2
0.6 0.4
demonstration = [0.6 0.4] - wavelength([idx{:}]) % They Are Not Exactly Equal To The Test Values
demonstration = 1×2
1.0e+00 * -1.11022302462516e-16 5.55111512312578e-17
See the documentation section on Floating-Point Numbers for a detailed explanation.
.

More Answers (1)

Walter Roberson
Walter Roberson on 14 Dec 2021
format long g
wavelength=0.35:0.001:0.8;
target = 0.6;
fprintf('%.999g\n', target);
0.59999999999999997779553950749686919152736663818359375
[~, idx6] = min(abs(wavelength-target))
idx6 =
251
what_is_really_there = wavelength(idx6)
what_is_really_there =
0.6
fprintf('%.999g\n', what_is_really_there);
0.600000000000000088817841970012523233890533447265625
target - what_is_really_there
ans =
-1.11022302462516e-16
num2hex(target)
ans = '3fe3333333333333'
num2hex(what_is_really_there)
ans = '3fe3333333333334'
So it is not the case that 0.6 is in the array. What is in the array is the very next representable number after the number that you get when you hard-code 0.6
Your mistake was in thinking that MATLAB codes numbers in decimal. If, hypothetically MATLAB coded numbers in decimal, then 0.35 would be exactly representable, and 0.001 would be exactlyt representable, and 0.6 would be exactly representable, and it would make sense that by adding 0.001 repeatedly starting from 0.35 that you would at some point get 0.6 exactly.
But the IBM Z series are the only common general-purpose computers that can represent floating point numbers in decimal. Everyone else uses IEEE 754 Binary floating point representation, which represents non-zero numbers as a power of 2 (the "exponent") times a binary number between 1.0 (inclusive) and 2.0 (exclusive). Effectively non-zero representable numbers are an integer between (2^52) and (2^53-1) times a power of 2. But 1/10 exactly cannot be represented exactly in such a system.
The reason that 1/10 exactly cannot be represented in a finite binary system is the same why 1/3 exactly cannot be represented in a decimal system. Suppose you had a decimal system with 5 decimal places, then 1/3 would be 0.33333 . Now add that three times: you get 0.99999 not 1.0 . Adding more decimal points does not help: 0.3333333333 added 3 times will give 0.9999999999 not 1.0 . 10 and 3 are relatively prime so 10/3 requires an infinite repeating decimal. Likewise 10 and 7 are relatively prime so 10/7 requires an infinite repeating decimal. 10 and 5 are not relatively prime, and 10/5 and 5/10 is exactly representable in decimal.
When it comes to binary, 1 and 10 are relatively prime. 1/10 in binary is b0.0(000101) repeated so any finite truncation of its representation in decimal is going to have the same problem that you have with 1/3 in decimal: add enough copies of the representation and you will come up short compared to the algebraic solution.
  2 Comments
Star Strider
Star Strider on 14 Dec 2021
I first learned FORTRAN on an IBM 1620 that did all its calculations as decimal calculations using lookup tables (that had to be loaded as cards in front of each program card deck). An IBM engineer I met years later, when I related to him my experiences with the 1620 (and later the 1130), told me that at IBM the 1620 was known as the ‘CADET’ machine: Can’t Add, Doesn’t Even Try!

Sign in to comment.

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!