# bug?

Ingo Krabbe ikrabbe@earthling.net
Mon Jun 18 11:46:00 GMT 2001

```Oh sorry,

(x^x) = 0 because this is bitwise: x (xor) x which is definetly 0.
I use this expression because it is a null with exactly the bit
length of the type of x.

~(x^x)= ~0 is a bitwise not of 0 which is all bits set to 1.

~(x^x)<<(8*sizeof(x)-n) which is left shift ~(x^x) number of the bits of
the type of x - n. This leaves the n upper bits as 1 and all others are 0.

finally we do a ~ upon this, which sets n upper bits to 0 and all others
to 1 . Together with the & it masks out the n upper bits of number x.

Hmm, I see that we can also do
x & (~(x^x)>>n) which is really easier :-)

> I propose that:
>
> x = number to clarify upper bits,
> n = index of the first byte to clear (0 .. 2^p-1 for a type with p bytes)

I mean n is the number of upper bits to clear and x is the number.

> #define CLEAR_UPPER_BITS(n,x)\
>                                                (x&((1<<(n))-1))
>
> Simple no ?
>

> By the way, it's not the shift that causes problems, it's the printf that
> assumes its arguments to be ints (that's in the specs). With addition
> you would have the same problem:
>

Nope. printf assumes its arguments as you say it. %x is an integer !!!!

I have done the following to test the code:

#include <stdio.h>

#define CLEAR_UPPER_BITS(n,x) \
((n<sizeof(x)*8) ? x&(~((~(x^x))<<(8*sizeof(x)-n))):0)

int main(int argc, char** argv)
{
unsigned long long y = 0xcc55cc55cc55cc55;

printf( "%Lx\n", CLEAR_UPPER_BITS( 32, y ));
return 0;
}

You see that the algorithm works for very long numbers. (Hope your
compiler knows long long!

CU INGO

```