Formats numériques


up.gif (853 octets) Entiers non signés

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

up.gif (853 octets) Operations sur les bits

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
 

up.gif (853 octets) Entiers signés

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

up.gif (853 octets) Virgule flottante

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).

up.gif (853 octets) Le format IEEE-754

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énormali
0.f x 2(-b+1)
0 00..01
:
11..10
XX..XX Réel Positif Normali
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énormali
-0.f x 2(-b+1)
1 00..01
:
11..10
XX..XX Réel Négatif Normali
-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 
  

up.gif (853 octets) 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.fr

Opé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/


up.gif (853 octets)