December 26, 2005Mysterious operator
Did you know that Java has three "and" operators? First, there is the very common logical and: &&:
Then, there is the bitwise and operator, which very few programmers will probably ever use:
And finally, there is...
Take a close look at this code. The expression calculated for result uses what looks like the bitwise and operator, and yet it seems to operate on boolean values (respectively x >= min and x <= max) and not scalar ones. There are actually two startling things in this code:
The solution to the puzzle is given in the Java Language Specification, chapter 15.22.2:
For all intents and purposes, it looks like the boolean logical & operator is exactly similar to the logical && operator. Is that so? Not really. If you run the following program:
You will get the following result:
As you can see, && will skip the second expression if the first expression is false (because at this point, it knows that the overall result will be false, so there is no point in evaluating the remainder of the expression) while & will always evaluate all its operands. Similarly, || will stop evaluating its operands as soon as one is found to be true while | will always evaluate all of them. Not surprisingly, logical operators are the most useful because not only do they typically run faster than their boolean counterparts, they also allow to write convenient expressions:
With that in mind, when would you want to use a boolean logical & or | operator? The theoretical answer is: whenever your code depends on side effects performed by the operators involved in the expression and you want to make sure that all of them are invoked, regardless of the final result of the expression. Why do I say "theoretical"? Such code would probably qualify as a design smell because having methods that return a value and perform side effects are usually frowned upon. Having said that, it is not an absolute rule and I have found myself having to do this a few times, so I would rather discourage the use of boolean logical operators for a totally different reason: don't use them because they will confuse readers of your code. Can someone come up with a convincing use for a boolean logical operator? Posted by cedric at December 26, 2005 07:02 AM Comments
I use them when I have to reproduce in code the result of an analysis made from a Karnaugh map, and I use them only with previously calculated boolean variables. The final expression is very compact and not easy to read, but it's not meant to be read without the map. The use of '&' or '|' in that case is still more readable than using '&&' or '||', because the boolean variable are named with a single character, and it's not good when the operator is longer than the variable. Plus, it acts as a strong signal for the reader that the complexity of the expression lies more in boolean algebra than from the methods called. Posted by: Damien B at December 27, 2005 08:19 AM&= and |= are probably used more often than & and |. In certain simple contexts, & and | may run faster than && and ||. Posted by: Tom Hawtin at December 27, 2005 10:15 AMYou can also have: boolean test = (a ? b : false); if you want to be really vague for your 'and' operators. In this case, the second argument (b) is only evaluated once if the first test (a) is true. A similar expression holds for 'or'. Posted by: Alex Blewitt at December 27, 2005 10:27 AMI used this construct for the semantic document validation. Assume there are 3 independent checks to be made. If the first validation fails and the failure is not fatal, you want to continue with the validation and to send a reply enumerating ALL errors at once. The validation check should be: isValid = checkA() & checkB & checkC(). Short-circuiting is not appropriate. Or, you can use a loop if the number od checks is not fixed. Posted by: at December 27, 2005 04:07 PMThe bitwise operators should be a lot faster than the logical ones when the left side expression is very simple. This is true today, but not a decade ago, and it's a matter of knowing how a CPU works. Modern CPUs have very deep pipelines, so branches have a very hight cost, this was not the case for the 80386. Given "a() && b()" x "a() & b()" the result should be something like: "a() && b()" "a() & b()" The generated code will be about the same size, and given that the code for b() is short any branch misprediction of the first test will cause enouth stall to make the bitwise version to perform better. As this is a peephole optimization I must say that it doesn't justify it's use enouth and likely others have said, the &=, |= forms are more frequent and userfull. Posted by: Rodrigo Kumpera at December 28, 2005 08:47 AMfindbugs flags uses of & it's neat, but I sure don't have a use for it. Posted by: Ron at December 30, 2005 10:04 AMI believe the third & operator is a serendipity. It is an interesting side effect of how Java language treats boolean types. The language lacks a true boolean type, and most compilers encode them as ints( or short, byte in some cases, but all upcastable to an int). As a result, the bitwise & and | works with boolean operands. The JVM spec says that "There are no Java virtual machine instructions solely dedicated to operations on boolean values.". Posted by: Ajith Kallambella at January 4, 2006 12:02 PM> The language lacks a true boolean type Incorrect. The Java language _does_ have a boolean type, but the JVM specification does not go out of its way to provide special support for it. Peace. Posted by: Cameron at January 9, 2006 07:28 PM-- "The language lacks a true boolean type" The Java language _does_ have a boolean type, but the JVM specification does not go out of its way to provide special support for it. Peace. Posted by: Cameron at January 9, 2006 07:29 PMtaste of home modular home home appraisal dealer home mobile rental home electronics home buying home care foreclosure home home shopping home theater better home and garden home builder adult novelties google home diabetic Handbags home improvement new apartment home home renovation home depot canada The bewildered scientist struck the match in a narrow tunnel to discover the dark secret. Posted by: footmania at January 6, 2007 07:06 PMPost a comment
|