Discussion in 'C Programming' started by Eric Sosman, Mar 28, 2012.

1. ### Eric SosmanGuest

On 3/28/2012 4:25 AM, Guillaume Dargaud wrote:
> Hello all,
> I wrote this small macro to provide a bit mask from bit L to bit H:
>
> // Does a bit mask from bit L to bit H inclusive on 64 bits.
> // Warning H must be<=62 (not 63) and L<=H
> #define BITMASK(H,L) ( ((1UL<<((H)-(L)+1))-1)<<(L) )
>
> The problem is that H must not be 63.
> Is there a better way to write it so that it works with all bits ?
>
> but there's probably a better way.

Untested:

#define BITMASK(H,L) ( (~0ULL >> (63 - (H)) ^ \
(~0ULL >> (63 - (L)) >> 1 )

--
Eric Sosman
d

Eric Sosman, Mar 28, 2012

2. ### BartCGuest

"Eric Sosman" <> wrote in message
news:jkuv47\$ohj\$...
> On 3/28/2012 4:25 AM, Guillaume Dargaud wrote:
>> Hello all,
>> I wrote this small macro to provide a bit mask from bit L to bit H:
>>
>> // Does a bit mask from bit L to bit H inclusive on 64 bits.
>> // Warning H must be<=62 (not 63) and L<=H
>> #define BITMASK(H,L) ( ((1UL<<((H)-(L)+1))-1)<<(L) )
>>
>> The problem is that H must not be 63.
>> Is there a better way to write it so that it works with all bits ?
>>
>> but there's probably a better way.

>
> Untested:
>
> #define BITMASK(H,L) ( (~0ULL >> (63 - (H)) ^ \
> (~0ULL >> (63 - (L)) >> 1 )

It needs the parentheses taken care of:

#define BITMASK(H,L) (~0ULL >> (63 - (H))) ^ (~0ULL >> (63 - (L)) >> 1 )

--
Bartc

BartC, Mar 28, 2012

3. ### Eric SosmanGuest

On 3/28/2012 11:35 AM, Guillaume Dargaud wrote:
>> #define BITMASK(H,L) (~0ULL>> (63 - (H))) ^ (~0ULL>> (63 - (L))>> 1 )

>
> Neat, thanks. A bit beyond my understanding !

The first piece produces a mask with 1 bits from position H
downward: With H==6 you get 00...001111111. The second piece has
two steps: It produces a mask with 1 bits from position L and below,
then right-shifts to get a mask with 1's from (L-1) and downward.
Then we XOR the pieces to invert (i.e., clear) those low bits out of
the first mask, and what remains is the middle span you wanted.

> It still needs parentheses around the whole thing, though:
> #define BITMASK(H,L) ( (~0ULL>> (63 - (H))) ^ (~0ULL>> (63 - (L))>> 1 ) )

Sorry about the parentheses, but I can take comfort in the fact
that their abundance confused more folks than just me! Besides, I
*said* it was untested, didn't I?

--
Eric Sosman
d

Eric Sosman, Mar 29, 2012
4. ### Francois GrieuGuest

On 29/03/2012 03:22, Eric Sosman wrote:
> On 3/28/2012 11:35 AM, Guillaume Dargaud wrote:
>>> #define BITMASK(H,L) (~0ULL>> (63 - (H))) ^ (~0ULL>> (63 - (L))>> 1 )

>>
>> Neat, thanks. A bit beyond my understanding !

>
> The first piece produces a mask with 1 bits from position H
> downward: With H==6 you get 00...001111111. The second piece has
> two steps: It produces a mask with 1 bits from position L and below,
> then right-shifts to get a mask with 1's from (L-1) and downward.
> Then we XOR the pieces to invert (i.e., clear) those low bits out of
> the first mask, and what remains is the middle span you wanted.
>
>> It still needs parentheses around the whole thing, though:
>> #define BITMASK(H,L) ( (~0ULL>> (63 - (H))) ^ (~0ULL>> (63 - (L))>> 1 ) )

>
> Sorry about the parentheses, but I can take comfort in the fact
> that their abundance confused more folks than just me! Besides, I
> *said* it was untested, didn't I?

Why not