Logical vs. Bitwise Operators
There are two different types of comparison operators in IDL: bitwise operators and logical operators.
A bitwise operator evaluates each bit of two expressions based on the logic that is defined by the operator. These include the AND, OR, NOT, and XOR operators. Each bit of the input expressions
will be compared independently of other bits. IDL will always evaluate both expressions.
A logical operator is very similar to a bitwise operator in that it evaluates two conditions. IDL's logical operators are && (logical and), || (logical or), and ~ (logical not). There are two significant differences between a logical and bitwise operator. First, a logical operator will always return 1 (for true) or 0 (for false). Additionally, a logical operator will perform "short circuit" logic, meaning that if the outcome is known after only checking the first condition, the second condition is ignored. For example, when using the logical and, we know that both conditions must be true in order for the result to be true; if the first of the two evaluates to false, then the result will be false regardless of the second condition, and therefore the second condition will not be evaluated.
In addition to simply being a bit more efficient, the logical and is extremely useful when you first need to check for the existence of a value before checking a condition of it. For instance, I have a variable called var, and I want to write an IF statement that is executed if the variable is greater than 5. However, in my code, I don't know for sure that var exists, so first I must check N_ELEMENTS on it. With the logical and, this can be done on one line.
IF N_ELEMENTS(var) GT 0 && var GT 5 THEN BEGIN
If var doesn't exist in the code above, then IDL isn't going to check to see if var is greater than 5. If the bitwise AND operator was used, IDL would have thrown an undefined variable error when checking the second half of the if statement. To use AND, this logic would need to be on two different lines.
IF N_ELEMENTS(var) GT 0 THEN BEGIN
IF var GT 5 THEN BEGIN
So when would you want to use a bitwise operator?
Well first of all, logical operators only work when the result from each expression is a scalar. For example, if I want to use a WHERE statement to check two different conditions on an array, then the bitwise operator needs to be used.
arr = INDGEN(6)
result = WHERE(arr GT 1 AND arr LT 4)
Substituting AND with && in the above expression would result in an error.
In less common cases, the conditional expressions might be the result of two different functions, and you want both functions to always be performed and not skipped (perhaps the functions do something to the variable as it's passed-by-reference, or maybe they change internal variables based on the input), then you could put them together with a bitwise operator.
IF my_function1(var) AND my_function2(var) THEN BEGIN
Note that if you wanted one to always run but didn't care about the second, you could use a logical operator and put the one you always want performed first.
You can even do tricks with bitwise logic. Because bitwise logic operates on all bits of each value and does so independently of all other bits, you get interesting results. For example:
PRINT, 3 AND 6
IDL will print 2. This is because 3 in binary is 011 and 6 in binary is 110. The result is... (first bit): 0 AND 1 = 0, (second bit): 1 AND 1 = 1, (third bit): 1 AND 0 = 0... 010, which is 2. This can sometimes be handy when processing image data to modify certain colors. A very useful example is that the logical NOT will convert a photograph to a negative.
As a final note, keep in mind that when multiple operations are performed in the same line of code, IDL will follow an operator precedence, similar to order of operations in mathematics.