Why isn't MATLAB counting this as equal to 1?
5 views (last 30 days)
Show older comments
I've been writing a code, a small part of which checks whether some of the inputs sum to 1 (as they're all proportions of a whole). If they do, the code continues. If not, the code stops and throws up an error message.
a = 0.4;
b = 0.3;
c = 0.2;
d = 0.1;
total = [a,b,c,d];
if sum(total) ~= 1
warning('Sum of a,b,c,d must be 1.')
return
end
The example I've given here DOES NOT WORK, even though a+b+c+d = 1. It throws up the error message and stops the script.
To be clear, this works fine for a,b,c and d = 0.25. It works for a = 0.5, b = 0.4, c and d = 0.05. It doesn't work for the example I've given, and it doesn't work for a,b,c = 0.3, d = 0.1. I haven't checked other combinations exhaustively.
Any help would be greatly appreciated, thanks.
2 Comments
Adam
on 8 Nov 2018
(most) Floating point numbers cannot be represented with 100% accuracy so even though they may appear to be exact they are not and when you do maths with these those minor errors accumulate. You should never test equality of floating point numbers though unless there is some very clear purpose in doing so (e.g. two places that implement the same maths to get to a result)
Accepted Answer
Steven Lord
on 8 Nov 2018
Edited: Steven Lord
on 8 Nov 2018
None of 0.4, 0.3, 0.2, or 0.1 can be exactly represented in IEEE double precision. See the "One-tenth" and "Hexadecimal format" sections of this post on Cleve Moler's blog for a bit more of an explanation. So those are not exactly equal to four-tenths, three-tenths, two-tenths, or one-tenth. This is not a MATLAB problem (other languages will behave the exact same way if they use double precision), this is a "double precision numbers aren't infinitely precise" situation.
To give a similar scenario that doesn't involve computers, take out a piece of paper and a pen or pencil (or anything you can use to write and something to write on.) Divide 1 by 3 to as many decimal places as you want and can write down. You're not allowed to just say that it's 0.3 repeating, you have to write out all the decimal places you want to use in the next step.
Now multiply the answer you computed in the first step by 3. Symbolically, (one third) * 3 is exactly 1. Practically, (the approximation you computed to one third) * 3 is not exactly 1.
The original code posted by madhan ravi has a mistake in it. [I saw it was edited, but I'm not sure if it was edited to correct the mistake.] Instead of this line:
if (sum(total) == 1) < 1e-4
you need to use:
if abs(sum(total) - 1) < 1e-4
This second line computes the distance between the sum of your vector and 1 (calling abs means we don't care which one is larger, we're just getting the absolute distance) and checks if that distance is "close enough" (which in this code is defined as a distance smaller than 1e-4.) If it is "close enough" the if statement's body will execute.
Added: You may wonder why it worked with 0.25, why sum([0.25 0.25 0.25 0.25]) was exactly 1. Unlike 0.4, 0.3, 0.2, and 0.1 the number 0.25 can be exactly represented in IEEE double precision. Using the fraction/mantissa and exponent notation from the "Single and Double Precision" section in Cleve's blog post, f is 0 and e is -2.
1 Comment
madhan ravi
on 8 Nov 2018
Edited: madhan ravi
on 8 Nov 2018
I'm not sure if it was edited to correct the mistake
yes it was edited to correct the mistake @Steven
but wouldn't have managed it to explain clearly like you did
+1
More Answers (1)
madhan ravi
on 8 Nov 2018
Edited: madhan ravi
on 8 Nov 2018
if abs(sum(total-1)) < 1e-4 %edited
The above is equivalent to
if sum(total)==1
12 Comments
madhan ravi
on 8 Nov 2018
Edited: madhan ravi
on 8 Nov 2018
There was a mistake in my part (corrected it)
see https://www.mathworks.com/matlabcentral/answers/428577-very-odd-error-with-simple-multiplication-ok-not-so-odd#answer_345716 for further explanation on float numbers
make sure to accept the answer if it answered your question so people know the question is solved
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!