Как получить логический правильный двоичный сдвиг в Python - PullRequest
25 голосов
/ 29 апреля 2011

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

(- 1000) >>> 3 = 536870787

(- 1000) >> 3 = -125

1000 >>> 3 = 125

1000 >> 3 = 125

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

Ответы [ 8 ]

35 голосов
/ 29 апреля 2011

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

>>> 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
7 голосов
/ 29 апреля 2011

Нет, нет.Сдвиг вправо в питоне арифметический.

3 голосов
/ 29 апреля 2011

Numpy предоставляет функцию right_shift(), которая делает это:

>>> import numpy
>>> numpy.right_shift(1000, 3)
125
2 голосов
/ 05 января 2015

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

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

2 голосов
/ 29 апреля 2011

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

>>> a = BitArray(int=-1000, length=32)
>>> a.int
-1000
>>> a >>= 3
>>> a.int
536870787
1 голос
/ 14 мая 2015

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

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

def rshift(val, n):
    s = val & 0x80000000
    for i in range(0,n):
        val >>= 1
        val |= s
    return val
1 голос
/ 10 июля 2012

Вот ответвление Ответ Экс .Обычный оператор смещения вправо будет работать, если вы передадите ему положительное значение, поэтому вы действительно ищете преобразование со знака в без знака.

0 голосов
/ 30 апреля 2019

Решение, которое работает без модуля:

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

Это работает, так как 7fffffff - положительное число и смещение вправо, которое добавит нули влево.

...