Question

Question

How would I change the least significant bit to 0 without affecting the rest of the value, for example: 0xffffffff , for example in C or Python? I am not a mathematical genius, so for me it's a hassle to find out how to achieve this.

Solution

n = 0 // clear this bit
0xffffffff &= ~(1U << n) = 0xfffffffe
Était-ce utile?

La solution

Try this to clear the least significant bit:

int x = 0xffffffff;

...

/* clear least significant bit */
x &= ~1;

To set the LSB

int x = 0xffffffff;

...

/* set least significant bit */
x |= 1;

To change the LSB

int x = 0xffffffff;

...

/* change least significant bit */
x ^= 1;

If you want to extent that to set / clear / change bit n, change the 1 to (1U<<n).

Autres conseils

Using bitwise NOT operator ~0 evaluates to all bits set to 1. Assign this to an unsigned int variable and shift it left by 1 bit so that all bits are 1 except the least significant bit. The use bitwise AND operator & on x to toggle the least significant bit.

unsigned int x = 0xffffffff;
unsigned int y = 0;
x = x & (~0 << 1);
 unsigned x = (x>>1U)    
          x = (x<<1U)  

This is easy to understand ....
example :
Let x = 10010101011

step 1 : x = 0 1001010101 // x>>1
step 2 : x = 1001010101 0 // x<<1

compare :

10010101011
10010101010

Another method can be unsigned x = x & 0Xfffffffe which is equal to 11111111111111111111111111111110 i.e 31 bits 1 to keep bit 31 to 1 as it occours in x .

Hope this helps !

If you don't want to dig into bit ops, just do i = (i / 2) * 2;. This will clear bit 0 (why?).

The C compiler can translate this to recommended (i / 2U) * 2U solution for unsigned numbers because of no need for 0xFF..FEu logical AND constant operand which can't be directly encoded as assembly instruction immediate at some cores (e.g. some Cortex ARMs) or the -Os compiler option favour this solution.

In assembly language, this mathematical expression turns to only two instructions - logical shift right and logical shift left without carry.

Alternative mathematical explanation not using the binary representation shifted right and left is, that the (i / 2U) * 2U results in nearest lower even number (result is the i again or i - 1U if i is odd). This means that the odd element was only removed from the number which is the 1*2^0 -> the lsb in binary representation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top