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