Expression for setting lowest n bits that works even when n equals word size

Viewed 91

NB: the purpose of this question is to understand Perl's bitwise operators better. I know of ways to compute the number U described below.

Let $i be a nonnegative integer. I'm looking for a simple expression E<$i>1 that will evaluate to the unsigned int U, whose $i lowest bits are all 1's, and whose remaining bits are all 0's. E.g. E<8> should be 255. In particular, if $i equals the machine's word size (W), E<$i> should equal ~02.

The expressions (1 << $i) - 1 and ~(~0 << $i) both do the right thing, except when $i equals W, in which case they both take on the value 0, rather than ~0.

I'm looking for a way to do this that does not require computing W first.


EDIT: OK, I thought of an ugly, plodding solution

$i < 1 ? 0 : do { my $j = 1 << $i - 1; $j < $j << 1 ? ( $j << 1 ) - 1 : ~0 }

or

$i < 1 ? 0 : ( 1 << ( $i - 1 ) ) < ( 1 << $i ) ? ( 1 << $i ) - 1 : ~0

(Also impractical, of course.)


1 I'm using the strange notation E<$i> as shorthand for "expression based on $i".

2 I don't have a strong preference at the moment for what E<$i> should evaluate to when $i is strictly greater than W.

4 Answers
Related