[Tutor] Shifting arrays as though they are a 'word'

Cameron Simpson cs at cskk.id.au
Fri Oct 5 18:51:48 EDT 2018

On 05Oct2018 16:17, Chip Wachob <wachobc at gmail.com> wrote:
>I have an array of bytes.  Up to 64, which makes for 512 bits.
>I am reading these bytes in serially, and once I have a collection of
>them, I want to shift them by 'n' bits.  The size of the array and the
>number of bits are both variable up to the limit of 64/512.
>Now, I've played around with looping through the bytes and taking the
>LSByte and shifting it by 'n' bits using >> or << and that works for
>the first byte.  But then I need to take the next byte in the sequence
>and shift it in the opposite direction by 8-n bits using << or >>
>(opposite the LSByte direction), respectively.

Shifting adjacent byte in opposite directions seems a little odd. Is that 
really what you need to do?

>Then I OR the two
>bytes and save them into the location of the LSByte and then move to
>the next byte in the sequence and so on.  While this works most of the
>time, I sometimes get strange behavior at the 'fringes' of the bytes.
>Sometimes I end up with zero, or the shift seems to 'roll over'.
>I'm thinking that maybe there's a way to treat the array / list and
>shift allowing the bits to transfer from byte to byte as needed.
>Maybe by concatenating the bytes into one huge word and then breaking
>it apart again?

Yes, not too hard.

Python ints are bigints, so you can do operations on values of arbitrary size.  
So if you can convert your array of bytes into a single int, you can shift it:

    Python 3.6.4 (default, Dec 28 2017, 14:20:21)
    [GCC 5.4.0 20160609] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 10000000000 <<17

Then convert back into bytes.

The easy way is to just accrue the bytes into a value as you read them:

    n = 0
    for b in the_bytes:
        n = n<<8 + b

if you're reading "big endian" data (high ordinal bytes come first).

So read them in, accruing the value into "n". Shift. Write them back out by 
decomposing "n" with successive division or successive shifts.

Cameron Simpson <cs at cskk.id.au>

More information about the Tutor mailing list