Why '&&' and Not '&'

Why '&&' and not '&'?

In most cases, && and || are preferred over & and | because the former are short-circuited, meaning that the evaluation is canceled as soon as the result is clear.

Example:

if(CanExecute() && CanSave())
{
}

If CanExecute returns false, the complete expression will be false, regardless of the return value of CanSave. Because of this, CanSave is not executed.

This is very handy in the following circumstance:

string value;
if(dict.TryGetValue(key, out value) && value.Contains("test"))
{
// Do Something
}

TryGetValue returns false if the supplied key is not found in the dictionary. Because of the short-circuiting nature of &&, value.Contains("test") is only executed, when TryGetValue returns true and thus value is not null. If you would use the bitwise AND operator & instead, you would get a NullReferenceException if the key is not found in the dictionary, because the second part of the expression is executed in any case.

A similar but simpler example of this is the following code (as mentioned by TJHeuvel):

if(op != null && op.CanExecute())
{
// Do Something
}

CanExecute is only executed if op is not null. If op is null, the first part of the expression (op != null) evaluates to false and the evaluation of the rest (op.CanExecute()) is skipped.

Apart from this, technically, they are different, too:

&& and || can only be used on bool whereas & and | can be used on any integral type (bool, int, long, sbyte, ...), because they are bitwise operators. & is the bitwise AND operator and | is the bitwise OR operator.

To be very exact, in C#, those operators (&, | [and ^]) are called "Logical operators" (see the C# spec, chapter 7.11). There are several implementations of these operators:

  1. For integers (int, uint, long and ulong, chapter 7.11.1):

    They are implemented to compute the bitwise result of the operands and the operator, i.e. & is implement to compute the bitwise logical AND etc.
  2. For enumerations (chapter 7.11.2):

    They are implemented to perform the logical operation of the underlying type of the enumeration.
  3. For bools and nullable bools (chapter 7.11.3 and 7.11.4):

    The result is not computed using bitwise calculations. The result is basically looked up based on the values of the two operands, because the number of possibilities is so small.

    Because both values are used for the lookup, this implementation isn't short-circuiting.

Usage of '&' versus '&&'

& is a bitwise AND, meaning that it works at the bit level. && is a logical AND, meaning that it works at the boolean (true/false) level. Logical AND uses short-circuiting (if the first part is false, there's no use checking the second part) to prevent running excess code, whereas bitwise AND needs to operate on every bit to determine the result.

You should use logical AND (&&) because that's what you want, whereas & could potentially do the wrong thing. However, you would need to run the second method separately if you wanted to evaluate its side effects:

var check = CheckSomething();
bool IsValid = isValid && check;

What is the difference between & and && in Java?

& <-- verifies both operands

&& <-- stops evaluating if the first operand evaluates to false since the result will be false

(x != 0) & (1/x > 1) <-- this means evaluate (x != 0) then evaluate (1/x > 1) then do the &. the problem is that for x=0 this will throw an exception.

(x != 0) && (1/x > 1) <-- this means evaluate (x != 0) and only if this is true then evaluate (1/x > 1) so if you have x=0 then this is perfectly safe and won't throw any exception if (x != 0) evaluates to false the whole thing directly evaluates to false without evaluating the (1/x > 1).

EDIT:

exprA | exprB <-- this means evaluate exprA then evaluate exprB then do the |.

exprA || exprB <-- this means evaluate exprA and only if this is false then evaluate exprB and do the ||.

Why '&&' and not '&'?

In most cases, && and || are preferred over & and | because the former are short-circuited, meaning that the evaluation is canceled as soon as the result is clear.

Example:

if(CanExecute() && CanSave())
{
}

If CanExecute returns false, the complete expression will be false, regardless of the return value of CanSave. Because of this, CanSave is not executed.

This is very handy in the following circumstance:

string value;
if(dict.TryGetValue(key, out value) && value.Contains("test"))
{
// Do Something
}

TryGetValue returns false if the supplied key is not found in the dictionary. Because of the short-circuiting nature of &&, value.Contains("test") is only executed, when TryGetValue returns true and thus value is not null. If you would use the bitwise AND operator & instead, you would get a NullReferenceException if the key is not found in the dictionary, because the second part of the expression is executed in any case.

A similar but simpler example of this is the following code (as mentioned by TJHeuvel):

if(op != null && op.CanExecute())
{
// Do Something
}

CanExecute is only executed if op is not null. If op is null, the first part of the expression (op != null) evaluates to false and the evaluation of the rest (op.CanExecute()) is skipped.

Apart from this, technically, they are different, too:

&& and || can only be used on bool whereas & and | can be used on any integral type (bool, int, long, sbyte, ...), because they are bitwise operators. & is the bitwise AND operator and | is the bitwise OR operator.

To be very exact, in C#, those operators (&, | [and ^]) are called "Logical operators" (see the C# spec, chapter 7.11). There are several implementations of these operators:

  1. For integers (int, uint, long and ulong, chapter 7.11.1):

    They are implemented to compute the bitwise result of the operands and the operator, i.e. & is implement to compute the bitwise logical AND etc.
  2. For enumerations (chapter 7.11.2):

    They are implemented to perform the logical operation of the underlying type of the enumeration.
  3. For bools and nullable bools (chapter 7.11.3 and 7.11.4):

    The result is not computed using bitwise calculations. The result is basically looked up based on the values of the two operands, because the number of possibilities is so small.

    Because both values are used for the lookup, this implementation isn't short-circuiting.

What's the difference between & and && in JavaScript?

& is bitwise AND

This operator is almost never used in JavaScript. Other programming languages (like C and Java) use it for performance reasons or to work with binary data. In JavaScript, it has questionable performance, and we rarely work with binary data.

This operator expects two numbers and retuns a number. In case they are not numbers, they are cast to numbers.

How does it work? Wikipedia has an answer: https://en.wikipedia.org/wiki/Bitwise_operation#AND

&& is logical AND

Most usually, programmers use this operator to check if both conditions are true, for example:

true && true        // returns true
true && false // returns false

However, in JavaScript, it is extended to allow any data type and any number of terms. It returns:

  • First term that evaluates to false
  • Last term otherwise (if all are true-y)

Here are some examples:

true && false && true         // returns false
true && 20 && 0 && false // returns 0 (it is first false-y)
10 && "Rok" && true && 100 // returns 100 (as all are true-y)

&& short-circuiting

As can be seen from above, as soon as you find one that term is false-y, you needn't to care about the following terms. This allows Javascript to stop evaluation altogether. This is called short circuiting.

This statement doesn't alert anything and false is returned:

true && false && alert("I am quiet!")     // returns false

Therefore, you could use the && operator as a shorter replacement for an if statement. These are equivalent:

if (user.isLoggedIn()) alert("Hello!")
user.isLoggedIn() && alert("Hello!")

Almost all JS compressors use this trick to save 2 bytes.

Boolean operators && and ||

The shorter ones are vectorized, meaning they can return a vector, like this:

((-2:2) >= 0) & ((-2:2) <= 0)
# [1] FALSE FALSE TRUE FALSE FALSE

The longer form evaluates left to right examining only the first element of each vector, so the above gives

((-2:2) >= 0) && ((-2:2) <= 0)
# [1] FALSE

As the help page says, this makes the longer form "appropriate for programming control-flow and [is] typically preferred in if clauses."

So you want to use the long forms only when you are certain the vectors are length one.

You should be absolutely certain your vectors are only length 1, such as in cases where they are functions that return only length 1 booleans. You want to use the short forms if the vectors are length possibly >1. So if you're not absolutely sure, you should either check first, or use the short form and then use all and any to reduce it to length one for use in control flow statements, like if.

The functions all and any are often used on the result of a vectorized comparison to see if all or any of the comparisons are true, respectively. The results from these functions are sure to be length 1 so they are appropriate for use in if clauses, while the results from the vectorized comparison are not. (Though those results would be appropriate for use in ifelse.

One final difference: the && and || only evaluate as many terms as they need to (which seems to be what is meant by short-circuiting). For example, here's a comparison using an undefined value a; if it didn't short-circuit, as & and | don't, it would give an error.

a
# Error: object 'a' not found
TRUE || a
# [1] TRUE
FALSE && a
# [1] FALSE
TRUE | a
# Error: object 'a' not found
FALSE & a
# Error: object 'a' not found

Finally, see section 8.2.17 in The R Inferno, titled "and and andand".



Related Topics



Leave a reply



Submit