如何在python中获得逻辑上正确的二进制移位

时间:2011-04-29 13:55:42

标签: python bitwise-operators

标题显示。在JavaScript中,有一个特定的运算符'>>>'。例如,在JavaScript中,我们将得到以下结果:

( - 1000)>>> 3 = 536870787

( - 1000)>> 3 = -125

1000>>> 3 = 125

1000>> 3 = 125

是否有某个方法或运算符代表此'>>>'?

12 个答案:

答案 0 :(得分:35)

此处没有内置运算符,但您可以轻松地自己模拟>>>

>>> def rshift(val, n): return val>>n if val >= 0 else (val+0x100000000)>>n
... 
>>> rshift(-1000, 3)
536870787
>>> rshift(1000, 3)
125

以下替代实现不再需要if

>>> def rshift(val, n): return (val % 0x100000000) >> n

答案 1 :(得分:7)

不,没有。 python的正确转变是算术的。

答案 2 :(得分:3)

Numpy提供执行此操作的right_shift()函数:

>>> import numpy
>>> numpy.right_shift(1000, 3)
125

答案 3 :(得分:2)

您可以使用bitstring运算符使用>>=模块使用零进行逐位移位填充:

>>> a = BitArray(int=-1000, length=32)
>>> a.int
-1000
>>> a >>= 3
>>> a.int
536870787

答案 4 :(得分:2)

尝试通过用0x100000000屏蔽它来翻转负数的符号位从根本上是错误的,因为它对字长做出了很难的假设。在我作为程序员的时候,我使用了24位,48位,16位,18位,32位,36位和64位数字。我也听说过使用奇数长度的机器,例如37和其他使用补码的机器,而不是二进制补码算术。您对数字的内部表示做出的任何假设,除了它们是二进制之外,都是危险的。

即使是二元假设并非绝对安全,但我认为我们会允许这样做。 :)

答案 5 :(得分:1)

这是aix's answer的衍生产品。如果你给它一个正值,那么普通的右移运算符就可以工作,所以你真的在寻找从有符号到无符号的转换。

def unsigned32(signed):
    return signed % 0x100000000

>>> unsigned32(-1000) >> 3
536870787L

答案 6 :(得分:1)

你需要记住,如果数字为负数,则设置最高位,并且每个右移都需要设置最高位。

这是我的实施:

$('#mounth').on('change', function() {
    $('#hiddenMounth').val($(this).val());
});

答案 7 :(得分:0)

一种无需取模的解决方案:

>>> def rshift(val,n): return (val>>n) & (0x7fffffff>>(n-1))

这是可行的,因为7fffffff是一个正数,向右移动会在左边加零。

答案 8 :(得分:0)

您还可以使用楼层划分:

def rshift(val, n):
    if val > 0:
        return val >> n
    return val // -(2^n)

答案 9 :(得分:0)

这不是一种有效的方法,但是可以按预期工作

def _toBinary(x):
    x=int(x)
    binary = []
    while x > 0:
        binary.append(str(x%2))
        x=int(x/2)
    return "".join(binary[::-1])

def _fromBinary(xs):
    ans = 0
    for i,x in enumerate(xs[::-1]):
        if x == '1':
            ans += 2**i
    return ans

def leftLogicalShift(x,n=1):
    if not type(x) == int:
        return x
    xs = _toBinary(x)
    xs = [x for x in xs]
    for _ in range(n):
        xs.pop(0)
        xs.append('0')
    return _fromBinary("".join(xs))

def rightLogicalShift(x,n=1):
    if not type(x) == int:
        return x
    xs = _toBinary(x)
    xs = [x for x in xs]
    for _ in range(n):
        xs.pop()
        xs.insert(0,'0')
    return _fromBinary("".join(xs))

def leftArithmeticShift(x,n=1):
    return leftLogicalShift(x,n)

def rightArithmeticShift(x,n=1):
    if not type(x) == int:
        return x
    xs = _toBinary(x)
    xs = [x for x in xs]
    for _ in range(n):
        tmp = xs[0]
        xs.pop()
        xs.insert(0,tmp)
    return _fromBinary("".join(xs))

lls = leftLogicalShift(10,2) 
print(lls) # 8

rls = rightLogicalShift(10,2) 
print(rls) # 2

las = leftArithmeticShift(10,2)
print(las) # 8

ras = rightArithmeticShift(10,2)
print(ras) # 14

参考:

https://open4tech.com/logical-vs-arithmetic-shift/

https://www.interviewcake.com/concept/java/bit-shift

答案 10 :(得分:0)

我认为逻辑右二进制移位在Python中不直接可用。相反,您可以在Python中使用Javascript,如下所示:

import js2py
rshift = js2py.eval_js('function $(a, b){ return a >>> b}')
print (rshift(244, 324)) #15

答案 11 :(得分:0)

最高投票的答案为 val < 0 和 n == 0 产生错误的结果!

**<III id_bloku="1"  status_kontroli="0"  status_weryfikacji="P"
/</III>
<III id_bloku="2"  status_kontroli="0"  status_weryfikacji="P"
/</III>
<III id_bloku="3"  status_kontroli="0"  status_weryfikacji="P"
/</III>
<III id_bloku="1"  status_kontroli="0"  status_weryfikacji="P"
/</III>
<III id_bloku="2"  status_kontroli="0"  status_weryfikacji="P"
/</III>
<III id_bloku="3"  status_kontroli="0"  status_weryfikacji="P"
/</III>
<III id_bloku="1"  status_kontroli="0"  status_weryfikacji="P"
/</III>
<III id_bloku="2"  status_kontroli="0"  status_weryfikacji="P"
/</III>
<III id_bloku="3"  status_kontroli="0"  status_weryfikacji="P"
/</III>**