问题描述
虽然我想出了一个使用多个 if/else if
语句的解决方法,但我很想知道我的 case
语句看起来有什么问题,如下图所示:
Although I have come up with a work-around using multiple if / else if
statements, I am curious in knowing what looks wrong with my case
statements, illustrated below:
function [ar_vo,bucket] = revEng(v)
...
s=solve(solve>0) * sqrt(T);
ar_vo=s;
bucket=ri(ar_vo);
%%%%%%%%%%%%%%%%%%%%%
function bucket = ri(ar_vo)
% switch(ar_vo)
% case ((ar_vo >= 0)&&(ar_vo < 0.005)) (1)
% bucket=1;
% case ((ar_vo >= 0.005)&&(ar_vo < 0.02)) (2)
% bucket=2;
% case ((ar_vo >= 0.02)&&(ar_vo < 0.05)) (3)
% bucket=3;
% case ((ar_vo >= 0.05)&&(ar_vo < 0.1)) (4)
% bucket=4;
% case ((ar_vo >= 0.1)&&(ar_vo < 0.15)) (5)
% bucket=5;
% case ((ar_vol >= 0.15)&&(ar_vol < 0.25)) (6)
% bucket=6;
% case (ar_vo >= 0.25) (7)
% bucket=7;
% otherwise
% error('MATLAB:RI Bucket:NotAvailable.'); (8)
% end
%
给定 ar_vo = 0.073...
在调试代码时,由于某些原因它会跳过 case (4)
并到达 case (8)
...
Given ar_vo = 0.073...
while debugging the code, it skips case (4)
for some reasons and reaches case (8)
...
低效但可行的解决方案,带有多个 if/else if
:
if ((ar_vo >= 0)&&(ar_vo < 0.005))
bucket=1;
else if ((ar_vo >= 0.005)&&(ar_vo < 0.02))
bucket=2;
else if ((ar_vo >= 0.02)&&(ar_vo < 0.05))
bucket=3;
else if ((ar_vo >= 0.05)&&(ar_vo < 0.1))
bucket=4;
else if ((ar_vo >= 0.1)&&(ar_vo < 0.15))
bucket=5;
else if ((ar_vo >= 0.15)&&(ar_vo < 0.25))
bucket=6;
else if (ar_vo >= 0.25)
bucket=7;
else
error('MATLAB:RI Bucket:NotAvailable.');
end
end
end
end
end
end
end
推荐答案
switch
语句的 case
表达式 不能是 MATLAB 中的条件.它们必须是值.
The case
expressions for your switch
statement cannot be conditionals in MATLAB. They must be values.
switch thing
case 1
% do thing
case {2, 3}
% do other thing
otherwise
end
那么 MATLAB 在您的情况下所做的是将您的条件 转换为 值.因此,当您提供 0.073 的值时,MATLAB 看到的是这个.
So what MATLAB is doing in your case, is that it is converting your conditionals into values. So when you supply a value of 0.073 what MATLAB sees is this.
switch 0.73
case 0
case 0
case 0
case 1
case 0
case 0
case 0
otherwise
end
由于 0.73 显然不匹配任何那些您落入 otherwise
并收到错误的值.
Since 0.73 obviously doesn't match any of those values you fall through to the otherwise
and receive the error.
这就是为什么 switch 语句实际上只最适合用于将输入值与 exact 可能值进行比较的分类数据(显然不适合浮点数).
This is why switch statements are really only best for categorical data where you are comparing the input value against exact possible values (obviously not good for a floating point number).
如果您真的想将其保留为 switch 语句,您可以做一些小把戏,实际上让您的 switch 表达式简单地1"(true
) 它将按照您的意愿行事.
If you REALLY want to keep this as a switch statement you could do a little trickery and actually make your switch expression simply "1" (true
) and it will behave as you want it to.
switch(1)
case ((ar_vo >= 0)&&(ar_vo < 0.005))
bucket=1;
case ((ar_vo >= 0.005)&&(ar_vo < 0.02))
bucket=2;
case ((ar_vo >= 0.02)&&(ar_vo < 0.05))
bucket=3;
case ((ar_vo >= 0.05)&&(ar_vo < 0.1))
bucket=4;
case ((ar_vo >= 0.1)&&(ar_vo < 0.15))
bucket=5;
case ((ar_vo >= 0.15)&&(ar_vo < 0.25))
bucket=6;
case (ar_vo >= 0.25)
bucket=7;
otherwise
error('MATLAB:RI Bucket:NotAvailable.');
end
请不要实际上这样做.
一个理智的方法是使用一系列 if/elseif
语句(与您的 if else if
语句的长树相反).这是一个很好的方法(并且非常适合浮点数),因为它只是检查该数字是否在给定范围内.
One sane approach is to use a series of if/elseif
statements (as opposed to your long tree of if else if
statements). This is a good approach (and is well-suited to floating point numbers) as it simply checks if that number is within a given range.
if ((ar_vo >= 0)&&(ar_vo < 0.005))
bucket=1;
elseif ((ar_vo >= 0.005)&&(ar_vo < 0.02))
bucket=2;
elseif ((ar_vo >= 0.02)&&(ar_vo < 0.05))
bucket=3;
elseif ((ar_vo >= 0.05)&&(ar_vo < 0.1))
bucket=4;
elseif ((ar_vo >= 0.1)&&(ar_vo < 0.15))
bucket=5;
elseif ((ar_vo >= 0.15)&&(ar_vo < 0.25))
bucket=6;
elseif (ar_vo >= 0.25)
bucket=7;
else
error('MATLAB:RI Bucket:NotAvailable.');
end
最佳解决方案
我个人会做的是删除所有代码并简单地用以下语句替换它.
The Best Solution
What I personally would do though, would be to remove all of that code and simply replace it with the following statements.
lowerlimits = [0, 0.005, 0.02, 0.05, 0.1, 0.15, 0.25]
upperlimits = [lowerlimits(2:end), inf];
bucket = find(ar_vo >= lowerlimits & ar_vo < upperlimits);
if isempty(bucket)
error('MATLAB:RI Bucket:NotAvailable.');
end
在这种方法中,我将 ar_vo
与所有范围 同时 进行比较,然后使用匹配的索引获取 bucket
值.如果没有分配bucket,则没有匹配,bucket
是一个空数组.
In this approach I compare ar_vo
to all ranges simultaneously and then get the bucket
value by using the index of the match. If there was no bucket assigned, there was no match, and bucket
is an empty array.
这大大减少了复制/粘贴错误的机会,并且如果您想在以后修改条件更容易.特别是对于必须遍历整个 if/elseif
构造的 > 0.25 的值,它可能也更高效.
This drastically reduces the chance of copy/paste errors and makes it easier if you want to modify the conditions at a later date. It is likely also more performant particularly for values > 0.25 which would have to traverse your entire if/elseif
construct.
这篇关于嵌套函数中间隔的多个 CASE 语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,WP2