Как получить логический правильный двоичный сдвиг в python

как показано в названии. В JavaScript есть определенный оператор'>>>'. Например, в JavaScript мы получим следующий результат:

(-1000) >>> 3 = 536870787

(-1000) >> 3 = -125

1000 >>> 3 = 125

1000 >> 3 = 125

Итак, есть ли определенный метод или оператор, представляющий это '>>>'?

7 ответов


для этого нет встроенного оператора, но вы можете легко имитировать >>> сам себе:

>>> 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

нет, нет. Правый сдвиг в python является арифметическим.


включает в себя предоставляет right_shift()


вы можете сделать побитовое заполнение сдвига с нулями с помощью bitstring модуль >>= оператор:

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

вот спинофф экс-ы. Обычный оператор сдвига вправо будет работать, если вы подадите ему положительное значение, поэтому вы действительно ищете преобразование из signed в unsigned.

def unsigned32(signed):
    return signed % 0x100000000

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

попытка перевернуть знаковый бит отрицательного числа, замаскировав его с помощью 0x100000000, принципиально ошибочна, поскольку она делает жесткие предположения о длине слова. В свое время программистом я работал с 24-, 48-, 16-, 18-, 32-, 36- и 64-битных чисел. Я также слышал о машинах, работающих на нечетных длинах, таких как 37 и других, которые используют арифметику, дополняющую единицы, а не двойки. Любые предположения, которые вы делаете о внутреннем представлении чисел, помимо этого они бинарны, опасны.

даже двоичное предположение не совсем безопасно, но я думаю, что мы это допустим. :)


вы должны помнить, что если число отрицательное, верхний бит установлен, и с каждым сдвигом вправо вам нужно сделать верхний бит установлен, а также.

вот моя реализация:

def rshift(val, n):
    s = val & 0x80000000
    for i in range(0,n):
        val >>= 1
        val |= s
    return val