IEEE-754

  • Réaliser un convertisseur permettant de donner l’écriture d’un flottant sous la forme d’un mot binaire de 64 bits suivant la norme IEEE-754 (cf. cours sur le codage des nombres).
  • Réaliser aussi le convertisseur inverse, du mot 64 bits au nombre décimal.

Pour vérifier

Nombre à convertir en mot machine 64 bits :

Mot machine 64 bits à convertir en nombre décimal :



Une solution possible

La fonction suivante convertit la partie fractionnaire du nombre n en binaire et donne ainsi son développement binaire (équivalent d’un dévelopement décimal).
Tous les nombres auront nécessairement un développement binaire fini (et seront donc des fractions dyadiques) puisque le flottant donné en argument a lui même une écriture fini (il est codé sur 64 bits !).

def conv_fract(n):
    n = abs(n)
    n = n-int(n)
    count = 0
    s = ''
    n *= 2
    eps = 1e-9
    while count < 64:
        print(n)
        if n >= 1:
            s += '1'
            if not 1-eps < n < 1+eps: 
                n = (n-1)*2
            else: # fin du développement binaire
                break
        else:
            s += '0'
            n *= 2
        count += 1
    return s

La méthode consiste à multiplié par 2 lorsque le nombre est inférieur à 1 et à retirer 1 lorsqu’il dépasse.
On constate sur l’enchaînement des résultats intermédiaires que le chiffre avant la virgule correspond au développement binaire du nombre :

>>> conv_fract(0.1)
0.2
0.4
0.8
1.6
1.2000000000000002
0.40000000000000036
0.8000000000000007
1.6000000000000014
1.2000000000000028
0.4000000000000057
0.8000000000000114
1.6000000000000227
1.2000000000000455
0.40000000000009095
0.8000000000001819
1.6000000000003638
1.2000000000007276
0.4000000000014552
0.8000000000029104
1.6000000000058208
1.2000000000116415
0.40000000002328306
0.8000000000465661
1.6000000000931323
1.2000000001862645
0.40000000037252903
0.8000000007450581
1.6000000014901161
1.2000000029802322
0.4000000059604645
0.800000011920929
1.600000023841858
1.2000000476837158
0.40000009536743164
0.8000001907348633
1.6000003814697266
1.2000007629394531
0.40000152587890625
0.8000030517578125
1.600006103515625
1.20001220703125
0.4000244140625
0.800048828125
1.60009765625
1.2001953125
0.400390625
0.80078125
1.6015625
1.203125
0.40625
0.8125
1.625
1.25
0.5
1.0
'00011001100110011001100110011001100110011001100110011010001100110011001100110011001100110011001100110011001101'


Un code possible pour obtenir l’écriture du nombre sur 64 bits via la norme IEEE-754.

def conv_iee(n: float) -> str:
    s = ''
    if n < 0:
        s += '1'
    else:
        s += '0'
    n = abs(n)
    if n > 1:
        mantisse_str = bin(int(n))[3:] # on enlève le 1er 1
        mantisse_str += conv_fract(n)[:52-len(mantisse_str)]
        exp = len(bin(int(n))[2:])-1 + 1023
        exp_str = bin(exp)[2:]
        s += (11-len(exp_str))*'0'+ exp_str
    else:
        if n == 0:
            exp = 0
            exp_str = '0'*11
            s += exp_str
            mantisse_str = '0'*52
        else:
            dvlpt = "0"+conv_fract(n)
            exp = 0
            while dvlpt[exp] == "0":
                exp += 1
            exp = exp*(-1) + 1023
            exp_str = bin(exp)[2:]
            s += (11-len(exp_str))*'0' + exp_str # on ajoute des 0 à gauche pour compléter à 11 caractères
            mant = conv_fract(n)
            mantisse_str = ""
            test = True
            for i in range(len(mant)):
                if not test or mant[i] != "0": # on enlève les 0 qui précèdent le 1er 1
                    mantisse_str += mant[i]
                    test = False
            mantisse_str = mantisse_str[1:] # on enlève le 1er 1
    if len(mantisse_str) < 52:
        mantisse_str += (52-len(mantisse_str))*'0'
    s += mantisse_str
    s = s[0]+" "+s[1:12]+" "+s[12:]
    return s

Enfin, code d’un convertisseur d’un mot machine 64 bits vers sa valeur décimale :

def deconv(s: str) -> float:
    mot = ''
    for c in s:
        if c != ' ':
            mot += c
    if int(mot) == 0:
        return 0
    exp = int(mot[1:12],2) - 1023
    nombre =  2**exp
    mantisse = mot[12:]
    for c in mantisse:
        exp -= 1
        nombre += int(c)*2**exp
    if mot[0] == "1":
        nombre *= -1
    return nombre