Search code examples
design-patternsbyte-shifting

Bit shifting repeating pattern


I'm looking for a way to bit shifting this pattern:

6 24 96

All these numbers are multiples of 2 so I was thinking there would be a way to shift them

I want to shift them so I get the pattern but it keeps repeating possibly in a loop

6,24,96,6,24,96...

Programming language isn't important, the concept is


Solution

  • Multiplying a number by 2n is equivalent to shifting it left by n bits. Multiplying by 4 can be done by shifting left 2 bits.

    0610 = 000001102
    2410 = 000110002
    9610 = 011000002

    If you want to loop this pattern, you could rotate left rather than simply shifting left. To rotate left 2 bits you would shift left 2 bits and then bitwise OR the leftmost two bits back onto the right side of the number. If you were working with 8-bit numbers this would be written in C-like syntax as:

    (n << 2) | (n >> 6)
    

    Interestingly, if you rotate 96 left two bits you won't get 384 since that's bigger than an 8-bit byte can hold. Instead you get 129, because one of the 1 bits ends up rotating back to the right side.

    00610 = 000001102
    02410 = 000110002
    09610 = 011000002
    12910 = 100000012

    If you then rotate 129 one more time you end up back at the beginning at 6.

    Here's an interactive Python session demonstrating this. Note that {0:3} formats n as a decimal and {0:08b} as a zero-padded binary number.

    >>> n = 6
    >>> n = ((n << 2) | (n >> 6)) & 0xFF; print '{0:3} {0:08b}'.format(n)
     24 00011000
    >>> n = ((n << 2) | (n >> 6)) & 0xFF; print '{0:3} {0:08b}'.format(n)
     96 01100000
    >>> n = ((n << 2) | (n >> 6)) & 0xFF; print '{0:3} {0:08b}'.format(n)
    129 10000001
    >>> n = ((n << 2) | (n >> 6)) & 0xFF; print '{0:3} {0:08b}'.format(n)
      6 00000110
    >>> n = ((n << 2) | (n >> 6)) & 0xFF; print '{0:3} {0:08b}'.format(n)
     24 00011000
    >>> n = ((n << 2) | (n >> 6)) & 0xFF; print '{0:3} {0:08b}'.format(n)
     96 01100000
    >>> n = ((n << 2) | (n >> 6)) & 0xFF; print '{0:3} {0:08b}'.format(n)
    129 10000001
    >>> n = ((n << 2) | (n >> 6)) & 0xFF; print '{0:3} {0:08b}'.format(n)
      6 00000110