Home Manual Packages Global Index Keywords Quick Reference |
#### 1.2.3.2 Combining conditions with `&&` and `||` The logical operators `&&` ("and") and `||` ("or") combine conditional expressions; the `!` ("not") operator negates them. The `!` has the highest precedence, then `&&`, then `||`; you will need parentheses to force a different order. (Beware of the bitwise "and" and "or" operators `&` and `|` -- these should never be used to combine conditions; they are for set-and-mask bit fiddling.) The operators for comparing numeric values are `==` (equal), `!=` (not equal), `>` (greater), `<` (less), `>=` (greater or equal), and `<=` (less or equal). These all have higher precedence than `&&`, but lower than `!` or any arithmetic operators.
    if ((a<b && x>a && x<b) || (a>b && x<a && x>b))
      write, "x is between a and b"
Here, the expression for the right operand to `&&` will execute only if its left operand is actually true. Similarly, the right operand to `||` executes only if its left proves false. Therefore, it is important to order the operands of `&&` and `||` to put the most computationally expensive expression on the right -- even though the logical "and" and "or" functions are commutative, the order of the operands to `&&` and `||` can be critical. In the example, if `a>b`, the `x>a` and `x<b` subexpressions will not actually execute since `a<b` proved false. Since the left operand to `||` was false, its right operand will be evaluated. Despite the cleverness of the `&&` and `||` operators in not executing the expression for their right operands unless absolutely necessary, the example has obvious inefficiencies: First, if `a>=b`, then both `a<b` and `a>b` are checked. Second, if `a<b`, but `x` is not between `a` and `b`, the right operand to `||` is evaluated anyway. Yorick has a ternary operator to avoid this type of inefficiency:
    expr_A_or_B= (condition? expr_A_if_true : expr_B_if_false);
The `?:` operator evaluates the middle expression if the condition is true, the right expression otherwise. Is that so? Yes : No. The efficient betweeness test reads:
    if (a<b? (x>a && x<b) : (x<a && x>b))
      write, "x is between a and b";