• Subject: Re: Logical shift
• From: Sean Conner <sean@...>
• Date: Sun, 13 Oct 2019 21:58:37 -0400

```It was thus said that the Great D Burgess once stated:
> Forgive me if this has been previously noted:
> The 5.3 manual says
> >  All bitwise operations convert its operands to integers (see §3.4.3), operate on all bits of those integers, and result in an integer.
> > Both right and left shifts fill the vacant bits with zeros.
>
> In other words an "unsigned" shift or logical shift. No sign extension.
>
> Lua 5.3.5  Copyright (C) 1994-2018 Lua.org, PUC-Rio
> > string.format("0x%016x",(1<<63)>>8)
> 0x0080000000000000
>
> Bash
> # printf '0x%016x\n' \$(( (1<<63)>>8 ))
> 0xff80000000000000
>
> PHP
> printf '0x%016x\n' \$(( (1<<63)>>8 ))
> 0xff80000000000000
>
> Perl
> # perl -e 'printf "0x%016x\n",(1<<63)>>8'
> 0x0080000000000000
>
> SQLite 3.29.0
> sqlite> select printf('0x%016x',(1<<63)>>8);
> 0xff80000000000000
>
> *I wish this was highlighted in the manual.*
>
> What was the reasoning in choosing logical shift for >> rather than arithmetic?

From the C89 standard (ISO/IEC 9899:1990), section 6.3.7 (emphasis added):

The result of El >> E2 is El right-shifted E2 bit positions. If El
has an unsigned type or if El has a signed type and a nonnegative
value, the value of the result is the integral part of the quotient
of El divided by the quantity, 2 raised to the power E2. If El has a
signed type and a negative value, the resulting value is
implementation-defined.
^^^^^^^^^^^^^^^^^^^^^^

From that, I would assume that the only way to ensure consistent values
across all C compilers is to only do unsigned shifts.

-spc

```