Représentation des données
I - Ecrire un nombre entier⚓︎
1) Quelle différence entre un chiffre et un nombre ?⚓︎
Définition
Un chiffre est un symbole pour représenter un nombre.
Différentes écritures d'un même nombre
(2345)occidental = (٢٣٤٥)arabe = (MMCCCXLV)romain = 二三四五(coréen)
Un nombre peut donc être représenté de différentes manières, cependant à l'exception de la notation romaine, les 3 autres exemples se basent sur une méthode commune : la notation en base 10, ou décimale.
Cette façon de représenter les nombres se base sur la décomposition en puissances de 10. Ainsi le nombre deux-mille-trois-cent-quarante-cinq se note usuellement 2345 car :
2345=2×1000 + 3×100 + 4×10 + 5×1
2345=2×103+3×102+4×101+5×100.
2) Comment écrire un nombre dans une autre base que 10 ?⚓︎
Cours
Il est parfaitement possible d'écrire un nombre dans une autre base que 10, il est cependant évident qu'il ne sera pas formé des mêmes chiffres. Pour ne pas être induit en erreur par la base dans laquelle est exprimée un nombre, on écrit le nombre entre parenthèses avec en indice le nombre correspondant à la base dans lequel il est écrit : (100)10 est le nombre s'écrivant un-zéro-zéro en base dix, il s'agit donc de cent. En revanche le nombre (100)8 est le nombre s'écrivant un-zéro-zéro en base huit (octal) qui correspond au nombre soixante-quatre !
La base la plus simple imaginable est le binaire, où un nombre se décompose en puissances de 2 successives et ne s'écrit donc qu'avec 2 chiffres différents : 0 et 1.
Convertir le nombre (343)5 en décimal :
(343)5=3×52+4×51+3×50
(343)5=3×25+4×5+3×=75 + 20 + 3=98
Convertir le nombre (343)10 en octal :
La démarche est un peu différente, du fait que la base 10 est notre base usuelle. On commence par lister les différentes puissance de la base d'arrivée :
80=(1)10 ; 81=(8)10 ; 82=(64)10 ; 83=(512)10 ; 84=(4096)10.
On voit que (343)10<(512)10, ce nombre s'écrira donc avec 3 chiffres en base 8.
(343)10=5×64+23
23=2×8+7
7=7×1
Ainsi (343)10 = 5×82+2×81+7×80
On a donc (343)10 = (527)8.
Et pour les bases > 10 ?
Dans ce cas, nous utilisons comme chiffres supplémentaires les lettres de l'alphabet :
0 ; 1 ; 2 ; 3 ; 4 ; 5 ; 6 ; 7 ; 8 ; 9 ; A ; B ; C ; D ; E ; F ...
La base la plus courante en informatique après le binaire est l'hexadécimal ou base 16. On utilise pour représenter les nombres dans cette base les chiffres de 0 à F [c'est à dire (15)10].
Convertir le nombre (2A3)16 en décimal :
(2A3)16=2×162+A×161+3×160
(2A3)16=2×256+10×16+3×=(675)10
Convertir le nombre (343)10 en hexadécimal :
On commence par lister les différentes puissance de la base d'arrivée : 160=(1)10 ; 161=(16)10 ; 162=(256)10 ; 163=(4096)10.
On voit que (343)10<(4096)10, ce nombre s'écrira donc avec 3 chiffres en base 16.
(343)10=1×256+87
87=5×16+7
7=7×1
Ainsi (343)10 = 1×162+5×161+7×160
On a donc (343)10 = (157)16.
3) Les exercices⚓︎
Réussir au moins 6 fois d'affilée chaque exercice
Écrire le nombre indiqué dans la base décimale :
(XXX)XXX=()10.
Réussite(s) successive(s):0
Écrire le nombre dans la base indiquée :
(XXX)10 = ()XXX.
Réussite(s) successive(s):0
4) Opérations mathématiques⚓︎
Regarder la vidéo récapitulative suivante :
Dans n'importe quelle base,
- La somme de 2 nombres s'écrit au maximum avec un chiffre de plus que le plus grand des deux nombres.
- Le produit de 2 nombres s'écrit au maximum avec autant de chiffres que la somme des chiffres de chaque nombre.
Exemple
En base 10, le plus grand nombre à 3 chiffres est 999 et 9999 est le plus grand à 4 chiffres.
- \(999+9999=10998\) → la somme s'écrit avec \(4+1=5\) chiffres.
- \(999×9999=9989001\) → le produit d'écrit avec \(4+3=7\) chiffres.
II - Représentation des nombres en binaire⚓︎
Le binaire étant la base numérique par excellence de l'informatique, on s'intéresse maintenant à la façon dont on peut écrire n'importe quel nombre.
1) Nombre de bits nécessaires⚓︎
Certains langages informatiques nécessitent de connaître à l'avance valeur maximale des nombres que l'on va manipuler. En effet, cela leur permet d'allouer préventivement la place nécessaire en mémoire.
A savoir
Pour les entiers naturels, sur n bits, il est possible d'encoder 2n nombres, soit les nombres allant de 0 jusqu'à 2n-1
Exemple
En considérant chaque doigt de nos 2 mains comme un bit de donnée, un doigt fermé représentant 0 et un doigt levé représentant 1, il est possible de former tous les nombres compris entre \((00000.00000)_2=(0)_{10}\) et \((11111.11111)_2=(1023)_{10}=2^{10} - 1\).
A vous !
Préciser sur combien de bits au minimum il est possible de coder les nombres suivants en binaire : 5, 32, 127, 554, 10 235 468
Cours
On utilise usuellement en informatique des longueurs multiples de 8 bits (1 octet)
Anecdote
J'ai codé un Tetris® pour arduino il y a quelques années. J'avais utilisé par défaut des nombres de 16bits pour toutes mes variables. Impossible de compiler le programme car il nécessitait trop de mémoire. En limitant la taille des variables au strict nécessaire, le programme fonctionne !
Voir le code (il a mal vieilli !)
#include <SPI.h>
#include "Ucglib.h"
/*
Hardware SPI Pins:
Arduino Uno sclk=13, data=11
Arduino Due sclk=76, data=75
Arduino Mega sclk=52, data=51
*/
/*
*/
Ucglib_ST7735_18x128x160_HWSPI ucg(/*cd=*/ 9, /*cs=*/ 10, /*reset=*/ 8);
//Ucglib_ST7735_18x128x160_SWSPI ucg(/*sclk=*/ 13, /*data=*/ 11, /*cd=*/ 9, /*cs=*/ 10, /*reset=*/ 8);
byte taille_brique=8; //unité de taille des éléments
bool briques[16*7]={ 0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0, //Barre
0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0, //carré
0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0, //2
0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0, //5
0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0, //L
0,0,1,0,0,0,1,0,0,1,1,0,0,0,0,0, //-L
0,0,0,0,0,0,1,0,0,1,1,1,0,0,0,0 //T
};
//valeur du score :
//pas de ligne +2
//1 ligne +10
//2 lignes +20
//3 lignes +50
//4 lignes +100
byte bonus[]={2,10,20,50,100};
// nombre de points a atteindre pour franchir un niveau
// 9 8 7 6 5 4 3 2 1
int niveaux[]={3600,2800,2100,1500,1000,600,300,100,0};//finish à 5000
byte grille_reelle[10*20]; //c'est la grille telle qu'affichée à l'écran
int score=0;
byte piece_actuelle[16]; //tableau dans lequel est stocké la pièce en cours
byte etat=0; //code les différentes étapes du jeu 0:accueil, 1:jeu, 2:game_over
short position_piece[2]={0,0}; //la position de la pièce sur la grille. -2<=x<=12 et -4<=y<=18, selon la forme de la pièce
byte num_prochaine=10; //un numéro supérieur à 8 indique que la pièce n'a pas été définie
byte num_actuelle=10;
short gauche=A2;
short droite=A1;
short bas=A3;
short tourne=A4;
byte couleurs[3*7]={ 200,0,0, //rouge
0,200,0, //vert
0,0,200, //bleu
150,150,0, //jaune
100,100,100, //gris
150,0,200, //violet
200,100,0 //orange
};
void setup(void)
{
delay(1000);
ucg.begin(UCG_FONT_MODE_TRANSPARENT);
ucg.setRotate180();
background();
raz();
choix_piece();
pinMode(A0,INPUT);
randomSeed(analogRead(0));
pinMode(gauche,INPUT_PULLUP);
pinMode(droite,INPUT_PULLUP);
pinMode(bas,INPUT_PULLUP);
pinMode(tourne,INPUT_PULLUP);
Serial.begin(9600);
}
void loop(void)
{
switch (etat){
case 0:
background();
accueil();
while(digitalRead(tourne)){delay(200);} // on reste sur l'écran d'accueil tant qu'on n'appuie pas de nouveau sur tourne
etat=1;
break;
case 1:
game();
break;
case 2:
game_over();
while(digitalRead(tourne)){delay(200);} // on reste sur l'écran game over tant qu'on n'appuie pas de nouveau sur tourne
etat=0;
break;
}
}
void game(){
bool perdu=false;
while(!perdu){
//mise à jour du score et du level
byte niveau=0;
while(score<niveaux[niveau]){
niveau++;
}
niveau=9-niveau;
ucg.setColor(150,200,200);
ucg.drawBox(11*taille_brique,4*taille_brique,4*taille_brique,2*taille_brique);
ucg.drawBox(11*taille_brique,9*taille_brique,4*taille_brique,2*taille_brique);
ucg.setFontPosTop();
ucg.setFont(ucg_font_helvB08_hr);
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setColor(80, 80, 80); // black color for the text
ucg.setPrintPos(11*taille_brique+2,4*taille_brique+2);
ucg.print(score);
ucg.setPrintPos(11*taille_brique+2,9*taille_brique+2);
ucg.print(niveau);
//on redessine la grille
redessine_grille();
bool passe=true;
choix_piece();
position_piece[0]=0;
position_piece[1]=-4;
while(passe){
for(byte i=0;i<5;i++){
short move_x=0;
short move_y=0;
//On regarde si un bouton est pressé
if(!digitalRead(gauche)) {
move_x=-1;
//Serial.println(move_x);
}
else if(!digitalRead(droite)) {
move_x=1;
//Serial.println(move_x);
}
else if(!digitalRead(tourne)) {
eff_piece_jeu(position_piece[0],position_piece[1]);
rotation();
dessine_piece_jeu(position_piece[0],position_piece[1]);
//Serial.println("rotation");
}
else if(!digitalRead(bas)) {
move_y=1;
//Serial.println(move_y);
}
if((move_x!=0 || move_y!=0) && translation(move_x,move_y)){
eff_piece_jeu(position_piece[0],position_piece[1]);
position_piece[0]+=move_x;
position_piece[1]+=move_y;
dessine_piece_jeu(position_piece[0],position_piece[1]);
}
delay(100-10*niveau);
}
//si la pièce peut avancer alors elle avance
if(translation(0,1)){
eff_piece_jeu(position_piece[0],position_piece[1]);
position_piece[1]++;
dessine_piece_jeu(position_piece[0],position_piece[1]);
}
//si elle ne peut pas avancer mais qu'elle n'est pas à sa position intiale
else if(position_piece[1]>0) {
//on commence par coller la pièce dans la grille
for(byte i=0;i<16;i++){
if(piece_actuelle[i]){grille_reelle[position_piece[0]+i%4+10*(position_piece[1]+i/4)]=num_actuelle;}
}
//on regarde ensuite si la ligne est complète
byte nb_lignes=0; //Nombre de lignes faites
for(byte i=0;i<20;i++){
bool ligne_complete=true;
for(byte j=0;j<10;j++){
//Une case vide a une valeur de 10, donc si on trouve
//la valeur 10 dans la ligne, on sait qu'elle n'est
//pas remplie
if(grille_reelle[10*i+j]==10) ligne_complete=false;
}
if (ligne_complete){ //si la ligne est complète
// on incrémente nb_lignes
nb_lignes++;
// on déplace les lignes au-dessus que l'on colle
for (byte k=0;k<10*(i+1);k++){
//on vide la ligne du haut
if(10*i+9-k<10) {grille_reelle[10*i+9-k]=10;}
//on remplace la valeur des lignes par celles de
//la ligne au-dessus
else {grille_reelle[10*i+9-k]=grille_reelle[10*i+9-k-10];}
}
}
}
// le score s'incrémente de 3^(nb_lignes+1)
score += bonus[nb_lignes];
passe=false;
}
else perdu=true;
}
}
etat=2;// c'est le game over
}
//assigne comme pièce actuelle la pièce précédémment annoncée
//définit la "nouvelle" future pièce
//et se relance si la pièce actuelle n'est pas encore définie (ie : au départ)
void choix_piece(){
num_actuelle=num_prochaine;
for(byte i=0;i<16;i++){
piece_actuelle[i]=briques[16*num_actuelle+i];
}
num_prochaine=random(7);
dessine_piece_prochaine(11,15);
if(num_actuelle>8)choix_piece();
}
//va tester la possibilité de faire tourner la pièce
//càd vérifier qu'il n'y a pas de collision avec le bord ou une pièce déjà placée
void rotation(){
byte piece_test[16]; //tableau temporaire servant à vérifier qu'on peut faire tourner la pièce
for(byte i=0;i<16;i++){
piece_test[4*(i/4)+i%4]=piece_actuelle[(i%4)*4+3-i/4]; //On colle la pièce actuelle en tournant de 90° dans la pièce test
}
//on vérifie maintenant qu'il n'y a pas de problème avec la pièce test
//càd qu'aucune partie ne se superpose à une pièce déjà présente sur la grille
//et qu'aucune partie ne se retrouve à l'extérieur de la grille mise à part
//l'extrêmité supérieure
bool collision=0;
for(byte i=0;i<16;i++){
//on vérifie d'abord qu'une partie de la pièce n'est pas à l'extérieur de la grille
if((position_piece[0]+i%4<0 ||position_piece[0]+i%4>9||position_piece[1]+i/4>19) && piece_test[i]!=0) collision=true;
//on vérifie ensuite qu'avec la rotation, une partie de la pièce n'entre pas en collision avec une pièce présente sur la grille
else if ((grille_reelle[10*(position_piece[1]+4*i/4)+position_piece[0]+i%4]!=10)&& piece_test[i]!=0) collision=true;
}
if(true){ //s'il n'y a pas de problème alors la rotation est validée en envoyant le résultat de la rotation
// dans la pièce actuelle.
for(int i=0;i<16;i++){
piece_actuelle[i]=piece_test[i];
}
}
}
//va tester la possibilité de déplacer la pièce
//retourne "true" si cela est possible, "false" dans le cas contraire
bool translation(short delta_x,short delta_y){
bool collision=0;
for(byte i=0;i<16;i++){
//on vérifie d'abord qu'une partie de la pièce n'est pas à l'extérieur de la grille
if((position_piece[0]+i%4+delta_x<0 ||position_piece[0]+i%4+delta_x>9||position_piece[1]+i/4+delta_y>19) && piece_actuelle[i]!=0) collision=true;
//on vérifie ensuite qu'avec le déplacement, une partie de la pièce n'entre pas en collision avec une pièce présente sur la grille
else if ((grille_reelle[10*(position_piece[1]+i/4+delta_y)+position_piece[0]+i%4+delta_x]!=10)&& piece_actuelle[i]!=0 && (position_piece[1]+i/4+delta_y)>0) collision=true;
}
if(!collision){return true;}
else return false;
}
void redessine_grille(){//redessine la grille en fonction des valeurs de ses cases
for (byte i=0;i<200;i++){
if(grille_reelle[i]!=10){
ucg.setColor(couleurs[3*grille_reelle[i]],couleurs[3*grille_reelle[i]+1],couleurs[3*grille_reelle[i]+2]);
}
else ucg.setColor(200,255,255);
ucg.drawBox(8*(i%10),8*(i/10),8,8);
}
}
void raz(){
position_piece[0]=0;
position_piece[1]=-4;
for(byte i=0;i<200;i++){
grille_reelle[i]=10; //une case vaut 10 si elle est vide et entre 0 et 7 si elle est pleine, ce nombre définit sa couleur
}
for(byte i=0;i<16;i++){
piece_actuelle[i]=0;
}
num_prochaine=10;
num_actuelle=10;
score=0;
}
void dessine_piece_prochaine(short posx, short posy){
for(byte i=0;i<16;i++){
if(briques[16*num_prochaine+i]){
ucg.setColor(couleurs[3*num_prochaine],couleurs[3*num_prochaine+1],couleurs[3*num_prochaine+2]);
ucg.drawBox(8*(posx+(i%4)),8*(posy+(i/4)),8,8);
}
else{
ucg.setColor(150,200,200);
ucg.drawBox(8*(posx+(i%4)),8*(posy+(i/4)),8,8);
}
}
}
void dessine_piece_jeu(short posx, short posy){ //dessine une pièce dans la grille de jeu
for(byte i=0;i<16;i++){
if(piece_actuelle[i]){
ucg.setColor(couleurs[3*num_actuelle],couleurs[3*num_actuelle+1],couleurs[3*num_actuelle+2]);
ucg.drawBox(8*(posx+(i%4)),8*(posy+(i/4)),8,8);
}
}
}
void eff_piece_jeu(short posx, short posy){
for(byte i=0;i<16;i++){
if(piece_actuelle[i]){
ucg.setColor(200,255,255);
ucg.drawBox(8*(posx+(i%4)),8*(posy+(i/4)),8,8);
}
}
}
void dessine_brique(short posx, short posy){ //dessine une brique du décors
byte brique[] = {80,80,80,80,80,200,188,80,80,188,128,80,80,80,80,80};
for(byte i=0;i<16;i++){
ucg.setColor(brique[i],brique[i],brique[i]);
ucg.drawBox(posx+2*(i%4),posy+2*(i/4),2,2);
}
}
void background(){
//zone de jeu
ucg.setColor(200,255,255);
ucg.drawBox(0,0,10*taille_brique,20*taille_brique);
//les briques
for(byte j=0;j<6;j++){
for(byte i=0;i<20;i++){
dessine_brique(80+taille_brique*j,taille_brique*i);
}
}
//les fenêtres d'affichage
ucg.setColor(150,200,200);
ucg.drawBox(11*taille_brique,2*taille_brique,4*taille_brique,4*taille_brique);
ucg.drawBox(11*taille_brique,7*taille_brique,4*taille_brique,4*taille_brique);
ucg.drawBox(11*taille_brique,12*taille_brique,4*taille_brique,2*taille_brique);
ucg.drawBox(11*taille_brique,15*taille_brique,4*taille_brique,4*taille_brique);
//le texte dans les fenêtres
ucg.setFontPosTop();
ucg.setFont(ucg_font_helvB08_hr);
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setColor(80, 80, 80); // black color for the text
ucg.setPrintPos(11*taille_brique+2,2*taille_brique+2);
ucg.print("Score");
ucg.setPrintPos(11*taille_brique+2,7*taille_brique+2);
ucg.print("Level");
ucg.setPrintPos(11*taille_brique+2,12*taille_brique+2);
ucg.print("NEXT");
}
void game_over(){
//zone de jeu
ucg.setColor(200,255,255);
ucg.drawBox(0,0,10*taille_brique,20*taille_brique);
//le texte dans les fenêtres
ucg.setFontPosTop();
ucg.setFont(ucg_font_helvB08_hr);
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setColor(80, 80, 80); // black color for the text
ucg.setPrintPos(3*taille_brique+2,7*taille_brique+2);
ucg.print("Game");
ucg.setPrintPos(3*taille_brique+2,8*taille_brique+2);
ucg.print("Over");
}
void accueil(){
//zone de jeu
ucg.setColor(200,255,255);
ucg.drawBox(0,0,10*taille_brique,20*taille_brique);
//le texte dans les fenêtres
ucg.setFontPosTop();
ucg.setFont(ucg_font_helvB08_hr);
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setColor(80, 80, 80); // black color for the text
ucg.setPrintPos(3*taille_brique+2,7*taille_brique+2);
ucg.print("Push");
ucg.setPrintPos(3*taille_brique+2,8*taille_brique+2);
ucg.print("Start");
}
2) Nombres négatifs⚓︎
Le binaire n'est qu'une succession de 0 et de 1, il n'est donc pas possible d'ajouter un signe "-" devant un nombre binaire pour signifier que celui-ci est négatif.
Une fois que le nombre de bits sur lequel va être encodé le nombre est défini, on utilisera le premier bit pour indiquer si ce nombre est positif ou négatif.
Exemple
Si l'on souhaite encoder le nombre (23)10 sur 8bits, alors on pourrait écrire \((23)_{10}=(0001.0111)_2\) et \((-23)_{10}=(1001.0111)_2\).
Cette possibilité pourrait être envisageable, mais a un énorme inconvénient : les règles de l'addition ne fonctionnent alors plus.
On utilise donc une méthode qui permettra de conserver le fonctionnement classique de l'addition : Le complément à 2.
Complément à 2
Pour représenter un nombre négatif, on code le nombre positif en binaire, on inverse ses chiffres (0 devient 1 et 1 devient 0) puis on ajoute 1, sans tenir compte du dépassement.
Exemples
-
Je veux coder \((-23)_{10}\) sur 8 bits :
\((23)_{10}=(0001.0111)_2\)
On inverse les bits : \((0001.0111)_2 → 1110.1000\)
On ajoute 1 : \(1110.1000 + 1 → 1110.1001=(-23)_{10}\) -
Je veux trouver le positif de \((1110.1001)_2\) que je sais être codé en complément à 2 sur 8 bits:
On inverse les bits : \((1110.1001)_2 → (0001.0110)_2\)
On ajoute 1 : \(0001.0110 + 1 → 0001.0111=(23)_{10}\) -
Je veux coder \((-157)_{10}\) sur 8 bits :
\((157)_{10}=(10011101)_2\)
✖ le bit de signe est déjà à 1, ce qui signifie que ce nombre sur 8 bits devrait déjà être considéré comme négatif, et qu'on ne peut pas le codé en bianire complément à 2 sur seulement 8 bits.
A savoir
Si on dispose de n bits pour coder des entiers relatifs, alors il sera possible d'utiliser les entiers compris entre \(-2^{n-1}+1\) et \(2^{n-1}-1\)
Exemple
Sur 8 bits, on peut coder les nombres compris entre \(-2^{n-1}+1=-2^{8-1}+1=-2^{7}+1=-127\) et \(2^{n-1}-1=2^{7}-1=127\).
Réussir au moins 3 fois d'affilée chaque exercice
-
Écrire le négatif de cet entier relatif binaire codé sur 8 bits:
XXX→.
Réussite(s) successive(s) : 0 -
Convertir l'entier relatif suivant codé sur 8 bits dans la base décimale :
(XXX)2 = ()10.
Réussite(s) successive(s) : 0
3) Les nombres réels⚓︎
A savoir
Il est également possible de trouver un moyen de coder un nombre réel en binaire. On commence par coder la partie entière, puis ensuite on code la partie fractionnaire selon la méthode suivante :
avec 23.375
\((23.375)_{10}= (23)_{10} + (0.375){10}\)
-
La partie entière : \((23)_{10}=(10111)_2\)
-
Pour la partie fractionnaire, il faut réaliser des multiplications par 2 successives.
Si le résultat est supérieur à 1, alors on ajoute un 1 dans la partie fractionnaire binaire, sinon on ajoute 0 :
\(0.375 \times 2=0.75\) → on ajoute 0
\(0.75 \times 2=1.5\) → on ajoute 1
\(0.5 \times 2=1.0\) → on ajoute 1
On s'arrête ici puisqu'il n'y a plus de reste. -
On a donc \((23.375)_{10}=(10111,011)_2\)
Réussir au moins 3 fois d'affilée chaque exercice
- Convertir le nombre suivant en binaire :
(XXX)10→()2.
Réussite(s) successive(s) : 0
(XXX)2→()10.
Réussite(s) successive(s) : 0
Remarque
La méthode précédente n'est en fait que la prolongation de l'écriture binaire :
Illustration
\((21.4375)_{10}=2 \times 10^{1}+2 \times 10^{0}+4 \times 10^{-1}+3 \times 10^{-2}+7 \times 10^{-3}+5 \times 10^{-4}\)
\((21.4375)_{10}=(10101.0111)_{2}=1 \times 2^{4}+0 \times 2^{3}+1 \times 2^{2}+0 \times 2^{1}+1 \times 2^{0}+0 \times 2^{-1}+1 \times 2^{-2}+1 \times 2^{-3}+1 \times 2^{-4}\)
Remarque
Tout comme il n'est pas toujours possible d'écrire exactement un nombre en base 10 ( \(\frac{1}{3} = 0.3333333...\) ou \(\pi = 3.141592....\)), certains nombres ne peuvent pas être écrits exactement en binaire.
Essayez pour voir :
Le langage javascript que j'utilise pour écrire les application de ce cours code les nombres dans un format que nous évoquerons plus bas, mais qui permet d'afficher jusqu'à 16 chiffres significatifs.
Testez ci-dessous l'ecriture binaire du nombre réel décimal de votre choix :
()10→(XXX)2.
Le nombre décimal qui correspond en réalité à ce nombre binaire est : (__)10
A savoir
Il faut être conscient qu'un nombre réel écrit en base 10, ne sera pas forcément traité à l'identique par la machine qui utilisera elle une notation binaire qui ne tombera pas forcément "juste".
Conséquence : Dans un programme, il faut éviter d'utiliser des comparaisons Si A = B, alors... si A et B ne sont pas des nombres entiers !
A essayer avec votre interpréteur Python :
>>> a = 0.1
>>> b = 0.2
>>> a + b
5.551115123125783e-17
>>> if a + b - 0.3 == 0:
print("Ca marche")
else :
print("Ca ne marche pas !")
Ca ne marche pas !
4) Ecrire un nombre réel en binaire⚓︎
Pour travailler avec des nombres qui peuvent être à la fois très grands et très petits, le plus simple est d'utiliser un analogue de la notation scientifique.
A savoir
Un nombre sera écrit sous la forme \(x = s \times m \times 2^{exp}\)
- Avec s qui correspond au signe,
- m appelé mantisse (\(1 \leq m < 2\)) dont on ne codera que la partie décimale, la partie entière étant implicite
- et exp, l'exposant.
Pour coder un nombre flottant sur 1 octet, on utilisera 1bit de signe, 3bits d’exposant et 4 bits de mantisse :
\((13.5)_{10} = (+1101,1)_2 = + 1,1011 \times 2^3\) | \((-2.3125)_{10} =(- 10,0101)_2= - 1,00101 \times 2^1\) |
---|---|
+1101,1 = + 1,1011 × 23 | – 10,0101= – 1,00101 × 21 |
00111011 | 10010010 |
Exercice
- En respectant l’exemple ci-dessus, écrire \((-10,125)_{10}\) en flottant sur 1 octet.
- Écrire ensuite ce code en hexadecimal
Corrigé
\((-10,125)_10 = (-1010.001)_2 = - 1.010001 \times 2^3\)
signe | exposant | mantisse |
---|---|---|
1 | 011 | 0100 |
Le code de \((-10,125)_{10}\) est donc 10110100 ce qui correspond en fait à \((-10.0)_{10}\)
Pour écrire Le code binaire 10110100 en hexadecimal il faut séparer le code par groupe de 4 bits, chaque groupe correspondant à un chiffre hexadecimal
Ainsi 1011 → B et 0100 → 4.
On a donc \((10110100)_{bin} \rightarrow (B4)_{16}\)
III - Coder un texte⚓︎
1) Introduction⚓︎
A faire vous-même
-
Ouvrir notepad ou notepad++, et tapez simplement la lettre "a". Enregistrez le fichier à l’endroit de votre choix puis à l’aide de l’explorateur, regardez la taille du fichier. Effacez maintenant la lettre "a" et écrivez le symbole "€" à la place. Enregistrez et regardez de nouveau la taille.
-
Taille avec "a" :
-
Taille avec "€" :
-
Qu’en concluez-vous ?
2) L'ASCII⚓︎
La première façon d’encoder du texte, la base des méthodes actuelles, est l’encodage ASCII. Les caractères sont codés entre 32 (espace) et 127 (delete) :
Voir la table ASCII
32 : | 33 : ! | 34 : " | 35 : # | 36 : $ | 37 : % | 38 : & | 39 : ' | 40 : ( | 41 : ) |
---|---|---|---|---|---|---|---|---|---|
42 : * | 43 : + | 44 : , | 45 : - | 46 : . | 47 : / | 48 : 0 | 49 : 1 | 50 : 2 | 51 : 3 |
52 : 4 | 53 : 5 | 54 : 6 | 55 : 7 | 56 : 8 | 57 : 9 | 58 : : | 59 : ; | 60 : < | 61 : = |
62 : > | 63 : ? | 64 : @ | 65 : A | 66 : B | 67 : C | 68 : D | 69 : E | 70 : F | 71 : G |
72 : H | 73 : I | 74 : J | 75 : K | 76 : L | 77 : M | 78 : N | 79 : O | 80 : P | 81 : Q |
82 : R | 83 : S | 84 : T | 85 : U | 86 : V | 87 : W | 88 : X | 89 : Y | 90 : Z | 91 : [ |
92 : \ | 93 : ] | 94 : ^ | 95 : _ | 96 : ` | 97 : a | 98 : b | 99 : c | 100 : d | 101 : e |
102 : f | 103 : g | 104 : h | 105 : i | 106 : j | 107 : k | 108 : l | 109 : m | 110 : n | 111 : o |
112 : p | 113 : q | 114 : r | 115 : s | 116 : t | 117 : u | 118 : v | 119 : w | 120 : x | 121 : y |
122 : z | 123 : { | 124 : | | 125 : } | 126 : ~ | 127 : del |
A faire vous-même
-
Le code ASCII comporte en tout 128 caractères : combien de bits sont nécessaires pour tous les encoder ?
-
Encodez en base 10 puis en binaire le texte "Bonjour !"
- Décimal :
- Binaire :
Encoder un texte
Entrez un texte :
Le code décimal des caractères que vous avez entrés est : ___.
Le code binaire des caractères que vous avez entrés est : ___.
Le code hexadécimal des caractères que vous avez entrés est : ___.
Décoder un texte
Entrez votre code en décimal (séparer les valeurs par un espace) :
Entrez votre code en hexadécimal (séparer les valeurs par un espace) :
Entrez votre code en binaire (séparer les groupes d'octets par un espace) :
Les caractères correspondants sont : .
A savoir
L'ASCII code chaque caractère sur 8bits mais n'en utilise en réalité que 7, ce qui fait que le code binaire d'un caractère ASCII est toujours de la forme 0xxx xxxx
2) L'UTF-8 en détail⚓︎
Le format UTF-8 a la particularité d’assigner une longueur variable de 1 à 4 octets au codage d’un caractère : s’il fait partie de la table ASCII, il sera codé sur 1 octet, commençant par 0.
Exemple :
Le caractère "@" a pour code \((64)_{10}\), soit \((100 0000)_2\), il sera codé en ASCII 0100 0000.
UTF-8
L'UTF-8 permet de coder un caractère sur un nombre non défini d'octets. Pour y arriver, il va devoir ajouter au premier octet la taille totale du caractère encodé et ensuite insérer le code du caractère.
Si le caractère ne fait pas partie de cette table comme "é", code \((233)_{10} = (1110 1001)_2\), il sera codé plutôt sur 2 octets : 11000011 10101001.
Dans le premier octet, les premiers 1 donnent le nombre d’octets utilisés par le caractère, les octets suivants commencent obligatoirement par 10. On insère ensuite le code binaire du caractère en commençant par la droite et s’il reste de la place, on complète par des 0.
A faire vous-même
Indiquer les codes UTF-8 des symboles "à" (224) et "€" (8364).