web-dev-qa-db-fra.com

Comment obtenir le décalage binaire droit logique dans python

Comme le révèle le titre, en JavaScript, il existe un opérateur spécifique >>>. Par exemple, en JavaScript, nous aurons le résultat suivant:

(-1000) >>> 3 = 536870787

(-1000) >> 3 = -125

1000 >>> 3 = 125

1000 >> 3 = 125

Existe-t-il une certaine méthode ou un opérateur représentant ce >>>?

30
dementrock

Il n'y a pas d'opérateur intégré pour cela, mais vous pouvez facilement simuler le >>> toi même:

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

L'implémentation alternative suivante supprime le besoin de if:

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

Non, il n'y en a pas. Le décalage à droite dans python est arithmétique.

7
Femaref

Essayer de retourner le bit de signe d'un nombre négatif en le masquant avec 0x100000000 est fondamentalement mal conçu car il fait des hypothèses difficiles sur la longueur du mot. En tant que programmeur, j'ai travaillé avec des nombres de 24, 48, 16, 18, 32, 36 et 64 bits. J'ai également entendu parler de machines qui fonctionnent sur des longueurs impaires, telles que 37 et d'autres qui utilisent l'arithmétique à complément unique et non à double complément. Toutes les hypothèses que vous faites sur la représentation interne des nombres, au-delà du fait qu'ils sont binaires, sont dangereuses.

Même l'hypothèse binaire n'est pas absolument sûre, mais je pense que nous l'autoriserons. :)

2
Raphael

Vous pouvez effectuer un remplissage de décalage au niveau du bit avec des zéros avec le module bitstring en utilisant l'opérateur >> = :

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

Numpy fournit la fonction right_shift() qui fait ceci:

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

Voici un spin-off de réponse d'Aix . L'opérateur de décalage à droite normal fonctionnera si vous lui fournissez une valeur positive, vous recherchez donc vraiment une conversion de signé à non signé.

def unsigned32(signed):
    return signed % 0x100000000

>>> unsigned32(-1000) >> 3
536870787L
1
Mark Ransom

Vous devez vous rappeler que si le nombre est négatif, le bit supérieur est défini et à chaque décalage vers la droite, vous devez également définir le bit supérieur.

Voici ma mise en œuvre:

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

Une solution qui fonctionne sans modulo:

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

Cela fonctionne puisque 7fffffff est un nombre positif et un décalage vers la droite qui ajoutera des zéros à gauche.

0
Victor010

Vous pouvez également utiliser la division du sol:

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