How does the bit store in the array? - c++

While doing my homework, I had a question about bits.
How does save bits in an array of int8_t?
And How can I access these bits?
Here are some example code
void someting_with_bits(int8_t bit_array[])
{
//Do sometings...
}
If there is a function like this,
when I call bit_array[0], do I return 8 length bits like 11100011?
If that be so, How can I access the first bits of bit_array[0]?

Yes, it will be saved like 11000011 in one array block.
To access a specified bit, you need to shift it and then AND it with a special mask.
For example, to access the highest bit of bit_array[0]:
int8_t highest_bit = (bit_array[0] >> 7) & 0x1;
to access the highest 4 bits of bit_array[0]:
int8_t highest_4_bits = (bit_array[0] >> 4) & 0xf;

If you want to access individual bits of each integer, you can do some bit manipulations.
for example if you want to check 3rd least significant bit of an integer, AND it with 0x4(100). Also you can right shift your int 2 times and then AND it with 0x1.
for example to check the 5th least significant bit of integer with index 3 in your array:
bool theBit = (bit_array[3] >> 4) & 0x1;
Of course you can use bitset.
http://www.cplusplus.com/reference/bitset/bitset/
for example to access 3rd least significant bit of a 32 bit integer
(don't forget to include bitset header):
int32_t number = 233;
std::bitset<32> bits(number);
std::cout << "The 3rd ls bit is: " << bits[2] << std::endl;

Related

Get the low portion of a number of any of the built-in types [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
How would I create a function template which returns the low portion of a number of N bits?
For example, for an 8 bit number, get the least significant 4 bits, for a 16 bit number, get the least significant 8 bits.
To get the lower half of a built-in integer type you can try something like this:
#include <iostream>
#include <climits>
using std::cout;
using std::endl;
template<typename T>
constexpr T lowbits(T v) {
return v & (T(1) << CHAR_BIT * sizeof v / 2) - 1;
}
int main() {
cout << std::hex << (int)lowbits<int8_t>(0xde) << endl; // will print e
cout << std::hex << lowbits<int16_t>(0xdead) << endl; // will print ad
cout << std::hex << lowbits<int32_t>(0xdeadbeef) << endl; // will print beef
cout << std::hex << lowbits<int64_t>(0xbeefdeaddeadbeef) << endl; // will print deadbeef
}
Note that
return v & (T(1) << CHAR_BIT * sizeof v / 2) - 1;
is equivalent to:
return v & (
(static_cast<T>(1)
<<
(CHAR_BIT * (sizeof v) / 2)) // number of bits divided by 2
- 1
);
In essence you are creating a bit-mask (simply another integer) that has 0-bits for all higher bits and 1-bits for all lower bits.
If an integer type has N bits this is done by shifting a 1-bit into the Nth position and then subtracting 1 from it. The subtraction has the result that all bits below the 1 will be set.
And-ing this with the given value yields only the lower half of the value v.
You can easily generalize this approach to retrieving any number of lower bits by replacing CHAR_BIT * sizeof v/2 with the number of bits you want to retrieve.
To get only the higher bits you can simply negate the resulting mask using the ~ operator.
If you require arbitrary sized integers you can try finding the equivalent operations for this procedure in the GNU gmp library.
Let us define a variable called mask which is the pattern to mask off (or retain) some bits. The operation to get the least significant bits is:
result = value & mask;
For an example, test with value == 13 and mask == 7.
This works will all POD types, except for floating point. The least significant Q bits of a floating point, doesn't make sense (unless you really need to do this).
If you have no need for more bits than the largest internal integral type, you could use something like this:
template <typename T>
T low_bits(T data, size_t bit_count)
{
T mask = (1U << bit_count) - 1U;
return value & mask;
}
For a non-template solution, one could use a macro:
#define LOW_BITS(value, bit_count) \
(value & ((1U << bit_count) - 1U))
This lets the compiler figure out the code based on the data type of value.
A macro form of the expression: value & mask.
The thorn or issue comes into play when N > sizeof(*largest type*). In this case, the number can't be represented by internal data types, so one has to come up with a different solution.
The solution for N-bit depends on whether the multi-byte representation of the number is Big Endian or Little Endian. For Big Endian platforms, the least significant value will be at highest address, while on Little Endian platforms, the least significant is at the lowest address.
The solution I'm proposing treats the N-bit number as an array of bytes. A byte contains 8-bits (on most platforms), and bytes can be masked differently than multibyte quantities.
Here's the algorithm:
1. Copy the least significant bytes that are completely masked to the result variable.
2. Mask the next largest byte and copy result byte to result number.
3. Pad remaining bytes with 0.
As far as the function parameters go, you'll need:
1) Pointer to the memory location of the original number.
2) Pointer to the result number.
3) Pointer to the mask.
4) Size of the number, in bytes.
The algorithm can handle N-bit numbers, limited by the amount of memory on the platform.
Note: sorry about not providing code, but I need to get back to work. :-(

Converting a bitset to signed

I have a std::bitset<32> and I want to isolate the right 16 bits and output those bits as if they were a signed number. I also am going to want to output the entire 32 bit thing as a signed number down the road. However, Bitset does not support a signed int to_string().
for example
1010000000100001 1111111111111111:
I want one output to be:
-1608384513 for the whole sequence
-1 for the right 16 bits.
Any slick ways of converting them?
To get a 16-bit number you can use to_ulong(), drop the upper 16 bits, and reinterpret as int16_t.
Similarly, for a signed 32-bit number you can call to_ulong(), and reinterpret as a signed int32_t.
std::bitset<32> b("10100000001000011111111111111111");
int16_t x16 = (int16_t)(b.to_ulong() & 0xFFFF);
int32_t x32 = (int32_t)b.to_ulong();
cout << x16 << endl;
cout << x32 << endl;
Demo.

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

converting one byte into 8 bits with same data set

I have a question. I have a data set of 32 by 32 integer matrix. As int holds 32 bit, i want to break down each elements of my matrix into 32 bit, suppose i have 255 decimal at first place of matrix and this can hold 32 bit as of integer, now i want to convert this 255 decimal into binary 255 i.e. 11111111 and padding with zero the remaining positions. I don't want to construct another matrix because then the data size will be greater than 32 bits. I want to do this with C++.
Something like this...
a[32][32];
for(int i=0;i<32;i++)
for(int j=0;j<32;j++)
a[i][j]=255+i+j;
Now let a[0][0]=255 in decimal form...i want to convert this and each element of matrix a into decimal and which will be like this..a[0][0]=00000000000000000000000011111111. This is 32 bit as int can hold 32 bit. Now my question is how i can access each bit of the a[0][0]. The important thing is that i want to stay in 32 bit format and don't want to create another matrix.
If you have any solution then please share with me. I am new to programming world. Thanks
To access bits of an integer you must use the bitwise operators.
To test if the nth bit is set use & and <<
if (m[0][0] & (1 << n))
cout << "bit " << n << " is set";
Remember to count from 0, so to test if the first (or lowest) bit is set use 1 << 0, the second use 1 << 1 etc.
To set the nth bit use |= and <<
m[0][0] |= (1 << n);
To clear the nth bit use &=, ~ and <<
m[0][0] &= ~(1 << n);
To invert the nth bit use ^= and <<
m[0][0] ^= (1 << n);
There are lots of other possibilities including testing or setting multiple bits at a time, extracting bit fields etc. I suggest you read a tutorial on this. There are lots and lots of these on the internet, for instance this one.

Shift left/right adding zeroes/ones and dropping first bits

I've got to program a function that receives
a binary number like 10001, and
a decimal number that indicates how many shifts I should perform.
The problem is that if I use the C++ operator <<, the zeroes are pushed from behind but the first numbers aren't dropped... For example
shifLeftAddingZeroes(10001,1)
returns 100010 instead of 00010 that is what I want.
I hope I've made myself clear =P
I assume you are storing that information in int. Take into consideration, that this number actually has more leading zeroes than what you see, ergo your number is most likely 16 bits, meaning 00000000 00000001 . Maybe try AND-ing it with number having as many 1 as the number you want to have after shifting? (Assuming you want to stick to bitwise operations).
What you want is to bit shift and then limit the number of output bits which can be active (hold a value of 1). One way to do this is to create a mask for the number of bits you want, then AND the bitshifted value with that mask. Below is a code sample for doing that, just replace int_type with the type of value your using -- or make it a template type.
int_type shiftLeftLimitingBitSize(int_type value, int numshift, int_type numbits=some_default) {
int_type mask = 0;
for (unsigned int bit=0; bit < numbits; bit++) {
mask += 1 << bit;
}
return (value << numshift) & mask;
}
Your output for 10001,1 would now be shiftLeftLimitingBitSize(0b10001, 1, 5) == 0b00010.
Realize that unless your numbits is exactly the length of your integer type, you will always have excess 0 bits on the 'front' of your number.