9
votes

Languages like i.e. Java and C# have both bitwise and logical operators.

Logical operators make only sense with boolean operands, bitwise operators work with integer types as well. Since C had no boolean type and treats all non-zero integers as true, the existence of both logical and bitwise operators makes sense there. However, languages like Java or C# have a boolean type so the compiler could automatically use the right kind of operators, depending on the type context.

So, is there some concrete reason for having both logical and bitwise operators in those languages? Or were they just included for familiarity reasons?

(I am aware that you can use the "bitwise" operators in a boolean context to circumvent the short-circuiting in Java and C#, but i have never needed such a behaviour, so i guess it might be a mostly unused special case)

6

6 Answers

6
votes

1) is there some concrete reason for having both logical and bitwise operators in those languages?

Yes:

  • We have boolean operators to do boolean logic (on boolean values).
  • We have bitwise operators to do bitwise logic (on integer values).

2) I am aware that you can use the "bitwise" operators in a boolean context to circumvent the short-circuiting in Java and C#,

For as far as C# goes this simply is not true.
C# has for example 2 boolean AND operators: & (full) and && (short) but it does not allow bitwise operations on booleans.

So, there really is no 'overlap' or redundancy between logical and bitwise operators. The two do not apply to the same types.

3
votes

in C#, with booleans

  • && is a short circuiting logical operator
  • & is a non short circuiting logical operator

bitwise, it just uses & as a legacy syntax from C / C++.... but it's really quite different. If anything, it would be better as a completely different symbol to avoid any confustion. But there aren't really many left, unless you wanted to go for &&& or ||| but thats a bit ugly.

3
votes

Late answer, but I'll try to get to your real point.

You are correct. And the easiest way to make your point is to mention that other typed languages (like Visual Basic) have logical operators that can act on both Boolean and Integer expressions.

VB Or operator: http://msdn.microsoft.com/en-us/library/06s37a7f.aspx

VB Bitwise example: http://visualbasic.about.com/od/usingvbnet/a/bitops01_2.htm

This was very much a language design decision. Java and C# didn’t have to be the way they are. They just are the way they are. Java and C# did indeed inherit much of their syntax from C for the sake of familiarity. Other languages didn’t and work just fine.

A design decision like this has consequences. Short circuit evaluation is one. Disallowing mixed types (which can be confusing for humans to read) is another. I’ve come to like it but maybe I’ve just been staring at Java for too long.

Visual Basic added AndAlso and OrElse as a way to do short circuit evaluation. Unlike basics other logical operators these work only on Booleans.

VB OrElse: http://msdn.microsoft.com/en-us/library/ea1sssb2.aspx

Short-circuit description: http://support.microsoft.com/kb/817250

The distinction wasn’t made because strong typing makes it impossible to only have one set of logic operators in a language. It was made because they wanted short circuit evaluation and they wanted a clear way to signal to the reader what was happening.

The other reason (besides short circuit) that c and c++ have different kinds of logical operators is to allow any non-zero number to be reinterpreted as TRUE and zero reinterpreted as FALSE. To do that they need operators that tell them to interpret that way. Java rejects this whole reinterpret idea and throws an error in your face if you try to do that using it's logical operators. If it wasn’t for short circuit evaluation the only reason left would simply be because they wanted the operators to look different when doing different things.

So yes, if the Java and C# language designers hadn't cared about any of that they could have used one set of logical operators for both bitwise and boolean logic and figured out which to do based on operand type like some other languages do. They just didn't.

2
votes

I'll say for Java

  • Logical operator are user with booleans and bitwise operators are used with ints. They can't be mixed.
  • Why not reduce them to one operator such as "&" or "|"? Java was designed to be friendly for C/C++ users, so it got their syntax. Nowadays these operators cannot be reduced because of backwards compatibility.
2
votes

As you have already said, there's some difference between & and && (the same goes for | and ||) so you need two sets of boolean operators. Now, independently from those above, you may need bitwise operators and the best choice is &, | s.o. since you don't have to avoid any confusion.


Why complicate things and use the two-character version ?

1
votes

compiler cannot infer proper operator looking only at arguments. it's a business decision which one to choose. it's about lazy calculations. e.g.

public boolean a() {
  doStuffA();
  return false;
}

public boolean b() {
  doStuffB();
  return true;
}

and now: a() & b() will execute doStuffB() while a() && b() will not