Deprecated: Array and string offset access syntax with curly braces is deprecated in /home/clients/a4e6fc1ce1761b72982b805de0f418c4/web/python/mesrecettespython/inc/init.php on line 563
conversions_en_binaire [Les recettes Python de Tyrtamos]

Outils pour utilisateurs

Outils du site


conversions_en_binaire

Ceci est une ancienne révision du document !



Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /home/clients/a4e6fc1ce1761b72982b805de0f418c4/web/python/mesrecettespython/inc/parser/handler.php on line 1458

Warning: preg_match(): Compilation failed: invalid range in character class at offset 3565 in /home/clients/a4e6fc1ce1761b72982b805de0f418c4/web/python/mesrecettespython/inc/parser/lexer.php on line 118
A PCRE internal error occured. This might be caused by a faulty plugin

====== Conversions entre un nombre entier et sa représentation binaire, y compris binaire signée (complément à 2) ====== ===== Conversion nombre entier -> chaîne binaire non-signée ===== Cette fonction permet de convertir un nombre entier positif ou nul, dans sa représentation binaire. Par exemple: dec2bin(75) => "1001011" Il est aussi possible de fixer la longueur du mot en nombre de bits, et la chaîne binaire est alors complétée si nécessaire avec des "0" à gauche. Par exemple pour un mot de 12 bits: dec2bin(75,12) => "000001001011" Le principe de calcul est le suivant. On part du nombre d. Si d est pair, son bit de droite est "0", sinon, il est "1". On remplace alors d par d divisé par 2 et on recommence en ajoutant le résultat ("0" ou "1") à gauche de la chaîne cherchée b. Jusqu'à ce que d soit nul. Et on renvoie la chaîne binaire b. Comme cet algorithme renvoie une chaîne vide lorsque d=0, on traite ce cas dès le départ en renvoyant b="0". Au lieu de renvoyer simplement b, on renvoie b.zfill(nb) qui complète éventuellement par des "0" à gauche de b pour que la chaîne binaire soit de la longueur demandée par nb. Bien sûr, quand nb=0 ou non donné à l'appel de la fonction, rien n'est ajouté. Pour diminuer le temps de calcul, on a utilisé des opérations sur les bits au lieu des opérations de calcul habituels: * %%d>>1 correspond à d//2 (= division entière par 2)%% * %%d&1 correspondant à d%2 ou d modulo 2 (= reste de la division entière par 2)%% Egalement pour gagner du temps, on utilise une astuce pour convertir le chiffre 0 ou 1 en caractère "0 ou "1": * %%"01"[0] donne "0"%% * %%"01"[1] donne "1"%% Voilà le code proposé: <code python> #!/usr/bin/python # -*- coding: utf-8 -*- def dec2bin(d,nb=0): """dec2bin(d,nb=0): conversion nombre entier positif ou nul -> chaîne binaire (si nb>0, complète à gauche par des zéros)""" if d==0: b="0" else: b="" while d!=0: b="01"[d&1]+b d=d>>1 return b.zfill(nb) # Exemple d'utilisation: print dec2bin(75) # affiche: "1001011" print dec2bin(75,12) # affiche: "000001001011" </code> ===== Conversion nombre entier -> chaîne binaire signée ===== Cette fonction permet de convertir un nombre entier quelconque positif ou négatif, dans sa représentation binaire signée. Par exemple: dec2bins(-91) => "10100101" dec2bins(-91,12) => "111110100101" dec2bins(-41) => "1010111" dec2bins(-41,8) => "11010111" Principe de la représentation binaire signée avec le "complément à 2". Exemple avec le nombre négatif -91: * représentation binaire de +91 => 1011011 * on inverse les bits (0 devient 1 et 1 devient 0) => 0100100 * et on ajoute +1 (avec retenues éventuelles!) => 0100101 * il ne reste plus qu'à ajouter un bit de signe à gauche de la chaine binaire: "1" pour un nombre négatif => 10100101. Avec cette opération, un mot de 8 bits, qui aurait pu représenter des valeurs positives entre 0 et 255, pourra contenir des valeurs signées entre -128 et +127. La taille minimale d'un binaire signée est de 2 bits, soit un bit de donnée et un bit de signe. Cela permet de coder 4 valeurs: * %%-2 => "10"%% * %%-1 => "11"%% * %% 0 => "00"%% * %%+1 => "01"%% Vous voyez d'ailleurs avec cet exemple, que la représentation binaire signée de 0 n'est pas "0", mais "00" parce qu'il faut le bit de signe! Vous vous rendez bien compte que la taille du mot compte dans la représentation binaire signée: * la représentation binaire signée doit avoir à gauche un bit de signe, égal à "0" pour un nombre positif, et "1" pour un nombre négatif. * la représentation de -91 nécessitera au minimum un mot de 8 bits, puisqu'il faut 7 bits pour le représenter + 1 bit de signe à gauche qui sera "1" puisque ce nombre est négatif. * pour représenter un même nombre signé dans un mot plus grand, il suffit: * s'il est positif ou nul, d'ajouter des "0" à gauche de la chaine binaire, le dernier "0 à gauche étant le bit de signe. Exemple: +91 dans un mot de 12 bits => %%000001011011%% * s'il est négatif, d'ajouter des "1" à gauche de la chaine binaire, le dernier "1" à gauche étant le bit de signe. Exemple: -91 dans un mot de 12 bits => %%111110100101%% Dans une version précédente de la fonction dec2bins(), je rendais obligatoire de donner la taille du mot. J'ai adopté ici un mode de calcul plus général: * si la taille du mot n'est pas donnée, on calcule la taille du mot minimale capable de contenir le nombre d en binaire signé. * avec la taille du mot "nb" (nb pour "nombre de bits") donnée à l'appel de la fonction ou calculée comme ci-dessus, on calcule la représentation binaire de d de la façon suivante: * si d est positif ou nul, on renvoie la même chose que dec2bin(d,nb) le "0" le plus à gauche étant pris comme bit de signe. * si d est négatif, on renvoie %%dec2bin((1<<nb)-abs(d))%%. En effet, la représentation binaire signée de -91 dans un mot de 8 bits, est identique à la représentation binaire non-signée de %%(1<<8)-91%% soit +165. Tout cela suppose, bien entendu, que la taille du mot donnée soit suffisante pour représenter le nombre donné en binaire signé! Pour rester simple, le code ci-dessous n'a fait aucune vérification des données. Utilise la fonction dec2bin() décrite plus haut. <code python> #!/usr/bin/python # -*- coding: utf-8 -*- def dec2bins(d,nb=0): """dec2bins(d,nb=0): conversion nombre entier signé d -> chaîne binaire pour un mot de nb bits (=0 par defaut) """ # calcul de la taille mini du mot permettant de représenter la valeur signée d (signe compris) n=1 if d>=0: x=d else: x=-d-1 while (1<<n)<=x: n+=1 n+=1 # valeur de nb à prendre pour la suite des calculs (si nb<n, le nb donné est trop faible pour le d donné) if (nb==0) or (nb<n): nb=n # calculs if d>=0: # on renvoie la chaîne normale, complétée par des "0" à gauche et par le bit de signe = "0" b='0' + dec2bin(d,nb-1) else: # on renvoie la chaîne signée, complétée par des "1" à gauche et par le bit de signe "1" b='1' + dec2bin((1<<(nb-1))+d,(nb-1)) return b # Exemple d'utilisation: print dec2bins(-2) # affiche: '10' print dec2bins(-1) # affiche: '11' print dec2bins(0) # affiche: '00' print dec2bins(1) # affiche: '01' print print dec2bins(-2,8) # affiche: '11111110' print dec2bins(135) # affiche: '010000111' print dec2bins(135,16) # affiche: '0000000010000111' print dec2bins(-75) # affiche: '10110101' print dec2bins(-75,8) # affiche: '10110101' print dec2bins(-91) # affiche: '10100101' print dec2bins(-91,12) # affiche: '111110100101' print dec2bins(-41) # affiche: '1010111' print dec2bins(-41,8) # affiche: '11010111' print dec2bins(2,8) # affiche: '00000010' print dec2bin(s127,8) # affiche: '01111111' print dec2bins(127,12) # affiche: '000001111111' print dec2bins(0,8) # affiche: '00000000' </code> ===== Convertion chaîne binaire non-signée -> nombre entier ===== Ça, c'était facile: ça existe déjà dans Python! Exemple: int("1001011",2) => 75 Pour des raisons d'homogénéité, et afin de pouvoir faire des contrôles sur la donnée, je propose une fonction qui fait la même chose: bin2dec("1001011") => 75 <code python> #!/usr/bin/python # -*- coding: utf-8 -*- def bin2dec(b): """bin2dec(b): Conversion chaîne binaire de longueur quelconque -> nombre entier positif""" return int(b,2) # Exemple d'utilisation: print bin2dec("1001011") # affiche 75 </code> ===== Convertion chaîne binaire signée -> nombre entier positif ou négatif ===== Cette fonction permet de convertir une chaîne binaire signée en nombre positif ou négatif. Par exemple: bin2decs("111110100101") => -91 Le principe de calcul est simple: * si le caractère de gauche est "0", alors, le nombre est positif, et sa valeur sera obtenue avec int(chainebinaire,2). * si le caractère de gauche est "1", alors le nombre est négatif, et sa valeur sera obtenue avec %%int(b,2)-(1<<len(b))%%. Cette expression est le contraire de ce nous avons utilisé plus haut. Nous avions dit que, par exemple, la représentation binaire signée de -91 était la même que la représentation binaire non-signée de 256-91=165 (la formule était %%(1<<nb)-abs(d)%% ). <code python> #!/usr/bin/python # -*- coding: utf-8 -*- def bin2decs(C): """bin2decs(C): Conversion chaîne binaire signée de longueur quelconque -> nombre entier signé""" if C[0]=="0": # le 1er chiffre est un '0' => le résultat sera positif return int(C,2) else: # le 1er chiffre est un '1' => le résultat sera négatif return int(C,2)-(1<<len(C)) # Exemple d'utilisation: print bin2decs("111110100101") # affiche -91 </code>

conversions_en_binaire.1207910315.txt.gz · Dernière modification: 2008/04/11 12:38 par tyrtamos

Outils de la page