I saw some code like this:
void testCase2 (int variant)
{
if (variant & 0x1)
{
return;
}
}
What does the & operator mean in the if statement, is it ==? Why to use &?
& is the bitwise AND operator. Given two integer operands, it does an AND operation on each bit position, i.e. in the result only those bits will be set that were set in both operands.
If one of the operands is 0x1 as in this case, the result will be 0x1 if, and only if, that bit is also set in the other operand (here, variant).
As C/C++ considers any non-zero integer to be true,
if (variant & 0x1)
checks if the least-significant bit in variant is set.
Similarly,
if (variant & 0x2)
would check if the second least-significant bit in variant is set, and
if (variant & 0x3)
would check if either of the two least-significant bits in variant is set.
It's a "bitwise and", basically that code will check if the lowest significant bit in 'variant' is set.
The operator does an AND operation on each relative bit of the two items being compared to get the result. It's a common way to examine variables that are being used to carry multiple bit 'flags'.
as an example, "bitwise anding" two variables with these binary representations:
00010001
00000001
would give:
00000001
http://en.wikipedia.org/wiki/Bitwise_operation#AND
variant: 1011 Bitwise AND
0x1 : 0001
-------
0001
-------
Bitwise AND is used to Turn-Off bits.
The bitwise AND operator is a single ampersand: &. A handy mnemonic is that the small version of the boolean AND, &&, works on smaller pieces (bits instead of bytes, chars, integers, etc). In essence, a binary AND simply takes the logical AND of the bits in each position of a number in binary form.
SRC : refer here
& operator is the boolean arithmetic AND operator i.e. bitwise AND
IN your code block, if (variant & 0x1) is evaluated as:
if (the result of ANDing variant and 0x1) is TRUE, them go inside the following block of code.
Consider the following code (see it in action on IDEONE):
#include <iostream>
using namespace std;
int main() {
int variant = 0x1f; // Declared in HEX format;
if (variant & 0x1){ // If the LSB is 1 i.e. if the
cout << "axious!!!"; // It'll print "axious!!!"
} else
{
cout << "It's something else!!!";
}
return 0;
}
But the following code:
#include <iostream>
using namespace std;
int main() {
int variant = 0x10; // Declared in HEX format;
if (variant & 0x1){ // If the LSB is 1
cout << "axious!!!";
} else
{
cout << "It's something else!!!"; // This will be printed!!
}
return 0;
}
Now remember that 0x1 will be 1 in binary i.e. the LSB will be 1 so you are actually checking for what is the first bit of your variant.
Related
I am trying to understand dbns code in foam-extend. But I am having bit of doubt in a specific part of the following code given below.
deltaRLeft & gradrho[own] or
deltaRRight & gradU[nei]
I thing & used here is a reference operator, but if any one can explain it in more detail, it will helpful for me.
Flux::evaluateFlux
(
rhoFlux_[faceI],
rhoUFlux_[faceI],
rhoEFlux_[faceI],
rho_[own] + rhoLimiter[own]*(deltaRLeft & gradrho[own]),
rho_[nei] + rhoLimiter[nei]*(deltaRRight & gradrho[nei]),
U_[own] + cmptMultiply(ULimiter[own], (deltaRLeft & gradU[own])),
U_[nei] + cmptMultiply(ULimiter[nei], (deltaRRight & gradU[nei])),
T_[own] + TLimiter[own]*(deltaRLeft & gradT[own]),
T_[nei] + TLimiter[nei]*(deltaRRight & gradT[nei]),
R[own],
R[nei],
Cv[own],
Cv[nei],
Cp[own],
Cp[nei],
Sf[faceI],
magSf[faceI]
);
What is the & exactly doing here, if it can be explained in detail.
The part of the code is from dbns/numericFlux/numericFlux.C
It's the bitwise and operator.
It compares each bit of the first operand to the corresponding bit of the second operand.
If both bits are 1, the result bit is set to 1 otherwise 0.
As example:
11001001
& 10111000
--------
= 10001000
I am afraid that the first and second answers are mostly not applicable within the OpenFOAM context.
In the OpenFOAM context, & is the inner product if the operands are tensors. Thereat, deltaRRight and gradT[nei] are in fact tensor objects.
Please look at the OpenFOAM's programmers' guide, Section 1.4.1 and 1.3.1.
There are two different & operators.
The bitwise AND operator (&) compares each bit of the first operand to the corresponding bit of the second operand. If both bits are 1, the corresponding result bit is set to 1. Otherwise, the corresponding result bit is set to 0.
Both operands to the bitwise AND operator must be of integral types.
For example:
#include <iostream>
using namespace std;
int main() {
unsigned short a = 0xFFFF; // pattern 1111 ...
unsigned short b = 0xAAAA; // pattern 1010 ...
cout << hex << ( a & b ) << endl; // prints "aaaa", pattern 1010 ...
}
can we access the bits shifted by bit shifting operators(<<, >>) in C, C++?
For example:
23>>1
can we access the last bit shifted(1 in this case)?
No, the shift operators only give the value after shifting. You'll need to do other bitwise operations to extract the bits that are shifted out of the value; for example:
unsigned all_lost = value & ((1 << shift)-1); // all bits to be removed by shift
unsigned last_lost = (value >> (shift-1)) & 1; // last bit to be removed by shift
unsigned remaining = value >> shift; // lose those bits
By using 23>>1, the bit 0x01 is purged - you have no way of retrieving it after the bit shift.
That said, nothing's stopping you from checking for the bit before shifting:
int value = 23;
bool bit1 = value & 0x01;
int shifted = value >> 1;
You can access the bits before shifting, e.g.
value = 23; // start with some value
lsbits = value & 1; // extract the LSB
value >>= 1; // shift
It worth signal that on MSVC compiler an intrinsic function exists: _bittest
that speeds up the operation.
I have tried to make a longer function but it has acted very weird. I had tried to isolate the problem and I have been able to find the buggy part.
This program made for an Arduino but this phenomenon probably appear in other environment. I have tried to make a lot of searches but I cannot find the solution.
So, my buggy part:
Why do not these two codes give the same result?
How can I construct a one line function without extra variable
but same operation like "Code 1"?
Results:
Code 1: 0b00101100
Code 2: 0b01101100
Source codes:
Code 1: (correct operation but not one line)
#include <binary.h>
const byte value=B00110110;
byte buffer,result;
void setup(){
Serial.begin(115200);
buffer = (value << 3);
result = (buffer >> 2);
Serial.println(result,BIN);
}
void loop(){
}
It gives: 0b00101100
Code 2: (incorrect operation but one line)
#include <binary.h>
const byte value=B00110110;
byte result;
void setup(){
Serial.begin(115200);
result = ((value << 3) >> 2);
Serial.println(result,BIN);
}
void loop(){
}
It gives: 0b01101100
Remove the extra bits by masking with 0xFF:
result = (((value << 3) & 0xFF) >> 2);
You can also trim the upper three bits off after the sequence of shifts:
result = 0x1F & ((value << 3) >> 2);
According to the language specification, default integer promotions are applied to shift operands before shifting, and the result of the operation is the promoted type of the first operand.
5.8.1 The operands shall be of integral or enumerated type and integral promotions are performed. The type of the result is that of the promoted left operand.
If an integral type can fit in an int, then int is the result of the promotion. When you shift left, the most significant bits "spill" into the upper part of the int. Your first snippet cuts them off by assigning back to byte; you can achieve the same result by masking the result with 0xFF.
Link to ideone.
If byte is a uint8_t (thanks Mr. Fernandes!), the result of (value << 3) is wider than a byte. More precisely, value is promoted to a wider type before the shift occurs, and the result is that wider type. To get the behavior of Code 1, you can change Code 2 to do this:
result = (static_cast<byte>(value << 3) >> 2);
This mimics the intermediate assignment to buffer in Code 1 with a cast.
I assume that your byte is some unsigned integral type smaller than int.
Most arithmetic operations in C++ are performed in the domain of int type, after all "smaller" operands are implicitly converted (promoted) to type int.
For this reason, your first group of shifts is equivalent to
buffer = (byte) ((int) value << 3);
result = (byte) ((int) buffer >> 2);
while your second group if shifts is equivalent to
result = (byte) (((int) value << 3) >> 2);
In the first variant, any bits that get shifted outside the range of type byte by the << 3 shift are lost during intermediate conversion and assignment to buffer. In the second variant all calculations are performed within the range of int, so nothing is lost.
If you want your second variant to produce the same results as the first, you need to explicitly "truncate" the intermediate shift result
result = ((byte) (value << 3) >> 2);
I'm in a the middle of creating a console based small game for our C programming class assignment and I decided to make it more presentable and unique by adding text colors and text backgrounds.
While I was on my quest searching for a solution, I've found this handy function that will do just the way I wanted for my project but the problem is that there is this part I do not understand:
WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);
Where, BackC and ForgC are given integers and the data type WORD is just a typedef for an unsigned short int. Specifically, what I don't understand is the ((BackC & 0x0F) << 4) + (ForgC & 0x0F) part. Can anyone help me with this? I know that I can just use the function but I really want to know how the function works...Thanks!
Here is the full source code (colorExample.c)
#include <windows.h>
#include <stdio.h>
void SetColorAndBackground(int ForgC, int BackC);
int main()
{
SetColorAndBackground(10,1); //color value range 0 up-to 256
printf("what is text background color \n");
SetColorAndBackground(11,1);
printf("how about this?");
getch();
return 0;
}
void SetColorAndBackground(int ForgC, int BackC)
{
WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor);
return;
}
ForgC and BackC are two values that can really only expand to take up of 4 bits each (you can tell this because they are being bitwise ANDed with 0x0F, which clears all but the last 4 bits of the first operand).
So if we look at them as 8-bit wide values, they would be of the form
ForgC 0000xxxx
BackC 0000yyyy
Then you bitwise shift ForgC 4 bits to the left, making
ForgC xxxx0000
BackC 0000yyyy
And then you add them together¹, making
ForgC xxxx0000
BackC 0000yyyy
Result xxxxyyyy
So what this does in effect is "combine" both values into one. SetConsoleTextAttribute might then separate them again, or it might use the combined value as-is.
¹ Technically this should be a bitwise OR instead of integer addition. Although in this specific case (where the two operands are guaranteed to not have an 1-bit in the same position) both operations will produce the same result, bitwise OR makes the intent clearer.
If takes the lower 4 bits of each BackC and ForgC and joins them to get a 8 bit value.
((
BackC & 0x0F // take last 4 bits of BackC
) << 4) // and shift 4 to the left
+
(
ForgC & 0x0F // plus take last 4 bits of ForgC
)
E.g. if BackC is 0b......abcd and ForgC is 0b.....efgh (both in binary representation) you'll get the value 0xabcdefgh.
I have a 5 byte data element and I need some help in figuring out how in C++ to set an individual bit of one of these byte; Please see my sample code below:
char m_TxBuf[4];
I would like to set bit 2 to high of byte m_TxBuf[1].
00000 0 00
^ This one
Any support is greatly appreciated;
Thanks!
Bitwise operators in C++.
"...set bit 2..."
Bit endianness.
I would like to set bit 2 to high of byte m_TxBuf[1];
m_TxBuf[1] |= 1 << 2
You can use bitwise-or (|) to set individual bits, and bitwise-and (&) to clear them.
int bitPos = 2; // bit position to set
m_TxBuf[1] |= (1 << bitPos);
m_TxBuf[1] |= 4;
To set a bit, you use bitwise or. The above uses compound assignment, which means the left side is one of the inputs and the output.
Typically we set bits using bitwise operator OR (operator| or operator|= as a shorthand).
Assuming 8-bits to a byte (where the MSB is considered the '7st' bit and the LSB considered the 0th: MSB 0) for simplicity:
char some_char = 0;
some_char |= 1 << 0; // set the 7th bit (least significant bit)
some_char |= 1 << 1; // set the 6th bit
some_char |= 1 << 2; // set the 5th bit
// etc.
We can write a simple function:
void set_bit(char& ch, unsigned int pos)
{
ch |= 1 << pos;
}
We can likewise test bits using operator&.
// If the 5th bit is set...
if (some_char & 1 << 2)
...
You should also consider std::bitset for this purpose which will make your life easier.
Just use std::bitset<40> and then index bits directly.