Lets say I have an int variable n = 8. On most machines this will be a 32 bit value. How can I only get the lower 8 bits (lowest byte) of this in binary? Also how can I access each bit to find out what it is?
unsigned n = 8;
unsigned low8bits = n & 0xFF;
Note a few things:
For bitwise operations, always use the unsigned types
Bits can be extracted from numbers using binary masking with the & operator
To access the low 8 bits the mask is 0xFF because in binary it has its low 8 bits turned on and the rest 0
The low 8 bits of the number 8 are... 8 (think about it for a moment)
To access a certain bit of a number, say the kth bit:
unsigned n = ...;
unsigned kthbit = (1 << k) & n;
Now, kthbit will be 0 if the kth bit of n is 0, and some positive number (2**k) if the kth bit of n is 1.
Use bitwise arithmetic to mask off the lowest 8 bits:
unsigned char c = (x & 0xFF);
To access the nth lowest bit, the equation is (x & (1 << n)) (n of zero indicates the least significant bit). A result of zero indicates the bit is clear, and non-zero indicates the bit is set.
The best way is to use the bit logical operator & with the proper value.
So for the lower 8 bits:
n & 0xFF; /* 0xFF == all the lower 8 bits set */
Or as a general rule:
n & ((1<<8)-1) /* generate 0x100 then subtract 1, thus 0xFF */
You can combine with the bit shift operator to get a specific bit:
(n & (1<<3))>>3;
/* will give the value of the 3rd bit - note the >>3 is just to make the value either 0, or 1, not 0 or non-0 */
You can test if a particular bit is set in a number using << and &, ie:
if (num & (1<<3)) ...
will test if the fourth bit is set or not.
Similarly, you can extract just the lowest 8 bits (as an integer) by using & with a number which only has the lowest 8 bits set, ie num & 255 or num & 0xFF (in hexadecimal).
Related
I am working on a project and it asks me to find the instruction and register from the given input using bit operators. For example:
Given: 0x316ac000 => The output will be lt R5 R10 R11
R: represent the register
I tried to convert it on paper. The way I did it was first convert that input to binary (ignore the 0x), then I group the left most 6 bits which give me a decimal = 12, 12 is sub base on the table.
So how can I actually code it? or the logic on this
Thank you for your help!
Binary is a notation for humans.
To get bits from a number, use the bit shift and bit mask operations. For example, to get bits 3-5 of a value:
(value >> 3) & 0x7
That is, shift right three bits (to get rid of bits 0, 1, and 2) and bit mask (logical AND) with a 7, which equals 0x111.
You can compute a mask by a bit shift and subtract:
(1 << N_bits) - 1
So we can write a function:
unsigned long get_bits( int start, int stop, unsigned long value )
{
unsigned long mask = (1UL << (stop - start + 1)) - 1;
return (value >> start) & mask;
}
BTW, bit shifts are tricky with integers. Use unsigned values.
I haven't been able to find an answer to this on Google, nor do I have any better search ideas. If I have a 2 byte number, a mask, and a third number, how do I replace the masked bits with the third number. For example if I have 0xABCD, the mask 0x0F00, and third number 4 - I would like to replace B with 4 to get A4CD. In other words, I want to be able to replace arbitrary bits selected by a mask with the bits of another arbitrary number (we are assuming that the number replacing the bits fits - i.e. if I mask 5 bits, the number to replace those 5 bits requires 5 bits or less to represent.)
The goal is to replace the bits of number selected by mask with those of value, shifted appropriately, assuming value does not exceed the target range.
Masking off the target bits is easy: number &= ~mask; achieves that simply.
The tricky part is to shift value to the left by the number of zero bits in mask below the set ones. You can write a loop for this.
Here is a simple implementation:
unsigned set_bits(unsigned number, unsigned mask, unsigned value) {
// assuming mask != 0
number &= ~mask;
while (!(mask & 1)) {
value <<= 1;
mask >>= 1;
}
return number | value;
}
You can compute the shift value as a multiplier this way: subtracting one from the mask sets all its 0 low bits to 1, or-ing this value with mask sets all low bits to 1 and xor-ing with mask yields a mask with just the low bits set. Adding 1 to this mask gives the power of 2 by which to multiply value to shift it in place. This works also if there are no 0 bits in the low order bits of mask.
As commented by aschepler, (A ^ (A | B)) == (~A & B) so the expression ((mask ^ (mask | (mask - 1))) + 1) can be simplified as (((mask - 1) & ~mask) + 1).
An elegant simplification was provided by Falk Hüffner: (((mask - 1) & ~mask) + 1) is just mask & -mask.
Here is a branchless version using this trick:
unsigned set_bits(unsigned number, unsigned mask, unsigned value) {
return (number & ~mask) | (value * (mask & -mask));
}
Making this an inline function may help the compiler generate optimal code for constant mask values.
In other words, sets the last 5 bits of integer variable x to zero, also it must be in a portable form.
I was trying to do it with the << operator but that only moves the bits to the left, rather than changing the last 5 bits to zero.
11001011 should be changed to 11000000
Create a mask that blanks out that last n integers if it is bitwise-ANDed with your int:
x &= ~ ((1 << n) - 1);
The expression 1 << n shifts 1 by n places and is effectively two to the power of n. So for 5, you get 32 or 0x00000020. Subtract one and you get a number that as the n lowest bits set, in your case 0x0000001F. Negate the bits with ~ and you get 0xFFFFFFE0, the mask others have posted, too. A bitwise AND with your integer will keep only the bits that the mask and your number have in common, which can only bet bits from the sixth bit on.
For 32-bit integers, you should be able to mask off those bits using the & (bitwise and) operator.
x & 0xFFFFFFE0.
http://en.wikipedia.org/wiki/Bitwise_operation#AND
You can use bitwise and & for this
int x = 0x00cb;
x = x & 0xffe0;
This keeps the higher bits and sets the lower bits to zero.
Consider the following integer:
uint32_t p = 0xdeadbeef;
I want to get:
0..3 bits so I did:
p & ((1 << 4) - 1); and that went good.
however, for 4..7 what I tried did not go as expected:
(p >> 16) & 0xFFFF0000
Why would it not extract the bits I want? Am I not moving p 16 positions to the right and then taking out 4 bits?
Would really appreciate an answer with explanation, thanks!
If you want to get bits from 4..7
(p>>4) & 0xf
If you want to get bits from N to (N+4-1)
(p>>N) & 0xf
And N should be <32 (if your system is 32 bits system). otherwise you will get undefined behaviour
No, you're actually removing bits 0 to 15 from p, so it will hold 0xdead and afterwards you perform the bitwise and so this will yield 0.
If you want to extract the upper 16 bits you will first have to the & operation and shift afterwards:
p = (p & 0xffff0000) >> 16;
To extracts the bits 4 to 7 you will want to do:
p = p & 0xf0;
or if you want them shifted down
p = (p & 0xf0) >> 4;
Btw. Could it be that mean the term nibble 4 to 7 instead of bit 4..7? Nibbles are 4 bits and represented by one hex digit, this would correlate with what you are trying to in the code
If we have a decimal value: 123
and its binary version: 01111011
How can I get four leftmost and the four rightmost bits from this byte into 2 separate int variables?
I mean:
int a = 7; // 0111 (the first four bits from the left)
int b = 11; // 1011 (the first four bits from the right)
Much appreciated!
int x = 123;
int low = x & 0x0F;
int high = (x & 0xF0) >> 4;
This is called masking and shifting. By ANDing with 0xF (which is binary 00001111) we remove the higher four bits. ANDing with 0xF0 (which is binary 11110000) removes the lower four bits. Then (in the latter case), we shift to the right by 4 bits, in effect, pushing away the lower 4 bits and leaving only what were the upper 4 bits.
As #owlstead says in the comments below, there's another way to get the higher bits. Instead of masking the lower bits then shifting, we can just shift.
int high = x >> 4;
Note that we don't need to mask the lower bits since whatever they were, they're gone (we've pushed them out). The above example is clearer since we explicitly zero them out first, but there's no need to do so for this particular example.
But to deal with numbers bigger than 16 bits (int is usually 32 bits), we still need to mask, because we can have the even higher sixteen bits getting in the way!
int high = (x >> 4) & 0x0F;