I am trying to understand the difference between & and &&operators in C#. I searched on the internet without success. Can somebody please explain with an example?
& is the bitwise AND operator. For operands of integer types, it'll calculate the bitwise-AND of the operands and the result will be an integer type. For boolean operands, it'll compute the logical-and of operands. && is the logical AND operator and doesn't work on integer types. For boolean types, where both of them can be applied, the difference is in the "short-circuiting" property of &&. If the first operand of && evaluates to false, the second is not evaluated at all. This is not the case for &:
bool f() {
Console.WriteLine("f called");
return false;
}
bool g() {
Console.WriteLine("g called");
return false;
}
static void Main() {
bool result = f() && g(); // prints "f called"
Console.WriteLine("------");
result = f() & g(); // prints "f called" and "g called"
}
|| is similar to && in this property; it'll only evaluate the second operand if the first evaluates to false.
Of course, user defined types can overload these operators making them do anything they want.
Strongly recommend this article from Dotnet Mob : http://codaffection.com/csharp-article/short-circuit-evaluation-in-c/
-&& is short-circuit logical operator
For AND operations if any of the operand evaluated to false then total expression evaluated to false, so there is no need to evaluate remaining expressions, similarly in OR operation if any of the operand evaluated to true then remaining evaluation can be skipped
-& operator can be used as either unary or binary operator. that is, unary & can be used to get address of it’s operand in unsafe context.
& can be used on either integral types (like int, long etc.) or on bool.
When used on an integral type, it performs a bitwise AND and gives you the result of that. When used on a bool, it performs a logical AND on BOTH its operands and gives you the result.
&& is not used as a bitwise AND. It is used as a logical AND, but it does not necessarily check both its operands. If the left operand evaluates to false, then it doesn't check the right operand.
Example where this matters:
void Action()
{
string name = null;
if(name != null && name.EndsWith("ack"))
{
SomeOtherAction();
}
}
If name is null, then name.EndsWith("ack") will never get executed. It is smart enough to know if the left operand is false, then the right operand doesn't need to be evaluated (aka "short-circuiting"). That's good because calling a method on null will throw a NullReferenceException.
If you changed it into if(name != null & name.EndsWith("ack")), both sides would get evaluated and it would throw a NullReferenceException.
One detail: & can also be a unary operator (so it has one operand) in an unsafe context. It will give the address of a value or object. It's not important though, as most people don't ever have to touch this part of the language.
Below example and explanation's may help.
Example:
public static bool Condition1()
{
Console.WriteLine("Condition1 is evaluated.");
return false;
}
public static bool Condition2()
{
Console.WriteLine("Condition2 is evaluated.");
return true;
}
1. Logical Operator
& (ampersand) Logical AND operator
| (pipeline) Logical OR operator
Used for ensuring all operands are evaluated.
if(Condition1() & Condition2())
{
Console.WriteLine("This will not print");
//because if any one operand evaluated to false ,
//thus total expression evaluated to false , but both are operand are evaluated.
}
if (Condition2() | Condition1())
{
Console.WriteLine("This will print");
//because any one operand evaluated to true ,
//thus total expression evaluated to true , but both are operand are evaluated.
}
2. Conditional Short Circuit Operator
&& (double ampersand) Conditional AND operator
|| (double pipeline) Conditional OR operator
Used for Skipping the right side operands , Has Side effects so use carefully
if (Condition1() && Condition2())
{
Console.WriteLine("This will not print");
//because if any one operand evaluated to false,
//thus total expression evaluated to false ,
//and here the side effect is that second operand is skipped
//because first operand evaluates to false.
}
if (Condition2() || Condition1())
{
Console.WriteLine("This will print");
//because any one operand evaluated to true
//thus remaining operand evaluations can be skipped.
}
Note:
To get better understanding test it in console sample.
References
dotnetmob.com
wikipedia.org
stackoverflow.com
& is a bitwise operator and && is a logical operator that applies to bool operands.
Easy way to look it is logical & will evaluate both sides of the & regardless if the left side is false, whereas the short-circuit && will only evaluate the right side if the left is true.
d=0;
n=10;
// this throws divide by 0 exception because it evaluates the
// mod even though "d != 0" is false
if ( (d != 0) & (n % d) == 0 )
Console.Writeline( d + " is a factor of " + n);
// This will not evaluate the mod.
if ( (d != 0) && (n % d) == 0 )
Console.Writeline( d + " is a factor of " + n);
The first one is bitwise and the second one is boolean and.
According to - C# 4.0 The Complete Reference by Herbert Schildt
& - Logical AND Operator
| - Logical OR Operator
&& - Short Circuited AND Operator
|| - Short Circuited OR Operator
A simple example can help understand the phenomena
using System;
class SCops {
static void Main() {
int n, d;
n = 10;
d = 2;
if(d != 0 && (n % d) == 0)
Console.WriteLine(d + " is a factor of " + n);
d = 0; // now, set d to zero
// Since d is zero, the second operand is not evaluated.
if(d != 0 && (n % d) == 0)
Console.WriteLine(d + " is a factor of " + n);
// Now, try the same thing without the short-circuit operator.
// This will cause a divide-by-zero error.
if(d != 0 & (n % d) == 0)
Console.WriteLine(d + " is a factor of " + n);
}
}
Here the & operator checks each and every operand and && checks only the first operand.
As you might notice for 'AND' operations any operand which is false will evaluate the whole expression to false irrespective of any other operands value in the expression.
This short circuited form helps evaluate the first part and is smart enough to know if the second part will be necessary.
Running the program will throw a divide-by-zero error for the last if condition where both the operands are checked for & operator and no exception handling is done to tackle the fact that 'd' can be 0 at any point of time.
The same case applies to '|' in C#.
This is slightly different than C or C++ where '&' and '|' were bitwise AND and OR operators. However C# also applies the bitwise nature of & and | for int variables only.
Hai Friend,
The Operator &&(Logical Operator) is used in conditional statements.
For Instance
if(firstName == 'Tilsan' && lastName == 'Fighter')
{
Response.Write("Welcome Tilsan The Fighter!");
}
the Response.Write statement will run only if both variables firstName and lastName match to their condition.
Whereas & (Bitwise Operator)operator is used for Binary AND operations, i.e., if we write:
bool a, b, c;
a = true;
b = false;
c = a & b;
Response.Write(c); // 'False' will be written to the web page
Here first Binary And operation will be performed on variables a and b, and the resultant value will be stored in variable c.
Related
This question already has answers here:
Usage of '&' versus '&&'
(4 answers)
Closed 1 year ago.
If I have
if (false && true)
...
can I be sure that every computer/compiler/whatever will do the shortcut that ignores the second condition? In my implementation, the second condition assumes that the first is true, otherwise it will cause a fatal error. For example:
if (Foobar is BoolContainer && Foobar.BoolVar)
...
where BoolContainer is an example class with a boolean property BoolVar.
MSDN states(https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators):
The conditional logical AND operator &&, also known as the "short-circuiting" logical AND operator, computes the logical AND of its operands. The result of x && y is true if both x and y evaluate to true. Otherwise, the result is false. If x evaluates to false, y is not evaluated.
So your assumption is correct. Though you should be careful when you use &:
The & operator computes the logical AND of its operands. The result of x & y is true if both x and y evaluate to true. Otherwise, the result is false.
The & operator evaluates both operands even if the left-hand operand evaluates to false, so that the operation result is false regardless of the value of the right-hand operand.
You might get unwanted evaluation when you use &.
There is an extreme edge case where && won't necessarily do what you expect. You won't experience this in normal code. ;)
In the below code both booleans will output as True, but if you && them the result will (on some versions of .NET, but not all) not be True (because true2 is an "unusual" true).
Again, this is not something you will ever experience in real life.
namespace MyNamespace
{
using System;
using System.Runtime.InteropServices;
namespace Work
{
[StructLayout(LayoutKind.Explicit)]
public struct HackedBoolean
{
[FieldOffset(0)] public int value;
[FieldOffset(0)] public bool boolean;
public bool GetBool(int seed)
{
value = seed;
return boolean;
}
}
public class MyClassCS
{
public static void Main(string[] args)
{
var hacked = new HackedBoolean();
var true1 = hacked.GetBool(1);
var true2 = hacked.GetBool(2);
Console.WriteLine(true1);
Console.WriteLine(true2);
Console.WriteLine(true1 && true2);
Console.WriteLine(true1 == true2);
Console.ReadLine();
}
}
}
}
Yes it is safe.
If you want both sides to be evaluated you can use & instead of &&.
Otherwise it will skip second condition in this case.
As per the documentation of Conditional Logical ANN operator && on MSDN condition using && operator evaluates to true only when all the conditions evaluates to true.
If any of the conditions evaluates to false, the entire evaluations results as false.
while evaluating the conditions from left to right, next condition is not evaluated if the previous one evaluates to false.
Yes, it is guaranteed by the language specification:
The operation x && y corresponds to the operation x & y, except that y is evaluated only if x is not false.
In my experience it is a very common idiom for the second part of a short-circuiting conditional expression like this to rely on this behavior.
You might be wondering about why it says "not false" instead of "true". For a bool type, these two are equivalent. At first I thought it was because bool? had a lifted operator to deal with null, but this is not the case. But you can do something similar with a type that overloads the true, false, &, and | operators, and in fact the spec provides the DBBool example struct which does just that.
How does it work?
public class Node
{
Node Left ;
Node Right ;
}
...
var a = new Node();
var b = new Node();
if (a.Right == b.Right == null) // <- compiles and resharper says it's always false
{
}
var aa = 1;
var bb = 2;
if (aa == bb == 0) // doesn't compile Cannot apply operator '==' to operands of type 'bool' and 'int'
{
}
Why do multiple comparands work with 'Node' and doesn't work with 'Int'?
An expression like
a == b == c
is interpreted as
(a == b) == c
so first a == b is evaluated and returns either true or false, a boolean.
Then someBool == c is evaluated. If c is 0, then you are comparing a bool against an int, which leads to your compile error.
However if c is null, then both that null and that "someBool" are promoted lifted to a Nullable<bool> (or bool?), so they can be compared. But of course a true or false is never equal to (bool?)null, which is what Resharper says.
So you cannot take this shortcut and will have to write it as
(a == c) && (b == c)
Or in your case:
if (a.Right == null && b.Right == null) ...
if (aa == 0 && bb == 0) ...
In short, you can't compare like this, ever...
In regards to if (a.Right == b.Right == null)
It compiles because you can compare a non-nullable value types with null and it's always false.
a.Right == b.Right // bool
bool == null //will be lifted and always equal false (see below)
To know the reason why you'll have to visit the specs and understand lifted operators
12.4.8 Lifted operators
Lifted operators permit predefined and user-defined operators that
operate on non-nullable value types to also be used with nullable
forms of those types
For the equality operators == !=
a lifted form of an operator exists if the operand types are both
non-nullable value types and if the result type is bool. The lifted
form is constructed by adding a single ? modifier to each operand
type. The lifted operator considers two null values equal, and a null
value unequal to any non-null value. If both operands are non-null,
the lifted operator unwraps the operands and applies the underlying
operator to produce the bool result.
In regards to if(aa == bb == 0) you can't compare bool with an int, there is no implicit conversion to bool
aa == bb // bool
bool == 0 // there is no implicit conversion to bool
Why do multiple comparands work with 'Node' and doesn't work with
'Int'?
A) I guess you should be asking why it works with Null and not Int values. In your example above Node is a reference type and integer 0 is a value type. Read details below
All Value Types can be compared to null because they are convertible to nullable and null is the default value assigned to a Reference Types
Value types include : Bool, Integers, Floating points, char
Reference types include : Class, string, objects, interface
Valid Cases:
bool a =true;
if(a == null) //a is converted to a Nullable Boolean and then compared with null`
if(a.Right==b.Right==null) //First 2 statements are evaluated to boolean, which is converted to a Nullable Boolean and then compared with null`
int i=5;
if(i==null) // i is converted to a Nullable int and then compared with null, which always ends up false as the value of i is 5
Nullable<int> ii = 5;
if(ii==null) // ii being a nullable int is compared with null, there will not be any warnings indicated by the compiler as it know before hand that ii has a chance of being null
int a =5; int b=4;
if(a==b) // Valid, because your comparing 2 Integers are equal
Invalid Cases:
int a =5; int b=4;
if(a==b==0) // First 2 statements evaulate to a boolean and a boolean is evaluated to a Integer, the compiler fails to understand how to convert a Boolean to Int and hence the error
if(a==true) // same as above, compiler fails to compare an integer to a boolean and results in an error
Given the following C++ Code:
void Check(DWORD64 ptr)
{
if ( ! (ptr & 0x8000000000000000) )
return;
}
In C# this results in the following Error:
CS0023 Operator '!' cannot be applied to operand of type 'ulong'
How do I bitwise check the ptr parameter in C#?
Comparing to not 0?
void Check(ulong ptr)
{
if ((ptr & 0x8000000000000000) != 0)
return;
}
or checking for 0?
void Check(ulong ptr)
{
if ((ptr & 0x8000000000000000) == 0)
return;
}
Googleing for this questions leads to all sorts of answers on different bitwise operations but I couldn't find an answer for this specific negation with exclemation mark.
When operator ! "logical not" is applied to a numeric value in C or C++, it produces a result as follows:
1 if its operand is zero
0 otherwise
C's conditional statement if interprets 0 as "false" and any non-zero value, including 1, as "true". Therefore, your second option is correct.
The second one. C++ would treat any nonzero value as true, so the ! check on an integer was effectively equivalent to !(value != 0) or (value==0)
Following this very interesting issue which was originated from this question -
I want to take 1 steps back please (removed the dynamic environment) :
Looking at this code : ( a variant of this one)
void Main()
{
int a;
int b = 100;
Console.WriteLine(X.M(1, out a));
}
public class X
{
public int H=0;
public static X M(int x, out int y)
{
Console.WriteLine("x = "+x);
y = x;
return new X(x);
}
public X(){}
public X(int h)
{
H=h;
}
public static bool operator false(X x) {Console.WriteLine("in false operator for "+ x.H); return true; }
public static bool operator true(X x) {Console.WriteLine("in true operator for "+ x.H); return true; }
public static X operator &(X a, X b) {Console.WriteLine("in & operator for "+ a.H+","+b.H); return new X(); }
public static implicit operator bool (X x) {Console.WriteLine("in bool operator for "+ x.H);return true; }
}
The result is :
x = 1
in bool operator for 1
True
This is understood :
The x = 1 is from the method itself ( using Console.Writeline)
in bool operator for 1 is from the implicit operator from X to Bool
(so - Console.WriteLine treats the whole expression as Console.Writeline(bool))
The last "True" is from the "return true" in the operator bool (X x)
OK - So let's change
Console.WriteLine(X.M(1, out a));
to
Console.WriteLine(X.M(1, out a) && X.M(2, out b));
Now - the result is :
x = 1
in false operator for 1
in bool operator for 1
True
2 questions :
Why does this in false operator for 1 executes ? I don't see any reason for false to be present here.
I could understand why the right part in X.M(1, out a) && X.M(2, out b) won't executes ONLY if the left part is false - but again I don't see how the left part can be false. It does return true (according to my first code)
NB
I've read many times the answers from the post :
Jon said :
The second && is a normal && between two bool expressions - because
Nop returns bool, and there's no &(X, bool) operator... but there is a
conversion from X to bool.
So it's more like:
bool first = X.M(1, out a) && X.M(2, out b);
if (first && Nop(a, b))
Now first is true even though only the first operand of && has been
evaluated... so b really hasn't been assigned.
Still I don't understand : "first is true(????) even though only the first operand of && has been evaluated"
Firstly, don't forget that this is deliberately bizarre code, used to find a corner case. If you ever find a type that behaves like this in a genuine program, find the author and have a quiet word with them.
Still I don't understand : "first is true(????) even though only the first operand of && has been evaluated"
Yes, because of the way the && operand is handled in the case where the operands aren't bool. It's specified in section 7.12.2 of the C# spec:
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 in &. In other words, x is first evaluated and operator false is invoked on the result to determine if x is definitely false. Then, if x is definitely false, the result of the operation is the value previously computed for x. 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.
So, in order:
X.M(1, out a) is invoked, to get a result - call it op1 for the moment
Next X.false(op1) is invoked, and returns true
Then by the above, the result of the expression X.M(1, out a) && X.M(2, out b) is op1
Next, the value of the conversion from op1 to bool is invoked, and that returns true. This is due to overload resolution for Console.WriteLine.
To answer your specific confusion:
but again I don't see how the left part can be false.It does return true (according to my first code)
It returns a value which is somewhat contradictory - it's false in that the false operator returns true, but it's true in that the conversion to bool returns true. Once you understand that it's the value returned by the false operator which determines whether or not to evaluate the second operand of &&, it should all be clear.
Newbie question.
How to calculate the value of the formula A f B, where f - the binary function OR or AND?
There is a distinction between the conditional operators && and || and the boolean operators & and |. Mainly it is a difference of precendence (which operators get evaluated first) and also the && and || are 'escaping'. This means that is a sequence such as...
cond1 && cond2 && cond3
If cond1 is false, neither cond2 or cond3 are evaluated as the code rightly assumes that no matter what their value, the expression cannot be true. Likewise...
cond1 || cond2 || cond3
If cond1 is true, neither cond2 or cond3 are evaluated as the expression must be true no matter what their value is.
The bitwise counterparts, & and | are not escaping.
Hope that helps.
Logical OR is ||, logical AND is &&.
If you need the negation NOT, prefix your expression with !.
Example:
X = (A && B) || C || !D;
Then X will be true when either A and B are true or if C is true or if D is not true (i.e. false).
If you wanted bit-wise AND/OR/NOT, you would use &, | and ~. But if you are dealing with boolean/truth values, you do not want to use those. They do not provide short-circuit evaluation for example due to the way a bitwise operation works.
if(A == "haha" && B == "hihi") {
//hahahihi?
}
if(A == "haha" || B != "hihi") {
//hahahihi!?
}
I'm not sure if this answers your question, but for example:
if (A || B)
{
Console.WriteLine("Or");
}
if (A && B)
{
Console.WriteLine("And");
}
Use '&&' for AND and use '||' for OR, for example:
bool A;
bool B;
bool resultOfAnd = A && B; // Returns the result of an AND
bool resultOfOr = A || B; // Returns the result of an OR
If what interests you is bitwise operations look here for a brief tutorial : http://weblogs.asp.net/alessandro/archive/2007/10/02/bitwise-operators-in-c-or-xor-and-amp-amp-not.aspx .bitwise operation perform the same operations like the ones exemplified above they just work with binary representation (the operation applies to each individual bit of the value)
If you want logical operation answers are already given.
&& it's operation return true only if both operand it's true which implies
bool and(bool b1, bool b2)]
{
if(b1==true)
{
if(b2==true)
return true;
}
return false;
}
|| it's operation return true if one or both operand it's true which implies
bool or(bool b1,bool b2)
{
if(b1==true)
return true;
if(b2==true)
return true;
return false;
}
if You write
y=45&&34//45 binary 101101, 35 binary 100010
in result you have
y=32// in binary 100000
Therefore, the which I wrote above is used with respect to every pair of bits
many answers above, i will try a different way:
if you are looking for bitwise operations use only one of the marks like:
3 & 1 //==1 - and
4 | 1 //==5 - or