Firstly I learnt that &
, |
, ^
are the bitwise operators, and now somebody mentioned them as logical operators with &&
, ||
, I am completely confused - the same operator has two names? There are already logical operators &&
, ||
, then why use &
, |
, ^
?

- 190,393
- 28
- 405
- 485

- 4,021
- 15
- 43
- 54
-
See also: http://stackoverflow.com/questions/11411907 – assylias Jul 22 '12 at 12:55
4 Answers
The Java operators &
, |
and ^
are EITHER bitwise operators OR logical operators ... depending on the types of the operands. If the operands are integers, the operators are bitwise. If they are booleans, then the operators are logical.
And this is not just me saying this. The JLS describes these operators this way too; see JLS 15.22.
(This is just like +
meaning EITHER addition OR string concatenation ... depending on the types of the operands. Or just like a "rose" meaning either a flower or a shower attachment. Or "cat" meaning either a furry animal or a UNIX command. Words mean different things in different contexts. And this is true for the symbols used in programming languages too.)
There are already logical operators
&&
,||
, why use&
,|
,^
?
In the case of the first two, it is because the operators have different semantics with regards to when / whether the operands get evaluated. The two different semantics are needed in different situations; e.g.
boolean res = str != null && str.isEmpty();
versus
boolean res = foo() & bar(); // ... if I >>need<< to call both methods.
The ^
operator has no short-circuit equivalent because it simply doesn't make sense to have one.

- 698,415
- 94
- 811
- 1,216
-
3@Crackers Check an example here, bitwise operator as logical operator, albeit non-short-circuited: http://www.anicehumble.com/2012/05/operator-precedence-101.html Don't forget to read about **Neonatal C**, the rationale is there http://cm.bell-labs.com/who/dmr/chist.html – Michael Buen Jul 22 '12 at 05:57
-
@Crackers He's already answered that. boolean => logical, integer => bitwise. – user207421 Jul 22 '12 at 08:34
Having a language reference is one thing, interpreting it correctly is another.
We need to interpret things correctly.
Even if Java documented that &
is both bitwise and logical, we could make an argument that &
really didn't lost its logical-operator-ness mojo since time immemorial, since C. That is, &
is first and foremost, an inherently logical operator(albeit a non-short-circuited one at that)
&
parses lexically+logically as logical operation.
To prove the point, both of these lines behaves the same, eversince C and upto now(Java, C#, PHP, etc)
if (a == 1 && b)
if (a == 1 & b)
That is, the compiler will interpret those as these:
if ( (a == 1) && (b) )
if ( (a == 1) & (b) )
And even if both variables a
and b
are both integers. This...
if (a == 1 & b)
... will still be interpereted as:
if ( (a == 1) & (b) )
Hence, this will yield a compilation error on languages which doesn't facilitate integer/boolean duality, e.g. Java and C#:
if (a == 1 & b)
In fact, on the compilation error above, we could even make an argument that &
didn't lost its logical(non-short-circuit) operation mojo, and we can conclude that Java continues the tradition of C making the &
still a logical operation. Consequently, we could say it's the other way around, i.e. the &
can be repurposed as bitwise operation (by applying parenthesis):
if ( a == (1 & b) )
So there we are, in another parallel universe, someone could ask, how to make the &
expression become a bitmask operation.
How to make the following compile, I read in JLS that
&
is a bitwise operation. Both a and b are integers, but it eludes me why the following bitwise operation is a compilation error in Java:if (a == 1 & b)
Or this kind of question:
Why the following didn't compile, I read in JLS that
&
is a bitwise operation when both its operands are integers. Both a and b are integers, but it eludes me why the following bitwise operation is a compilation error in Java:if (a == 1 & b)
In fact, I would not be surprised if there's already an existing stackoverflow questions similar to above questions that asked how to do that masking idiom in Java.
To make that logical operation interpretation by the language become bitwise, we have to do this (on all languages, C, Java, C#, PHP, etc):
if ( a == (1 & b) )
So to answer the question, it's not because JLS defined things such way, it's because Java(and other languages inspired by C)'s &
operator is for all intents and purposes is still a logical operator, it retained C's syntax and semantics. It's the way it is since C, since time immemorial, since before I was even born.
Things just don't happen by chance, JLS 15.22 didn't happen by chance, there's a deep history around it.
In another parallel universe, where &&
was not introduced to the language, we will still be using &
for logical operations, one might even ask a question today:
Is it true, we can use the logical operator
&
for bitwise operation?
&
doesn't care if its operands are integers or not, booleans or not. It's still a logical operator, a non-short-circuited one. And in fact, the only way to force it to become a bitwise operator in Java(and even in C) is to put parenthesis around it. i.e.
if ( a == (1 & b) )
Think about it, if &&
was not introduced to C language(and any language who copied its syntax and semantics), anyone could be asking now:
how to use
&
for bitwise operations?
To sum it up, first and foremost Java &
is inherently a logical operator(a non-short-circuited one), it doesn't care about its operands, it will do its business as usual(applying logical operation) even if both operands are integers(e.g. masking idiom). You can only force it to become bitwise operation by applying parenthesis. Java continues the C tradition
If Java's &
really is a bitwise operation if its operands(integer 1 and integer variable b
on example code below) are both integers, this should compile:
int b = 7;
int a = 1;
if (a == 1 & b) ...

- 38,643
- 9
- 94
- 118
-
Those who don't know history are doomed to just cite the [language reference](http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.22) – Michael Buen Jul 23 '12 at 19:25
-
1My response to this is the same as to the other answer. I am aware that Java has antecedents in C / C++. But the real reason that the Java & and | operators are the way they are is because they *work*. In fact, since they DIDN'T borrow the C / C++ semantics, they actually work BETTER than C / C++ ... in the sense that they are simpler, easier to understand, and less fragile. This also means that describing the Java operators in terms of their history doesn't actually 1) answer the question, or 2) help in understanding. (And using confused terminology doesn't help either.) – Stephen C Aug 18 '12 at 03:45
-
And here's a counter example for your assertion that Java `&` and `|` are "inherently" logical. `a = b & 42;` There is no typing of `a` or `b` such that `&` is a logical operator. I'm sorry, but your argument simply does not hold water, and placing whole paragraphs in bold doesn't alter that. – Stephen C Aug 18 '12 at 03:52
-
@StephenC I'm saying it in context of logical operation only, e.g. on if statement. While inside of condtional expression, there's nothing inherent on the operands type that will make the `&` become an integer(e.g. masking idiom) or logical operation. `&` always parses as logical operation while inside of conditional expressions. Only parenthesizing the operands will make it an integer operation one. Don't put me out of context m'kay? – Michael Buen Aug 18 '12 at 10:19
-
What's my confused terminology by the way? I would be glad to learn that :-) Using the right terminologies makes for effective communication – Michael Buen Aug 18 '12 at 10:30
-
11) This question is not about the operators in `if`. It is about the operators in all contexts in Java. 1a) and the JLS does not make an arbitrary distinction between the contexts in its terminology 2) The confused terminology comment refers to the fact that you are contradicting what the JLS says. That makes your terminology wrong and confusing in the Java context. What the JLS says is **definitive**. – Stephen C Aug 19 '12 at 01:52
-
If you go back to the original question, you will see that the problem is that the OP was **confused** by seemingly contradictory terminology that different people are using. The only solution to that confusion is to point out what the JLS actually says about this, and use its (consistent) terminology. – Stephen C Aug 19 '12 at 02:02
-
@StephenC Thanks for clearing those (RE: in all contexts) up for me. I dwell too much on `&`'s corner case on conditional expression only,that I **almost** forgot that my assertion on `&`'s inherent logical nature contradicted the assignment statement. Next time I encounter a question about confusion on logical and bitwise (regardless of context) operations,I'll just refer them to your answer. Though I hope that JLS specification should at least pointed out the `&`'s integer operands(`b` and `42` are both integers) corner case when it is inside a conditional expression, e.g. `if(a == b & 42`) – Michael Buen Aug 19 '12 at 07:13
-
@StephenC Had JLS pointed out the `&`'s integer operands corner case: http://ideone.com/b4Nap (will not compile), that will make the specification truly **definitive**. Integer operands on arithmetic operator works: http://ideone.com/PQ4R1 (compiles). +1'd your answer now ツ – Michael Buen Aug 19 '12 at 07:17
-
I wouldn't advocate changing the JLS like that. The purpose of the JLS is to be a specification rather than a tutorial on Java, or on PL concepts. – Stephen C Aug 19 '12 at 07:33
-
@StephenC I would rather have it mentioned even in just a short snippet in the specification. Sometimes, corner cases can bite us in the foot when the problem was caught only by the time the user uses our app, an example: http://stackoverflow.com/questions/194484/whats-the-strangest-corner-case-youve-seen-in-c-sharp-or-net/847353#847353 The corner case on Java's `&`(when it's in the conditional expression) is just mildly surprising though as it can be caught by the language during development anyway. It won't shoot you in the foot,unlike languages like C which has a boolean/integer duality – Michael Buen Aug 19 '12 at 07:53
-
How I see it, the only reason why that code does not compile is because `==` takes precedence over `&`. The result is that the left hand side of `&` is a boolean, and _not_ an integer. So in your last paragraph you are basically saying that for `&` to be 'really a bitwise operation in Java', it should take precedence over `==`? – NickL Dec 30 '17 at 18:28
They(&
and |
) were used for two purposes long time ago, logical operator and bitwise operator. If you'll check out the neonatal C (the language Java was patterned after), &
and |
were used as logical operator.
But since disambiguating the bitwise operations from logical operations in the same statement is very confusing, it prompted Dennis Ritchie to create a separate operator(&&
and ||
) for logical operator.
Check the Neonatal C section here: http://cm.bell-labs.com/who/dmr/chist.html
You can still use the bitwise operators as logical operators, its retained operator precedence is the evidence of that. Read out the history of bitwise operator's past life as logical operator on Neonatal C
Regarding the evidence, I made a blog post on comparing the logical operator and bitwise operator. It will be self-evident that the so called bitwise operators are still logical operators if you try contrasting them in an actual program: http://www.anicehumble.com/2012/05/operator-precedence-101.html
I also answered a question related to your question on What is the point of the logical operators in C?
So it's true, bitwise operators are logical operators too, albeit non-short-circuited version of short-circuited logical operators.
Regarding
There are already logical operators &&, ||, then why use &, |, ^?
The XOR can be easily answered, it's like a radio button, only one is allowed, code below returns false. Apology for the contrived code example below, the belief that drinking both beer and milk at the same time is bad was debunked already ;-)
String areYouDiabetic = "Yes";
String areYouEatingCarbohydrate = "Yes";
boolean isAllowed = areYouDiabetic == "Yes" ^ areYouEatingCarbohydrate == "Yes";
System.out.println("Allowed: " + isAllowed);
There's no short-circuit equivalent to XOR bitwise operator, as both sides of the expression are needed be evaluated.
Regarding why the need to use &
and |
bitwise operators as logical operators, frankly you'll be hard-pressed to find a need to use bitwise operators(a.k.a. non-short-circuit logical operators) as logical operators. A logical operation can be non-short-circuited (by using the bitwise operator, aka non-short-circuited logical operator) if you want to achieve some side effect and make your code compact(subjective), case in point:
while ( !password.isValid() & (attempts++ < MAX_ATTEMPTS) ) {
// re-prompt
}
The above can re-written as the following(removing the parenthesis), and still has exactly the same interpretation as the preceding code.
while ( !password.isValid() & attempts++ < MAX_ATTEMPTS ) {
// re-prompt
}
Removing the parenthesis and yet it still yields the same interpretation as the parenthesized one, can make the logical operator vestige of &
more apparent. To run the risk of sounding superfluous, but I have to emphasize that the unparenthesized expression is not interpreted as this:
while ( ( !password.isValid() & attempts++ ) < MAX_ATTEMPTS ) {
// re-prompt
}
To sum it up, using &
operator (more popularly known as bitwise operator only, but is actually both bitwise and logical(non-short-circuited)) for non-short-circuit logical operation to achieve side effect is clever(subjective), but is not encouraged, it's just one line of savings effect in exchange for readability.
Example sourced here: Reason for the exsistance of non-short-circuit logical operators

- 1
- 1

- 38,643
- 9
- 94
- 118
-
-1: This is more about C and its history, not about Java specifics. The wording in Java _is_ a little bit different and does not carry _so much_ of the history of C. – A.H. Jul 22 '12 at 07:55
-
This answer is mostly incorrect and mostly off topic. The && and || operators were invented by John McCarthy, and they aren't in C just to reduce confusion: they do different things from & and |. – user207421 Jul 22 '12 at 08:36
-
@A.H. and EJP The same principle applies, Java inherits C's operators and their precedence intact, Java didn't deviate from it. The same principle applies. I just provide a backgrounder why Java bitwise operator is also a logical operator, it can be traced back to C – Michael Buen Jul 22 '12 at 10:11
-
@EJP Thanks for knowing that (McCarthy operator), I didn't purport that `&&` was invented(it's very trivial to begin with to be even called **invention**, you have to come up with a language token for a short-circuit operator one way or another) by Dennis Ritchie, he introduced it into the language to reduce confusion, it's not wise to re-invent(to think of another token for short-circuit operator) the wheel, isn't it? – Michael Buen Jul 22 '12 at 10:24
-
@MichaelBuen: Java differs from C, that there is a distinct boolean type. Hence the distinction between _pure logical_ and _pure bitwise_ is mood in Java. – A.H. Jul 22 '12 at 10:32
-
If Java don't have any affinity with C operator rules and precedence, the following expression would be invalid (you cannot do an XOR between "YES" and value): `areYouDiabetic == "Yes" ^ areYouEatingCarbohydrate == "Yes"`, but since Java share the same rules as C's operators, that expression is valid. I would dig back more why the bitwise operators can be used as logical operator, if bitwise operators behaves the same as arithmetic operators precedence (`+`,`*`,`-`,`/`), that expression shall be invalid, no one will even mention to the OP that bitwise operator can be used as logical operator – Michael Buen Jul 22 '12 at 10:32
-
@A.H. Even Java has a first-class boolean, it shares the same rules as C's bitwise operator and logical operator. Hence Java's bitwise operator can be repurposed as logical operator, the same as C. The code I provided in my answer is a Java code, and a valid one at that. – Michael Buen Jul 22 '12 at 10:38
-
Read the JLS: There `&` is a bitwise op for integers and a logical for booleans. In C it is simply a bitwise op in any case. Second: In Java there is no `&&` for non-boolean type. For booleans they are called "conditional". In C... they are called differently and so on... – A.H. Jul 22 '12 at 10:45
-
@A.H. Exactly my point, Java's `&` can be used for boolean/logical operations. And I go extra mile for the answer, repurposing Java's `&` to boolean didn't just happen like that. If Java didn't adopt C's `&` operator precedence, we will not be able to use Java's `&` for non-short-circuit logical operation(any logical operation for that matter). If Java didn't adopt C's operator precedence, this will not be a valid Java construct: `int i = 7; j = 8; boolean isOk = i == 7 & j == 8;` – Michael Buen Jul 22 '12 at 10:58
-
@MichaelBuen - I suggest you read the JLS link in my answer. It clearly states that there are two distinct `&` operators, not one operator used for two different things. – Stephen C Jul 22 '12 at 11:14
-
@StephenC I already know that, what I provided is the background why Java's `&` can even be used as logical operator in the first place – Michael Buen Jul 22 '12 at 11:17
-
@MichaelBuen - I'm afraid that that "background" is largely a construct of your imagination. Java's `&` logical operator can be used as a logical operator because it is defined that way. Likewise for the `&` bitwise operator. Clearly, Java borrowed the syntax from C, but it did NOT borrow the semantics, as illustrated by the fact that you cannot mix boolean and integer operands in Java – Stephen C Jul 22 '12 at 11:25
-
@StephenC I know that you cannot mix boolean and integer operands in Java (I'm using both C# and Java), what I'm saying is if C didn't retain the operator precedence of `&`, and likewise if Java didn't adopt it, the following will not be a valid construct, if `&` is interpreted like arithmetic operator, this: `boolean isOk = i == 7 & j == 8;` will be interpreted as `boolean isOk = (i == (7 & j)) == 8;` Not a valid construct. Go figure. – Michael Buen Jul 22 '12 at 11:31
-
@Crackers - 1) I didn't downvote this, or your answer. 2) It is NOT YOUR PLACE to tell me how I should vote. – Stephen C Jul 23 '12 at 02:10
-
@Crackers - on the substantive point. Yes, I am aware that Java has antecedents in C / C++. But the real reason that the Java `&` and `|` operators are the way they are is because they *work*. In fact, since they DIDN'T borrow the C / C++ semantics, they actually work BETTER than C / C++ ... in the sense that they are simpler, easier to understand, and less fragile. And this means that describing the Java operators in terms of their history doesn't actually 1) answer the question, or 2) help in understanding. (And using confused terminology doesn't help either.) – Stephen C Jul 23 '12 at 02:32
-
@StephenC Look at the following answer, it will give you another **"background"** http://stackoverflow.com/questions/11597978/are-the-bitwise-operators-or-logical-operators/11611743#11611743 – Michael Buen Jul 23 '12 at 19:14
The Java type byte is signed which might be a problem for the bitwise operators. When negative bytes are extended to int or long, the sign bit is copied to all higher bits to keep the interpreted value. For example:
byte b1=(byte)0xFB; // that is -5
byte b2=2;
int i = b1 | b2<<8;
System.out.println((int)b1); // This prints -5
System.out.println(i); // This prints -5
Reason: (int)b1 is internally 0xFFFB and b2<<8 is 0x0200 so i will be 0xFFFB
Solution:
int i = (b1 & 0xFF) | (b2<<8 & 0xFF00);
System.out.println(i); // This prints 763 which is 0x2FB

- 11
- 3