Reconstructing a value from an array of bits - c++

I have an array of bits (stored as Boolean) that I want to reconstruct into an integer. I want to insert bits from the right hand side and shift them left for every bit in my array.
How do I insert a bit at the LSB side and shift it over at the same time?

You would do something like this:
bool yourarray[32];
int output = 0;
for(int i = 0; i < 32; i++)
{
// Shift the bits left by 1. The first time through the loop this
// will have no real effect since 0 << 1 == 0.
output <<= 1;
// If this particular bit is "on", activate the LSB using a bitwise-or
if(yourarray[i] == true)
output |= 1; // this turns on the LSB
// We could also do this for completeness, but it has no effect since
// the LSB is already 0:
else
output &= ~1; // this turns off the LSB
}
I'm assuming an int of size 32 here.
There are other considerations to take into account, like endianness but this should give you an idea. Also beware of signing issues, since in this case the highest (left-most) bit will affect whether the int comes out positive or negative.

This is just to give a bit of explanation on what's happening when you use bitwise operators.
Let's say we have a 1 byte (8 bits) value: val1 = 00000011. And we have another 1 byte value: val2 =00100001
If we shift the bits of val1 to the left 2, like so:
val1 = val1 << 2;
val1 now looks like this: 00001100.
Then, if we OR (|) val2 with val1 like this:
val1 = val1 | val2
val1 will look like this: 00101101.
I hope this helps ^_^

Related

How to shift left one specific bit?

I want to shift left only one bit in a specific place leaving its position 0, so I do not want to shift the whole variable with << operator, here is an example: say the variable has the value 1100 1010 and I want to shift the fourth bit then the result should be 1101 0010.
Steps to get there.
Pull out bit value from the original number.
Left shift the bit value by one.
Merge the bit-shifted value back to the original number.
// Assuming C++14 or later to be able to use the binary literal integers
int a = 0b11001010;
int t = a & 0b00001000; // Pull out the 4-th bit.
t <<= 1; // Left shift the 4-th bit.
a = a & 0b11100111; // Clear the 4-th and the 5-th bit
a |= t; // Merge the left-shifted 4-th bit.
For C++, I'd just use a std::bitset. Since you set the bit of pos + 1 to the value of the bit at pos, and then set the bit at pos to 0 this translate into bitset code that is quite easy to read. That would give you a function like
unsigned char shift_bit_bitset(unsigned char val, unsigned pos)
{
std::bitset<8> new_val(val);
new_val[pos + 1] = new_val[pos];
new_val[pos] = 0;
return new_val.to_ulong();
}
Maybe not the shortest/cleanest way, but this'll do it:
unsigned shift_bit = 4;
unsigned char val = 0xCA; // 1100 1010
unsigned char bit_val = val & (1 << shift_bit - 1); // Get current bit value
val = val & ~(1 << shift_bit - 1); // Clear initial bit location
val = bit_val ? // Update next bit to 0 or 1
val | (1 << shift_bit) :
val & ~(1 << shift_bit);
See it work with the test cases specified in your question and comments here: ideone
A simpler way is
(x & 0b11101111) + (x & 0b00001000)
that is, clear the bit that will be shifted into and add the bit to be shifted, which will overflow to the left if it is 1.

Bits shifted by bit shifting operators(<<, >>) in C, C++

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.

Storing 0s and 1s in an array in a 32-bit integer and performing bit operation

I have a array of size 32. Each element in the array is a 0 or 1. I want to be able to store them into the bit positions of a 32-bit integer, and perform bit-wise operations on it. How can I do this ?
Also, if I have two arrays of size 32, and I want to do bitwise operations on the elements with the same index all at once, could I do this ?
op_and[31:0] = ip_1[31:0] & ip_2 [31:0];
I am using the gcc compiler.
You can use the or operator | and bitshifting ( << and >> ).
uint32_t myInt = 0;
for( int index=0; index < 32; index++ )
{
myInt |= ( arrayOf32Ints[i] << i );
}
This example assumes that the values of arrayOf32Ints are either 0 or 1 as per your question.
If they may contain "any true" or false value, one should ask for that explicitly (some people would tell you to use !! but the standard does not guarantee that true is 1).
The line would then be
myInt |= ( (arrayOf32Ints[i])?1:0) << i );
In the case you want to set individual bits on or off, you can do:
myInt |= (1<<3); //Sets bit 3 true by shifting 1 3 bits up (1 becomes 4), and ANDing it with myInt.
myInt |= 4; // Sets bit 3 by ANDing 4 (The binary form of 4 is 100) with myInt.
myInt ^= (1<<5);; // Turns OFF bit 5 by XORing it with myInt (XOR basically means "Any bits which are not the same in both numbers")
myInt ^= 16; //Sets bit 5 by XORing it with myInt (16 is 10000 in binary)

How to set specific bits?

Let's say I've got a uint16_t variable where I must set specific bits.
Example:
uint16_t field = 0;
That would mean the bits are all zero: 0000 0000 0000 0000
Now I get some values that I need to set at specific positions.
val1=1; val2=2, val3=0, val4=4, val5=0;
The structure how to set the bits is the following
0|000| 0000| 0000 000|0
val1 should be set at the first bit on the left. so its only one or zero.
val2 should be set at the next three bits. val3 on the next four bits. val4 on the next seven bits and val5 one the last bit.
The result would be this:
1010 0000 0000 1000
I only found out how to the one specific bit but not 'groups'. (shift or bitset)
Does anyone have an idea how to solve this issue?
There are (at least) two basic approaches. One would be to create a struct with some bitfields:
struct bits {
unsigned a : 1;
unsigned b : 7;
unsigned c : 4;
unsigned d : 3;
unsigned e : 1;
};
bits b;
b.a = val1;
b.b = val2;
b.c = val3;
b.d = val4;
b.e = val5;
To get the 16-bit value, you could (for one example) create a union of that struct with a uint16_t. Just one minor problem: the standard doesn't guarantee what order the bit fields will end up in when you look at the 16-bit value. Just for example, you might need to reverse the order I've given above to get the order from most to least significant bits that you really want (but changing compilers might muck things up again).
The other obvious possibility would be to use shifting and masking to put the pieces together into a number:
int16_t result = val1 | (val2 << 1) | (val3 << 8) | (val4 << 12) | (val5 << 15);
For the moment, I've assumed each of the inputs starts out in the correct range (i.e., has a value that can be represented in the chosen number of bits). If there's a possibility that could be wrong, you'd want to mask it to the correct number of bits first. The usual way to do that is something like:
uint16_t result = input & ((1 << num_bits) - 1);
In case you're curious about the math there, it works like this. Lets's assume we want to ensure an input fits in 4 bits. Shifting 1 left 4 bits produces 00010000 (in binary). Subtracting one from that then clears the one bit that's set, and sets all the less significant bits than that, giving 00001111 for our example. That gives us the first least significant bits set. When we do a bit-wise AND between that and the input, any higher bits that were set in the input are cleared in the result.
One of the solutions would be to set a K-bit value starting at the N-th bit of field as:
uint16_t value_mask = ((1<<K)-1) << N; // for K=4 and N=3 will be 00..01111000
field = field & ~value_mask; // zeroing according bits inside the field
field = field | ((value << N) & value_mask); // AND with value_mask is for extra safety
Or, if you can use struct instead of uint16_t, you can use Bit fields and let the compiler to perform all these actions for you.
finalvle = 0;
finalvle = (val1&0x01)<<15;
finalvle += (val2&0x07)<<12;
finalvle += (val3&0x0f)<<8
finalvle += (val4&0xfe)<<1;
finalvle += (val5&0x01);
You can use the bitwise or and shift operators to achieve this.
Use shift << to 'move bytes to the left':
int i = 1; // ...0001
int j = i << 3 // ...1000
You can then use bitwise or | to put it at the right place, (assuming you have all zeros at the bits you are trying to overwrite).
int k = 0; // ...0000
k |= i // ...0001
k |= j // ...1001
Edit: Note that #Inspired's answer also explains with zeroing out a certain area of bits. It overall explains how you would go about implementing it properly.
try this code:
uint16_t shift(uint16_t num, int shift)
{
return num | (int)pow (2, shift);
}
where shift is position of bit that you wanna set

Set individual bit in C++

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.