【发布时间】:2012-12-20 10:34:31
【问题描述】:
MATLAB 中的| 和|| 逻辑运算符有什么区别?
【问题讨论】:
标签: matlab logical-operators short-circuiting
MATLAB 中的| 和|| 逻辑运算符有什么区别?
【问题讨论】:
标签: matlab logical-operators short-circuiting
【讨论】:
逻辑运算符
MATLAB 提供三种逻辑operators 和functions:
| 是 Element-wise — 对逻辑数组的相应元素进行操作。
示例:
向量输入 A 和 B
A = [0 1 1 0 1]; B = [1 1 0 0 1];
一个 | B = 11101
|| 是短路 - 对标量、逻辑表达式进行操作
例子:
|| :如果任一输入或两者的计算结果为真,则返回逻辑 1 (true),否则返回逻辑 0 (false)。
操作数: 包含标量值的逻辑表达式。
A || B(仅当 A 为假时才评估 B)
A = 1;
B = 0;
C =(A || (B = 1));
B 在这个表达式之后是 0 和 C is 1。
其他的是,按位 - 对整数值或数组的相应位进行操作。
reference link
【讨论】:
| 将OR 表示为logical operator。 || 也是一个逻辑运算符,称为short-circuit OR
短路运算符最重要的优点是,您可以仅在满足某些条件时使用它们来计算表达式。例如,您希望仅当函数文件位于当前 MATLAB 路径上时才执行函数。当找不到文件 myfun.m 时,短路可防止以下代码生成错误:
comp = (exist('myfun.m') == 2) && (myfun(x) >= y)
同样,此语句避免尝试除以零:
x = (b ~= 0) && (a/b > 18.5)
您还可以在if 和while 语句中使用&& 和|| 运算符来利用它们的短路行为:
if (nargin >= 3) && (ischar(varargin{3}))
【讨论】:
我确定您已经阅读了 short-circuiting operators 和 element-wise operators 的文档。
一个重要的区别是元素运算符可以对数组进行操作,而短路运算符仅适用于标量逻辑操作数。
但可能关键的区别在于短路问题。对于短路运算符,表达式从左到右进行计算,一旦可以确定最终结果,则不计算其余项。
例如,考虑
x = a && b
如果a 的计算结果为false,那么我们知道a && b 的计算结果为false,而与b 的计算结果无关。所以没有必要评估b。
现在考虑这个表达式:
NeedToMakeExpensiveFunctionCall && ExpensiveFunctionCall
我们认为ExpensiveFunctionCall 需要很长时间来评估。如果我们可以执行一些其他廉价的测试,允许我们跳过对ExpensiveFunctionCall 的调用,那么我们就可以避免调用 ExpensiveFunctionCall。
因此,假设 NeedToMakeExpensiveFunctionCall 的计算结果为 false。在这种情况下,因为我们使用了短路操作符,ExpensiveFunctionCall 将不会被调用。
相反,如果我们使用逐元素运算符并这样编写函数:
NeedToMakeExpensiveFunctionCall & ExpensiveFunctionCall
那么对ExpensiveFunctionCall 的调用将永远不会被跳过。
事实上,我希望你已经阅读了MATLAB documentation,其中包含一个很好的例子,很好地说明了这一点:
x = (b ~= 0) && (a/b > 18.5)
在这种情况下,如果b 为零,我们将无法执行a/b。因此测试b ~= 0。短路运算符的使用意味着我们避免在b 为零时计算a/b,从而避免可能出现的运行时错误。显然,逐元素逻辑运算符无法避免运行时错误。
有关短路评估的详细讨论,请参阅有关该主题的Wikipedia article。
【讨论】:
| 也可以对数组进行操作,而|| 只能对标量进行操作。此外,Loren Shure 指出here | 也可以短路(!!),但仅限于if/while 语句。
短路|| 意味着,只有在表达式中必须对参数进行评估。
在我们的示例expr1 || expr2 中,如果expr1 的计算结果为TRUE,则不需要计算第二个操作数——结果将始终为TRUE。如果您有一长串短路运算符A || B || C || D 并且您的第一个评估结果为真,那么其他人将不会被评估。
如果您将元素逻辑 | 替换为 A | B | C | D,则无论之前的操作数如何,都会计算所有元素。
【讨论】: