61

Possible Duplicate:
What is the diffference between the | and || or operators?

Logical AND and OR:

(x & y)
(x | y)

Conditional AND and OR:

(x && y)
(x || y)

I've only known about conditional operands up to this point. I know what it does and how to apply it in if-statements. But what is the purpose of logical operands?

Community
  • 1
  • 1
Sahat Yalkabov
  • 32,654
  • 43
  • 110
  • 175

3 Answers3

86

I prefer to think of it as "bitwise vs. conditional" rather than "logical vs conditional" since the general concept of "logical" applies in both cases.

x & y    // bitwise AND, 0101 & 0011 = 0001
x | y    // bitwise OR,  0101 | 0011 = 0111

x && y   // true if both x and y are true
x || y   // true if either x or y are true

Edit

By popular demand, I should also mention that the arguments are evaluated differently. In the conditional version, if the result of the entire operation can be determined by the first argument, the second argument is not evaluated. This is called short-circuit evaluation. Bitwise operations have to evaluate both sides in order to compute the final value.

For example:

x.foo() && y.bar()

This will only call y.bar() if x.foo() evaluates to true. Conversely,

x.foo() || y.bar()

will only call y.bar() if x.foo() evaluates to false.

Cogwheel
  • 22,781
  • 4
  • 49
  • 67
  • Lazy evaluation is a subset of the logical operations way of operating. Should be mentioned, but is irrelevant to the question. – John Weldon Jun 30 '10 at 23:32
  • 1
    @John Weldon: The question is about the differences between the operators. And laziness surely is one of them. – Dirk Vollmar Jun 30 '10 at 23:44
  • @0xA3, the concept of 'short-circuiting' is specific to a logical operation. It doesn't really apply to bitwise operations except in certain cases. – John Weldon Jun 30 '10 at 23:46
  • @Robert, @0xA3 -- I've retracted most of my opinions and arguments here... see my answer for specifics. – John Weldon Jul 01 '10 at 00:07
  • @Robert Harvey: I tossed this answer up as I was leaving work... Just getting back to it now. I've added an edit per your suggestion :) – Cogwheel Jul 01 '10 at 01:46
  • 1
    Just a note - Logical vs Conditional is Microsoft's naming definitions of them http://msdn.microsoft.com/en-us/library/6a71f45d%28v=vs.80%29.aspx – Mad Halfling Aug 24 '12 at 10:35
  • Sloppy answer because it does not differentiate (enough) between boolean and numerical operands. There are no bitwise operators on booleans in C#. – H H Aug 09 '13 at 16:00
  • @Henk: See the question I'm answering... Data types weren't specified. This is a general concept answer, not a nitpicky details one. – Cogwheel Aug 14 '13 at 00:48
  • 1
    I cam here when this answer was used under another question to 'proof' that `&` is a bitwise boolean operator. There is no general answer, your opening sentence is flat out wrong. – H H Aug 14 '13 at 08:41
  • @Henk: So you voted this answer down because it doesn't apply to a question it wasn't meant to answer?? O.o I suggest you re-read the question that this answer actually applies to. My first sentence is not wrong, it is clearing up a misconception in the original question. – Cogwheel Aug 14 '13 at 17:46
  • The answer is perpetuating the notion of _the_ `&` operator where C# actually has 3. The question is indeed vague too. But in questions that's allowed more. – H H Aug 14 '13 at 18:37
  • First sentence is confusing when Microsoft explicitly refers to them as Logical and Conditional operators. – mallardz Oct 23 '14 at 10:05
  • @mallardz: thanks for the feedback... how about now? – Cogwheel Oct 24 '14 at 15:28
  • Looks good, although you still refer to the 'conditional' && as 'logical' in your second paragraph. I'm more used to bitwise vs logical, but since Microsoft has its own terminology, it should at least be acknowledged. Otherwise people like me get easily confused! – mallardz Oct 24 '14 at 15:55
35
(x && y) 

is lazy. It will only evaluate y if x is true.

(x & y)

is not lazy. y will always be evaluated.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • 1
    This is flat wrong I believe? Can you cite? ( I agree with the first assertion, but not the second) – John Weldon Jun 30 '10 at 23:27
  • 17
    That's only half the story, and arguably the less important half. – Kennet Belenky Jun 30 '10 at 23:27
  • 1
    Sure, but there's more to it than this, no? Supposing x and y are not booleans? Without mentioning the bitwise nature of | and &, this answer is lacking something. – spender Jun 30 '10 at 23:28
  • could whoever is upvoting this post explain? this seems very wrong. – John Weldon Jun 30 '10 at 23:31
  • 3
    @John, it's absolutely correct. When operating on booleans, the only difference is "laziness". Effectively the operation is no different whether operating on booleans or larger integral types. It's doing a bitwise on two single bits and returning a bit. – spender Jun 30 '10 at 23:31
  • 3
    @John That is flat true. From the C# Spec in Section 7.10.3 Boolean logical operators: "The result of x | y is true if either x or y is true. Otherwise, the result is false." Also see Section 7.11 Conditional logical operators: "The operation x || y corresponds to the operation x | y, except that y is evaluated only if x is false." . – Michael Stum Jun 30 '10 at 23:32
  • @John: here is a reference. http://steve-fair-dev.blogspot.com/2007/02/c-lazy-or-full-boolean-evaluation.html – Robert Harvey Jun 30 '10 at 23:32
  • Yes, but the question is about the operators in general not as they apply to *one* type (bool) – John Weldon Jun 30 '10 at 23:33
  • 3
    @Robert, I concede that reference in relation to *booleans*. Surely you agree that the question is more broad than that? – John Weldon Jun 30 '10 at 23:34
  • 1
    @John, for the second, y will always be evaluated regardless of type. – Matthew Flaschen Jun 30 '10 at 23:35
  • 5
    Meh. I think I'll go answer some other questions. – Robert Harvey Jun 30 '10 at 23:35
  • 1
    I absolutely agree about the short-circuit. It's just irrelevant when comparing bitwise vs. logical operators. – John Weldon Jun 30 '10 at 23:36
  • @John, & is not *only* bitwise (which incidentally the question doesn't mention). It is also overloaded as a "boolean logical operator". – Matthew Flaschen Jun 30 '10 at 23:39
  • @Michael; I explicitly stated that I agreed with the fact that the double operator is a short-circuit operator... my real concern is that if you compare logical and bitwise operators (on all types, not a subset), short circuit evaluation is not relevant. – John Weldon Jun 30 '10 at 23:42
  • 1
    @John: I'm pretty sure that short-circuiting is the primary reason one chooses conditional over bitwise operators. – Anon. Jun 30 '10 at 23:47
  • @Anon; and that could be the cause of all the disagreement. It doesn't factor as an important reason to me. Maybe for some people it does. The risk is that choosing a bitwise comparison blindly because it doesn't short-circuit could lead to confusing results if one doesn't realize that it's in fact a bitwise operation. – John Weldon Jun 30 '10 at 23:49
  • 2
    @John: Indeed, I do feel that this post is lacking and only really answers half the question. And I feel the same about the accepted answer. – Anon. Jun 30 '10 at 23:55
  • @Anon, @Michael, @Robert, @Matthew; Updated my answer after reading the spec. – John Weldon Jul 01 '10 at 00:08
  • @John Sorry, I understood it as "I don't agree with the second assertion", rather than "Lazy Evaluation isn't the point of this". I agree that using & and | aren't to be used for these types of "make sure to evaluate all conditions" scenarios, but _this is perfectly legal and acceptable according to the spec_. – Michael Stum Jul 01 '10 at 00:16
  • @Michael; makes sense... my info was misleading. @Robert, it appears SO isn't letting me remove my downvote... My apologies. – John Weldon Jul 01 '10 at 00:20
11

Updated Answer - my original was misleading and incomplete.

First I should apologize for much of my comments and responses to this question.

After reading the spec, the distinction between bitwise and conditional operators is much less clear cut.

According to section 14.10 of ECMA-334:

The &, ^, and | operators are called the logical operators.

for integer operations:

1 The & operator computes the bitwise logical AND of the two operands, the | operator computes the bitwise logical OR of the two operands, and the ^ operator computes the bitwise logical exclusive OR of the two operands. 2 No overflows are possible from these operations.

According to section 14.11:

The && and || operators are called the conditional logical operators. 2 They are also called the "short-circuiting" logical operators.

14.11.1

1 When the operands of && or || are of type bool, or when the operands are of types that do not define an applicable operator & or operator |, but do define implicit conversions to bool, the operation is processed as follows: 2 The operation x && y is evaluated as x ? y : false. 3 In other words, x is first evaluated and converted to type bool. 4 Then, if x is true, y is evaluated and converted to type bool, and this becomes the result of the operation. 5 Otherwise, the result of the operation is false. 6 The operation x || y is evaluated as x ? true : y. 7 In other words, x is first evaluated and converted to type bool. 8 Then, if x is true, the result of the operation is true. 9 Otherwise, y is evaluated and converted to type bool, and this becomes the result of the operation.

14.11.2

1 When the operands of && or || are of types that declare an applicable user-defined operator & or operator |, both of the following must be true, where T is the type in which the selected operator is declared: 2 The return type and the type of each parameter of the selected operator must be T. 3 In other words, the operator must compute the logical AND or the logical OR of two operands of type T, and must return a result of type T. 4 T must contain declarations of operator true and operator false. Paragraph 2 1 A compile-time error occurs if either of these requirements is not satisfied. 2 Otherwise, the && or || operation is evaluated by combining the user-defined operator true or operator false with the selected user-defined operator: 3 The operation x && y is evaluated as T.false(x) ? x : T.&(x, y), where T.false(x) is an invocation of the operator false declared in T, and T.&(x, y) is an invocation of the selected operator &. 4 In other words, x is first evaluated and operator false is invoked on the result to determine if x is definitely false. 5 Then, if x is definitely false, the result of the operation is the value previously computed for x. 6 Otherwise, y is evaluated, and the selected operator & is invoked on the value previously computed for x and the value computed for y to produce the result of the operation. 7 The operation x || y is evaluated as T.true(x) ? x : T.|(x, y), where T.true(x) is an invocation of the operator true declared in T, and T.|(x, y) is an invocation of the selected operator |. 8 In other words, x is first evaluated and operator true is invoked on the result to determine if x is definitely true. 9 Then, if x is definitely true, the result of the operation is the value previously computed for x. 10 Otherwise, y is evaluated, and the selected operator | is invoked on the value previously computed for x and the value computed for y to produce the result of the operation. Paragraph 3 1 In either of these operations, the expression given by x is only evaluated once, and the expression given by y is either not evaluated or evaluated exactly once. Paragraph 4 1 For an example of a type that implements operator true and operator false, see §18.4.2.

John Weldon
  • 39,849
  • 11
  • 94
  • 127