Home > front end >  Bitwise operator in java's if condition has to be written inside parentheses. Why is it so?
Bitwise operator in java's if condition has to be written inside parentheses. Why is it so?

Time:01-08

I can't seem to write bitwise operators (e.g. &) without parentheses like other operators (e.g. %, /, , etc.) in if condition in Java.

import java.util.*;

public class alpha{
    public static void main(String args[]){
      Scanner sc = new Scanner(System.in);
      int a = sc.nextInt();
      if ((a&1) == 1) {
          System.out.println("Odd");
      } else{
          System.out.println("Even");
      }
    }
}

This code works, but I want to know why I have to put parentheses around the bitwise operator in order for it to work.

CodePudding user response:

Operator precedence rules. == has higher precedence than & and | and ^.

Why is that? Because == having higher precendence than ||/&& is the right thing to do, and there is a plausible argument that | and & should have a similar precedence level because the operators are similar in looks and meaning.

Read on for a detailed explanation.

What is operator precedence?

Given a § b § c § d where § stands for 'some arbitrary operator', how does the language 'pair up' the expression? Is that to be parsed as (a § b) § (c § d), or ((a § b) § c) § d, or a § (b § (c § d))? Some languages say: Always left to right. But that's not how math itself works; e.g. 5 * 2 10 * 5 is to be read as (5 * 2) (10 * 5) because multiply has higher 'precedence'.

Most programming languages copied 'math' and define sets of operators together in increasing precedence orders. Any operator from a higher precedence level is resolved first. Thus, in java, int x = 5 * 2 10 * 5 results in x having the value 60 ((5 * 2) (10 * 5)), matching common mathematics. Every operator is mentioned in the operator precedence table.

== has higher precedence than &, meaning, these:

  • a & b == c
  • a == b & c

are treated as:

  • a & (b == c)
  • (a == b) & c

Hence, you have to write (a & 1) == 1 because if you don't add the parens, java treats it as a & (1 == 1). Parentheses are the tool you use to 'override' the order in which java is to resolve your chain of operators.

Going one level deeper, why would a language designer set it up like this?

booleans are just values

First, keep in mind when reading this answer that booleans are just values that themselves can have operators applied to them. a == b is a boolean value, and thus, a == b == c is perfectly valid java:

int a = 5;
int b = 10;
boolean c = false;
if (a == b == c) System.out.println("A");

This prints A. Why would a language designer 'allow' it? The question is more: Why would they explicitly disallow it? What would you write in the language specification to make this not possible? An additional restriction that the expressions that are part of an == binary operation are restricted and have to be atomic? That'd be quite annoying; it would mean I couldn't write a b == c d and then you or someone else would be asking a question about: "Why can't I do that"?

Precedence of && and ||

Consider the boolean variants, && and ||. The precedence order actually makes sense. If I write:

if (a == b || c == d) {}

It's rather obvious that the intent is: "If a equals b OR c equals d", and not that the intent is: "Calculate if a is equal to the result of calculating b || c. Then, this value (true) - is that equal to d? That last one is crazy. And yet that's what would happen if &&/|| has higher precedence than ==. Or, that this is to be read as: "Take the true/false value you get by evaluation a == b, then || that with boolean value c, getting you another boolean value. Is that boolean value equal to d?

Hence, giving == higher precedence than && and || is the obvious thing to do, good job, language designers.

Finally: Precedence of &, |, and ^

That finally gets us to the precedence of &, |, and ^. As per the java documentation on operator precedence, they have higher precedence than || and &&, but lower precedence than ==, hence why you need those parentheses.

Why is that? It's tricky. On one hand its sensible to keep their operator precedence 'close' to their && and || variants because & and && feel so similar. On the other hand, in practical use its perhaps more common you'd want them to have higher precedence than ==/!=. There are good reasons for both of these.

Java chose to keep them close to && and || (but, one precedence level 'higher', which is perhaps the larger WTF in this, that seems like an unnecessary amount of separate levels).

Let's go another level.

Why did java choose that wonky precedence order?

Because when java was designed, a lot of business programming was done in C or C . Hence, java by design copies all syntax of C it can without causing problems. And The C operator precedence list should look familiar - it's identical to java's. That's intentional: Java just copied C's list. Why did java do this? Presumably to ensure that java code looked familiar to C coders, making it easier for them to make the decision to learn java. Say what you will about this crazy scheme, it sure seems to have worked. Of all the hundreds of languages around, java 'won'.

So, why does java's operator precedence list look like that? Simple. Because C's did.

Let's go to a third level?

Why is C's list like that?

I don't know. Perhaps you have to ask the designers of C, the language: Dennis Ritchie. He died over a decade ago so that might be tough. Also, I bet he just copied it from B or whatnot.

CodePudding user response:

If i'm not mistaken its because if the ( ) are not there it would read as :

a & (1 == 1) 

Hope this helps.

CodePudding user response:

As explained in other answers, the '==' operator has higher priority than the '&' operator. As also stated, Java inherited this from C. This answer adds a little historical background.

C in its turn got its operator priorities from B. Don't forget that C did not arrive fully-formed; it underwent stages of development. '&' and '|' existed in C, and were used for logical connectives, before the short-circuiting operators '&&' and '||' were added.

Dennis Ritchie has said that, in retrospect, it's a blemish on the current C language to have '==' higher priority than '&' or '|', which they should have fixed when '&&' and '||' were added.

In B one writes if (a==b & c) ... to check whether a equals b and c is non-zero; in such a conditional expression it is better that & have lower precedence than ==. In converting from B to C, one wants to replace & by && in such a statement; to make the conversion less painful, we decided to keep the precedence of the & operator the same relative to ==, and merely split the precedence of && slightly from &. Today, it seems that it would have been preferable to move the relative precedences of & and ==, and thereby simplify a common C idiom: to test a masked value against another value, one must write if ((a&mask) == b) ... where the inner parentheses are required but easily forgotten.

Link: The Development of the C Language.

  • Related