Set last n bits in C - c

I wan't to set the last n bits of any given number to 1. I have a number (which is variable in it's lenght) and a variable n.
Example:
12 (dec) set last 2 bits
Output: 15
Now the basic operation should be something like:
return 0b11 | 12;
But how can I make 0b11 variable in length?
Thank you!

Try this:
int SetLastBits(int value,int numOfBits)
{
return value | ((1<<numOfBits)-1);
}

You can set the last n bits of a number to 1 in the following manner:
int num = 5; // number of bits to set to 1
int val = <some_value>;
val |= (1 << num) - 1;

You can do it like this:
uint32_t set_last_n_bits(uint32_t x, uint32_t bits)
{
return x | ((1U << bits) - 1U);
}
This is also a relatively rare case where a macro might be justifiable, on the grounds that it would work with different integer types.

As all others have showed the same approach I will show one more approach
int value;
//...
value |= ~( ~0u << n );
Here is a demonstrative program
#include <stdio.h>
int set_bits( int x, size_t n )
{
return x | ~( ~0u << n );
}
int main(void)
{
int x = 12;
printf( "%d\t%d\n", x, set_bits( x, 2 ) );
return 0;
}
The output is
12 15

Related

Why is the wrong binary number displayed?

Code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
long int x;
x = 1000000;
printf("%ld\n", x);
for(int i = 0; i < 32; i++)
{
printf("%c", (x & 0x80) ? '1' : '0');
x <<= 1;
}
printf("\n");
return 0;
}
This code is supposed to convert a decimal int to binary, but why doesn't it work correctly?
P.S. I solved this problem by replacing 0x80 with 0x80000000. But why was the wrong number displayed at 0x80?
EDIT2:
OP asks "P.S. I solved this problem by replacing 0x80 with 0x80000000. But why was the wrong number displayed at 0x80?"
What was wrong was 0x80 is equal to 0x00000080. 0x80 will never test any bits above b7 (where bits, right to left, are numbered b0 to b31.
The corrected value, 0x80000000, sets the MSB high and can be used (kind of) to 'sample' each bit of the data as the data value is 'scrolled' to the left.
//end edit2
Two concerns:
1) Mucking with the sign bit of a signed integer can be problematic
2) "Knowing" there are 32 bits can be problematic.
The following makes fewer presumptions. It creates a bit mask (only the MSB is set in an unsigned int value) and shifts that mask toward the LSB.
int main() {
long int x = 100000;
printf("%ld\n", x);
for( unsigned long int bit = ~(~0u >> 1); bit; bit >>= 1 )
printf("%c", (x & bit) ? '1' : '0');
printf("\n");
return 0;
}
100000
00000000000000011000011010100000
Bonus: Here is a version of the print statement that doesn't involve branching:
printf( "%c", '0' + !!(x & bit) );
EDIT:
Having seen the answer by #Lundin, the suggestion to insert SP's to improve readability is an excellent idea! (Full credit to #Lundin.)
Below, not only is the long string of bits output divided into "hexadecimal" chunks, but the compile time value is shown in a way to easily see it is 10million. (1e7 would have done, too.)
A new-and-improved version:
#include <stdio.h>
#include <stdlib.h>
int main() {
long int x = 10 * 1000 *1000;
printf("%ld\n", x);
for( unsigned long int bit = ~(~0u >> 1); bit; bit >>= 1 ) {
putchar( '0' + !!(x & bit) );
if( bit & 0x11111111 ) putchar( ' ' );
}
putchar( '\n' );
return 0;
}
10000000
0000 0000 1001 1000 1001 0110 1000 0000
1000000 dec = 11110100001001000000 bin.
80 hex = 10000000 bin.
And this doesn't make much sense at all:
11110100001001000000
& 10000000
Instead fix the loop body to something like this:
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
long int x;
x = 1000000;
printf("%ld\n", x);
for(int i = 0; i < 32; i++)
{
unsigned long mask = 1u << (31-i);
printf("%c", (x & mask) ? '1' : '0');
if((i+1) % 8 == 0) // to print a space after 8 digits
printf(" ");
}
printf("\n");
return 0;
}
Without using an integer counter to see what digit is at the ith position, you can instead use an unsigned variable which is equal to 2^i at the ith iteration. If this variable is unsigned, when it overflows it will become zero. Here is how the code would look like. It displays the number in reversed order (first position means the coefficient of 2^0 in the polynomial decomposition of the number).
int
main()
{
int x;
x = 1000000;
printf("%lx\n", x);
for(unsigned b = 1; b; b<<=1)
printf("%c", x & b ? '1':'0');
printf("\n");
return 0;
}
I would use functions
void printBin(long int x)
{
unsigned long mask = 1UL << (sizeof(mask) * CHAR_BIT - 1);
int digcount = 0;
while(mask)
{
printf("%d%s", !!(x & mask), ++digcount % 4 ? "" : " ");
mask >>= 1;
}
}
int main(void)
{
printBin(0); printf("\n");
printBin(1); printf("\n");
printBin(0xf0); printf("\n");
printBin(-10); printf("\n");
}

Re-Indexing Bits Within a Char

I have an exercise where I have to encode and decode strings at the bit level that are given in by the command line.
The caveat for this is that I have to use a permutation mapping to re-order the bits.
Here's an Example:
The User Inputs The Character To Encode
H
The Binary for H is
01001000
However, that is the regular mapping of the 8 bits, through 0-7.
My program will have to permute the bits to whatever Mapping Patter I use.
For Example, If I use Mapping 64752031
The Bits for the Char 'H'
01001000
Turn To
01000001
When encoding the char, the 0th bit turns to the 6th bit, the 2nd bit turns to the 4th bit, the 3rd bit turns to the 7th bit, and so on. Whatever is based on for that mapping.
Is there a way that I can manipulate and change the order of bits based on the permutation map given?
Thank you.
If you need to process large strings, it is probably better to use a look-up table that will precompute the translation.
#include <stdio.h>
unsigned char perm[256]; // permutation table
unsigned mapping[8]={6,4,7,5,2,0,3,1};
// assumes 7 6 5 4 3 2 1 0
// => 6 4 7 5 2 0 3 1
void mkperm(unsigned char perm[256]) {
for (int i=0; i<256; i++)
perm[i]=0;
for (int i=0;i<256;i++) {
for (int j=7; j>=0; j--) {
int pos=mapping[7-j]; // at mapping[0] is the new position of bit 7
if (i & (1<<j)) // only considers set bits, the table is previously cleared
perm[i] |= (1<<pos) ;
}
}
}
int main() {
mkperm(perm);
printf("%.2x => %.2x\n",'H',perm['H']);
}
mkperm() computes the permutation table by scanning the successive bits of every char. If a bit is set in char i, we set at position i in the translation table a bit at one at a logical weight given by the mapping. Setting this one is done by oring the content of cell i with a 1 properly shifted.
Use bitwise operators.
Here's an example of how to move the second bit to the seventh bit:
x |= (x & 1<<1) << 6;
x &= ~(1<<1);
If my bit numbering bothers anybody, I'm sorry. This is just how I read binary numbers.
You can also put this into an inline function:
inline int bit_mode(int *x, int bit1, int bit2)
{
*x |= *x & (1<<(bit1-1)) << (bit2-1);
*x &= ~(1<<(bit1-1));
return *x;
}
int a;
bit_mode(&a, 2, 7);
Just shift the bits to proper positions. After some fun, I think I've got this:
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <limits.h>
#include <stdint.h>
/**
* A little helper function
* get the bit number 'as' from the byte 'in'
* and put that bit as the number 'num' in the output
*/
static inline
uint8_t map_get_bit_as(uint8_t in,
uint8_t num, uint8_t as)
{
return (!!(in & (1 << as))) << num;
}
uint8_t map(unsigned long mapping, uint8_t in)
{
// static_assert(CHAR_BIT == 8, "are you insane?");
const int bit0 = mapping / 10000000 % 10;
const int bit1 = mapping / 1000000 % 10;
const int bit2 = mapping / 100000 % 10;
const int bit3 = mapping / 10000 % 10;
const int bit4 = mapping / 1000 % 10;
const int bit5 = mapping / 100 % 10;
const int bit6 = mapping / 10 % 10;
const int bit7 = mapping / 1 % 10;
return
map_get_bit_as(in, 0, bit0) |
map_get_bit_as(in, 1, bit1) |
map_get_bit_as(in, 2, bit2) |
map_get_bit_as(in, 3, bit3) |
map_get_bit_as(in, 4, bit4) |
map_get_bit_as(in, 5, bit5) |
map_get_bit_as(in, 6, bit6) |
map_get_bit_as(in, 7, bit7);
}
int main() {
printf("%#02x %#02x\n\n", 'H', map(64752031, 'H'));
}
will output:
0x48 0x41
tested on repl.
If I have correctly understood the order of bits as you are counting them then the corresponding function can look the following way as it is shown in the demonstrative program.
#include <stdio.h>
#include <limits.h>
#include <stdint.h>
char encode( char c, uint32_t mask )
{
unsigned char result = '\0';
for ( size_t i = 0; i < 2 * sizeof( mask ) ; i++ )
{
uint32_t bit = ( ( ( uint32_t )1 << ( CHAR_BIT - 1 - ( mask & 0xf ) ) ) & c ) != 0;
result |= bit << i;
mask >>= 4;
}
return ( char )result;
}
int main( void )
{
uint32_t mask = 0x64752031;
char c = 'H';
printf( "c = %hhx\n", c );
c = encode( c, mask );
printf( "c = %hhx\n", c );
}
The program output is
c = 48
c = 41

Extracting a particular range of bits and find number of zeros between them in C

I want to extract a particular range of bits in an integer variable.
For example: 0xA5 (10100101)
I want to extract from bit2 to bit5. i.e 1001 to a variable and count number of zeros between them.
I have another variable which give the starting point, which means in this case the value of the variable is 2. So the starting point can be find by 0xA5 >> 2.
5th bit position is a random position here..means it can be 6 or 7. The main idea is whichever bit is set to 1 after 2nd bit. I have to extract that..
How can I do rest of the part ?
Assuming you are dealing with unsigned int for your variable.
You will have to construct the appropriate mask.
Suppose you want the bits from position x to position y, there need to be y - x + 1 1s in the mask.
You can get this by -
int digits = y - x + 1;
unsigned int mask = 1u << digits - 1;
Now you need to remove the lower x bits from the initial number, which be done by -
unsigned int result = number >> x;
Finally apply the mask to remove the upper bits -
result = result & mask;
In this example we put 0 or 1 values into array. After that you can treat array as you like.
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv) {
uint8_t value = 0xA5;
unsigned char bytes[8];
unsigned char i;
for (i = 0; i < 8; i++) {
bytes[i] = (value & (1 << i)) != 0 ? 1 : 0;
}
for (i = 0; i < 8; i++) {
printf("%d", bytes[i]);
}
return 0;
}
You could use a mask and the "&" (AND) operation:
a = 0xA5;
a = a >> OFFSET; //OFFSET
mask = 0x0F; // equals 00001111
a = a & mask;
In your example a = 0xA5 (10100101), and the offset is 2.
a >> 2 a now equals to 0x29 (00101001)
a & 0x0F (00101001 AND
00001111) = 00001001 = 0x09
If you want bits from the offset X then shift right by X.
If you want Y bits, then then mask (after the shift) will be 2 to the power of Y minus one (for your example with four bits, 2 to the power of 4 is 16, minus one is 15 which is 1111 binary). This can be dome by using left-shifting by Y bits and subtracting 1.
However, the masking isn't needed if you want to count the number of zeros in the wanted bits, only the right shift. Loop Y times, each time shifting a 1 left one step, and check using bitwise and if the value is zero. If it is then increment a counter. At the end of the loop the counter is the number of zeros.
To put it all in code:
// Count the number of zeros in a specific amount of bits starting at a specific offset
// value is the original value
// offset is the offset in bits
// bits is the number of bits to check
unsigned int count_zeros(unsigned int value, unsigned int offset, unsigned int bits)
{
// Get the bits we're interested in the rightmost position
value >>= offset;
unsigned int counter = 0; // Zero-counter
for (unsigned int i = 0; i < bits; ++i)
{
if ((value & (1 << i)) == 0)
{
++counter; // Bit is a zero
}
}
return counter;
}
To use with the example data you have:
count_zeros(0xa5, 2, 4);
The result should be 2. Which it is if you see this live program.
int32_t do_test(int32_t value, int32_t offset)
{
int32_t _zeros = 1;
value >>= offset;
int i = 1;
while(1) {
if((value >> i) % 2 == 0) {
_zeros += 1;
i++;
} else {
break;
}
}
}
int result = (0xA5 >> 2) & 0x0F;
Truth table for the & operator
| INPUTS | OUTPUT |
-----------------------
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
-----------------------

Bitwise Operation on a byte and an int

I have a byte array represented as
char * bytes = getbytes(object); //some api function
I want to check whether the bit at some position x is set.
I've been trying this
int mask = 1 << x % 8;
y= bytes[x>>3] & mask;
However y returns as all zeros? What am I doing incorrectly and is there an easier way to check if a bit is set?
EDIT:
I did run this as well. It didn't return with the expected result either.
int k = x >> 3;
int mask = x % 8;
unsigned char byte = bytes[k];
return (byte & mask);
it failed an assert true ctest I ran. Byte and Mask at this time where "0002" and 2 respectively when printed from gdb.
edit 2: This is how I set the bits in the first place. I'm just trying to write a test to verify they are set.
unsigned long x = somehash(void* a);
unsigned int mask = 1 << (x % 8);
unsigned int location = x >> 3;
char* filter = getData(ref);
filter[location] |= mask;
This would be one (crude perhaps) way from the top of my head:
#include "stdio.h"
#include "stdlib.h"
// this function *changes* the byte array
int getBit(char *b, int bit)
{
int bitToCheck = bit % 8;
b = b + (bitToCheck ? (bit / 8) : (bit / 8 - 1));
if (bitToCheck)
*b = (*b) >> (8 - bitToCheck);
return (*b) & 1;
}
int main(void)
{
char *bytes = calloc(2, 1);
*(bytes + 1)= 5; // writing to the appropiate bits
printf("%d\n", getBit(bytes, 16)); // checking the 16th bit from the left
return 0;
}
Assumptions:
A byte is represented as:
----------------------------------------
| 2^7 | 2^6 | 2^5 | 2^4 | 2^3 |... |
----------------------------------------
The left most bit is considered bit number 1 and the right most bit is considered the max. numbered bit (16th bit in a 2 byte object).
It's OK to overwrite the actual byte object (if this is not wanted, use memcpy).

Understanding bit manipulation (set/clear) in C programming

I'm stuck understanding bit operations on integers in C.
Suppose I have the number 13. Its binary representation is 1101. How can I set the bit at its second position? How can I clear the bit?
Here is the function I wrote so far for setting the bit:
int setBit(int data, int pos, int val)
{
if (val==1)
data |= (1U << (pos - 1));
else
data ^= (1U << (pos-1));
return data;
}
Will this work correctly?
n = n & (~(1U <<x)) will reset the bit in position x.
Actually what we are doing suppose n=1101
We want to reset 3rd bit.
How does it work?
So 1U <<3=000....1000
~( 1U <<3)=111....0111
n=000..1101
& 111..0111
Result is 000..0101.
For inserting a bit y at position x:(position starts from 0)
1101---->11y01
Giving the example for position 2.
num= FFFF FFFF (in hex)(all 1's) //1111......1111
number=N // in which you will insert bit
num1=num<<x; //for x=2 as in this case
//num1=1111.....1100
num2=~(num1); //num2=0000.....0011
lowbits=N & num2; // =0000.....0001 (N=1101)
highbits= N &num1;// =0000.....1100
highbits<<=1; // =0000....11000
N= highbits | lowbits;//=0000....11001
Now set the x-th bit(here x=2) as you required using the method described below
Note: More generally changing the kth bit of number n to y (maybe 0 or 1) can be done this way
n^=(-y ^ n) & (1U <<k); (&- logical and)
Deletion of a bit is similar to insertion. Step by step perform the operation and you will get it.
EDIT: I have changed the use of 1 to 1U because in first case when using only 1 without any modifiers is defined to be an signed int. From K&R the right shifts of signed values are implementation defined. Also if you left-shift a signed number so that the sign bit is affected, the result is undefined.
These operations on unsigned value have well define behaviour: Vacated fields are filled with zeroes.
Setting, clearing and toggling the state of a bit is straightforward:
inline void bit_set (unsigned long *bf, unsigned char n)
{ *bf |= (1 << n); }
inline void bit_clear (unsigned long *bf, unsigned char n)
{ *bf &= ~(1 << n); }
inline void bit_toggle (unsigned long *bf, unsigned char n)
{ *bf ^= (1 << n); }
Note: bitfields, and the functions above, are zero based (i.e. the least significant bit is bit 0 not bit 1) So if you want to clear, set or toggle the second bit from the right (bit index 1, the 2's bit (binary), or bit 2 counting right-to-left), you pass a bit index of 1. n in the functions above is the bit index. The following is a quick reference:
+-----+-----+-----+-----+-----+-----+-----+-----+
bit index | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-----+-----+-----+-----+-----+-----+-----+-----+
binary | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
+-----+-----+-----+-----+-----+-----+-----+-----+
Here is a quick example of the use operating on bit 1, (the 2's bit in binary):
#include <stdio.h>
#include <stdlib.h>
#define WDSZ 64
/* bit functions */
inline void bit_set (unsigned long *bf, unsigned char n) { *bf |= (1 << n); }
inline void bit_clear (unsigned long *bf, unsigned char n) { *bf &= ~(1 << n); }
inline void bit_toggle (unsigned long *bf, unsigned char n) { *bf ^= (1 << n); }
/* simple return of binary string */
char *binstr (unsigned long n);
int main (int argc, char **argv) {
unsigned long bf = (argc > 1) ? strtoul (argv[1], NULL, 10) : 13;
printf ("\n original value : %3lu (%s)\n", bf, binstr (bf));
bit_set (&bf, 1);
printf (" set bit 1 : %3lu (%s)\n", bf, binstr (bf));
bit_clear (&bf, 1);
printf (" clear bit 1 : %3lu (%s)\n", bf, binstr (bf));
bit_toggle (&bf, 1);
printf (" toggle bit 1 : %3lu (%s)\n\n", bf, binstr (bf));
return 0;
}
/* simple return of binary string */
char *binstr (unsigned long n) {
static char s[WDSZ + 1] = {0};
char *p = s + WDSZ;
while (n) {
p--;
*p = (n & 1) ? '1' : '0';
n >>= 1;
}
return p;
}
Output
$ ./bin/bitsetcleartoggle
original value : 13 (1101)
set bit 1 : 15 (1111)
clear bit 1 : 13 (1101)
toggle bit 1 : 15 (1111)
Here is a simple answer for what I understand your problem to be:
int setBit(int data, int pos, int val) {
if (val)
return data | (1U << (pos - 1));
else
return data & ~(1U << (pos - 1));
}
But I think numbering the bits starting at 1 is not a good idea. The more common usage is to number the bits from 0 to sizeof(type) * CHAR_BIT - 1
whenever I have a problem like this I will break it down into smaller parts...
suppose i have no 13 binary of 13 is 1101
now how can i add extra bit at second position?
ok that is pretty straight forward... first let make a number with a bit in the second position, zero's everywhere else... we will use an int for convenience...
int mask = 2; // or 0x2 if you rather or 0b10 if your compiler supports that ...
well that isn't very special, I can't reuse that machinery as it were... so let try a different way...
int mask = 1 << 1; // 1 in the fist position moved one to the left...
ok now we have part, now there are 2 intuitive ways to set that on our 13...
int answer = 13 | mask; // binary OR
or
int answer = 13 + mask;
these 2 are the same for 13... but will give you different answers for 14... because + always adds the value, and | will only change the bits that aren't set on the left side... so you need to pick the semantics that are correct for you...
now your second question is a little trickier ... first we will pick the same mask...
//pick nth bit
int mask = 1 < n;
// now to toggle that on a number... XOR
int answer = q ^ mask;
I like using the n'th vs position because it makes more sense in the 0 case...
//For Inserting Bit
int insertbit(int data,int pos,int val)
{
int no1,no2;
no1=data;
no1=no1>>(pos-1);
no1=no1<<(pos-1);
no2=data-no1;
no1=no1<<1;
no1=no1 | no2;
if(val==1)
{
no1=setbit(no1,pos,val);
}
return no1;
}
//Setting Bits
int setbit(int data,int pos,int val)
{
int no=1;
no=no<<(pos-1);
if(val==0)
{
no=~no;
data=data&no;
}
else
{
data=no|data;
}
return data;
}
I Coded This Way But I Need Some Shortcut for code insert function

Resources