TP9 : nombres

Cliquez sur cette invitation pour récupérer le repository du TP.

Exo 1 : nombres palindromiques

Déterminer grâce à un code Python le plus petit nombre supérieur ou égal à $10,000$ dont l’écriture est palindromique (se lisant pareil dans les deux sens) à la fois en base 10 et en base 2.

### VOTRE CODE
Correction (cliquer pour afficher)
a = False
b = False
i = 10000
while not (a and b):
    str_i_10 = str(i)
    str_i_2 = bin(i)[2:]
    a = str_i_10 == str_i_10[::-1] # i palindromique en base 10
    b = str_i_2 == str_i_2[::-1]   # i palindromique en base 2
    i += 1
print(str_i_10,str_i_2)
Saffiche alors :
15351 11101111110111
# Affectez votre réponse (l'écriture en base 10 du nombre entier trouvé) à la variable nb
nb = 3
Correction (cliquer pour afficher)
$15\,351$

 

Exo 2 : missiles Patriot

Une batterie de missiles Patriot détecte les missiles ennemis et les intercepte avec un contre-missile. La batterie mesure le temps pour prévoir le déplacement des missiles ennemis.
Elle dispose d’un compteur (un entier) que nous appellerons c qui compte le nombre de dixièmes de secondes écoulés depuis sa mise en marche. Le temps écoulé t est calculé par l’opération t=c*0.1. Nous nous intéressons à l’erreur de calcul commise lors de cette multiplication.
D’après un rapport du General Accounting Office, le logiciel du Patriot utilise des nombres à virgule fixe stockés dans un registre de 24 bits.
La représentation en virgule fixe utilisée est le format $Q1.23$ où seulement 1 bit est utilisé pour la partie entière et 23 bits le sont pour la partie fractionnaire.
La partie fractionnaire d’un réel ${x}=x-\lfloor x\rfloor$ est stockée sur les 23 bits en la transformant en l’entier $\lfloor {x}\times 2^{23}\rfloor$ (où $\lfloor\rfloor$ est la partie entière), les chiffres au delà du 23ème après la virgule sont donc tronqués.

Écrivez en base 2 le nombre 0,1 en ne gardant que 24 chiffres (23 après la virgule). On notera $z$ le nombre obtenu.
Vous pourrez vous aidez du code suivant (après l’avoir modifié de manière adéquate) pour déterminer la réponse ou utiliser la dernière phrase de l’énoncé (mais attention alors au petit piège).

a = 2.7
avt = bin(int(a))[2:] + ','
n = a - int(a)
apres = ''
while len(apres)<9 :
    n *= 2
    if n > 1 :
        apres += '1'
        n -= 1
    else :
        apres += '0'
print(avt+apres)

10,101100110

# Affectez à la variable z la chaîne de caractères correspondant à l'écriture binaire demandée :
z = '0,...'
Correction (cliquer pour afficher)
a = 0.1
avt = bin(int(a))[2:] + ','
n = a - int(a)
apres = ''
while len(apres)<23:
    n *= 2
    if n > 1:
        apres += '1'
        n -= 1
    else:
        apres += '0'
print(avt+apres)
Saffiche alors :
0,00011001100110011001100
Commentaire (cliquer pour afficher)
On aurait aussi pu obtenir l'écriture en moins de lignes en utilisant bin sur $\lfloor 0,1\times2^{23} \rfloor$ (ce qui revient à décaler la virgule de 23 rangs en binaire) :
a = bin(int(0.1*2**23))[2:23] # mais attention, il manque des zéros avant !
z = '0,'+'0'*(23-len(a))+a

On note $\varepsilon = |0,1 − z|$. La batterie de missiles Patriot fait une erreur de $\varepsilon$ en approximant 0,1.

Faites calculer par Python la valeur de $\varepsilon$ et affectez cette valeur à une variable epsilon.

# Vous affecterez la valeur à la variable epsilon
epsilon = 
Correction (cliquer pour afficher)
z = '0,00011001100110011001100'
eps = abs(0.1*2**23-int(z[2:],2))/2**23

Début février 1991, l’armée israélienne a empiriquement constaté qu’au bout de 8h, la précision des missiles est significativement réduite. Puis, le 25 février 1991, six batteries de missiles Patriot (un bataillon) ont été déployées à Dhahran, en Arabie Saoudite, pendant 100h.

Nous noterons $e_8$ et $e_{100}$ l’erreur commise sur $t$ par la batterie au bout de 8h puis au bout de 100h.

Calculez des deux erreurs précédentes.

# Vous affecterez les valeurs aux variables e_8 et e_100
e_8 = 
e_100 = 
Correction (cliquer pour afficher)
e8 = eps*8*3600*10
e100 = eps*100*3600*10

Un Scud a une vitesse de croisière de 1676 m/s (Mach 5).

Pendant une durée $e_{100}$, de quelle distance $d$ (en m) se déplace un Scud ?

# Vous affecterez la valeur à la variable d
d =
Correction (cliquer pour afficher)
d = e100*1676

Suite à cette imprécision, un Scud irakien ne fut pas intercepté et causa 28 morts parmi les soldats américains.

 

Exo 3 : overflows

Les 3 “évènements” suivant correspondent au même bug : un dépassement de capacité d’entiers (signés ou non) codés sur 32 bits.

La FAA (Federal Aviation Administration) publie en 2015 une Airworthiness Directive ou AD (notification technique que les compagnies aériennes sont obligées de suivre) concernant un bug dans le logiciel des Boeing 787 : “This AD was prompted by the determination that a Model 787 airplane that has been powered continuously for 248 days can lose all alternating current (AC) electrical power due to the generator control units (GCUs) simultaneously going into failsafe mode.” Le logiciel mesure le temps depuis sa mise en route en incrémentant un compteur toutes les centisecondes.

D’après les informations fournies et vos réflexions, au bout de combien de centisecondes exactement, la capacité du compteur se trouve dépassée, expliquant le bug ?

# Vous affecterez la valeur entière à la variable nb_centi
nb_centi = 
Correction (cliquer pour afficher)
On cherche un nombre de centisecondes correspondant à 248 jours.
Comme 231 cs correspondent à 248,6 jours, on peut supposer que le nombre de cs est codé en 32 bits signés.

En 2004, l’oubli d’un technicien de rebooter un serveur a provoqué une immense pagaille dans le ciel californien. En effet, le 14 septembre, les aiguilleurs du ciel des aéroports du sud californien ont perdu le contact vocal avec 400 avions pendant plus de 3 heures, heureusement sans graves conséquences (grâce à la réaction rapide des contrôleurs qui ont tout de suite utilisé leurs portables pour contacter d’autres centres de contrôle aérien). La maintenance de routine du système de communication consistait à le rebooter tous les 30 jours. Ce système mesure le temps depuis sa mise en route en incrémentant un compteur toutes les millisecondes.

D’après les informations fournies et vos réflexions, au bout de combien de millisecondes exactement, la capacité du compteur s’est trouvée dépassée, expliquant le bug ?

# Vous affecterez la valeur entière à la variable nb_milli
nb_milli = 
Correction (cliquer pour afficher)
On cherche un nombre de millisecondes dépassant les 30 jours (mais pas trop).
Comme 232 ms correspondent à 49,7 jours. On peut supposer que le nombre de ms est codé en 32 bits non signés.

Le bug de l’an 2038 concerne les horloges des systèmes unix 32 bits dont le temps 0, appelé epoch, est le 1 janvier 1970 à 00:00:00 UT.

import time
time.gmtime(0)

time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0

Cela montre que les serveurs hébergeant Colab tournent sous Unix.

Au bout de combien de secondes exactement le problème lié au bug de 2038 se pose ?

# Vous affecterez la valeur entière à la variable 
nb_sec = 
Correction (cliquer pour afficher)
On cherche un nombre de secondes correspondant à 68 ans.
Comme 231 s correspondent à 68,05 années. On peut supposer que le nombre de secondes est codé en 32 bits signés.

Les overflows peuvent aussi avoir des conséquences plus sympatiques comme la machine à sous d’un casino qui a décidé un jour d’imprimer un ticket de 42 949 672,96 $ !! Malheureusement pour le gagnant, le casino a refusé de payer sous prétexte que la machine indiquait un prix maximum de 10 000 $ et le tribunal a finalement donné raison au casino…