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
More information about the Gcc-help
mailing list