views:

208

answers:

5

Here is the code segments

Can you explain why outputs are varying

1)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t && ((i++) == 0));
        b = (f && ((i+=2) > 0));
        System.out.println(i);      
    }
}

output in this case is 1

2)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t & ((i++) == 0));
        b = (f & ((i+=2) > 0));
        System.out.println(i);      
    }
}

output in this case is 3

3)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t || ((i++) == 0));
        b = (f || ((i+=2) > 0));
        System.out.println(i);      
    }
}

output in this case is 2

4)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t | ((i++) == 0));
        b = (f | ((i+=2) > 0));
        System.out.println(i);      
    }
}

output in this case is 3

+11  A: 

Why is the output different in case of &&, &, || ?

Just as in C/C++ && is evaluated "lazily" while & is not.

If a is false then a && b will return false without even evaluating b.

Same goes for a || b: If the first operand, a is true, the whole expression is true and the second operand, b is never evaluated. For a | b however, both a and b will be evaluated.

This has consequences if the operand that's not being evaluated when using && (or ||) has side effects, as in your examples.


Side note: Few java-programmers know that ^ (xor) works for booleans as well. (A ^^ version does not exist simply because it would be redundant.)

aioobe
+1  A: 

&& and || are the logical AND and OR operators, they always result in a boolean expression. & and | are bitwise AND and OR operators, they do a bitwise comparison of each side. For more information about what those operators do, see this link

Dave McClelland
Downvoter - any explanation why?
Dave McClelland
polygenelubricants
Dave McClelland
+1  A: 

This is because && and || are logical operators which a "short circut mechanism". If you use || and the first expression evaluates to true, the second won't be evaluated and hence i will not be udated. & and | are bitwise operators which do bit calculations on the input. These do not have short circut and hence the entire expression is evaluated no matter what.

Polymorphix
+1  A: 

The & and | operators are bitwise, and thus must have both sides of the expression evaluated before the operator can be used, so in cases 2 and 4 both sides of the operator are always evaluated.

The difference between cases 1 and 3 is based on short-circuit logic.

In case 1 the && operator in the second expression short-circuits as false on the first false, causing the second half of the expression not to be evaluated.

In case 3 the false in the first half of the second expression leads to the evaluation of the second half of the expression, incrementing i. false || expr can only be false if expr is also false (so it must be evaluated).

Mark E
+5  A: 

There are 4 boolean binary operators that we're concerned with here:

  • && is the conditional and operator
    • & is the logical and operator
  • || is the conditional or operator
    • | is the logical or operator

Here's the key point:

  • "conditional" means it short-circuits: it does not evaluate the right operand if it will not affect the result of the operation
  • "logical" does not short-circuit: it evaluates both operands, left first, then right.
  • The result of "and" is true only if both operands are true
    • If the left operand is false, the result is false regardless of right operand
  • The result of "or" is true only if at least one operand is true
    • If the left operand is true, the result is true regardless of right operand

In other words, assuming no exception etc:

  • & and | always evaluate both operands
  • && and || evaluate the right operand conditionally; the right operand is evaluated only if its value could affect the result of the binary operation. That means that the right operand is NOT evaluated when:
    • The left operand of && evaluates to false
      • (because no matter what the right operand evaluates to, the entire expression is false)
    • The left operand of || evaluates to true
      • (because no matter what the right operand evaluates to, the entire expression is true)

References

See also

Related questions

polygenelubricants