Le langage binaire, la « langue » des ordinateurs....

L'alphabet occidental utilise 26 lettres qui permettent de former une infinité de mots ; comme on l'a déjà vu, « l'alphabet » des ordinateurs est beaucoup plus réduit, puisqu’il ne contient que 2 lettres !
On les nomme par convention « 0 » et « 1 ».

Le langage qui en découle, utilisant 2 signes uniquement, est donc appelé langage binaire. On l'appelle aussi langage machine, puisque c'est le seul que comprennent les ordinateurs...

Le but de cette page est de faire comprendre la manière d'exprimer des nombres avec seulement deux chiffres; toute information dans la mémoire d'un ordinateur étant stockée sous forme de nombres, cette manière de faire est à la racine du langage des ordinateurs...

Quelques définitions

Dans la suite de ce document, on travaillera, pour des soucis de simplicité, principalement sur des octets, mais toutes les notions abordées se transposent bien sur à des nombres plus importants...

Comment "fonctionne" la numération binaire ?

La manière de représenter un nombre s'appelle une numération.

Nous exprimons ainsi les nombres grâce aux 10 chiffres de la numération décimale ( on dit aussi « en base 10 »); un ordinateur ne peut lui utiliser que la numération binaire ( « en base 2 »).

La question qui se pose alors est : comment passe-t-on des nombres en base 10 à leur équivalent binaire ?

1. Principe de la numération binaire : cas d'un nombre sur un octet

A l'aide de l’interpréteur de IDLE, trouver la représentation binaire des valeurs décimales du tableau suivant.

Utiliser pour cela la fonction :
	bin(nombre en base 10)
				
Exemple :
	>>> bin(12)
	'0b1100'
	>>>
				
Les caractères '0b' indiquent que ce qui suit est un nombre binaire, qui s'affiche comme une chaîne de caractères ( entre guillemets simples )
Nombre décimal Équivalent binaire
1 ?0b1
2 ?0b10
4 ?0b100
8 ?0b1000
16 ?0b10000
32 ?0b100000
64 ?0b1000000
128 ?0b10000000

Que remarque-t-on alors ?

Qu'ont de particulier les valeurs décimales de la première colonne ?

Ce sont les puissances croissantes de 2 : 1 = 20, 2 = 21, 4 = 22, 8 = 23,....

Dans la représentation binaire des ces valeurs décimales, à quoi correspond alors le bit de position n ( n = 0, 1, 2,....,7 en commençant par la droite ) lorsqu'il est égal à 1 ?
Prenons quelques exemples du tableau ci-dessus : → un nombre binaire avec un bit à 1 en position n ( tous les bits suivants étant alors à 0 ) correspond donc à la valeur 2n.
Dans la base que nous utilisons ( la base 10 ), quelle en est l'analogie ? Par exemple, comment peut-on décomposer le nombre 234 en base 10 ?
( Indice : les nombres, aussi bien binaires que décimaux, utilisent la numération de position )

En base 10, un nombre tel que 1 000 peut être décomposé en la somme suivante : 1 x 1000 + 0 x 100 + 0 x 10 + 0 x 1 soit : 1 x 103 + 0 x 102 + 0 x 101 + 0 x 100.
→ tout nombre est donc la somme de termes égaux chacun au produit d'un chiffre par une puissance de 10 croissante de droite à gauche.

Dans la numération de position de manière très générale, chaque chiffre correspond donc, en allant de la droite vers la gauche du nombre, à une puissance croissante de la base utilisée.

Ainsi, on aura par exemple : 234 = 2 x 100 + 3 x 10 + 4 x 1 = 2 x 102 + 3 x 101 + 4 x 100

Par analogie, un nombre binaire suivra le même schéma, aux deux différences suivantes près :

Mais le principe est exactement le même !

Quelle est alors la valeur décimale du nombre binaire : 0b 1 0 0 1 1 0 ?
D'après le principe ci-dessus :
0b100110 = 1 x 25 + 0 x 24 + 0 x 23 + 1 x 22 + 1 x 21 + 0 x 20 = 0 + 0 + 32 + 0 + 0 + 4 + 2 + 0 = 38
Quel est le nombre le plus grand que peut représenter un octet ?
0b11111111 = 1 x 27 + 1 x 26 + 1 x 25 + 1 x 24 + 1 x 23 + 1 x 22 + 1 x 21 + 1 x 20 = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255

Application :

Déterminer ainsi le nombre décimal correspondant aux nombres binaires suivants :

Nombre binaire Équivalent décimal
0b 0 1 1 0 0 1 1 0 ?102
0b 1 0 0 0 0 0 0 1 ?129
0b 0 0 1 1 0 0 0 1 ?49
0b 1 0 1 0 1 0 1 0 ?170

2. Et pour des nombres entiers plus grands ?

Le principe est le même, en considérant les puissances suivantes de 2 ( 28, 29,....).

Remarque : Pour la clarté de la lecture, lorsque le nombre de bits devient élevé, on les regroupe souvent par octet ( un peu comme lorsqu’on insère des espaces pour séparer les groupes de chiffres d'un nombre décimal : ainsi, on écrira 1 897 569 au lieu de 1897569...)

Nombre de bits utilisés Nombre d'octet(s) correspondant Valeur binaire maximale Valeur décimale correspondante
8 1 0b11111111 255
16 2 0b11111111 11111111 65 535
32 4 0b11111111 11111111 11111111 11111111 4 294 967 295
64 8 0b11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 18 446 744 073 709 551 615

3. Le codage hexadécimal

On constate que tout cela devient un peu fastidieux dès que le nombre de bits devient un peu élevé !! C'est en effet la rançon de l’utilisation de seulement deux "chiffres" pour écrire les nombres...
Pour améliorer la compréhension humaine, on a introduit un codage, dit hexadécimal, qui permet de « condenser » la représentation des nombres binaires ; la base utilisée est cette fois-ci la base seize.

L'alphabet de 16 signes est alors le suivant :

décimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
hexa-
décimal
0 1 2 3 4 5 6 7 8 9 A B C D E F
Principe de la conversion :

On sépare l'octet en 2 groupes de 4 bits, et on fait correspondre chaque groupe avec le symbole hexadécimal correspondant :

Exemple :

124 = 0b 0111 1100
0b0111 = 7 = 0x7 et : 0b1100 = 12 = 0xC
⇒ 124 = 0x7C

Les caractères '0x' indiquent un nombre exprimé sous forme hexadécimal.
Exemple :

Compléter le tableau ci-dessous :

Binaire Hexadécimal Décimal
0b 0 1 0 0 0 0 1 0 ?0x42 ?66
?0b 0 0 1 0 1 0 1 0 0x2A ?42
?1 1 1 1 1 1 1 1 0xFF ?255

Il existe bien sur des fonctions directement disponibles dans Python pour ces conversions :

Pour la conversion décimal → hexadécimal, utiliser la fonction :

	hex(nombre en base 10)
					
Exemple :
	>>> hex(245)
	'0xf5'
					

Et pour l'inverse ( hexadécimal → décimal ) :

	>>> int('0xf5',16)
	245				
					

3. Exercices

1. Comment savoir simplement si un nombre binaire correspond à un nombre en base 10 pair ? impair ?

RÉPONSE
Un nombre binaire pair a son bit de "poids" le plus faible ( c'est à dire le LSB, correspondant à : 20 = 1 ), égal à 0.
De même, un nombre impair aura son LSB égal à 1

2. Pour multiplier par dix un entier naturel exprimé en base dix, il suffit d'ajouter un 0 à sa droite, par exemple : 12 × 10 = 120.
Réalisée en base deux, quel est le résultat de la même opération ?
Exprimer en base deux les nombres 3, 6, 12 et 24 pour illustrer ce fait.

RÉPONSE
Logiquement, rajouter un 0 à droite d'un nombre binaire conduit à le multiplier par 2 ( on peut aussi remarquer que cela revient à décaler tous ses bits d'une position vers la gauche...)
On peut le vérifier à l'aide des exemples proposés :
      3 = 0b11 → si on ajoute un 0 à droite : 0b110 = 1 x 4 + 1 x 2 + 0 x 1 = 6 soit 3 x 2 : OK
      12 = 0b1100 → si on rajoute un 0 à droite : 0b11000 = 1 x 16 + 1 x 8 + 0 x 4 + 0 x 2 + 0 x 1 = 24 : OK
      ...et ainsi de suite....

3. Et pour finir, êtes-vous capable maintenant d'apprécier la subtilité de cette phrase célèbre :

"Il n'y a que 10 sortes de personnes : celles qui comprennent le binaire et celles qui ne le comprennent pas."
RÉPONSE
Il faut bien entendu comprendre cette phrase exprimée en binaire, qui devient donc en décimal :
"Il n'y a que 2 sortes de personnes : celles qui comprennent le binaire et celles qui ne le comprennent pas."

4. Applications

Vous aurez besoin de manipuler pour ces applications des chaînes de caractères, c'est à dire des suite de caractères successifs pouvant former des mots, des phrases,...
Par exemple, c'est le type de la variable "renvoyée" par la fonction input() ( qu'il a souvent fallu transtyper en nombre dans les chapitres précédents....)

Les chaînes de caractères sont des types de variables pour lesquelles quelques spécificités existent, et sur lesquelles des fonctions particulières peuvent s'appliquer :

  1. Lors de l'initialisation d'une chaîne, on utilise les guillemets simples ou doubles pour encadrer le contenu à stocker.
    Par exemple :
    	maChaine = "ABCDEF"
    	monAutreChaine = 'abcdefghg'				
    					
    La différence entre les deux écritures est que l’utilisation des guillemets doubles permet de stocker une chaîne contenant à l'intérieur des guillemets simples :
    	maChaine = "J'adore l'ISN !"			
    					
  2. pour adresser un caractère particulier d'une chaîne ( et éventuellement le copier dans une autre variable ), on utilise l'écriture suivante :
     
    	chaine[index]	
    						
    "chaine" est le nom de la variable contenant la chaîne, et "index" la position du caractère dans celle-ci.

    MAIS ATTENTION : une chaîne est, comme beaucoup de choses en informatique, "zéro-indexée", c'est à dire que la numérotation des caractères commence de zéro et pas de 1

    Par exemple :
    	maChaine = "Fastoche le Python !"
    	car1 = maChaine[0] # car1 contient "F"
    	car2 = maChaine[4] # car2 contient "o"
    	......				
    					
    Le travail sur les index de chaîne ( que vous retrouverez en abordant les listes ) n'est pas évident : il peut être bon de travailler sur un exemple sur papier...
  3. une fois une chaîne de caractères créée, il n'est plus possible d'en modifier ou d'en supprimer un ou plusieurs caractères : on dit qu'une chaîne est un objet non-mutable.
    On ne peut que "copier" un ou plusieurs caractères dans une autre variable, ou ajouter d'autre(s) caractère(s) en début en en fin de chaîne.
    Par exemple, on obtient une erreur en cherchant à remplacer un caractère par un autre :
    	>>> nom = "Dupont"
    	>>> nom[5] = "d"				
    	
    	Traceback (most recent call last):
      	File , line 1, in  
      	nom[5]="d"
    	TypeError: 'str' object does not support item assignment
    						

1. Écrire un programme qui demande à l’utilisateur d'entrer une valeur binaire et qui la convertit en valeur décimale.

L’utilisateur rentrera le nombre binaire à convertir, qui sera stocké dans une variable de type chaîne ( ce que retourne justement la fonction input(), ça tombe bien !!! )

La fonction : len(chaîne) renvoie un entier égal au nombre de caractères d'une chaîne.
Par exemple :
	>>> alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	>>> print(len(alphabet))
	26		
				
AIDE 1
Inspirez-vous de la manière avec laquelle vous avez converti "à la main" un nombre binaire en nombre en base 10 dans l'introduction de ce cours...

AIDE 2
L'idée est de parcourir tous les caractères de la chaîne entrée par l'utilisateur et représentant le nombre binaire à convertir.
La valeur convertie sera stockée dans une autre variable numérique.
Principe de la conversion : si un caractère de la chaîne est égal à 1, on ajoute à la valeur convertie la puissance de 2 correspondant à la position de ce 1 dans la chaîne; si c'est un 0, on ne fait rien...

AIDE 3
  • Pour parcourir la chaîne, on utilisera une boucle qui "balayera" toute la longueur de la chaîne; une boucle for ou while peut être utilisée ici.( en fait, puisque le nombre de tours de boucle est connu ( il s'agit du nombre de caractères du nombre binaire à convertir ), une boucle for semble plus indiquée...)
  • plusieurs possibilités existent, mais une méthode est d'utiliser une seule et même variable pour le compteur de boucle et pour "pointer" un caractère de la chaîne; une autre variable contiendra elle l'exposant de la puissance de 2 à ajouter.
    Ne pas hésiter à faire un schéma sur papier à partir d'un exemple...

AIDE 4

Les variables compteur et exposant doivent évoluer en sens inverse.
Pour s'en convaincre, examiner l'exemple suivant :

nombre binaire à convertir 1 1 0 1
index du caractère 0 1 2 3
exposant de la puissance de 2 correspondant 3 2 1 0

ALGORITHME
binaire ← chaîne entrée par l'utilisateur
decimal ← 0
expo ← exposant de la plus grande puissance de 2 dans le nombre binaire à convertir
pour compteur variant de 0 à l'index de la fin de la chaîne :
si le caractère d'index "compteur" dans la chaîne "binaire" est égal à 1
alors ajouter 2^expo au contenu de la variable "decimal"
sinon ne rien faire
fin si
décrémenter la variable expo
fin boucle compteur
afficher variable decimal

Et il existe aussi un algorithme utilisant une boucle while : voila encore un exemple qui montre qu'il existe plusieurs possibilités pour arriver au même résultat....


AIDE 5
  • "plus grande puissance de 2 dans le nombre binaire à convertir" = nombre de caractères de la chaîne - 1 ( voir l'exemple de l'AIDE 4 pour s'en convaincre... )
  • "index de la fin de la chaîne" = nombre de caractères de la chaîne - 1 ( même remarque ! )

Lien vers la RÉPONSE

2. Écrire un programme qui demande à l’utilisateur d'entrer un nombre décimal et qui le convertit en nombre binaire

C'est un problème qui oblige à appliquer un algorithme particulier :

Exemple : pour convertir 13 en base 2

13 : 2 = 6 reste 1
6 : 2 = 3 reste 0
3 : 2 = 1 reste 1
1 : 2 = 0 reste 1
⇒ 13 = 0b1101

Vous aurez là-aussi besoin de manipuler une chaîne de caractères : le nombre binaire recherché sera en effet constitué d'une suite de caractères '0' ou '1'.

Cette chaîne se construira au fur et à mesure des divisions successives, en lui "ajoutant" ( on dit plus rigoureusement concaténer ) les '0' et les '1' obtenus par les calculs...

Il faudra au préalable créer une chaîne vide ( = constituée d'aucun caractère ) :

	chaine = ''
					

Pour concaténer un ou plusieurs caractère(s) au début ou à la fin d'une chaîne, utiliser l'opérateur de concaténation, c'est à dire "d'addition" de chaîne. Il s'agit du signe "+" :

	>>> chaine1 = 'abc'
	>>> chaine2 = chaine1 + 'def'# ajout A LA FIN de chaine1
	>>> print(chaine2)
	'abcdef'
	
	>>> chaine3 = 'def' + chaine1  # ajout AU DÉBUT de chaine1
	>>> print(chaine3)
	'defabc'
				

Enfin, dernière remarque, penser qu'on ne peut pas directement concaténer un entier à une chaîne ( ce serait comme ajouter des choux et des carottes :-) : il faut tout d'abord transtyper cet entier en caractère; utiliser pour cela la fonction :

	str(entier)
					

AIDE 1
Boucle for ou boucle while ???

AIDE 2
D'après le principe de l'algorithme, il faut prendre l'ensemble des restes à l'envers pour obtenir les bits dans le "bon ordre"; autrement dit, il est plus simple d'ajouter chaque bit calculé au début de la chaîne pour les avoir dans l'ordre correct à la fin de la boucle...

ALGORITHME
decimal ← valeur entrée par l'utilisateur
binaire ← chaîne vide
quotient ← valeur de la division entière de decimal par 2
tant que quotient n'est pas nul :
calculer quotient
calculer reste
ajouter reste de la division entière de decimal par 2 au début de la chaîne binaire
remplacer decimal par quotient
fin boucle tant que
afficher variable binaire

Lien vers la RÉPONSE

3. Écrire un programme qui convertit un nombre binaire sur un octet en son équivalent en hexadécimal.

Rappelez-vous la méthode pour convertir un octet en hexadécimal : il faut le séparer en deux groupes de 4 bits, et convertir chaque groupe en un nombre de 0 à 16 codé par les symboles 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E et F.

Si le nombre binaire est stocké comme précédemment dans une chaîne de caractères, il faut donc disposer d'une méthode pour la séparer en deux parties...

En Python, une partie d'une chaîne de caractères s'appelle une slice, c'est à dire une tranche ou encore une séquence.
On utilise pour désigner une séquence deux valeurs placées entre crochets comme pour les index de caractères :

MAIS ATTENTION : ces deux valeurs ne correspondent pas à des index de caractères mais à ceux des espaces entres les caractères.

Par exemple :

	>>> gamme = 'dorémifasollasido'
	>>> note1 = gamme[0:2]
	>>> print(note1)
	'do'
	
	>>> note2 = gamme[4:8]
	>>> print(note2)
	'mifa'			
				

On peut remarquer que la première valeur est bien égale à l'index du premier caractère de la tranche, mais que la deuxième est égale à celui du dernier + 1...

Et de nombreuses autres possibilités existent pour désigner une séquence : voir pour cela le mémento...

AIDE 1
La suite des caractères '012....def' sera stockée dans une variable, dans laquelle le programme viendra "piocher" en extrayant le caractère d'index correspondant au groupe de 4 bits à convertir...

AIDE 2
Chaque groupe de 4 bits ayant été converti en valeur décimale, l'index dans la chaîne '012....def' du caractère hexadécimal correspondant est égal à cette valeur décimale.
Par exemple :
  • 0b000 = 0 → correspond au caractère d'index 0 ( = '0' ) dans la chaîne
  • 0b1101 = 13 → correspond au caractère d'index 13 ( = 'd' ) dans la chaîne
  • etc...
Pour convertir du binaire au décimal, on peut reprendre le programme de l'application 1, ou, de manière plus simple, utiliser les fonctions intégrées à Python ( à vous de les rechercher ! ).

ALGORITHME
base16 ← suite des caractères '0123.....ef'
binaire ← entrée utilisateur
groupe1 ← séquence des 4 premiers caractères de binaire
groupe2 ← séquence des 4 derniers caractères de binaire
conversion en décimal de groupe1 et groupe2
hexa ← caractère d'index groupe1 dans la chaîne base16 + caractère d'index groupe2 dans la chaîne base16
afficher hexa

Lien vers la RÉPONSE