简体   繁体   中英

Bitwise Operations in C: setting bits from left

Given an integer like 10, how could I write 10 1 bits (starting from the left) in a total of 16 bits like so:

11111111.11000000

Or given an integer like 4, it would write:

11110000.00000000

Thanks, I'm still learning C and am not familiar with bitwise operations.

-(1 << wordsize - numbits) ought to do it.

It's instructive to see what happens in your example. 1 << wordsize - numbits is 1 << 12 , which is 00010000.00000000 . Recalling that -x = ~x+1 , we compute ~(1 << 12) = 11101111.111111 . Add 1 and you get 11110000.00000000 .

Actually, the int it is usually 32 bits. But I just put 16 bits in the comments, to make it more clear.

int i = 0; //00000000 00000000
int mask = 65536; //10000000 00000000
int retVal = 0; //00000000 00000000
int yourAmountOfBitsToOne = 2;

for(i = 0; i < yourAmountOfBitsToOne; i++){
    retVal = retVal | (mask >> i);
}

printf("%d", retVal);

If you run this the output should be 2ˆ16 + 2ˆ15 = 98304.

Why?

Iteration 0:

line 1: retVal = 00000000 00000000 | (10000000 00000000 >> 0)
line 1: retVal = 10000000 00000000

Iteration 1:

line 1: retVal = 10000000 00000000 | (10000000 00000000 >> 0)
line 1: retVal = 10000000 00000000 | (01000000 00000000)
line 1: retVal = 11000000 00000000 

After the for finishes, you print the integer value of 11000000 00000000 which is 98304 .

Create a function now that prints the int retVal bit by bit, it will make you easy to check if the output is correct. And it is also a very good exercise to learn bitwise operators.

Hope it helps.

ints are typically 32 bits. If you're referring to short integers, then:

unsigned short MakeMask16(unsigned short width,unsigned short offsetFromLeft)
{
    unsigned short mask = -1;
    mask <<= (sizeof(unsigned short)*8-width);
    mask >>= offsetFromLeft;
    return mask;
}

Or all on one line:

unsigned short MakeMask16(unsigned short width,unsigned short offsetFromLeft)
{
    return (unsigned short(-1<<(sizeof(unsigned short)*8-width)) >> offsetFromLeft);
}

Note that if you don't cast it to an unsigned short before right-shifting, the 1's you thought you pushed off the left will still be there. If you don't need to offset from the left, then you can ignore that and strip away the right-shifting.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM