IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Manipulation de bit et Rotation


Sujet :

Python

  1. #1
    Membre habitué
    Inscrit en
    Mai 2008
    Messages
    317
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 317
    Points : 135
    Points
    135
    Par défaut Manipulation de bit et Rotation
    Bonjour à tous.

    Pour la petit histoire, je suis en train de retaper un vieux prog fait en JS vers Python.
    Quasiement tout est terminé, sauf pour une chose qui ne veux pas fonctionner: la manipulation de bit.

    Précisement, c'est l'operateur "<<" qui me casse les bonbons ^^

    En théorie:
    Décale les bits vers la gauche (multiplie par 2 à chaque décalage). Les zéros qui sortent à gauche sont perdus, tandis que des zéros sont insérés à droite
    donc, en théorie (et c'est le cas en python):
    1751007518 << 1 = 3502015036

    le soucis c'est qu'avec des nombres aussi grand, en javascript ça "déconne" puisque, si j'ai bien compris, on touche au 32em bit, qui est reservé au bit du signe.
    Si bien que, en javascript:
    1751007518 << 1 = -792952260

    comparaison des nombre binaire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    0 1101000010111100100000100011 110  (1751007518)
    1 1010000101111001000001000111 100 (3502015036) (res python)
    1 0101111010000110111110111000 100  (-792952260) (res js)
    J'ai aussi remarqué que les deux partie en rouge (le resultat en python et le restulat en js) sont des inverse (NON), je comprends pas exactement pourquoi m'enfin...

    Bref, ma question, c'est de savoir comment faire pour reproduire ce "bug" en python pour que la comparaison des nombres enregistrée via l'ancienne application JS coresponde toujours en Python
    Pour ceux qui voudrais plus de précision, j'ai déjà pausé quelques question sur ce comportement dans le forum javascript: http://www.developpez.net/forums/d11...e/#post6408962


    Edit: Aucune urgence: je viens de me rendre compte que la fonction que j'essayai de recoder est simplement la fonction sha1 mdr ^^
    Par contre, par curiosité j'aimerai bien connaître la réponse quand même

  2. #2
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Peut-être avec le module struct, il me semble avoir déjà eu à faire à cette question
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  3. #3
    Membre expérimenté Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Points : 1 481
    Points
    1 481
    Par défaut
    Bonjour

    pour struct, je pense que "ça ne passe pas". Dès qu'on soumet, avec un format i, un entier qui ne peut pas être stocké, classiquement, sur 4 octets, ça couine :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> from struct import pack
    >>> pack('i',2**31-1)
    '\xff\xff\xff\x7f'
    >>> pack('i',2**31)
    Traceback (most recent call last):
      File "<pyshell#42>", line 1, in <module>
        pack('i',2**31)
    error: long too large to convert to int
    Alors, penser à faire un truc dans le genre aller-retour, ...

    Certains modules le font peut-être mais "à la main", c'est faisable. Une façon de faire (pour 4 octets/32 bits) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    >>> def decalage_gauche_sauce_js(entier):
    	# je ne conserve que les 32 bits des puissances de 2 les plus petites
    	binary = [((2*entier)>>(31-i)) & 1 for i in range(32)]
    	# a decoder comme un positif	
    	if binary[0] == 0:
    		return sum(map(lambda (i,b):(2**(30-i))*b,enumerate(binary[1:])))
    	else:
    		# inversion des 31 bits de droite
    		inverse = map(lambda b:0 if b else 1,binary[1:])
    		# calcul de la somme
    		valeur = sum(map(lambda (i,b):(2**(30-i))*b,enumerate(inverse)))
    		# resultat : oppose de somme+1
    		return -1 * (valeur+1)
    >>>
    >>> decalage_gauche_sauce_js(1751007518)
    -792952260
    >>> decalage_gauche_sauce_js(123)
    246
    >>> decalage_gauche_sauce_js(-123)
    -246
    >>> decalage_gauche_sauce_js(2**30-1)
    2147483646
    >>> decalage_gauche_sauce_js(0)
    0
    "La simplicité ne précède pas la complexité, elle la suit." - Alan J. Perlis
    DVP ? Pensez aux cours et tutos, ainsi qu'à la FAQ !

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Il y a plus simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> import ctypes
    >>> ctypes.c_int32(1751007518 << 1).value
    -792952260
    Et aussi, je pense que ta conversion en binaire est incorrecte, c'est pourquoi le résultat n'est pas le même en binaire. La valeur binaire que tu donnes pour Python est la valeur correcte, même en javascript. La valeur que tu donnes pour Javascript est un 1 suivi de 31 bits qui représentent 792952260, mais ce n'est pas la façon dont les nombres négatifs sont représentés (ce n'est pas -792952260 mais -1354531388). Les nombres négatifs sont représentés en complément à 2, qui correspond à l'inversion de tous les bits et à l'ajout de 1. Si tu inverses les bits de ta valeur JS (sauf le bit de signe), et que tu ajoutes 1, tu retombes bien sur la valeur correcte.

Discussions similaires

  1. manipulation de bits d'un byte
    Par orelero dans le forum Langage
    Réponses: 6
    Dernier message: 22/08/2008, 10h41
  2. word_t et Manipulation de bits
    Par fmichael dans le forum C#
    Réponses: 2
    Dernier message: 19/03/2007, 09h33
  3. [VS 2005] Manipuler des bits
    Par b_lob dans le forum C#
    Réponses: 5
    Dernier message: 05/02/2007, 09h51
  4. [Ada] Manipulation de "Bits"
    Par BoBy9 dans le forum Ada
    Réponses: 2
    Dernier message: 14/06/2006, 11h57
  5. Manipulation de bits
    Par Tsly dans le forum C++
    Réponses: 2
    Dernier message: 28/09/2005, 12h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo