L'apparition des ordinateurs modernes a profondément transformé notre façon de représenter et de manipuler l'information. Dès les premiers systèmes électroniques, la notion de base numérique est devenue un élément fondamental de l'informatique, car elle permet de représenter les nombres sous différentes formes adaptées aux besoins des machines et des programmeurs. Alors que les humains utilisent naturellement le système décimal basé sur dix symboles, les ordinateurs travaillent principalement en binaire, un système ne comportant que deux chiffres, 0 et 1. Cette différence a conduit au développement de nombreuses techniques de conversion entre diverses bases numériques. Aujourd'hui encore, ces conversions jouent un rôle essentiel dans la programmation, l'électronique, les télécommunications, les systèmes embarqués et le traitement des données. Les bases numériques servent non seulement à représenter des quantités, mais également à encoder des adresses mémoire, des couleurs graphiques, des identifiants, des clés de chiffrement et de nombreuses autres formes d'information numérique.
Les systèmes de numération disponibles sont extrêmement variés. Parmi les plus connus figurent la base binaire (2), la base ternaire (3), la base quintale (5), la base octale (8), la base décimale (10) et la base hexadécimale (16), chacune possédant ses propres avantages selon le contexte d'utilisation. Toutefois, rien n'empêche de définir des bases moins conventionnelles, telles que la base 5, la base 13, la base 36 ou encore la base 62, qui utilisent un ensemble élargi de symboles afin de représenter les valeurs de manière plus compacte. En théorie, la seule véritable limite est le nombre de caractères disponibles pour représenter les chiffres d'une base donnée. Les tableaux présentés ci-dessous illustrent les correspondances entre plusieurs systèmes de numération populaires et permettent de visualiser comment une même valeur décimale peut être représentée différemment selon la base utilisée. Cette comparaison met en évidence le caractère relatif de l'écriture des nombres et démontre que seule la représentation change, tandis que la quantité représentée demeure identique.
Les exemples en langage C qui suivent montrent comment implémenter différentes fonctions de conversion numérique. Le premier programme illustre la transformation d'un nombre décimal vers sa représentation en base ternaire à l'aide de divisions successives et de la récupération des restes. Le second exemple présente une méthode particulièrement efficace de conversion d'un octet vers sa représentation hexadécimale, technique largement utilisée dans les outils de débogage, les éditeurs hexadécimaux et les systèmes informatiques de bas niveau. Un troisième programme démontre la conversion vers la base 62, un système souvent employé pour générer des identifiants compacts, des URL raccourcies ou des codes uniques utilisant à la fois des chiffres, des lettres majuscules et des lettres minuscules. Enfin, l'exemple de conversion vers une base X généralise le principe afin de permettre la création de convertisseurs pour pratiquement n'importe quelle base comprise dans l'intervalle supporté. Ensemble, ces programmes constituent une excellente introduction aux mécanismes de représentation des nombres et démontrent comment quelques algorithmes simples permettent de passer facilement d'un système de numération à un autre. Ils illustrent également l'un des fondements les plus importants de l'informatique moderne : la capacité de représenter une même information sous de multiples formes adaptées aux besoins de chaque application.
Voici tout d'abord une table des bases les plus populaires :
| Base 2 (Binaire) | Base 3 (Ternaire) | Base 8 (Octale) | Base 10 (Décimal) | Base 16 (Hexadécimal) | Base 62 |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 | 1 | 1 |
| 10 | 2 | 2 | 2 | 2 | 2 |
| 11 | 10 | 3 | 3 | 3 | 3 |
| 100 | 11 | 4 | 4 | 4 | 4 |
| 101 | 12 | 5 | 5 | 5 | 5 |
| 110 | 20 | 6 | 6 | 6 | 6 |
| 111 | 21 | 7 | 7 | 7 | 7 |
| 1000 | 22 | 10 | 8 | 8 | 8 |
| 1001 | 100 | 11 | 9 | 9 | 9 |
| 1010 | 101 | 12 | 10 | A | A |
| 1011 | 102 | 13 | 11 | B | B |
| 1100 | 110 | 14 | 12 | C | C |
| 1101 | 111 | 15 | 13 | D | D |
| 1110 | 112 | 16 | 14 | E | E |
| 1111 | 120 | 17 | 15 | F | F |
| 10000 | 121 | 20 | 16 | 10 | G |
| 10001 | 122 | 21 | 17 | 11 | H |
| 10010 | 200 | 22 | 18 | 12 | I |
| 10011 | 201 | 23 | 19 | 13 | J |
| 10100 | 202 | 24 | 20 | 14 | K |
| 10101 | 210 | 25 | 21 | 15 | L |
| 10110 | 211 | 26 | 22 | 16 | M |
| 10111 | 212 | 27 | 23 | 17 | N |
| 11000 | 220 | 30 | 24 | 18 | O |
| 11001 | 221 | 31 | 25 | 19 | P |
| 11010 | 222 | 32 | 26 | 1A | Q |
| 11011 | 1000 | 33 | 27 | 1B | R |
| 11100 | 1001 | 34 | 28 | 1C | S |
| 11101 | 1002 | 35 | 29 | 1D | T |
| 11110 | 1010 | 36 | 30 | 1E | U |
| 11111 | 1011 | 37 | 31 | 1F | V |
| 100000 | 1012 | 40 | 32 | 20 | W |
| 100001 | 1020 | 41 | 33 | 21 | X |
| 100010 | 1021 | 42 | 34 | 22 | Y |
| 100011 | 1022 | 43 | 35 | 23 | Z |
| 100100 | 1100 | 44 | 36 | 24 | a |
| 100101 | 1101 | 45 | 37 | 25 | b |
| 100110 | 1102 | 46 | 38 | 26 | c |
| 100111 | 1110 | 47 | 39 | 27 | d |
| 101000 | 1111 | 50 | 40 | 28 | e |
| 101001 | 1112 | 51 | 41 | 29 | f |
| 101010 | 1120 | 52 | 42 | 2A | g |
| 101011 | 1121 | 53 | 43 | 2B | h |
| 101100 | 1122 | 54 | 44 | 2C | i |
| 101101 | 1200 | 55 | 45 | 2D | j |
| 101110 | 1201 | 56 | 46 | 2E | k |
| 101111 | 1202 | 57 | 47 | 2F | l |
| 110000 | 1210 | 60 | 48 | 30 | m |
| 110001 | 1211 | 61 | 49 | 31 | n |
| 110010 | 1212 | 62 | 50 | 32 | o |
| 110011 | 1220 | 63 | 51 | 33 | p |
| 110100 | 1221 | 64 | 52 | 34 | q |
| 110101 | 1222 | 65 | 53 | 35 | r |
| 110110 | 2000 | 66 | 54 | 36 | s |
| 110111 | 2001 | 67 | 55 | 37 | t |
| 111000 | 2002 | 70 | 56 | 38 | u |
| 111001 | 2010 | 71 | 57 | 39 | v |
| 111010 | 2011 | 72 | 58 | 3A | w |
| 111011 | 2012 | 73 | 59 | 3B | x |
| 111100 | 2020 | 74 | 60 | 3C | y |
| 111101 | 2021 | 75 | 61 | 3D | z |
Ternaire
Voici un programme permettant d'effectuer une conversion d'une valeur décimal à ternaire en C :
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- char ReturnString[255];
-
- char * DecimalToTernaire(int value) {
- if(0 == value) {
- return "0";
- }
- strcpy(ReturnString,"");
- int base = value;
- while(base > 0) {
- char Temp[255];
- sprintf(&Temp,"%i",(int)(base % 3));
- strcat(&Temp,&ReturnString);
- strcpy(&ReturnString,&Temp);
- base = (int)(base / 3);
- }
- return ReturnString;
- }
-
- int main()
- {
- int I;
- for(I=0; I <= 20; I++) {
- printf("%i = %s\n",I,DecimalToTernaire(I));
- }
- return 0;
- }
on obtiendra le résultat suivant :
0 = 01 = 1
2 = 2
3 = 10
4 = 11
5 = 12
6 = 20
7 = 21
8 = 22
9 = 100
10 = 101
11 = 102
12 = 110
13 = 111
14 = 112
15 = 120
16 = 121
17 = 122
18 = 200
19 = 201
20 = 202
Hexadécimal
Voici un programme très performant permettant d'effectuer une conversion d'une valeur d'un octet à hexadécimal en C :
- #include <stdio.h>
- #include <stdlib.h>
-
- char ReturnString[255];
-
- char * ByteHex2Str(unsigned char value) {
- char matrix[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
- ReturnString[0] = matrix[(value >> 4) & 0x0F];
- ReturnString[1] = matrix[value & 0xF];
- ReturnString[2] = 0;
- return ReturnString;
- }
-
- int main()
- {
- printf("00h = %s\n",ByteHex2Str(0x00));
- printf("01h = %s\n",ByteHex2Str(0x01));
- printf("02h = %s\n",ByteHex2Str(0x02));
- printf("0Ah = %s\n",ByteHex2Str(0x0A));
- printf("0Fh = %s\n",ByteHex2Str(0x0F));
- printf("10h = %s\n",ByteHex2Str(0x10));
- printf("20h = %s\n",ByteHex2Str(0x20));
- printf("56h = %s\n",ByteHex2Str(0x56));
- printf("73h = %s\n",ByteHex2Str(0x73));
- printf("EFh = %s\n",ByteHex2Str(0xEF));
- printf("FFh = %s\n",ByteHex2Str(0xFF));
- return 0;
- }
on obtiendra le résultat suivant :
00h = 0001h = 01
02h = 02
0Ah = 0A
0Fh = 0F
10h = 10
20h = 20
56h = 56
73h = 73
EFh = EF
FFh = FF
Base62
Voici un programme permettant d'effectuer une conversion d'une valeur décimal à «Base62» en C :
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- char ReturnString[255];
-
- char * DecimalToBase62(int value) {
- char TBase[62] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- if(0 == value) {
- return "0";
- } else {
- strcpy(ReturnString,"");
- while(value > 0) {
- char Temp[255];
- sprintf(&Temp,"%c",TBase[value % 62]);
- strcat(&Temp,&ReturnString);
- strcpy(&ReturnString,&Temp);
- value /= 62;
- }
- return ReturnString;
- }
- }
-
- int main()
- {
- char I;
- for(I = 60; I <= 80; I++) {
- printf("%i = %s\n",I,DecimalToBase62(I));
- }
- return 0;
- }
on obtiendra le résultat suivant :
60 = y61 = z
62 = 10
63 = 11
64 = 12
65 = 13
66 = 14
67 = 15
68 = 16
69 = 17
70 = 18
71 = 19
72 = 1A
73 = 1B
74 = 1C
75 = 1D
76 = 1E
77 = 1F
78 = 1G
79 = 1H
80 = 1I
BaseX
Avec exemples les précédents, vous l'aurez compris, il est possible d'avoir une formule pour n'importe quel base. En somme, voici un programme permettant d'effectuer une conversion d'une valeur décimal à base relative entre 1 et 61 (mais 13 très pour celui-ci) en C :
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- char ReturnString[255];
-
- char * DecimalToBaseX(int value,char baseNumber) {
- char TBase[62] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- if(0 == value) {
- return "0";
- } else {
- strcpy(ReturnString,"");
- while(value > 0) {
- char Temp[255];
- sprintf(&Temp,"%c",TBase[value % baseNumber]);
- strcat(&Temp,&ReturnString);
- strcpy(&ReturnString,&Temp);
- value /= baseNumber;
- }
- return ReturnString;
- }
- }
-
- int main()
- {
- char I;
- for(I = 0; I <= 20 ; I++) {
- printf("%i = %s\n",I,DecimalToBaseX(I,13));
- }
- return 0;
- }
on obtiendra le résultat suivant :
0 = 01 = 1
2 = 2
3 = 3
4 = 4
5 = 5
6 = 6
7 = 7
8 = 8
9 = 9
10 = A
11 = B
12 = C
13 = 10
14 = 11
15 = 12
16 = 13
17 = 14
18 = 15
19 = 16
20 = 17