# machine dependent left shift results

Discussion in 'Perl Misc' started by easily_confused, Oct 1, 2009.

1. ### easily_confusedGuest

On a 32 bit machine, ~0<<32 gives 11111111111111111111111111111111 (I was
expecting 0)

(~0<<31)<<1 gives 0.

I was trying ~(~0<<\$size) to create a mask of \$size ones.

((1<<\$size) -1) was what I tried first but it also failed for the same
reason, I guess.

I like that in verilog I can just say {\$size{1'b1}}

I know I can use Math::BigInt, but I still wonder what the rationale is
behind the first example failing.

EC

easily_confused, Oct 1, 2009

2. ### Guest

On Thu, 1 Oct 2009 13:22:10 -0700, "easily_confused" <> wrote:

>On a 32 bit machine, ~0<<32 gives 11111111111111111111111111111111 (I was
>expecting 0)
>
>(~0<<31)<<1 gives 0.
>

And this is correct.

I don't understand what you mean.

~0 << 0 (or just ~0) gives
11111111111111111111111111111111

~0<<32 gives
11111111111111111111111111111111

32 bit shifts later you get the same thing.
Which makes sence.
I'm pretty sure that you only get 0-31 bit shifts
on 32 bit systems.

So that:
<< 32 equals << 0
<< 33 equals << 1
<< 34 equals << 2
..
..
<< 31 equals << 31

Therefore
~0 << 32 equals ~0 << 0

and
(~0<<31) << 1 equals 0
(~0<<31) << 2 equals 0
(~0<<31) << 3 equals 0
..
..
(~0<<31) << 33 equals (~0<<31) << 1 equals 0

This is just my guess. I imagine the pre-processor
rolls 32 back to 0.

-sln
-------------------

use strict;
use warnings;

for (0 .. 35) {
printf "\$_\t %b \n", ~0<<\$_;
}
print "\n";

for (0 .. 35) {
printf "\$_\t %b \n", 1<<\$_;
}
print "\n";

for (0 .. 35) {
printf "\$_\t %b \n", 4<<\$_;
}

__END__

0 11111111111111111111111111111111
1 11111111111111111111111111111110
2 11111111111111111111111111111100
3 11111111111111111111111111111000
4 11111111111111111111111111110000
5 11111111111111111111111111100000
6 11111111111111111111111111000000
7 11111111111111111111111110000000
8 11111111111111111111111100000000
9 11111111111111111111111000000000
10 11111111111111111111110000000000
11 11111111111111111111100000000000
12 11111111111111111111000000000000
13 11111111111111111110000000000000
14 11111111111111111100000000000000
15 11111111111111111000000000000000
16 11111111111111110000000000000000
17 11111111111111100000000000000000
18 11111111111111000000000000000000
19 11111111111110000000000000000000
20 11111111111100000000000000000000
21 11111111111000000000000000000000
22 11111111110000000000000000000000
23 11111111100000000000000000000000
24 11111111000000000000000000000000
25 11111110000000000000000000000000
26 11111100000000000000000000000000
27 11111000000000000000000000000000
28 11110000000000000000000000000000
29 11100000000000000000000000000000
30 11000000000000000000000000000000
31 10000000000000000000000000000000
32 11111111111111111111111111111111
33 11111111111111111111111111111110
34 11111111111111111111111111111100
35 11111111111111111111111111111000

0 1
1 10
2 100
3 1000
4 10000
5 100000
6 1000000
7 10000000
8 100000000
9 1000000000
10 10000000000
11 100000000000
12 1000000000000
13 10000000000000
14 100000000000000
15 1000000000000000
16 10000000000000000
17 100000000000000000
18 1000000000000000000
19 10000000000000000000
20 100000000000000000000
21 1000000000000000000000
22 10000000000000000000000
23 100000000000000000000000
24 1000000000000000000000000
25 10000000000000000000000000
26 100000000000000000000000000
27 1000000000000000000000000000
28 10000000000000000000000000000
29 100000000000000000000000000000
30 1000000000000000000000000000000
31 10000000000000000000000000000000
32 1
33 10
34 100
35 1000

0 100
1 1000
2 10000
3 100000
4 1000000
5 10000000
6 100000000
7 1000000000
8 10000000000
9 100000000000
10 1000000000000
11 10000000000000
12 100000000000000
13 1000000000000000
14 10000000000000000
15 100000000000000000
16 1000000000000000000
17 10000000000000000000
18 100000000000000000000
19 1000000000000000000000
20 10000000000000000000000
21 100000000000000000000000
22 1000000000000000000000000
23 10000000000000000000000000
24 100000000000000000000000000
25 1000000000000000000000000000
26 10000000000000000000000000000
27 100000000000000000000000000000
28 1000000000000000000000000000000
29 10000000000000000000000000000000
30 0
31 0
32 100
33 1000
34 10000
35 100000

, Oct 2, 2009

3. ### Peter J. HolzerGuest

On 2009-10-02 17:43, <> wrote:
> On Thu, 1 Oct 2009 13:22:10 -0700, "easily_confused" <> wrote:
>>On a 32 bit machine, ~0<<32 gives 11111111111111111111111111111111 (I was
>>expecting 0)
>>
>>(~0<<31)<<1 gives 0.
>>

> And this is correct.
>
> I don't understand what you mean.
>
> ~0 << 0 (or just ~0) gives
> 11111111111111111111111111111111
>
> ~0<<32 gives
> 11111111111111111111111111111111
>
> 32 bit shifts later you get the same thing.
> Which makes sence.

Mathematically it doesn't make sense.

(x << y) << z should be same as x << (y + z)

However, from the point of view of a processor designer it does make
sense.

> I'm pretty sure that you only get 0-31 bit shifts
> on 32 bit systems.
>
> So that:
> << 32 equals << 0
> << 33 equals << 1
> << 34 equals << 2
> ..
> ..
> << 31 equals << 31

[...]
> This is just my guess. I imagine the pre-processor
> rolls 32 back to 0.

Actually, it's the processor. x86 type CPUs (since the 386 or 486, IIRC)
use a so-called barrel shifter to shift by arbitrary amounts in a single
cycle. To keep that shifter at a reasonable size (by 1980's standards of
processor design) it uses only the lower 5 bits of shift width and
ignores the rest.

hp

Peter J. Holzer, Oct 2, 2009