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
Related
I am writing a C# program that modifies a binary file. In the file there is a byte that stores ALL the information on what a person is wearing.
Example:
1 = Hat
2 = Shoes
4 = Socks
8 = Pants
16 = Shirt
32 = Glasses
64 = Watch
128 = Earrings
Sally is wearing shoes, pants and a shirt = 2 + 8 + 16 = 26. The byte stored is 26.
Fred is wearing a hat, shoes, socks, paints, shirt, glasses and a watch: 1 + 2 + 4 + 8 + 16 + 32 + 64 = 127. The byte stored is 127
Now I want to take that number and figure out what they are wearing. A person cannot wear two of the same things, and there are only the 8 options.
You have a bit mask.
Using your 2 + 8 + 16 = 26 example, you can pull out each bit using the bitwise "and" operator &. To check if the person is wearing shoes, "and" the bit mask with 2 and check the result:
011010 = 26
& 000010 = 2 <-- bitwise "and" operator
-------------
000010 = 2
If the bitmask was 5 instead of 26, the result would be:
000101 = 5
& 000010 = 2 <-- bitwise "and" operator
-------------
000000 = 0
So take the result and check if it's greater than zero. That's it:
bool isHat = bitMask & 1 > 0;
bool isShoes = bitMask & 2 > 0;
bool isSocks = bitMask & 4 > 0;
//and so on
FYI: I'm guessing that you are setting your bit mask by adding powers of two to an accumulator like this:
byte SetWatch(byte bitMask) {
return bitMask + 64;
}
You can also use a bitwise operation to do this. Use the bitwise "or" like this:
byte SetWatch(byte bitMask) {
return bitMask | 64;
}
Use an enum with the [Flags] attribute, then use the HasFlag method to determine whether a given instance of the enum has that flag set.
https://msdn.microsoft.com/en-us/library/system.enum.hasflag(v=vs.110).aspx
You could use this technique.
Referencing your example with Sally:
26 / 2 = 13 , Remainder = 0 <-- Hat
13 / 2 = 6 , Remainder = 1 <-- Shoes
6 / 2 = 3 , Remainder = 0 <-- Socks
3 / 2 = 1 , Remainder = 1 <-- Pants
1 / 2 = 0 , Remainder = 1 <-- Shirt
You can use bit-wise operators to figure this out.
var outfit = 26; //this is the same as 2 & 8 & 16
var bIsWearingPants = ((outfit | 8) != 0);
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;
}
}
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.
What's the short, elegant, bitwise way to write the last line of this C# code without writing b twice:
bool getAsIs = ....
bool b = ....
getAsIs ? b : !b
The truth table can be expressed as:
getAsIs b getAsIs ? b : !b
--------------------------------
0 0 1
0 1 0
1 0 0
1 1 1
The result can be expressed as:
result = (getAsIs == b);
Try using binary XOR (^ Operator (C# Reference)):
bool getAsIs = true;
bool b = false;
bool result = !(getAsIs ^ b);
I think it's
var foo = !(getAsIs ^ b)
Short, elegant, but definitely a head-scratcher!
Is there any difference between Arithmetic + and bitwise OR. In what way this is differing.
uint a = 10;
uint b = 20;
uint arithmeticresult = a + b;
uint bitwiseOR = a | b;
Both the results are 30.
Edit : Small changes to hide my stupidity.
(10 | 20) == 10 + 20 only because the 1-bits do not appear in the same digit.
1010 = 10
or 10100 = 20
————————
11110 = 30
However,
11 = 3 11 = 3
or 110 = 6 + 110 = 6
—————— ——¹——————
111 = 7 1001 = 9
# ^ ^
# (1|1==1) (1+1=2)
Counterexample:
2 + 2 == 42 | 2 == 2
Bitwise OR means, for each bit position in both numbers, if one or two bits are on, then the result bit is on. Example:
0b01101001
|
0b01011001
=
0b01111001
(0b is a prefix for binary literals supported in some programming languages)
At the bit level, addition is similar to bitwise OR, except that it carries:
0b01101001
+
0b01011001
=
0b11000010
In your case, 10+20 and 10|20 happen to be the same because 10 (0b1010) and 20 (0b10100) have no 1s in common, meaning no carry happens in addition.
Try setting a = 230 and b = 120. And you'll observer the difference in results.
The reason is very simple. In the arithmentic addition operation the bit-wise add operation may generate carry bit which is added in the next bit-wise addition on the bit-pair available on the subsequent position. But in case of bit wise OR it just performs ORing which never generates a carry bit.
The fact that you're getting same result in your case is that the
numbers co-incidentally don't generate any
carry-bit during addition.
Bit-wise arithmetic Addition
alt text http://www.is.wayne.edu/drbowen/casw01/AnimAdd.gif
Bitwise OR goes through every bit of two digits and applies the following truth table:
A B | A|B
0 0 | 0
0 1 | 1
1 0 | 1
1 1 | 1
Meanwhile the arithmetic + operator actually goes through every bit applying the following table (where c is the carry-in, a and b are the bits of your number, s is the sum and c' is the carry out):
C A B | S C'
0 0 0 | 0 0
0 0 1 | 1 0
0 1 0 | 1 0
0 1 1 | 0 1
1 0 0 | 1 0
1 0 1 | 0 1
1 1 0 | 0 1
1 1 1 | 1 1
For obvious reasons, the carry-in starts-off being 0.
As you can see, sum is actually a lot more complicated. As a side effect of this, though, there as an easy trick you can do to detect overflow when adding positive signed numbers. More specifically, we expect that a+b >= a|b if that fails then you have an overflow!
The case when the two numbers will be the same is when every time a bit in one of the two numbers is set, the corresponding bit int he second number is NOT set. That is to say that you have three possible states: either both bits aren't set, the bit is set in A but not B, or the bit is set in B but not A. In that case the arithmetic + and the bit-wise or would produce the same result... as would the bitwise xor for that matter.
Using arithmetic operations to manipulate bitmasks can produce unexpected results and even overflow. For instance, turning on the n-th bit of a bitmask if it is already on will turn off the n-th bit and turn on the n+1-th bit. This will cause overflow if there are only n-bits.
Example of turning on bit 2:
Arithmetic ADD Bitwise OR
0101 0101
+ 0100 | 0100
---- ----
1001 0101 //expected result: 0101
Like-wise, using arithmetic subtract to turn off the n-th bit will fail if the n-th bit was not already on.
Example of turning off bit 2:
Arithmetic SUB Bitwise AND~
0001 0001
- 0100 &~ 0100
---- ----
0001 0001
+ 1100 & 1011
---- ----
1101 0001 //expected result: 0001
So bitwise operators are safer than arithmetic operators when you are working with bitmasks.
The following bitwise operations have analogous arithmetic operations:
Bitwise Arithmetic
Check n-th bit x & (1 << n) !(x - (1 << n))
Turn on n-th bit x |= (1 << n) x += (1 << n)
Turn off n-th bit x &= ~(1 << n) x -= (1 << n)
Try a = 1 and b = 1 ;)
+ and | have different when two bits at the same positions are 1
00000010
OR
00000010
Result
00000010
VS
00000010
+
00000010
Result
00000100