Home > Software design >  How to Toggle all bits in a number?
How to Toggle all bits in a number?

Time:01-28

#include <stdio.h>

int main() {
    int n = 10;
    int ans = n ^ (1 << 2);
    printf("%d", ans);
}

this code toggle specific digits, But I need entire bits to toggle example: 10 -> 0b1010 -> 0b0101 -> 5

CodePudding user response:

You toggle all bits with tilde (~):

#include<stdio.h>

int main(void)
{
    int n = 10;
    int ans = ~n; // toggle all bits with "tilde"

    printf("x =\n"
           "x =\n", n, n, ans, ans);
}

Possible output:

0000000a  10
fffffff5 -11

There was a new requirement after I posted this answer:

But I need entire bits to toggle example: 10 -> 1010 -> 0101 -> 5

You could create some macros to help you to toggle the exact bits you're interested in. I've created a few below to get you started. They are probably not the most elegant bit twiddling macros around but should be clear enough for you to decipher.

#include <stdio.h>
#include <limits.h>

// the number of bits in the supplied `v`:
#define BITS(v) (sizeof(v) * CHAR_BIT)

// right-shift all but `n` bits from ~0ull (an unsigned long long with all 1:s)
// if `n == 0` we right-shift one less than wanted and remove it afterwards,
// creating a mask with all zeroes
#define MASKnBITS(n) ((~0ull >> (BITS(~0ull) - ((n)   ((n)==0)))) - ((n) == 0))

// create a mask for a range of bits. Example: 4,8 will create the mask
// ...11110000
#define MASKRANGE(bx,by) (MASKnBITS(by)^MASKnBITS(bx))

// toggle the bits in a masked range by using XOR:
#define TOGGLEBITSbxTOby(bx,by,v) (MASKRANGE((bx),(by)) ^ (v))

Usage:

int main(void) {
    // some examples:
    printf("%llx\n", MASKnBITS(4));    // f
    printf("%llx\n", MASKnBITS(8));    // ff
    printf("%llx\n", MASKRANGE(4,8));  // f0 == 0f ^ ff
    printf("%llx\n", MASKRANGE(8,4));  // f0 == ff ^ 0f

    // your case:
    int n = 10;
    int ans = TOGGLEBITSbxTOby(4,0,n); // toggle the 4 least significant bits
    printf("%d\n", ans);               // 5
}

CodePudding user response:

As Ted and others have mentioned Bitwise Compliment Operator ~ can be used to flip all the bits in a number.

For your problem though, you can use the following:

#include <stdio.h>

int main() {
    int n = -3;
    int inv = 0;
    int size = sizeof(n)*8;
    int in[size],x;
    
    if(n>=0){
        for(int i=0; i<size;i  ){
            x = ((n >> (size - i -1)) & 1);
            if(x)
                inv = 1;
            if(inv) {
                in[i] = !x;
            } else {
                in[i] = x;
            }
        }
    } else {
        for(int i=0; i<size;i  ){
            x = ((n >> (size - i -1)) & 1);
            if(!x)
                inv = 1;
            if(inv) {
                in[i] = !x;
            } else {
                in[i] = x;
            }
        }
    }
    
    for(int i=0; i<size;i  ){
        printf("%d",in[i]);
    }
}

basically looping over all the bits, storing them in an array and inverting them if the inv flag is high...which itself gets high when the first 1 or in case of negative numbers 0 is reached, leaving all the leading 0's or 1's intact.

  • Related