Bitwise masking - c

Assuming an environment where long int is a 64-bit type, suppose I have an long int = 0x0123456789ABCDEF and I want to get the byte that represents 89. Would this line work?
n = (n >> (b << 3)) & 0xFF;
where n is the long int and b is the byte I want. So b would be 3 and shifting it left 3 would multiply it by 8 changing it into a byte so shifting should look like this 0x0123456789. Is using & 0xFF the right way to mask to get the last byte?

Yes, this is the correct approach. This online example on ideone.com prints 89 as expected.

Related

How to find the leftmost 6 bits of a number

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.

Getting four bits from the right only in a byte using bit shift operations

I wanted to try to get only the four bits from the right in a byte by using only bit shift operations but it sometimes worked and sometimes not, but I don't understand why.
Here's an example:
unsigned char b = foo; //say foo is 1000 1010
unsigned char temp=0u;
temp |= ((b << 4) >> 4);//I want this to be 00001010
PS: I know I can use a mask=F and do temp =(mask&=b).
Shift operator only only works on integral types. Using << causes implicit integral promotion, type casting b to an int and "protecting" the higher bits.
To solve, use temp = ((unsigned char)(b << 4)) >> 4;

Extracting 4 bits from N to N+4 in unsigned long

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

bitwise operationd to write individual byte of an integer

How do I set the nth byte of an 64 bit unsigned integer regardless of endian type in c ? One of the possible methods I tried is set each bit in a loop.
Assuming n = 0 is the least significant byte, why can't you just do the following:
x |= (0xffull << (n * 8));
If x = 0 and n = 2 this sets x to 0x0ff0000. Unless I am missing something? I don't see what endian-ness has to do with the problem.

Exchange the bytes

I want to exchange the bytes of a number. Example the binary representation of a number is
00000001 00011000 00000100 00001110. I want to reverse it: 00001110 00000100 00011000 00000001.
Can you please help? The current code is below:
void showBits(int n)
{
int i,k,andMask;
for(i=15;i>=0;i--)
{
andMask=1<<i;
k=n&andMask;
k==0?(cout<<"0"):(cout<<"1");
}
}
int reverse(int a)
{
int b=a<<8;
int c=a>>8;
return (b|c);
}
int main()
{
int a=10;
showBits(a);
int b=reverse(a);
showBits(b);
cin.get();
}
Something like this should work:
result = ((number & 0xFF) << 24) | ((number & 0xFF00) << 8) |
((number & 0xFF0000) >> 8) | ((number & 0xFF000000) >> 24);
int myInt = 0x012345678
__asm {
mov eax, myInt
bswap eax
mov myInt, eax
}
If you want to simply reverse a 32-bit number, you can use a bit-shifting technique that isolates each byte region using bit-masks and logical AND, and then swaps those bytes by the appropriate number of shifted bits using the bit-shift operators >> and <<. You can then recombined the bits using logical OR like so:
int temp = 0x12345678;
temp = ((0xFF & temp) << 24) | ((0xFF00 & temp) << 8) | ((0xFF0000 & temp) >> 8) |
((0xFF000000 & temp) >> 24));
You'll now end up with a final value in temp of 0x78563412.
Update: Okay, I'm looking over you code, and noting the following:
The size of int it seems like you're wanting to work with from the binary digit you have posted is 32-bits ... so your showBits function is not cycling through enough bits to display an entire 32-bit integer. As far as I can see right now, it will only show up to the 16 lower bits. So you'll need to be clear on whether you're working on a platform that defines int as 16 or 32-bits.
Your reverse functions is not correct. If you have a 32-bit int like 0x12345678, and you shift it left by 8-bits, you will end up with 0x34567800. Likewise, when you shift it right by 8-bits, you will just end up with 0x00123456. Shifting a number does not rotate the values through their respective positions (i.e., a shift left of 8-bits would not give you 0x34567812). Plus, even if it did, the logical OR of the rotated values would still not be a correct reversal of the values. Instead, you must use the technique described above that uses bit-masks and logical AND to isolate each byte, and then shift those bits the appropriate number of places in order to reverse the bits in a 32-bit word.
If your original task to to convert from machine-specific byte order to big endian and back, take a look at the hton* and ntoh* functions.
http://minix1.woodhull.com/manpages/man3/hton.3.html

Resources