L'électronique produit le format numérique le plus simple dans la mesure ou seuls un niveau "bas" et un niveau "haut" peuvent exister sur une ligne logique (Je fais volontairement abstraction du niveau "ouvert", qui n'a aucune incidence dans cette explication). En utilisant parallèlement plusieurs lignes logiques, il est possible d'étendre la plage de valeurs produites. Ceci est possible en affectant un "poids" à chaque ligne logique. Le tableau ci-dessous illustre comment il est possible de générer des valeurs comprises entre 0 et 7 (8 pas) en utilisant 3 lignes logiques
Poids | |||
4 | 2 | 1 | Valeurs résultantes |
0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 |
0 | 1 | 0 | 2 |
0 | 1 | 1 | 3 |
1 | 0 | 0 | 4 |
1 | 0 | 1 | 5 |
1 | 1 | 0 | 6 |
1 | 1 | 1 | 7 |
Exemple: La valeur résultante 5 est le résultat de: 1 x 1 + 0 x 2 + 1 x 4 = 1 + 0 + 4 = 5. Le premier terme de chaque produit est la valeur du niveau logique, le second terme est son poids.
De cette démonstration, il est possible d'extrapoler les valeurs qu'il est possible d'atteindre avec 4, 8, 16 et 32 lignes (on parle de bits) et plus
Mini | Maxi | |||
Bits | Décimal | Binaire | Décimal | Binaire |
4 | 0 | 0000 | 15 | 1111 |
8 | 0 | 0000 0000 | 255 | 1111 1111 |
16 | 0 | 0000 0000 0000 0000 | 65535 | 1111 1111 1111 1111 |
32 | 0 | 0000 0000 0000 0000 0000 0000 0000 0000 | 4294967295 | 1111 1111 1111 1111 1111 1111 1111 1111 |
Nota: Convertir de grandes valeurs binaires en décimal est un peu fastidieux; vous pouvez utiliser le convertisseur de la Calculatrice disponible dans l'environnement Windows (en mode Scientifique).
VB: VB offre un type de variable pour les variables booléennes (1 bit pouvant prendre les valeurs 0 ou 1), il s'agit du format "Boolean". Notez que malgré les apparences, ce format consomme 16bits!
Conversions (par l'exemple)
Entier en binaire
La méthode classique des restes:
Public Function Integer2Binary( _ ByVal Value As Long) As String Dim BitsString As String Dim Remainder As Integer Do While Value 0 'compute remainder Remainder = Value Mod 2 'upadte value Value = Value \ 2 'format result BitsString = Format(Remainder) & BitsString Loop 'format result If BitsString = "" Then BitsString = "0" End If 'returned value Integer2Binary = BitsString End Function
Variante:
Public Function Integer2BinaryPwrMethod( _ ByVal Value As Long, _ Optional ByVal NbrBits As Long = 8) As String Dim BitIndex As Integer Dim BitsString As String Dim BitValue As Integer For BitIndex = NbrBits To 1 Step -1 'compare values sign If Value >= 2 ^ (BitIndex - 1) Then 'upadte value Value = Value - 2 ^ (BitIndex - 1) BitValue = 1 Else BitValue = 0 End If 'format result BitsString = BitsString & Format(BitValue) Next 'returned value Integer2BinaryPwrMethod = BitsString End Function
Binaire en entier
Public Function Binary2Integer( _ ByVal BinaryValue As String) As Long Dim BitIndex As Integer Dim BitValue As Integer Dim IntegerValue As Long For BitIndex = 1 To Len(BinaryValue) BitValue = Val(Mid(BinaryValue, BitIndex, 1)) IntegerValue = IntegerValue + BitValue * 2 ^ (Len(BinaryValue) - BitIndex) Next 'returned intefer value Binary2Integer = IntegerValue End Function
Jusque là, tout va bien, au détail près que les ces valeurs entières sont toutes positives. Il va donc falloir utiliser un artifice pour "signer" les valeurs décimales à l'aide d'un codage binaire spécifique. Deux options sont possibles: complément par 1 et complément par 2
L'algèbre de Bool (du nom de son inventeur), régit les opérations qu'il est possible d'effectuer sur codes valeurs binaires. Ces opérations sont généralement présentées sous forme de tableaux à plusieurs colonnes. La ou les premières colonnes contiennent les valeurs que peuvent prendre un ou plusieurs bits (les variables), la dernière colonne contient le résultat attendu pour l'opération. Ces tables portent là encore de le nom de leur inventeur: Karnaugh
Fonction Not
b0 | Not |
0 | 1 |
1 | 0 |
Fonction Or
b1 | b0 | Or |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
Application: l'exemple ci dessous utilise la fonction Or pour attribuer la valeur 1 à un bit particulier d'une valeur binaire
Function BitSet( _ ByVal Value As Long, _ ByVal BitIndex As Integer) As Long 'apply OR to the bit mask BitSet = (Value Or 2 ^ (BitIndex - 1)) End Function
Fonction Nor (Not or)
b1 | b0 | Nor |
0 | 0 | 1 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 0 |
Fonction Xor (Or exclusif: ou l'un ou l'autre, mais pas les deux!)
b1 | b0 | Xor |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
Application: l'exemple ci dessous utilise les fonctions Xor pour inverser la valeur d'un bit particulier d'une valeur binaire
End Function Function BitToggle( _ ByVal Value As Long, _ ByVal BitIndex As Integer) As Long 'apply XOR with the negation to the bit mask BitToggle = (Value Xor 2 ^ (BitIndex - 1)) End Function
Fonction And
b1 | b0 | And |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
Application: l'exemple ci dessous utilise les fonctions And and Not pour attribuer la valeur 0 à un bit particulier d'une valeur binaire
Function BitClear( _ ByVal Value As Long, _ ByVal BitIndex As Integer) As Long 'apply AND with the negation to the bit mask BitClear = (Value And Not 2 ^ (BitIndex - 1)) End Function
Application: l'exemple ci dessous utilise les fonctions And pour lire la valeur d'un bit particulier d'une valeur binaire
Function BitStatus( _ ByVal Value As Long, _ ByVal BitIndex As Integer) As Boolean 'apply AND to the bit mask BitStatus = Value And 2 ^ (BitIndex - 1)
Fonction Nand (Not And)
b1 | b0 | Nand |
0 | 0 | 1 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
Signe et magnitude
C'est la méthode la plus simple; elle consiste à réserver un bit pour le signe et à utiliser les autres bits pour définir la grandeur de la valeur numérique
Exemples: Le tableau ci-dessous exprime les valeurs 0 et 5 en positif et négatif
Poids |
|||||
Signe | 4 | 2 | 1 | Binaire | Décimal |
0 | 1 | 0 | 1 | 0101 | +5 |
0 | 0 | 0 | 0 | 0000 | (+) 0 |
1 | 0 | 0 | 0 | 1000 | (-) 0 |
1 | 1 | 0 | 1 | 1101 | -5 |
L'observation du tableau montre qu'il existe deux manière de représenter la valeur 0, ce qui pose quelques problèmes au niveau des processeurs pour l'exécution d'opérations binaires (ex: addition). Aussi ce mode de représentation est très peu usité
Complément par 1
Cette méthode est utilisée par certains types de processeurs. Elle consiste très simplement à inverser les bits de la valeur binaire de la valeur entière positive. De même que dans le cas des valeurs exprimées en format "signe et magnitude", le premier bit est réservé au signe.
Exemples: Le tableau ci-dessous exprime les valeurs 0 et 5 en positif et négatif
Poids |
|||||
Signe | 4 | 2 | 1 | Binaire | Décimal |
0 | 1 | 0 | 1 | 0101 | +5 |
0 | 0 | 0 | 0 | 0000 | (+) 0 |
1 | 1 | 1 | 1 | 1111 | (-) 0 |
1 | 0 | 1 | 0 | 1010 | -5 |
L'observation du tableau montre qu'il existe deux manière de représenter la valeur 0, ce qui pose quelques problèmes au niveau des processeurs pour l'exécution d'opérations binaires (ex: addition). Aussi ce mode de représentation est très peu usité
Complément par 2
C'est la méthode est un peu plus compliquée, mais elle présente l'avantage de ne proposer qu'un seul format pour la valeur 0, et de retourner une valeur 0 lors de l'exécution de l'opération binaire -x + x = 0. La méthode est la suivante:
Exemples: Créer la valeur -13 sous 8 bits
Convertir la valeur absolue décimale en binaire
Poids |
|||||||||
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | Binaire | Décimal |
0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 00001101 | 13 |
Inverser tous les bits
Poids |
|||||||||
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | Binaire | Décimal |
1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 11110010 | (242) |
Ajouter 1
Poids |
|||||||||
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | Binaire | Décimal |
1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 11110010 | (242) |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 00000001 | 1 |
1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 11110010 | -13 (243) |
-13 converti en binaire signé égale donc 11110010
La conversion inverse s'effectue en appliquant la méthode suivante:
Retenir la valeur du premier bit
Poids |
|||||||||
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | Binaire | Décimal |
1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 11110010 | -13 (243) |
1= signe négatif
Inverser tous les bits
Poids |
|||||||||
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | Binaire | Décimal |
1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 11110010 | -13 (243) |
0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 00001100 | 12 |
Ajouter 1
Poids |
|||||||||
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | Binaire | Décimal |
0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 00001100 | 12 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 00000001 | +1 |
0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 00001101 | 13 |
Par ailleurs, on vérifie que -13 + 13 =0
1 | 1 | 1 | 1 | 1 | 1 | 1 | Retenue | ||
1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 11110010 | -13 (243) |
0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 00001101 | 13 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 00000000 | résultat |
VB: VB offre différents types de variables qui appliquent les règles précédemment expliques
Nom du format | Nombre de bits | Mini | Maxi |
"Integer" | 16 | -32,768 | 32,767 |
"Long" | 32 | -2147483648 | 2147483647 |
Nous avons vu comment exprimer des valeurs entières signés ou non dans une plage de valeurs dépendant du nombre de bits utilisés. Cependant, ces formats présentent deux inconvénients: il ne permettent pas l'expression de valeurs fractionnaires et la plage de valeurs décimales équivalente est réduite. C'est la raison pour laquelle les formats en Virgule Flottante ont été mis au point. Il s'agit ni plus ni moins que du format scientifique appliqué au binaire.
Le principe est relativement simple: chaque valeur numérique est représentée sous la forme d'une mantisse (normalisée et signée) et d'un exposant (signé). La mantisse est elle même constituée d'une somme de fractions; chaque fraction est l'inverse de 2 élevé à la puissance correspondant au poids du bit. Exemple le premier bit de mantisse exprimera la valeur 1 / 2^1 soit un demi, le bit suivant exprimera la valeur 1 / 2^2 soit un quart et ainsi de suite. Et pourquoi ne démarre t'on pas à 1 / 2^0? Tout simplement parce que 1 / 2^0 = 1 et que 1 est l'élément neutre des produits et donc inutile et superflu dans l'expression de la mantisse! Autre question: comment définir un exposant négatif? Très simple, la valeur binaire est décalée de la moitié de sa plus grande valeur. Si l'exposant utilise 4 bits, le décalage est donc de (2^3)-1 soit 7
L'exemple de représentation de valeurs décimales en formats virgule flottante; le nombre de bits est volontairement réduit pour faciliter la compréhension: 1 bit de signe, 4 bits d'exposant et 3 bits de mantisse
Bit de signe | Bits d'exposant | Bit de mantisse | Valeur décimale | |||||
1==+ | 8 | 4 | 2 | 1 | 4 | 2 | 1 | |
1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 |
0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | -1.5 |
VB: VB offre différents types de variables, compatibles avec la norme IEEE 754 qui appliquent les règles précédemment expliquées
Nom du format | Nombre de bits | Mini négatif | Maxi négatif | Mini positif | Maxi positif |
"Single" | 32 | -3.402823e38 | -1.401298e-45 | 1.401298e-45 | 3.402823e38 |
"Double" | 64 | -1.79769313486232e308 | -4.94065645841247e-324 | 4.94065645841247e-324 | 1.79769313486232e308 |
Représentation du format IEEE 754 32 bits
Bit de signe | Bits d'exposant | Bits de mantisse | |||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
Conversions (par l'exemple)
Fractionnaire en binaire
Public Function Fractional2Binary( _ ByVal Value As Double, _ Optional ByVal NumberDecimalPlaces As Integer = 16) As String Dim BitsString As String Dim IntegerValue As Integer Dim NumberBits As Integer Do While Value 0 'compute twice the Value Value = Value * 2 'compute integer IntegerValue = Int(Value) 'retain fractional value Value = Value - IntegerValue 'format result BitsString = BitsString & Format(IntegerValue) 'Number of bits limitation (avoid infinite looping) NumberBits = NumberBits + 1 If NumberBits >= NumberDecimalPlaces Then Exit Do End If Loop 'returned value Fractional2Binary = BitsString End Function
Binaire en fractionnaire
Public Function Binary2Fractional( _ ByVal BinaryValue As String) As Double Dim BitIndex As Integer Dim BitValue As Integer Dim FractionalValue As Double 'trim separator BinaryValue = Right(BinaryValue, Len(BinaryValue) - 1) 'compute fractional value For BitIndex = 1 To Len(BinaryValue) BitValue = Val(Mid(BinaryValue, BitIndex, 1)) FractionalValue = FractionalValue + BitValue / (2 ^ BitIndex) Next 'returned value Binary2Fractional = FractionalValue End Function
Ayant procédé à la conversion de la valeur décimale (type eee.ffff) en valeur binaire (type bbb.bbb), il est maintenant nécessaire de normaliser la valeur sous la forme b.bbbbb ou b est fatalement égal à "1", et de noter la puissance (de 2) à laquelle il faut élever la valeur normaliser pour qu'elle soit toujours égale à sa valeur initiale (type bbb.bbb).
Cas spéciaux
Encore plus fort, le format IEEE 754 permet aussi la codification de valeurs spéciales. Le tableau ci-dessous récapitules ces cas pour le format sous sous 32 bits
Signe | Exposant (e) | Fraction (f) | Valeur |
---|---|---|---|
0 | 00..00 | 00..00 | +0 |
0 | 00..00 | 00..01 : 11..11 |
Réel Positif Dénormalisé 0.f x 2(-b+1) |
0 | 00..01 : 11..10 |
XX..XX | Réel Positif Normalisé 1.f x 2(e-b) |
0 | 11..11 | 00..00 | +Infini |
0 | 11..11 | 00..01 : 01..11 |
NaN |
0 | 11..11 | 10..00 : 11..11 |
NaN |
1 | 00..00 | 00..00 | -0 |
1 | 00..00 | 00..01 : 11..11 |
Réel Négatif Dénormalisé -0.f x 2(-b+1) |
1 | 00..01 : 11..10 |
XX..XX | Réel Négatif Normalisé -1.f x 2(e-b) |
1 | 11..11 | 00..00 | -Infini |
1 | 11..11 | 00..01 : 01..11 |
NaN |
1 | 11..11 | 10..00 : 11.11 |
NaN |
NaN=Not a Number
Le résultat des opérations portant sur des nombres en virgule flottante au format IEEE 754 correspond aux données du tableau ci-dessous
Opération | Résultat |
---|---|
n / ±Infini | 0 |
±Infini x ±Infini | ±Infini |
±non zéro / 0 | ±Infini |
Infini + Infini | Infini |
±0 / ±0 | NaN |
Infini - Infini | NaN |
±Infini / ±Infini | NaN |
±Infini x 0 | NaN |
La totale
Les deux exemples de code ci-dessous permettent de convertir une valeur numérique décimale en une valeur hexadécimale (et vis versa) sous 32bits, 100% compatible avec le standard IEEE-754. Les trois premières lignes doivent être collées dans la partie déclaration du module
Public Const DCV_ERR_FLT_INF = 0
Public Const DCV_ERR_FLT_NAN_SIG = 1
Public Const DCV_ERR_FLT_NAN_QUI = 2
Décimal à hexadécimal
Public Function Decimal2HEX_IEEE754_dcv( _ ByVal Value As Double) As Variant Dim Result As String Dim Sign As Long Dim Mantissa As Variant Dim Exponent As Variant Dim PoweredValue As Double Dim Buffer As String If Value = 0 Then Sign = &H0 Exponent = &H0 Mantissa = &H0 Else 'get sign If Value 1 If PoweredValue >= 2 Then PoweredValue = PoweredValue / 2 Exponent = Exponent + 1 Else PoweredValue = PoweredValue * 2 Exponent = Exponent - 1 End If Loop If Exponent >= -126 Then 'normalized value 'compute mantissa Mantissa = (PoweredValue - 1) * &H800000 'compute exponent Exponent = (127 + Exponent) * &H800000 Else 'de normalized value 'compute mantissa Mantissa = Int(PoweredValue * 2 ^ (149 + Exponent)) 'set exponent Exponent = &H0 End If End If 'concatenate strings Result = "&H" & Hex(Sign + Exponent + Mantissa) 'returned value Decimal2HEX_IEEE754_dcv = Result End Function
Hexadécimal à décimal
Public Function HEX_IEEE7542Decimal_dcv( _ ByVal Value As Variant) As Variant Dim Exponent As Long Dim Mantissa As Long Dim Sign As Integer Dim SignBit As Boolean Dim Result As Single 'apply bit mask to extract sign status SignBit = Value And &H80000000 'compute sign Sign = ((-1) ^ SignBit) 'apply bit mask to extract mantissa Mantissa = (Value And &H7FFFFF) 'apply bit mask to extract exponent Exponent = (Value And &H7F800000) 'shift bits 23 positions to the right Exponent = Exponent \ &H800000 'compute result If Exponent = 0 Then If Mantissa = 0 Then 'whatever the sign Result = 0 Else 'denormalized result Result = Sign * Mantissa * 2 ^ -149 End If ElseIf Exponent = &HFF Then If Mantissa = 0 Then 'infinite ErrorCode = DCV_ERR_FLT_INF Exit Function ElseIf Mantissa
Liens
Les formats numériques de VB passés au peigne fin
http://www.codeguru.com/vb/gen/vb_misc/algorithms/article.php/c7495/
IEEE Standard 754 http://stevehollasch.com/cgindex/coding/ieeefloat.html
http://fred.just.free.fr/francais/index.php?from=http://fred.just.free.fr/francais/exemples/Ieee.html
http://www.trotek.ec-lyon.fr/~muller/cours/numeration/flp_ieee.html.frOpérations sur les valeurs binaires
http://www.evergreen.edu/biophysics/technotes/misc/bin_math.htm
http://www.evergreen.edu/biophysics/technotes/program/2s_comp.htm
http://www.fact-index.com/n/ne/negative_and_non_negative_numbers.html
http://www.codeguru.com/vb/gen/vb_misc/algorithms/article.php/c7495/