Is the compound operator '&=' logical or bitwise AND ?
In other words, is a &= b the same as:
a = a & b
a = a && b
a &= b is using the bitwise AND operator. Think of the += operation:
a += 5;
is the same as:
a = a + 5;
It's just a combination of two operations: & and =.
It's the bitwise AND, not the logical. (have to add some characters)
In C, a &= b is a = a & b, i.e. bitwise. In C++, where there is a dedicated bool type, &= on booleans is boolean as well, as is a simple & on bool. None of these does exhibit the short-circuit behaviour of &&, though.
It's bitwise ANDsimple
When you do a&=b It means a=a&b
Remember aand bshould be integral typeor promoted to integer type
While && is logical AND.
This is one of the queries that can be resolved through experimentation rather than interrogation:
#include <stdio.h>
#include <inttypes.h>
int main(int argc, char *argv[]) {
uint8_t a = 0xFF;
uint8_t b = 0x0F;
a &= b;
printf("a &= b : %02X\n",a);
a = 0xFF;
printf("a & b : %02X\n", a & b);
printf("a && b: %02X\n", a && b);
}
Prints:
a &= b : 0F
a & b : 0F
a && b: 01
to the console.
Related
I have the following C code which works:
int ex(unsigned int x) {
int mask = 0x55555555;
int a = ((x >> 0) & mask );
return a + ((x >> 1) & mask );
}
However, when I expand it to this, I get a different result:
int ex(unsigned int x) {
int mask = 0x55555555;
int a = ((x >> 0) & mask );
int b = ((x >> 1) & mask );
return a + b;
}
What is the reason for this difference?
EDIT:
Note, I'm compiling this for 32bit.
What is the reason for this difference?
The 1st snippet returns the result of adding two unsigneds with the result being (implicitly) converted to an int.
The 2nd snippet returns the result of adding two ints .
More on "The Usual Arithmetic Conversions":
Usual arithmetic conversions in C : Whats the rationale behind this particular rule
C usual arithmetic conversions
Implicit integer type conversion in C
If I have an int a, which is lets say equal to 0.
Is there a way for me to say left shift 101 into the variable and then in another step shift in 011 into it? Then I could get the int decimal number at the end? It would end up becoming 0b00000000000000000000000000101011.Or should I only use the OR operation.
You can't shift bits into the variable; you can OR them in:
int a = 0;
a |= 5;
printf("a = %d\n", a);
a <<= 3;
a |= 3;
printf("a = %d\n", a);
If your system supports binary constants, you can use those instead of decimals (and you can prefix 5 and 3 with 0 for octal or 0x for hexadecimal if you prefer — and you can print with a different format according to taste, too). If the starting value for a isn't known to be 0, you would do a shift-assignment operation before the first |= operation.
Eventually, you have to worry about left-shifting a signed integer value such that overflow occurs — that leads to undefined behaviour. It isn't a problem with the values in the question, though.
You would need to first shift by the required number of bits then perform a bitwise OR of the new data.
int a = 0;
a = a << 3;
a = a | 0x5;
a = a << 3;
a = a | 0x3;
printf("a=%x\n", a);
( Used separate assignments and operators instead of compound operators to make it clearer to beginners. )
Result:
a=2b
Is there a way for me to say left shift 101 into the variable
No. You need to left shift first, then add (or OR) the new value.
int eax = 0;
eax <<= 3;
eax |= 5;
int a = 0;
a << 3;
a |= 0x5;
a << 3;
a |= 0x3;
There isn't a predefined way to "shift in" a value like that. It wouldn't take much time to write a function that could though.
There is - to my knowledge - no operation that "shifts" a number of bits from one integer into another. The left shift operator always fills the arising spaces with 0, such that you have to combine it with, for example, an |-operation (actually a + would have the same effect in your case).
#include <stdio.h>
void printBinary(int b, int nrOfBits) {
for (int mask = (1 << nrOfBits); mask != 0; mask >>=1 ) {
char c = (b & mask) ? '1' : '0';
printf("%c", c);
}
}
int main()
{
int a = 0;
a = (a << 3) | 0x5;
printBinary(a, 8);printf("\n");
a = (a << 3) | 0x3;
printBinary(a, 8);printf("\n");
return 0;
}
When using left shift operators on signed datatypes be careful not to produce undefined behaviour (cf. cppreference concerting arithmetic operations):
When signed integer arithmetic operation overflows (the result does
not fit in the result type), the behavior is undefined
Can you tell me what convertLedNumberToBit and LedDriver_TurnOn do? I do not understand what is happening with 1 << (num - 1) and |=
static uint16_t * ledsAddress;
static uint16_t convertLedNumberToBit(int ledNumber)
{
return 1 << (ledNumber - 1);
}
void LedDriver_TurnOn(int ledNumber)
{
*ledsAddress |= convertLedNumberToBit(ledNumber);
}
<< is a bitwise shift to the left. A uint16_t of 1 in binary is 0b0000000000000001, so when you shift left by the quantity ledNumber-1, the result is a uint16_t with a single-bit set to the position specified by ledNumber.
From the variable name ledNumber, I'm guessing that this function sets a specific LED to work on.
| performs a bitwise OR on the two operands it is passed.
For example,
byte b = 0x0A | 0x50;
If you look at the underlying bits for 0x0A and 0x50, they are 0b00001010 and 0b01010000 respectively. When combined with the OR operator the result in b is 0b01011010, or 0x5A in hexadecimal.
|= is a bitwise OR assignment. |= is analogous to operators like += and -= in that it will perform a bitwise OR on the two operands then store the result in the left operator.
byte b = 0x0A;
b |= 0x50;
// after this b = 0x5A
To switch 'ON' the LED[ledNumber] at I/O port ledsAddress, it is necessary to set the equivalent bit to '1'. But, when changing the I/O port value, you have to keep the state of all others LED still 'ON'.
The convertLedNumberToBit(int ledNumber) is using a mask b0000000000000001 (16bits) to set the ledNumber bit to '1' by switching to left of (ledNumber-1) { no shift needed when ledNumber is 1.
Ex: (ledNumber = 4) => returned value is b0000000000001000= 0x0008.
Then the call |= convertLedNumberToBit(ledNumber) will force only the ledNumber bit to '1' without changing others by a binary-OR.
Ex: (led1, led3 & led7 are 'ON')
before the OR b0000000001000101 = 0x0045.
LedDriver_TurnOn(4) => b0000000000001000= 0x0008
after the OR b0000000001001101 = 0x004D.
To switch 'OFF' the same LED, you have just to replace the OR function by the AND function of the NOT mask.
void LedDriver_TurnOff(int ledNumber)
{
*ledsAddress &= ~(convertLedNumberToBit(ledNumber));
}
cppreference - Arithmetic operators to the rescue
The bitwise shift operator expressions have the form
lhs << rhs (1)
lhs >> rhs (2)
1) left shift of lhs by rhs bits
2) right shift of lhs by rhs bits
So 1 << (ledNumber - 1) shifts the least significant bit to the left, e.g. if ledNumber = 5
0x0001 << (5 - 1)
will become
0x0010
Also cppreference - Assignment operators
|= is a (bitwise OR) assignment operator, where
*ledsAddress |= convertLedNumberToBit(ledNumber);
is equivalent to
*ledsAddress = *ledsAddress | convertLedNumberToBit(ledNumber);
I see the following bit operation statement, but what is the order of the execution:
// Example program
#include <iostream>
#include <string>
#include <stdio.h>
int main()
{
unsigned int age = 2;
unsigned int agemap = 0x111 ;
if(age > 0 && age <= 32)
{
agemap &= (unsigned int)~((unsigned int)1 << (unsigned int)(age - 1));
}
}
This is used to remove the age(value 2) from the agemap(0x111), but based on what order it is executed?
It's of course "based" on the order of precendence of C's operators, like in any other expression. There are plenty of parentheses of course, so you have to take those into account.
Wikipedia has a good table. Note that it's complicated since C has quite a few operators.
Basically, the right-hand side evaluates to ~(1 << 1), which is ~2, which is 0xfffffffd assuming a 32-bit unsigned int.
agemap &= (unsigned int)~((unsigned int)1 << (unsigned int)(age - 1));
If you remove (unnecesary) casts:
agemap &= ~(1U << (age - 1));
age - 1
1U << 1
~2
How does this code work:
int a = 1;
int b = 10;
a |= b;
how the a |= b; works? Seems like |= is not an operator in C?
It works like the | + the = operator, in a similar way as += works.
It is equivalent as
a = a|b;
I suggest you to read this article about operators: http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Bitwise_operators
Ans this one about bitwise operation
http://en.wikipedia.org/wiki/Bitwise_operation
Following the pattern of, for example, +=:
a |= b;
// Means the same thing as:
a = a | b;
That is, any bits that are set in either a or b shall be set in a, and those set in neither shall not be set in a.
That's the "bitwise or" equal. It follows in the pattern of the plus equal +=, minus equal -=, etc.
a |= b; is the same as a = a | b;
The expression a |= b; is equivalent to the expression a = a | b;.
This is compound assignment operator.
It has meaning:
a = a | b;
This is the same as
a = a | b;
The same way as += -= etc
Its the bitwise OR operator, and
a |= b;
Its the same thing as
a = a | b;