What is the purpose of &= and |= operator in C# [duplicate] - c#

This question already has answers here:
What does the &= operator do in C#? [closed]
(5 answers)
Closed 9 years ago.
I'm not sure what these operators are accomplishing:
byteInfo[x, y, z] |= (byte)info;
as well as:
byteInfo[x, y, z] &= (byte)255 - (byte)info;
From msdn:
class AndAssignment
{
static void Main()
{
int a = 0x0c;
a &= 0x06;
Console.WriteLine("0x{0:x8}", a);
bool b = true;
b &= false;
Console.WriteLine(b);
}
}
/*
Output:
0x00000004
False
*/
But, what did it do?

They are a combination of the & and | operators and assignment. a &= b is doing the same thing as a = a & b.
& and | are the bitwise and and or operators. & is the intersection of all bits in its operands, | is the union:
10011100101
& 00100011110
-------------
00000000100
10011100101
| 00100011110
-------------
10111111111
Basically, when you're using & on two numbers, all the bits are set that are set in both operands, while with | all the bits are set that are set in at least one operand.

Those are bitwise operators. & represents the logical AND operator and | the OR. There is also ~ for NOT and ^ for XOR.
In your example, it is simply calculating the AND between two binary values : 1100 AND 0110 = 0100 (Which is 4, as in your output). The second one can be seen as 1 AND 0 = 0.
You can refer to Truth Tables to see how it works exactly : AND operation, OR operation
However, one of the most common use is with enumerations. For example, let's say you have the days of the week
[Flags]
public enum DaysOfTheWeek
{
Sunday = 0x1,
Monday = 0x2,
Tuesday = 0x4,
Wednesday = 0x8,
Thursday = 0x16,
Friday = 0x32,
Saturday = 0x64
}
You can use bitwise operators to easily assign values. For example, if you want to represent the weekend you can use the OR operator to set the binary flags :
DaysOfTheWeek weekend = DaysOfTheWeek.Saturday | DaysOfTheWeek.Sunday;
To check if a value contains the correct flag, you can use the AND operator :
bool isSundayAWeekend = (weekend & DaysOfTheWeek.Sunday) == DaysOfTheWeek.Sunday

These are shortcuts for the standard bitwise operators AND (&) and OR (|).
a &= 0x06;
is equivalent to:
a = a & 0x06
For an explanation of AND and OR see this wikipedia article.

Related

Enum Flags Negative Value

Got a negative number (-2147483392)
I don't understand why It (correctly) casts to a flags enum.
Given
[Flags]
public enum ReasonEnum
{
REASON1 = 1 << 0,
REASON2 = 1 << 1,
REASON3 = 1 << 2,
//etc more flags
//But the ones that matter for this are
REASON9 = 1 << 8,
REASON17 = 1 << 31
}
why does the following correctly report REASON9 and REASON17 based off a negative number?
var reason = -2147483392;
ReasonEnum strReason = (ReasonEnum)reason;
Console.WriteLine(strReason);
.NET Fiddle here
I say correctly, as this was an event reason property being fired from a COM component, and when cast as the enum value, it was correct in the values it casts to (as per that event). The flags enum was as per the SDK documentation for the COM object. The COM object is third party and I have no control over the number, based off the interface it will always be supplied as an INT
The topmost bit set (31-th in your case of Int32) means negative number (see two's complement for details):
int reason = -2147483392;
string bits = Convert.ToString(reason, 2).PadLeft(32, '0');
Console.Write(bits);
Outcome:
10000000000000000000000100000000
^ ^
| 8-th
31-th
And so you have
-2147483392 == (1 << 31) | (1 << 8) == REASON17 | REASON9

& operator with enum values in C#

I have following code and Console.WriteLine is returning Bottom even though Bottom is not in both enum expressions.
Question
What is the logic behind returning Bottom in code snippet given below? My understanding of & operator is that it returns the common part, but in this case there is nothing common between the two enum expressions.
void Main()
{
Console.WriteLine(( Orientations.Left | Orientations.Bottom) &
(Orientations.Right| Orientations.Top));//returns Bottom
}
[Flags]
public enum Orientations {
Left = 0, Right= 1, Top=2, Bottom =3
};
You assign values to the enums, and the operators | and & work on the enum values, like they would work on the corresponding values.
You have set the values of the enum values yourself, and you have not set them orthogonal. Since integers are in fact bitstrings (with fixed length), you can see it as a 32-dimensional vector (with every vector element having domain {0,1}). Since you defined for instance Bottom as 3, it means that Bottom is actually equal to Right | Top, since:
Right | Top
1 | 2 (integer value)
01 | 10 (bitwise representation)
11 (taking the bitwise or)
Bottom
So that means that if you write &, this is a bitwise AND, and |, is a bitwise OR on the values of the enum values.
So if we now evaluate it, we get:
(Orientations.Left|Orientations.Bottom) & (Orientations.Right|Orientations.Top)
(0 | 3 ) & (1 | 2)
3 & 3
3
Orientations.Bottom
If you want to define four orthogonal values, you need to use powers of two:
[Flags]
public enum Orientations {
Left = 1, // 0001
Right = 2, // 0010
Top = 4, // 0100
Bottom = 8 // 1000
};
Now you can see the enum as four different flags, and and the & will create the intersection, and | the union of the flags. In comment the bitwise representation of each value is written.
As you can see, we can now see Left, Right, Top and Bottom as independent elements, since we can not find a monotonic bitwise construction ( to combine Left, Right and Top to construct Bottom (except negation).
In order for flag enums to work as expected, the enum constants need to be powers of 2.
In your example the binary values look like this (I show 4 bits only for sake of simplicity)
Left = 0 0000
Right = 1 0001
Top = 2 0010
Bottom = 3 0011
Left | Right | Top | Bottom = 0011 which is 3 or Bottom again
If you choose powers of 2 exactly one bit is set and you get
Left = 1 = 2^0 0001
Right = 2 = 2^1 0010
Top = 4 = 2^2 0100
Bottom = 8 = 2^3 1000
Left | Right | Top | Bottom = 1111
I.e., with powers of 2, different bits are set and therefore they combine neatly with the bitwise OR operator (|).
Since C# 7.0 you can use binary literals
[Flags]
public enum Orientations {
Left = 0b0001,
Right = 0b0010,
Top = 0b0100,
Bottom = 0b1000
};
In previous versions of C# you can also use the left shift operator to get powers of 2
[Flags]
public enum Orientations {
Left = 1 << 0,
Right = 1 << 1,
Top = 1 << 2,
Bottom = 1 << 3
};
It is a good practice to also include the enum constant None = 0 because enum fields are initialized to default(MyEnum) == 0, otherwise resulting in a value having no corresponding enum constant.
You can also create new combined enum values like this
[Flags]
public enum Orientations {
None = 0,
Left = 1 << 0,
Right = 1 << 1,
Top = 1 << 2,
Bottom = 1 << 3,
Horizontal = Left | Right,
Vertical = Top | Bottom,
All = Horizontal | Vertical
};
Note that every enum has an implicit conversion from 0. Therefore you could do this test
if((myOrientations & Orientations.Vertical) != 0) {
// We have at least a Top or Bottom orientation or both
}
It is & and | bitwise operation. In the example:
(( Orientations.Left | Orientations.Bottom) &
(Orientations.Right| Orientations.Top))
Will replace with
((0 | 3) & (1 | 2)) with in bit (show only last 3 bit):
((000 |011) & (001 | 010))
= (011 & 011)
= 011
011 is 3 in int value which is Orientations.Bottom value. Therefore, It is always returning Orientations.Bottom.

Merge first n bits of a byte with last 8-n bits of another byte

How can I merge first n bits of a byte with last 8-n bits of another byte?
I know something like below for picking 3 bits from first and 5 from second (Which I have observed in DES encryption algorithm)
zByte=(xByte & 0xE0) | (yByte & 0x1F); But I don't know maths behind why we need to use 0XE0 and 0X1F in this case. So I am trying to understand the details with regards to each bit.
In C#, that would be something like:
int mask = ~((-1) << n);
var result = (x & ~mask) | (y & mask);
i.e. we build a mask that is (for n = 5) : 000....0011111, then we combine (&) one operand with that mask, the other operand with the inverse (~) of the mask, and compose them (|).
You could also probably do something more quickly just using shift operations (avoiding a mask completely) - but only if the data can be treated as unsigned (so Java might struggle here).
It just sounds like you don't understand how boolean arithmetic works? If this is your question it works like this:
0xEO and 0x1F are hexidecimal representations of numbers. If we convert these numbers to binary they would be:
0xE0 = 11100000
0x1F = 00011111
Additionally & (and) and | (or) are bitwise logical operators. To understand logical operators, first remember the 1 = true and 0 = false.
The truth table for & is:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
The truth table for | is:
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
So let's breakdown your equation piece by piece. First we will evaluate the code in parenthesis first. We will walk through each number in binary and for the & operator if each operand has a 1 in the same bit position we will return 1. If either number has a 0 then we will return 0. After we finish the evaluation of the operands in the parenthesis we will then take the 2 resulting numbers and apply the | operator bit by bit. If either number has a 1 in the same bit position we will return 1. If both numbers have a 0 in the same bit position we will return 0.
For the sake of discussion, let's say that
xByte = 255 or (FF in hex and 11111111 in binary)
yByte = 0 or (00 in hex and 00000000 in binary)
When you apply the & and | operators we are going to compare each bit one at a time:
zByte = (xByte & 0xEO) | (yByte & 0x1F)
becomes:
zByte = (11111111 & 11100000) | (00000000 & 00011111)
zByte = 111000000 | 00000000
zByte = 11100000
If you understand this and how boolean logic works then you can use Marc Gravell's answer.
The math behind those numbers (0xE0 and 0x1F) is quite simple. First we are exploiting the fact that 0 & <bit> always equals 0 and 1 & <bit> always equals <bit>.
0x1F is 00011111 binary, which means that the first 3 bits will always be 0 after an & operation with another byte - and the last 5 bits will be the same they were in the other byte. Remember that every 1 in a binary number represents a power of 2, so if you want to find the mask mathematically it would be the sum of 2^x from x = 0 to n-1. Then you can find the opposite mask (the one that is 11100000) to extract the first 3 bit, you simply need to subtract the mask from 11111111, and you will get 11100000 (0xE0).
In java,
By using the following function we can get the first n bits of the first Byte and last 8 n bits of the second byte.
public class BitExample {
public static void main(String[] args) {
Byte a = 15;
Byte b = 16;
String mergedValue=merge(4, a, b);
System.out.println(mergedValue);
}
public static String merge(int n, Byte a, Byte b) {
String mergedString = "";
String sa = Integer.toBinaryString(a);
String sb = Integer.toBinaryString(b);
if(n>sa.length()) {
for(int i=0; i<(n-sa.length()); i++) {
mergedString+="0";
}
mergedString+=sa;
}else{
mergedString+=sa.substring(0, n);
}
if(8*n>sb.length()) {
for(int i=0; i<(8*n-sb.length()); i++) {
mergedString+="0";
}
mergedString+=sb;
}
return mergedString;
}
}

C# & operator clarification

I saw a couple of questions here about the diference between && and & operators in C#, but I am still confused how it is used, and what outcome results in different situations. For example I just glimpsed the following code in a project
bMyBoolean = Convert.ToBoolean(nMyInt & 1);
bMyBoolean = Convert.ToBoolean(nMyInt & 2);
When it will result 0 and when >0? What is the logic behind this operator? What are the diferences between the operator '|'?
bMyBoolean = Convert.ToBoolean(nMyInt | 1);
bMyBoolean = Convert.ToBoolean(nMyInt | 2);
Can we use the &&, || operators and get the same results (possibly with different code)?
The && is a conditional and used in if statements and while
if(x>1 && y<3)
this means that x should be greater than 1 and y less than 3, satisfy both conditions
if(x>1 || y<3)
satisfy one of them
However, & and | are bitwise AND and OR respectively.
ex:
1 | 0 => 1
1 & 0 => 0
1 & 1 => 1
if this apply for straight integers, their corresponding binary value will be calculated and applied
2&1
=> 10 // the binary value of 2
&
01 // the binary value of 1
--
00 // the result is zero
The ampersand does bitwise AND on the integers in their binary representations.
The pipe does bitwise OR.
See here what those bitwise operations mean: http://en.wikipedia.org/wiki/Bitwise_operation
& and | is bit operations. You must use it on bit masks. && and || is logical operations so you can use it for only bool values.
Example of bit operation:
var a = 1;
var b = 2;
var c = a|b;
in binary format this means a = 00000001, b = 00000010
c = 00000011
So if you use bitmask c it will pass values 1, 2 or 3.
One more difference is that & operator computes the logical bitwise AND of its operands, if operands are not bool (integer in your case)
& operator is BItwise AND operator,it does manipulation on bits.
e.g. 5 & 3
0101 //5
0011 //3
----------
5&3= 0001 //1
| operator is BItwise OR operator,it does manipulation on bits.
5|3
0101 //5
0011 //3
----------
5|3= 0111 //7
&& operator is logical AND operator- it returns true if all conditions are true
e.g.
if((3>5)&&(3>4)) //returns true
if((6>5)&&(3>4)) //returns false
|| operator is logical OR operator- it returns true if one of the conditions is true
e.g.
if((3>5)||(3>4)) //returns true
if((6>5)||(3>4)) //returns true
if((6>5)||(5>4)) //returns false
Other answers explains for you the different between && and &, so assume you understand this. In here, I just try to explain your specified case.
First case
bMyBoolean = Convert.ToBoolean(nMyInt & 1);
bMyBoolean false when nMyInt = 0 because:
00
& 01
= 00;
Second case:
bMyBoolean = Convert.ToBoolean(nMyInt & 2);
bMyBoolean false when nMyInt = 0 or 1 because
00
& 10
= 00;
Or:
01
& 10
= 00;
The third and fourth cases with bitwise | are trivial because bMyBoolean always true with any nMyInt
bMyBoolean = Convert.ToBoolean(nMyInt | 1);
bMyBoolean = Convert.ToBoolean(nMyInt | 2);
You cannot apply && or || in this case because they are constraint only for bool, you will compiled errors.
Here is something interesting for & . bit-wise as & be, it can be used
to bool as in example below.
bool result = true;
result &= false;
Console.WriteLine("result = true & false => {0}", result );
//result = true & false => False
result = false;
result &= false;
Console.WriteLine("result = false & false => {0}", result );
//result = false & false => False
result = true;
result &= true;
Console.WriteLine("result = true & true => {0}", result );
//result = true & true => True

What is the tilde (~) in the enum definition?

I'm always surprised that even after using C# for all this time now, I still manage to find things I didn't know about...
I've tried searching the internet for this, but using the "~" in a search isn't working for me so well and I didn't find anything on MSDN either (not to say it isn't there)
I saw this snippet of code recently, what does the tilde(~) mean?
/// <summary>
/// Enumerates the ways a customer may purchase goods.
/// </summary>
[Flags]
public enum PurchaseMethod
{
All = ~0,
None = 0,
Cash = 1,
Check = 2,
CreditCard = 4
}
I was a little surprised to see it so I tried to compile it, and it worked... but I still don't know what it means/does. Any help??
~ is the unary one's complement operator -- it flips the bits of its operand.
~0 = 0xFFFFFFFF = -1
in two's complement arithmetic, ~x == -x-1
the ~ operator can be found in pretty much any language that borrowed syntax from C, including Objective-C/C++/C#/Java/Javascript.
I'd think that:
[Flags]
public enum PurchaseMethod
{
None = 0,
Cash = 1,
Check = 2,
CreditCard = 4,
All = Cash | Check | CreditCard
}
Would be a bit more clear.
public enum PurchaseMethod
{
All = ~0, // all bits of All are 1. the ~ operator just inverts bits
None = 0,
Cash = 1,
Check = 2,
CreditCard = 4
}
Because of two complement in C#, ~0 == -1, the number where all bits are 1 in the binary representation.
Its better than the
All = Cash | Check | CreditCard
solution, because if you add another method later, say:
PayPal = 8 ,
you will be already done with the tilde-All, but have to change the all-line with the other. So its less error-prone later.
regards
Just a side note, when you use
All = Cash | Check | CreditCard
you have the added benefit that Cash | Check | CreditCard would evaluate to All and not to another value (-1) that is not equal to all while containing all values.
For example, if you use three check boxes in the UI
[] Cash
[] Check
[] CreditCard
and sum their values, and the user selects them all, you would see All in the resulting enum.
For others who found this question illuminating, I have a quick ~ example to share. The following snippet from the implementation of a paint method, as detailed in this Mono documentation, uses ~ to great effect:
PaintCells (clipBounds,
DataGridViewPaintParts.All & ~DataGridViewPaintParts.SelectionBackground);
Without the ~ operator, the code would probably look something like this:
PaintCells (clipBounds, DataGridViewPaintParts.Background
| DataGridViewPaintParts.Border
| DataGridViewPaintParts.ContentBackground
| DataGridViewPaintParts.ContentForeground
| DataGridViewPaintParts.ErrorIcon
| DataGridViewPaintParts.Focus);
... because the enumeration looks like this:
public enum DataGridViewPaintParts
{
None = 0,
Background = 1,
Border = 2,
ContentBackground = 4,
ContentForeground = 8,
ErrorIcon = 16,
Focus = 32,
SelectionBackground = 64,
All = 127 // which is equal to Background | Border | ... | Focus
}
Notice this enum's similarity to Sean Bright's answer?
I think the most important take away for me is that ~ is the same operator in an enum as it is in a normal line of code.
It's a complement operator,
Here is an article i often refer to for bitwise operators
http://www.blackwasp.co.uk/CSharpLogicalBitwiseOps.aspx
Also msdn uses it in their enums article which demonstrates it use better
http://msdn.microsoft.com/en-us/library/cc138362.aspx
The alternative I personally use, which does the same thing than #Sean Bright's answer but looks better to me, is this one:
[Flags]
public enum PurchaseMethod
{
None = 0,
Cash = 1,
Check = 2,
CreditCard = 4,
PayPal = 8,
BitCoin = 16,
All = Cash + Check + CreditCard + PayPal + BitCoin
}
Notice how the binary nature of those numbers, which are all powers of two, makes the following assertion true: (a + b + c) == (a | b | c). And IMHO, + looks better.
I have done some experimenting with the ~ and find it that it could have pitfalls. Consider this snippet for LINQPad which shows that the All enum value does not behave as expected when all values are ored together.
void Main()
{
StatusFilterEnum x = StatusFilterEnum.Standard | StatusFilterEnum.Saved;
bool isAll = (x & StatusFilterEnum.All) == StatusFilterEnum.All;
//isAll is false but the naive user would expect true
isAll.Dump();
}
[Flags]
public enum StatusFilterEnum {
Standard =0,
Saved =1,
All = ~0
}
Each bit in [Flags] enum means something enabled (1) or disabled (0).
~ operator is used to invert all the bits of the number. Example: 00001001b turns into 11110110b.
So ~0 is used to create the value where all bits are enabled, like 11111111b for 8-bit enum.
Just want to add that for this type of enums it may be more convenient to use bitwise left shift operator, like this:
[Flags]
enum SampleEnum
{
None = 0, // 0000b
First = 1 << 0, // 0001b
Second = 1 << 1, // 0010b
Third = 1 << 2, // 0100b
Fourth = 1 << 3, // 1000b
All = ~0 // 1111b
}

Categories

Resources