I have a coordinate pair of values that each range from [0,15]. For now I can use an unsigned, however since 16 x 16 = 256 total possible coordinate locations, this also represents all the binary and hex values of 1 byte. So to keep memory compact I'm starting to prefer the idea of using a BYTE or an unsigned char. What I want to do with this coordinate pair is this:
Let's say we have a coordinate pair with the hex value [0x05,0x0C], I would like the final value to be 0x5C. I would also like to do the reverse as well, but I think I've already found an answer with a solution to the reverse. I was thinking on the lines of using & or | however, I'm missing something for I'm not getting the correct values.
However as I was typing this and looking at the reverse of this: this is what I came up with and it appears to be working.
byte a = 0x04;
byte b = 0x0C;
byte c = (a << 4) | b;
std::cout << +c;
And the value that is printing is 76; which converted to hex is 0x4C.
Since I have figured out the calculation for this, is there a more efficient way?
EDIT
After doing some testing the operation to combine the initial two is giving me the correct value, however when I'm doing the reverse operation as such:
byte example = c;
byte nibble1 = 0x0F & example;
byte nibble2 = (0xF0 & example) >> 4;
std::cout << +nibble1 << " " << +nibble2 << std::endl;
It is printout 12 4. Is this correct or should this be a concern? If worst comes to worst I can rename the values to indicate which coordinate value they are.
EDIT
After thinking about this for a little bit and from some of the suggestions I had to modify the reverse operation to this:
byte example = c;
byte nibble1 = (0xF0 & example) >> 4;
byte nibble2 = (0x0F & example);
std:cout << +nibble1 << " " << +nibble2 << std::endl;
And this prints out 4 12 which is the correct order of what I am looking for!
First of all, be careful about there are in fact 17 values in the range 0..16. Your values are probably 0..15, because if they actually range both from 0 to 16, you won't be able to uniquely store every possible coordinate pair into a single byte.
The code extract you submitted is pretty efficient, you are using bit operators, which are the quickest thing you can ask a processor to do.
For the "reverse" (splitting your byte into two 4-bit values), you are right when thinking about using &. Just apply a 4-bit shift at the right time.
Related
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;
I am currently working on a project for school covering bit manipulation. We are supposed to show the bits for an unsigned integer variable and allow the user to manipulate them, turning them on and off and shifting them. I have all of the functionality working, except for displaying the bits once they have been manipulated. We are NOT allowed to use bitset to display the bits, and it will result in a heavy grade reduction.
I have tried using if statements to determine whether the bits are on or off, but this does not seem to be working. Whenever a bit is changed, it will simply print a lot of 0's and 1's.
std::cout << "Bits: ";
for (int i = sizeof(int)*8; i > 0; i--)
{
if (a | (0 << i) == 1)
std::cout << 1;
if (a | (0 << i) == 0)
std::cout << 0;
}
std::cout << std::endl << a;
I would expect that if I turn a bit on, that one bit will display a 1 instead of a 0, with the rest of the bits being unchanged and still displaying 0; instead it prints a string of 1010101 about the length of half the console.
There are a couple of problems here, and you might want to do a detailed review of bit manipulation:
for (int i = sizeof(int)*8; i > 0; i--) should be for (int i = sizeof(int)*8 - 1; i >= 0; i--), because bits are 0-indexed (shifting 1 to the left 0 times gives a set bit on the rightmost position).
We use bitwise AND (&) instead of bitwise OR (|) to check if a bit is set. This is because when we use bitwise AND with a number that only has a single bit set, the result will be a mask with the bit at the position of the 1 being in the same state as the corresponding bit in the original number (since anything AND 1 is itself), and all other bits being 0's (since anything AND 0 is 0).
We want a mask with 1 in the position that we want to check and 0 elsewhere, so we need 1 << i instead of 0 << i.
If the bit we're checking is set, we'll end up with a number that has one bit set, but that's not necessarily 1. So we should check if the result is not equal to 0 instead of checking if it's equal to 1.
The == operator has a higher precedence compared to the | and the & operators, so parenthesis is needed.
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. :-(
I am new here, and would like to ask this question.
I am working with a binary file that each byte, multiple bytes or even parts of a byte have a different meaning.
What I have been trying so far is to read a number of bytes (4 in my example) as a one block.
I have them in Hexadecimal representation like: 00 1D FB C8.
Using the following code, I read them separately:
for (int j = 36; j < 40;j++)
{
cout << dec << (bitset<8>(fileBuf[j])).to_ulong();
}
where j is the position of the byte in the file. The previous code gives me 029251200 which is wrong. What I want is read the 4 bytes at once and get the answer of 1965000
I appreciate any help.
Thank you.
DWORD final = (fileBuf[j] << 24) + (fileBuf[j+1] << 16) + (fileBuf[j+2] << 8) + (fileBuf[j+3]);
Also depends what kind of endian you want (ABCD / DCBA / CDAB)
EDIT (cant reply due to low rep, just joined today)
I tried to extend the bitset, however it gave the value of the first byte only
It will not work because the fileBuf is 99% byte array, extending from 8bit to 32bit(int) wont make any difference because its still a byte array which is 8bit. You have to mathematicly calculate the value from 4 array elements into original integer representation. see code above edit
The answer isnt "Wrong" this is a logic error. Youre not storing the values and adding the computation
C8 is 200 in decimal form, so youre not appending the value to the original subset.
The answer it spit it out, was infact what you programmed it to do.
You need to either extend the bitset to a larger amount to append the other hex numbers or provide some other means of outputting
Keeping the format of the function from the question, you could do:
//little-endian
{
int i = (fileBuf[j]<<0) | (fileBuf[j+1]<<8) | (fileBuf[j+2]<<16) | (fileBuf[j+3]<<24);
cout << dec << i;
}
// big-endian
{
int i = (fileBuf[j+3]<<0) | (fileBuf[j+2]<<8) | (fileBuf[j+1]<<16) | (fileBuf[j]<<24);
cout << dec << i;
}
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.