Bit masking and separation in c - c

I am new to c programming and i need help in bit manipulation.
I would like to separate the number from a register which have encoded numbers in BCD.
for example;
the register got '29' as value two bits will denote 2 ='10' and four bits will denote 9='1001'.
It is an 8 bit register and rest bits are zero.
So shifting out the 4 bits will give me 2 at disposal.But what about getting the unit digit?
I need some help regarding that
I'm posting the code here:
#include<stdio.h>
main()
{
int x,y;
y=0x29;
x=y;
x=x>>4;
x=x*10;
printf("%d",x);
return(0);
}

You need to mask it out with binary 00001111, which is decimal 15 or hexadecimal 0x0f.
uint8_t reg = 41; // binary 00101001
uint8_t lo_nibble = (reg >> 0) & 0x0f;
uint8_t hi_nibble = (reg >> 4) & 0x0f;

To form a mask to capture the bottom n bits of a number, you can perform these steps (pen and paper at first, eventually in your head):
start with the value 1.
(1) // == 1 or 00000001
shift the value 1 up by n bits.
(1<<4) // == 16 or 00010000
subtract 1.
(1<<4)-1 // == 15 or 00001111
ANDing this mask with another value or variable will yield the bottom n bits of the number.
int in, hi, lo;
lo = in & ((1<<4)-1);
hi = (in>>4) & ((1<<4)-1);

Related

Swapping bits in an integer in C, can you explain this function to me?

I want to write a function that receives an unsigned char and swaps between bit 2 and bit 4 and returns the new number.
I am not allowed to use if statement.
So I found this function, among other functions, but this was the most simple one to understand (or try to understand).
All other functions involve XOR which I don't really understand to be honest.
unsigned char SwapBits(unsigned char num)
{
unsigned char mask2 = ( num & 0x04 ) << 2;
unsigned char mask4 = ( num & 0x10 ) >> 2;
unsigned char mask = mask3 | mask5 ;
return ( num & 0xeb ) | mask;
}
Can someone explain me what happens here and most important, why?
Why AND is required here and why with hex address?
Why should I AND with 0xeb (255)? I know that's the range of char but why should I do that.
In short,
I know how to read codes. I understand this code, but I don't understand the purpose of each line.
Thanks.
First, the usual convention is that bits are numbered starting from 0 for the least significant bit and counting up. In this case, you have an 8-bit value, so the bits go from 0 on the right up to 7 on the left.
The function you posted still isn't quite right, but I think I see where you (it) was going with it. Here are the steps it's doing:
Pull out bit 2 (which is 3rd from the right) using a mask
Pull out bit 4 (which is 5th from the right) using a mask
Shift bit 2 left 2 positions so it's now in bit 4's original position
Shift bit 4 right 2 positions so it's now in bit 2's original position
Join these two bits together into one value that is now bits 2 and 4 swapped
Mask out (erase using &) only bits 2 and 4 from the original value
Join in (insert using |) the new swapped bits 2 and 4 to complete the transformation
I have rewritten the function to show each step one at a time to help make it clearer. In the original function or other examples you find, you'll see many of these steps all happen together in the same statement.
unsigned char SwapBits(unsigned char num)
{
// preserve only bit 2
unsigned char bit2 = num & 0x04;
// preserve only bit 4
unsigned char bit4 = num & 0x10;
// move bit 2 left to bit 4 position
unsigned char bit2_moved = bit2 << 2;
// move bit 4 right to bit 2 position
unsigned char bit4_moved = bit4 >> 2;
// put the two moved bits together into one swapped value
unsigned char swapped_bits = bit2_moved | bit4_moved;
// clear bits 2 and 4 from the original value
unsigned char num_with_swapped_bits_cleared = num & ~0x14;
// put swapped bits back into the original value to complete the swap
return num_with_swapped_bits_cleared | swapped_bits;
}
The second to last step num & ~0x14 probably needs some explanation. Since we want to save all the original bits except for bits 2 and 4, we mask out (erase) only the bits we're changing and leave all the others alone. The bits we want to erase are in positions 2 and 4, which are the 1s in the mask 0x14. So we do a complement (~) on 0x14 to turn it into all 1s everywhere except for 0s in bits 2 and 4. Then we AND this value with the original number, which has the effect of changing bits 2 and 4 to 0 while leaving all the others alone. This allows us to OR in the new swapped bits as the final step to complete the process.
You have to read about binary representation of number
unsigned char SwapBits(unsigned char num)
{
// let say that [num] = 46, it means that is is represented 0b00101110
unsigned char mask2 = ( num & 0x04 ) << 2;
// now, another byte named mask2 will be equal to:
// 0b00101110 num
// 0b00000100 0x04
// . .1. mask2 = 4. Here the & failed with . as BOTH ([and]) bits need to be set. Basically it keeps only numbers that have the 3rd bit set
unsigned char mask4 = ( num & 0x10 ) >> 2;
// 0b00101110 num
// 0b00010000 0x10 -> means 16 in decimal or 0b10000 in binary or 2^4 (the power is also the number of trailing 0 after the bit set)
// 0b00.....0 mask4 = 0, all bits failed to be both set
unsigned char mask = mask3 | mask5 ;
// mask will take bits at each position if either set by mask3 [or] mask5 so:
// 0b1001 mask3
// 0boo11 mask4
// 0b1011 mask
return ( num & 0xeb ) | mask; // you now know how it works ;) solve this one. PS: operation between Brackets have priority
}
If you are interested to learn the basics of bitwise operators you can take a look at this introduction.
After you build confidence you can try solving algorithms using only bitwise operators, where you will explore even deeper bitwise operations and see its impact on the runtime ;)
I also recommend reading Bit Twiddling Hacks, Oldies but Goodies!
b = ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32; // reverse your byte!
Simple function to understand swap of bit 3 and 5:
if you want to swap bit index 3 and bit index 5, then you have to do the following:
int n = 0b100010
int mask = 0b100000 // keep bit index 5 (starting from index 0)
int mask2 = 0b1000 // keep bit index 3
n = (n & mask) >> 2 | (n & mask2) << 2 | (n & 0b010111);
// (n & mask) >> 2
// the mask index 5 is decrease by 2 position (>>2) and brings along with it the bit located at index 5 that it had captured in n thanks to the AND operand.
// | (n & mask2) << 2
// mask2 is increased by 2 index and set it to 0 since n didn't have a bit set at index 3 originally.
// | (n & 0b010111); // bits 0 1 2 and 4 are preserved
// since we assign the value to n all other bits would have been wiped out if we hadn't kept their original value thanks to the mask on which we do not perform any shift operations.

Extracting specific bits from a 4 byte value into a new variable in C

I'm very new to bit manipulations.
let's suppose I have a 32 bit value myInput4ByteValue.
From this 32 bit value I need to extract the bits 25 ..2
What would be the best approach here?
My Idea is to split them into 3 bytes and copy the values there:
struct myOutput3ByteValue.
{
uint8 FirstPart // Bits 9..2 Least Significant 8 Bits from myInput4ByteValue.
uint8 SecondPart // Bits 17 ..10
uint8 ThirdPart // Bits 25 ..18
}
I started with:
myOutput3ByteValue.FirstPart = (myInput4ByteValue & 0x3FC0) // Here I will the bits 9..2
myOutput3ByteValue.SecondPart = ...? //How to fill the rest?
I'm really not sure if I started correctly.
Suggestions would be helpful.
The reason why I split them into 3 bytes is because I will have an own 3 byte-type at the end with which I have to work with it.
What you've got there wont' quite work. 0x3FC0 is a 16 bit int and you're assigning it to an 8 bit int, so it'll get truncated. You need to bitshift << or >>.
So bits 9..2 are:
FirstPart = (value >> 1); // No need to mask as bits 9+ will be truncated
SecondPart = (value >> 9); // Second set of 8 bits
Let's assume you want to put the extracted bits in a single UINT32 variable. What you need is simply to filter first 26 bits and shift them twice:
uint32 filteredValue = ( myInput4ByteValue & 0x03FFFFFF ) >> 2;
With the same logic, you can extract whatever you need and place them in any set of variable, according to the use you have to do wit the filtered bits.
You might want to define a general function performing the bits extraction:
uint32 filterValue( uint32 inValue, uint8 msb, uint8 lsb )
{
uint32 retValue = inValue;
// Let's just check that input params are ok
if( msb < 32 && lsb <32 && msb >= lsb )
{
retValue = ( inValue & ( 0xFFFFFFFF >> ( 31 - msb ) >> lsb;
}
//else... input value unchanged. It doesn't make sense, but it's just an example..
return retValue;
}
I personally wrote and tested it, and it works. Note: it's just an example! Change it according to your requirements.
myInput4ByteValue & 0x3FFFFFF extracts the last 26 bits (the leftmost bit would be bit 25, as one usually starts counting from the right with bit 0).
(myInput4ByteValue & 0x3FFFFFF) >> 2 shifts bits these two places to the right. This would hold your complete 23 bits.
If, however you want to have everything in 8-bit chunks, you could do:
myOutput3ByteValue.FirstPart = (myInput4ByteValue & 0x7F8) >> 2; // bits 9..2
myOutput3ByteValue.SecondPart = (myInput4ByteValue & 0x7F800) >> 10; // bits 17..10
myOutput3ByteValue.ThirdPart = (myInput4ByteValue & 0x3F80000) >> 18; // bits 25..18
Another approach, which could be much easier to read and maintain, is the use of bitfields. See e.g. http://www.catb.org/esr/structure-packing/#_bitfields .
Depending on whether individual bits or groups of bits have a particular meaning, you can give them their own name. If you align the structure nicely, you can simply copy the 32 bit input upon a variable with such a struct as type.
Just write a separate function that extracts no more than 8 bits starting from a given position from a number of the type uint32_t.
Here is a demonstrative program
#include <stdio.h>
#include <stdint.h>
uint8_t getbits( uint32_t x, unsigned p, unsigned n)
{
const unsigned N = 8;
n %= N + 1;
return ( x >> p ) & ~( ~( uint32_t )0 << n );
}
int main(void)
{
uint32_t x = 0x12345678;
/*0001 0010 0011 0100 0101 0110 0111 1000 */
/* ^^^^^^^^^^ = 0x9E */
struct myOutput3ByteValue
{
uint8_t FirstPart; // Bits 9..2 Least Significant 8 Bits from myInput4ByteValue.
uint8_t SecondPart; // Bits 17 ..10
uint8_t ThirdPart; // Bits 25 ..18
} s =
{
.FirstPart = getbits( x, 2, 8 ),
.SecondPart = getbits( x, 10, 8 ),
.ThirdPart = getbits( x, 18, 8 )
};
printf( "%x, %x, %x\n", s.FirstPart, s.SecondPart, s.ThirdPart );
return 0;
}
Its output is
9e, 15, 8d

How do I extract bits from 32 bit number

I have do not have much knowledge of C and I'm stuck with a problem since one of my colleague is on leave.
I have a 32 bit number and i have to extract bits from it. I did go through a few threads but I'm still not clear how to do so. I would be highly obliged if someone can help me.
Here is an example of what I need to do:
Assume hex number = 0xD7448EAB.
In binary = 1101 0111 0100 0100 1000 1110 1010 1011.
I need to extract the 16 bits, and output that value. I want bits 10 through 25.
The lower 10 bits (Decimal) are ignored. i.e., 10 1010 1011 are ignored.
And the upper 6 bits (Overflow) are ignored. i.e. 1101 01 are ignored.
The remaining 16 bits of data needs to be the output which is 11 0100 0100 1000 11 (numbers in italics are needed as the output).
This was an example but I will keep getting different hex numbers all the time and I need to extract the same bits as I explained.
How do I solve this?
Thank you.
For this example you would output 1101 0001 0010 0011, which is 0xD123, or 53,539 decimal.
You need masks to get the bits you want. Masks are numbers that you can use to sift through bits in the manner you want (keep bits, delete/clear bits, modify numbers etc). What you need to know are the AND, OR, XOR, NOT, and shifting operations. For what you need, you'll only need a couple.
You know shifting: x << y moves bits from x *y positions to the left*.
How to get x bits set to 1 in order: (1 << x) - 1
How to get x bits set to 1, in order, starting from y to y + x: ((1 << x) -1) << y
The above is your mask for the bits you need. So for example if you want 16 bits of 0xD7448EAB, from 10 to 25, you'll need the above, for x = 16 and y = 10.
And now to get the bits you want, just AND your number 0xD7448EAB with the mask above and you'll get the masked 0xD7448EAB with only the bits you want. Later, if you want to go through each one, you'll need to shift your result by 10 to the right and process each bit at a time (at position 0).
The answer may be a bit longer, but it's better design than just hard coding with 0xff or whatever.
OK, here's how I wrote it:
#include <stdint.h>
#include <stdio.h>
main() {
uint32_t in = 0xd7448eab;
uint16_t out = 0;
out = in >> 10; // Shift right 10 bits
out &= 0xffff; // Only lower 16 bits
printf("%x\n",out);
}
The in >> 10 shifts the number right 10 bits; the & 0xffff discards all bits except the lower 16 bits.
I want bits 10 through 25.
You can do this:
unsigned int number = 0xD7448EAB;
unsigned int value = (number & 0x3FFFC00) >> 10;
Or this:
unsigned int number = 0xD7448EAB;
unsigned int value = (number >> 10) & 0xFFFF;
I combined the top 2 answers above to write a C program that extracts the bits for any range of bits (not just 10 through 25) of a 32-bit unsigned int. The way the function works is that it returns bits lo to hi (inclusive) of num.
#include <stdio.h>
#include <stdint.h>
unsigned extract(unsigned num, unsigned hi, unsigned lo) {
uint32_t range = (hi - lo + 1); //number of bits to be extracted
//shifting a number by the number of bits it has produces inconsistent
//results across machines so we need a special case for extract(num, 31, 0)
if(range == 32)
return num;
uint32_t result = 0;
//following the rule above, ((1 << x) - 1) << y) makes the mask:
uint32_t mask = ((1 << range) -1) << lo;
//AND num and mask to get only the bits in our range
result = num & mask;
result = result >> lo; //gets rid of trailing 0s
return result;
}
int main() {
unsigned int num = 0xd7448eab;
printf("0x%x\n", extract(num, 10, 25));
}

How can I access a specific group of bits from a variable?

I have a variable with "x" number of bits. How can I extract a specific group of bits and then work on them in C?
You would do this with a series of 2 bitwise logical operations.
[[Terminology MSB (msb) is the most-significant-bit; LSB (lsb) is the least-significant-bit. Assume bits are numbered from lsb==0 to some msb (e.g. 31 on a 32-bit machine). The value of the bit position i represents the coefficient of the 2^i component of the integer.]]
For example if you have int x, and you want to extract some range of bits x[msb..lsb] inclusive, for example a 4-bit field x[7..4] out of the x[31..0] bits, then:
By shifting x right by lsb bits, e.g. x >> lsb, you put the lsb bit of x in the 0th (least significant) bit of the expression, which is where it needs to be.
Now you have to mask off any remaining bits above those designated by msb. The number of such bits is msb-lsb + 1. We can form a bit mask string of '1' bits that long with the expression ~(~0 << (msb-lsb+1)). For example ~(~0 << (7-4+1)) == ~0b11111111111111111111111111110000 == 0b1111.
Putting it all together, you can extract the bit vector you want with into a new integer with this expression:
(x >> lsb) & ~(~0 << (msb-lsb+1))
For example,
int x = 0x89ABCDEF;
int msb = 7;
int lsb = 4;
int result = (x >> lsb) & ~(~0 << (msb-lsb+1));
// == 0x89ABCDE & 0xF
// == 0xE (which is x[7..4])
Make sense?
Happy hacking!
If you're dealing with a primitive then just use bitwise operations:
int bits = 0x0030;
bool third_bit = bits & 0x0004; // bits & 00000100
bool fifth_bit = bits & 0x0010; // bits & 00010000
If x can be larger than a trivial primitive but is known at compile-time then you can use std::bitset<> for the task:
#include<bitset>
#include<string>
// ...
std::bitset<512> b(std::string("001"));
b.set(2, true);
std::cout << b[1] << ' ' << b[2] << '\n';
std::bitset<32> bul(0x0010ul);
If x is not known at compile-time then you can use std::vector<unsigned char> and then use bit-manipulation at runtime. It's more work, the intent reads less obvious than with std::bitset and it's slower, but that's arguably your best option for x varying at runtime.
#include<vector>
// ...
std::vector<unsigned char> v(256);
v[2] = 1;
bool eighteenth_bit = v[2] & 0x02; // second bit of third byte
work on bits with &, |. <<, >> operators.
For example, if you have a value of 7 (integer) and you want to zero out the 2nd bit:
7 is 111
(zero-ing 2nd bit AND it with 101 (5 in decimal))
111 & 101 = 101 (5)
here's the code:
#include <stdio.h>
main ()
{
int x=7;
x= x&5;
printf("x: %d",x);
}
You can do with other operators like the OR, shift left, shift right,etc.
You can use bitfields in a union:
typedef union {
unsigned char value;
struct { unsigned b0:1,b1:1,b2:1,b3:1,b4:1,b5:1,b6:1,b7:1; } b;
struct { unsigned b0:2,b1:2,b2:2,b3:2; } b2;
struct { unsigned b0:4,b1:4; } b4;
} CharBits;
CharBits b={0},a={0};
printf("\n%d",b.value);
b.b.b0=1; printf("\n%d",b.value);
b.b.b1=1; printf("\n%d",b.value);
printf("\n%d",a.value);
a.b4.b1=15; printf("\n%d",a.value); /* <- set the highest 4-bit-group with one statement */

How do I get the lower 8 bits of an int?

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).

Resources