Why isn't MATLAB counting this as equal to 1?

5 views (last 30 days)
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
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)
BecomeAnAstronaut
BecomeAnAstronaut on 8 Nov 2018
Hi Adam, thanks for your response. I'm just trying to write a bit of code that stops if the values a,b,c,d don't sum to 1, as they're all supposed to proportions of the work done in a compressor, so the sum must be 1. I get that, with floating numbers, errors can build up, but surely adding four numbers together and checking if they're equal to 1 should work. I don't understand how that much error can accumulate, especially given that I tried madhan ravi's answer of including a tolerance.

Sign in to comment.

Accepted Answer

Steven Lord
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
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

Sign in to comment.

More Answers (1)

madhan ravi
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
BecomeAnAstronaut
BecomeAnAstronaut on 8 Nov 2018
Hi both, There was clearly a hardware issue on my end. I came home to test the code on my laptop and a couple of the suggested solutions work fine. No idea what I'll do about my computer... I'll have to debug it or something. Sorry for the inconvenience and thanks for your help.
madhan ravi
madhan ravi on 8 Nov 2018
Edited: madhan ravi on 8 Nov 2018
There was a mistake in my part (corrected it)
make sure to accept the answer if it answered your question so people know the question is solved

Sign in to comment.

Categories

Find more on Programming in Help Center and File Exchange

Products


Release

R2018a

Community Treasure Hunt

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

Start Hunting!