Les bases numériques en informatique
Un système de numération est une méthode de comptage basée sur un ensemble de symboles et une règle de progression. En informatique, nous utilisons principalement quatre bases :
- Décimal (Base 10) : Utilise les chiffres de 0 à 9. C'est le système standard utilisé par les humains.
- Binaire (Base 2) : Utilise uniquement 0 et 1. C'est le langage natif des circuits logiques (allumé/éteint).
- Octal (Base 8) : Utilise les chiffres de 0 à 7.
- Hexadécimal (Base 16) : Utilise les chiffres de 0 à 9 et les lettres A à F (représentant les valeurs 10 à 15). Il permet de condenser les longues suites binaires.
Représentation des littéraux en Java
Java permet de définir des entiers dans différentes bases en utilisant des préfixes spécifiques :
public class BasesDemo {
public static void main(String[] args) {
int dec = 1024; // Décimal par défaut
int bin = 0b10000000000; // Préfixe 0b pour le binaire
int oct = 02000; // Préfixe 0 pour l'octal
int hex = 0x400; // Préfixe 0x pour l'hexadécimal
// L'affichage standard se fait toujours en base 10
System.out.println("Binaire (0b10000000000) -> " + bin);
System.out.println("Octal (02000) -> " + oct);
System.out.println("Hexadécimal (0x400) -> " + hex);
}
}
Mécanismes de conversion
Conversion d'une base R vers le décimal
On utilise la somme pondérée des puissances de la base : Coefficient * (Base^Exposant).
Exemple pour 0b101010 :
(1 * 2^5) + (0 * 2^4) + (1 * 2^3) + (0 * 2^2) + (1 * 2^1) + (0 * 2^0) = 32 + 8 + 2 = 42.
Conversion du décimal vers une base R
On procède par divisions successives par la base R jusqu'à ce que le quotient soit nul. On lit ensuite les restes dans l'ordre inverse de leur apparition.
Conversions rapides entre binaire, octal et hexadécimal
Puisque 8 et 16 sont des puissances de 2, nous pouvons utiliser des groupements de bits :
- Binaire vers Octal : Grouper les bits par 3 à partir de la droite. Chaque groupe de 3 bits correspond à un chiffre octal (0-7).
- Binaire vers Hexadécimal : Grouper les bits par 4. Chaque groupe de 4 bits correspond à un caractère hexadécimal (0-F).
Utilisation de l'API Java pour les conversions
La classe Integer fournit des méthodes statiques efficaces pour transformer des entiers en chaînes de caractères représentant différentes bases :
public class ConversionAPI {
public static void main(String[] args) {
int valeur = 42;
// Vers différentes bases (retourne un String)
System.out.println("Binaire : " + Integer.toBinaryString(valeur));
System.out.println("Octal : " + Integer.toOctalString(valeur));
System.out.println("Hexa : " + Integer.toHexString(valeur));
// Conversion personnalisée vers n'importe quelle base (radix)
System.out.println("Base 10 depuis Hexa : " + Integer.toString(0x2A, 10));
System.out.println("Binaire vers Base 8 : " + Integer.toString(0b101010, 8));
}
}
Représentation des nombres signés
En mémoire, le bit de poids fort (le plus à gauche) est réservé au signe : 0 pour positif, 1 pour négatif.
Formes de représentation
- Code original : Valeur absolue avec bit de signe. Problématique pour les calculs arithmétiques.
- Complément à un (Inverse) : Pour les nombres négatifs, on inverse tous les bits (0 devient 1 et vice versa) sauf le bit de signe.
- Complément à deux : C'est la norme utilisée par les processeurs modernes. Pour un nombre négatif, on prend son complément à un et on ajoute 1.
Le complément à deux permet de traiter les soustractions comme des additions simples (ex: 1 - 2 devient 1 + (-2)) sans gestion complexe du signe.
Transit de données et débordement (Overflow)
Lors d'un transtypage (casting) vers un type plus petit, les bits de poids fort sont tronqués. Le résultat final est interprété selon la règle du complément à deux du type cible.
Exemple : Conversion de int 130 vers byte.
// 130 en int (32 bits) : 0000...0000 10000010
// Conversion en byte (8 bits) : 10000010
// Le bit de signe est 1 (négatif).
// En complément à deux, 10000010 correspond à -126.
byte b = (byte) 130;
System.out.println(b); // Affiche -126
Stockage des nombres à virgule flottante (IEEE 754)
Les types float et double suivent la norme IEEE 754. Un nombre est décomposé en trois parties : V = (-1)^s * M * 2^E.
- s (Signe) : 1 bit.
- E (Exposant) : 8 bits pour float, 11 pour double. Un décalage (bias) de 127 est appliqué.
- M (Mantisse/Significande) : La partie fractionnaire de la valeur normalisée.
Précision et erreurs de calcul
Certaines valeurs décimales (comme 0.1) ne peuvent pas être représentées exactement en binaire, ce qui entraîne des erreurs de précision lors des calculs répétitifs.
public class PrecisionCalcul {
public static void main(String[] args) {
System.out.println(2.0f - 1.3f); // Résultat : 0.70000005 au lieu de 0.7
// Solution recommandée pour la précision financière
java.math.BigDecimal val1 = new java.math.BigDecimal("2.0");
java.math.BigDecimal val2 = new java.math.BigDecimal("1.3");
System.out.println("Avec BigDecimal : " + val1.subtract(val2));
}
}