One function with different arguments to push certain bits of an input integer to the left

℡╲_俬逩灬. 提交于 2019-12-04 22:00:47

You could store functions in your lookup table:

table = [
    lambda x:x,
    lambda x:x,
    lambda x:x | ((x & 0b0001) << 1),
    ...
    ]

I would question why you are doing this by bit-shifting integers in Python. If it's for performance, I think doing this via a series of bit-shift operations is a bad idea. The interpreter overhead is going to utterly swamp any speed benefit that the bit-shifting could achieve. If it's for memory usage, because you need to fit millions of these in memory, you would probably do well to look at numpy, which can create memory-efficient arrays and apply operations simultaneously across the whole array.

One good reason I could think of for doing this in Python is because you want to experiment with the algorithm before implementing it in a low level language like C. Even then, I suspect the performance benefit would only be noticeable if you're working on very constrained hardware or doing some very intensive calculations - perhaps you are simulating tens of thousands of games of Bejeweled. If you are just doing this to calculate the logic for a single instance of the game played by a human in real-time, I doubt the bit-shifting optimization is going to be meaningful.

If you're intent on doing this with bit-shifting, could you perhaps do something like this? Rather than do it in a single step, loop until there are no more bits that can "fall". You should only need to loop at most as many times as you have bits in your integer.

Suppose you have this pattern:

        PATTERN : ab--c--d
          HOLES : 00110110

Find the highest set bit: the leftmost hole. (You can do something quite similar to this: https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 )

  LEFTMOST HOLE : 00100000

Now eliminate just that hole. Everything on the left won't change. Everything on the right will shift left by one. Create masks for these areas.

       CAN FALL : 00011111  ( == LEFTMOST HOLE - 1)
   WON'T CHANGE : 11000000  ( == invert CAN FALL and shift left )

Use those masks to chop up, shift and reassemble all your other bitfields.

      KEEP THIS : ab
     SHIFT THIS :    -c--d
         RESULT : ab-c--d-

Finally, repeat the process until the CAN FALL mask selects only holes. It won't perform your operation in the strict minimum number of operations, but it should be relatively understandable and not require the complexity of large lookup tables.

def f(t, x):  # template, number to convert
    t = bin(t).replace("0b", "").rjust(8, "0")
    x = bin(x).replace("0b", "").rjust(8, "0")
    return int("".join([x[i] for i, b in enumerate(t) if int(b)]).ljust(8, "0"), 2)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!