Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 一个具有不同参数的函数,用于将输入整数的某些位向左推_Python_Optimization_Bit Manipulation_Lookup Tables - Fatal编程技术网

Python 一个具有不同参数的函数,用于将输入整数的某些位向左推

Python 一个具有不同参数的函数,用于将输入整数的某些位向左推,python,optimization,bit-manipulation,lookup-tables,Python,Optimization,Bit Manipulation,Lookup Tables,这个问题涉及到 设x为8位整数。我将从左到右对位进行编号,因为这就是我们阅读的方式。如果我想得到第三位和第五位,然后把它们放在第一位和第二位,其他的都是零,我可以使用f(x)=(5*x)&0b11000000。简而言之: 00a0b000 -> ab000000 | f_0b00101000(x) = (5*x) & 0b11000000 但是,如果我希望第五、第六和第八位位于前三位,f(x)是不同的: 000ab0cd -> abcd0000 | f_0b00011011

这个问题涉及到

x
为8位整数。我将从左到右对位进行编号,因为这就是我们阅读的方式。如果我想得到第三位和第五位,然后把它们放在第一位和第二位,其他的都是零,我可以使用
f(x)=(5*x)&0b11000000
。简而言之:

00a0b000 -> ab000000 | f_0b00101000(x) = (5*x) & 0b11000000
但是,如果我希望第五、第六和第八位位于前三位,
f(x)
是不同的:

000ab0cd -> abcd0000 | f_0b00011011(x) = ((x << 3) & 0b11000000) | (x << 4)
这些函数都可以组合成
f(x,m,a)=(m*x)&a
,我可以创建一个查找表,通过索引从
n
获取
m
a
的值:

t = [(1, 0), (4, 4), (2, 4), (2, 6), (1, 4), (3, 6), (1, 6), (1, 7)]
所以
f_n(x)
变成
f(x,*t[n])
。我认为
f(x,m,a)=(m*x)&a
最适合3位。3位的原始版本为:

f(x, a, b, c, d, e, f) = ((x & a) << b) |
                         ((x & c) << d) |
                         ((x & e) << f)

f(x,a,b,c,d,e,f)=((x&a)您可以在查找表中存储函数:

table = [
    lambda x:x,
    lambda x:x,
    lambda x:x | ((x & 0b0001) << 1),
    ...
    ]
找到最高的设定位:最左边的孔。(你可以做类似的事情:)

现在只消除那个洞。左边的一切都不会改变。右边的一切都会向左移动一个。为这些区域创建遮罩

       CAN FALL : 00011111  ( == LEFTMOST HOLE - 1)
   WON'T CHANGE : 11000000  ( == invert CAN FALL and shift left )
使用这些掩码切碎、移位和重新组合所有其他位字段

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

最后,重复这个过程,直到防坠落遮罩只选择孔。它不会以严格的最小操作数执行您的操作,但它应该相对容易理解,并且不需要大型查找表的复杂性。

这里明确不清楚您要问什么。您是否可以编辑以简化操作?我认为nk标题与你的描述不符?顺便说一句,我在一篇关于“盲目否决票”的评论中没有任何抱怨。否决票的人很久以前就走了,不会看到你的评论。其他人会看到。通常情况下,比特数是从另一端算起的。或者我被困在格列佛旅行社的世界里了?这是某种原因吗“带掩码的左移位”?参数的顺序是
masked\u shift\u left(mask,shift)
?@SylvainLeroux您可以
许多
masked\u left()
s。但我认为这不是最佳选择。查找表中只有256个条目。是否可以执行我想要的操作,并且比您描述的方法更有效?另外,对于您的方法,我会执行
pattern=(pattern&~leftmost\u-hole)我用
timeit
对每个解决方案进行计时,得到了一些有趣的结果。另一个解决方案使用字符串操作:
43.593s
。您的解决方案:
17.549s
。使用具有非最佳函数的查找表:
5.742s
。这是一个非常明显的
7.6x
改进,从最差到最好,甚至是口译员“完全淹没”了任何速度优势。计时基于对
n
x
的每种可能组合进行100次评估(总共
6553600
呼叫)。我在问题的结尾添加了一点。使用8位的naive函数:
9.714s
。如果该函数可以减少到7个操作,我相信它甚至比具有最佳函数的查找表都要快。我真的认为你需要给我们更多关于这是为了什么的信息。我们可以尝试很多疯狂的东西来优化Python,但计时结果之间甚至没有一个完整的数量级。这是程序的瓶颈,还是只是为了好玩?我担心当这可能一点也不重要,b)如果它真的重要,很可能有办法获得x100加速。这是我的“只是为了好玩”和“教育”计划中的一个瓶颈。所以回答你的问题:两者都有。
table = [
    lambda x:x,
    lambda x:x,
    lambda x:x | ((x & 0b0001) << 1),
    ...
    ]
        PATTERN : ab--c--d
          HOLES : 00110110
  LEFTMOST HOLE : 00100000
       CAN FALL : 00011111  ( == LEFTMOST HOLE - 1)
   WON'T CHANGE : 11000000  ( == invert CAN FALL and shift left )
      KEEP THIS : ab
     SHIFT THIS :    -c--d
         RESULT : ab-c--d-