problem using switch with logical operators, (larger than do this or less than do this)

45 views (last 30 days)
Hi,
If anyone can help me explain why my code (below) does not work that would be very much appreciated. I would expect the results to be 'less than'.
Thanks
>> pos=-10000
switch pos
case pos==0
disp('equal')
case pos<0
disp('less than')
case pos>0
disp('more than')
otherwise
disp('not working')
end
pos =
-10000
not working

Accepted Answer

Oleg Komarov
Oleg Komarov on 23 Jul 2011
Switch doesn't work the way you expect it, for:
pos = -1e4
pos == 0 --> false
pos < 0 --> true
pos > 0 --> false
So the switch really becomes:
switch pos
case false
disp('equal')
case true
disp('less than')
case false
disp('more than')
otherwise
disp('not working')
end
but pos is -1e4.
You wanna use:
msg = {'less than','equal','more than'};
msg(logical(histc(pos,[-inf,0,0+eps,+inf])))
or
if pos < 0
disp('less than')
elseif pos == 0
disp('equal')
else
disp('more than')
end
  2 Comments
Jan
Jan on 24 Jul 2011
@Oleg: My +1 vote concerns the explanation of the problem and the IF/ELSEiF method.
The LOGICAL(HISTC()) approach is nice for a cabinet of oddities. Freaky.

Sign in to comment.

More Answers (5)

Jan
Jan on 24 Jul 2011
The following would work, but I strongly recommend not to do this:
switch true % <-- difference is here
case pos==0 % triggers if: true == (pos==0)
disp('equal')
case pos<0
disp('less than')
case pos>0
disp('more than')
otherwise
disp('not working')
end
This takes the argument TRUE and compares it to the results of the comparisons in the CASE expressions. Although this is valid and documented, it is confusing - most of all for experienced programmers.
  5 Comments
Walter Roberson
Walter Roberson on 27 Jul 2018
I have been programming for over 40 years. Best Practices in programming is to write clearly and quickly understandably, except in cases where measured performance requires a less-clear form.
So if you want to compare a value to zero, then compare the value to zero,
if val < 0
...
elseif val == 0
...
else
...
end
instead of introducing the extra layer of introducing the constant true and comparing the result of a logical test to the constant
switch true
case val < 0
...
case val == 0
...
case val > 0
...
end
In nearly all programming languages, the syntax of switch is to switch on an expression with the cases being constants. Some programming languages implement that by using hash tables (in general) or lookup tables (in dense situations). Very few permit switching on an expression with the cases being expressions.
A way that would be acceptable would be
switch sign(val)
case -1
...
case 0
...
case 1
...
otherwise
%nan
end
Kevin Dixon
Kevin Dixon on 17 Feb 2021
The reason this question is being pushed out there is because MATLAB homeworks are being created to force us to use multiple methods to solve the same problem. Thank you Jan and Walter for showing how it can be done with switch instead of immediately saying use the if statement.
I am so tired of people making answers without actually answering the question. Just answer the question, and then state that there is a better way of doing it, then show that.
Again, thanks to the both of you.

Sign in to comment.


Walter Roberson
Walter Roberson on 24 Jul 2011
You are asking to "switch" based upon the value of pos, which means that the value of pos will be compared to the value of the expressions. The expressions you list are logical values, so they will all evaluate numerically to either 0 (false) or 1. As neither 0 nor 1 is equal to -10000, the "otherwise" will come in to effect.
If you look back at Oleg's answer, his answer is really the same, but with slightly less emphasis.
If you really wanted to, you could write
switch true
case pos==0
disp('equal');
case pos<0
disp('less than');
case pos>0
disp('greater than');
otherwise
disp('an error')
end
then the value true would be compared in turn to the logical values you list in the cases.
"switch" is not designed for classifying numbers in to ranges.
  3 Comments
Walter Roberson
Walter Roberson on 24 Jul 2011
I was in the middle of answering when it became time to cook and eat dinner; by the time I got back and finished up the posting, you had developed the same code structure.
Kevin Dixon
Kevin Dixon on 17 Feb 2021
Thank you for actually answering the question, like Jan above. And not immediately say do it this way instead. Thanks again, this was an Actual MATLAB Grader problem, but with integraded equations.

Sign in to comment.


Elin
Elin on 24 Jul 2011
Hi thanks for your answer, I just would like to understand why its working/not working. it works fine if I use values instead of logical statements(see below), how can that be?
pos=-10000
switch pos
case 0
disp('equal')
case -10000
disp('less than')
case 10000
disp('more than')
otherwise
disp('not working')
end
pos =
-10000
less than
  1 Comment
Oleg Komarov
Oleg Komarov on 24 Jul 2011
As I wrote in my answer the case should be a value or a collection of values and pos == 0 is a value, "true". That's why I rewrote the swtich with the false/true.
What it does is it asks: is -1e4 false or is it true or is it false, otherwise.

Sign in to comment.


Elin
Elin on 24 Jul 2011
thank you all. not only does it work now, but I also understand why.

Kelly Carter
Kelly Carter on 17 Sep 2020
I disagree with some of the arguments above. I agree that a primary goal of coding should be clarity, but I disagree that one of the coding approaches is "unclear to experienced programmers" (I myself have over 40 years of coding, plus teaching coding at the university level). Below is a perfectly good and clear example of using the "switch true" type expression:
% Calculate basic tax
switch true
case (income >= 0 && income <= 6000)
tax = 0;
case (income > 6000 && income <= 34000)
tax = 0.15 * (income - 6000);
case (income > 34000 && income <= 80000)
tax = 4200 + 0.30 * (income - 34000);
case (income > 80000 && income <= 180000)
tax = 18000 + 0.40 * (income - 80000);
case (income > 180000)
tax = 58000 + 0.45 * (income - 180000);
otherwise
tax = 0;
disp('ERROR: Invalid income value');
end
  3 Comments
Kelly Carter
Kelly Carter on 17 Sep 2020
Wow. Interesting solution. For those that thought the "switch true" construct was hard to read/understand, I'm guessing they'd really be stumped by your approach. I know my freshmen/sophmore college students would be clueless. Once one learns your approach and the "discretize" technique, it would be more readable. Thanks for sharing.
Walter Roberson
Walter Roberson on 17 Feb 2021
Edited: Walter Roberson on 17 Feb 2021
switch true was less than clear to me when I discovered it. I had questions such as:
  • what order are the tests done in?
  • what happens if more than one are true?
  • since these are function evaluations, and function evaluations can have side effects, will evaluation of the case labels stop when there is a match?
  • what happens if the function that is the case label does not return any output?
  • if the switch is logical, do the case labels need to be logical, or will the common zero = false, non-zero = true hold, or will switch true only match numeric 1?
  • does this mean more generally that you can switch on a numeric value and have the case labels be functions that return values that are compared to the value?
  • if it does, then can you return a cell array and expect that the entries in the array will be compared to the value, or is the {} switch syntax syntactical rather than an actual cell array?
  • if it is a functional cell array rather than a syntactical one, what do you return when you really do want a cell as the value
  • is the syntax for listing a constant cell array to be tested against a scalar cell array switch, case {{scalar}} ?

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!