15

First, some background: I am an IT teacher-in-training and I'm trying to introduce the boolean operators of java to my 10th grade class. My teacher-mentor looked over a worksheet I prepared and commented that I could let them use just a single & or | to denote the operators, because they "do the same thing".

I am aware of the difference between & and &&.
& is a bitwise operator intended for use between integers, to perform "bit-twiddling".
&& is a conditional operator intended for use between boolean values.

To prove the point that these operators do not always "do the same thing" I set out to find an example where using the bitwise between boolean values would lead to an error. I found this example

boolean bitwise;
boolean conditional;
int i=10, j=12;
bitwise = (i<j) | ((i=3) > 5); // value of i after oper: 3
System.out.println(bitwise+ " "+ i);
i=10; 
conditional = (i<j) || (i=3) > 5 ;  // value of i after oper: 10
System.out.println(conditional+ " "+ i);
i=10; 
bitwise = (i>j) & (i=3) > 5;   // value of i after oper: 3
System.out.println(bitwise+ " "+ i);
i=10; 
conditional = (i>j) && (i=3) > 5;  // value of i after oper: 10
System.out.println(conditional+ " "+ i);

This example shows that if a value has to be changed by the second half of the expression, this would lead to a difference between the results, since bitwise is an eager operator, while the conditional behaves as a short circuit (does not evaluate the second half, if the first half is false in the case of && and true in the case of ||).

I have an issue with this example. Why would you want to change a value at the same time as you do a comparision on it? It doesn't seem like a robust way to code. I've always been averse to doing multiple operations in a single line in my production code. It seems like something a "coding cowboy" with no conscience as to the maintainability of his code would do. I know that in some domains code needs to be as compact as possible, but surely this is a poor practice in general?

I can explain my choice of encouraging the use of && and || over & and | because this is an accepted coding convention in software engineering.

But could someone please give me a better, even real-world, example of using a bitwise operator in a conditional expression?

5 Answers 5

16

it is appropriate when you are performing a masking operation

if ((a & b) > 0) { ... }

where a and b are integers

|| and | and && and & are not interchangable

| and & will amost never appear in a conditional expression by themselves (the point of the link you included is that such things are most often errors)

EDIT: Don't argue with your mentor; even if you win, you lose. Instead, explain that you don't want to confuse the students by mixing logical operators and bitwise operators in the same lesson. You could explain that if i=3 and j=2 then i&j = 2, while i&&j is an error. However, the simpler explanation is that you're teaching boolean (logical) operators, so throwing in special-case bitwise equivalents is a distraction from the main point of the lesson. There's no need to make the mentor "wrong", and no need to produce counter-examples. The focus of the lesson is on boolean operators, not bitwise operators.

As a corollary, when you start to teach bitwise operators, there's no need to show the special cases where + and - produce the same results as & and |

7
  • The code above isn't wrong though, it may be confusing but as it stands that code does not contain an error does it? I agree that using bitwise operators in this way is not very readable, I wouldn't like it if I saw it in a code review, but it is legal Java (and C# too, ignoring the System.out.println).
    – Steve
    Commented Apr 14, 2011 at 18:17
  • Thanks for answering @Steven A. Lowe. You said "|| and | and && and & are not interchangeable" but bitwise = !(true & true == false); and condition = !(true && true == false); will both evaluate to true, so in this case they are interchangeable? Syntactically perhaps, since the code still compiles. I would agree that they are used for different things semantically, as I mentioned in paragraph 2. You say that ! and & "almost never appear in a conditional by themselves". I am looking for these "almost never" cases, and wondering whether they do legitimately exist.
    – Deerasha
    Commented Apr 14, 2011 at 19:05
  • @Deerasha: || and && operate only on booleans. & and | operate on integers and booleans - there is little point in using bitwise operators (intended to operate on multiple bits) to manipulate booleans, and doing so with abandon can lead to confusing code and unexpected behaviors (i.e. if you accidentally use an integer instead of a boolean, the bitwise operators will not complain) Commented Apr 14, 2011 at 19:09
  • Yes @Steve Haigh, the compiler doesn’t reject it, but it isn’t the right way to use them, judging from the published coding standard I linked to. Can I comfortably rest on dismissing it because it does not comply with a coding standard, or should java maybe indicate that this is an improper use?
    – Deerasha
    Commented Apr 14, 2011 at 19:11
  • 2
    @Steven A. Lowe: if i=3 and j=2 then i&j = 2, while i&&j is an error This is brilliant! It’s simple and it makes the point. At 10th grade level this is also a likely mistake to make, since they are still getting used to the Boolean type and what the operators would apply to. Thank you so much! Great advice on not arguing with my mentor either.
    – Deerasha
    Commented Apr 14, 2011 at 20:11
13

The non-bitwise operators && and || are short-circuit operators. In other words, with &&, if the LHS is false, the RHS will never be evaluated; with || if the LHS is true, then the RHS will never be evaluated. On the other hand, the bitwise operators & and | are non-short-circuit, and will always evaluate both the LHS and the RHS. Otherwise, they're equivalent in an if statement.

The only time I can see value in using the non-short-circuit operators is if the RHS has some kind of desirable side-effect that you want to happen in all cases. I can't think of a specific example where you would want this, and I don't believe it's good practice, but that's the difference.

2
  • 1
    +1. Exactly right, when comparing booleans bitwise and logical operators always return the same result, but (in Java and C# at least) only the logical operators short circuit.
    – Steve
    Commented Apr 14, 2011 at 18:14
  • Thank you for answering. Your paragraph 1 was what I was trying to get at in my paragraph 4, by stating that bitwise is an eager operator while the conditional behaves as a short circuit. Your paragraph 2 is the concern I described in my paragraph 5. So I’m aware of the difference but I’m looking for that specific example neither you nor I can think of.
    – Deerasha
    Commented Apr 14, 2011 at 19:30
7

The general philosophical answer is that using bitwise operators for boolean operators is atypical and makes the code harder to read. In practice (for code that is in production), more readable code is easier to maintain and thus more desirable.

For a real-world use of the need for short-circuit operators, see cases such as:

if (args.length > 0 && args[0] == 'test') ....

if (b != NULL && b.some_function()) ...

if (b == NULL || b.some_function()) ...

These type of operations show up frequently in real-world code.

2
  • Tfa. How do I explain to my 15 yr olds that 1 & is “harder to read” than 2? I don’t have an example in which the 2 operators don’t work in the same way for Boolean operands. I agree on your point about more readable and easier to maintain code. I want to encourage them to write beautiful code. But having some proof in my bag of tools would be more convincing than “because I said so”. I do have it stated as a standard at that link, and may have to rely on that alone if I don’t get the example I’m looking for. As I asked @Steve Haigh: should java be indicating this as an improper use?
    – Deerasha
    Commented Apr 14, 2011 at 20:04
  • @Deerasha I was thinking more of an argument with your mentor. For the class don't even try to tell them that you can use bitwise operators for logical conditions. Commented Apr 15, 2011 at 18:40
5

You will use bitwise operators if you compare Bitmask enumerations. For example, you have an enumeration of states and an object that can be in more than one of those states. In this case, you'll do a bitwise or to assign more than one state to your object.

for example state = CONNECTED | IN_PROGRESS where CONNECTED could be 0x00000001 and IN_PROGRESS 0x00000010

For more info, look up flag enums documentation.

3
0

a simpler example of wrongness:

int condA=1, condB=2;

if (condA!=0 && condB!=0) {
    // correct!
}
if ((condA & condB)!=0) {
    // never executed
}

here you have two conditions, both are non-zero; but the bitwise & results in zero.

6
  • @Javier: Thank you for answering, but I’m a little confused. I’m working in java, and this code does not compile. (condA && condB) errors, because the && does not work for 2 ints, only 2 booleans. (condA & condB) while correct, evaluates to an int and in java we cannot say if(int) so it errors too. You’re the first to understand what I’m looking for though- exactly that example of wrongness.
    – Deerasha
    Commented Apr 14, 2011 at 19:39
  • haven't used Java in a long time... try (Boolean(condA) && Boolean(condB)) (i think Boolean(x) is true for non-zero integers, right?)
    – Javier
    Commented Apr 14, 2011 at 20:32
  • Nope @Javier: Cannot cast from int to boolean.
    – Deerasha
    Commented Apr 14, 2011 at 20:35
  • what about ((condA!=0) && (condB!=0)) ?
    – Javier
    Commented Apr 14, 2011 at 20:41
  • @Javier yay it compiles, but the "wrongness" is no longer illustrated if (((condA!=0) && (condB!=0))) { System.out.println("correct"); } if (((condA!=0) & (condB!=0))) { System.out.println("never executed?"); } executes both print statements.
    – Deerasha
    Commented Apr 14, 2011 at 21:10

Not the answer you're looking for? Browse other questions tagged or ask your own question.