Problème avec les grands nombres ?

Résolu
Phil_1857 - 29 juin 2024 à 18:59
yg_be Messages postés 22911 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 30 juin 2024 - 30 juin 2024 à 18:37

Bonjour,

Tout est dans le code:

#A-B+C = A-(B-C)

A, B, C = 225, 220, 10
print(A-B+C)
print(A-(B-C))
#affiche 15 puis 15 : OK

A, B, C = 50000181502235777316, 5.000018150016471e+19, 5000009075
print(A-B+C)
print(A-(B-C))
#affiche 7071077747.0 puis 7071080448.0 : pas OK !

Etonnant, non ?
Windows / Edge 126.0.0.0

2 réponses

Whismeril Messages postés 19085 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 30 juin 2024 916
29 juin 2024 à 22:22

Au temps pour moi, j'avais laissé trainé un #

#A-B+C = A-(B-C)

A, B, C = 225, 220, 10
print(A-B+C)
print(A-(B-C))
#affiche 15 puis 15 : OK

A, B, C = 50000181502235777316, 50000181500164710000, 5000009075

print(A-B+C)
print(A-(B-C))
# affiche 7071076391 et 7071076391

D, E, F = 50000181502235777316, 5.000018150016471e+19, 5000009075
print('D-E+F', D-E+F)
print('D-(E-F)', D-(E-F))
print('')
# affiche 7071077747.0 et 7071080448.0

print('A - B', A - B)
print('D- E', D - E)

print('B - C', B - C)
print('E - F', int(E - F))

Non seulement les résultats sont différents, mais en plus, aucun n'est correct.

C'est dû au fait que 5.000018150016471e+19 est différent de 50000181500164710000

La façon dont est codé un float est basée sur le fait qu'un nombre limité de valeurs peuvent être encodées et que pour toutes les autres, elles sont encodées au plus proche. On admet que seule la valeur significative compte.

Comme additionner ou soustraire un float et un int donne un float, celui-ci est aussi encodé au plus proche.

Et d'approximation en approximation, on arrive à deux résultats incorrects.


0

Bonjour Whismeril,

Merci de ta réponse, je me doutais qu'il y avait un truc de ce genre

On peut marquer comme résolu 

0
Whismeril Messages postés 19085 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 30 juin 2024 916
30 juin 2024 à 13:01

De rien

0
yg_be Messages postés 22911 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 30 juin 2024 1 480
30 juin 2024 à 16:06

bonjour,

import decimal
X=1e+16
Y=1
print(str(X)+" plus " +str(Y)+" moins "+str(X)+" est égal à ",X+Y-X)
X=decimal.Decimal(X)
Y=1
print(str(X)+" plus " +str(Y)+" moins "+str(X)+" est égal à ",X+Y-X)
0
Whismeril Messages postés 19085 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 30 juin 2024 916 > yg_be Messages postés 22911 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 30 juin 2024
30 juin 2024 à 18:02

Salut,

c'est vrai, je n'y ai pas pensé.

J'ai répondu à la question, mais pas à la problématique finalement.

Par contre, à priori tu ne connais pas les fstring (formated string), je me permets de te montrer.

import decimal
X = 1e+16
Y = 1
# construction d'une string avec les valeurs directement incorporées, sans formatage particulier
print(f"{X} plus {Y} moins {X} est égal à {X+Y-X}")
X = decimal.Decimal(X)
Y = 1
# formatage d'un X en tant que float dans la string
print(f"{X:0.0} plus {Y} moins {X} est égal à {X+Y-X}")
0
yg_be Messages postés 22911 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 30 juin 2024 1 480 > Whismeril Messages postés 19085 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 30 juin 2024
30 juin 2024 à 18:37

Merci pour la suggestion.  Je n'apprécie guère ces formatted strings.

Surtout, ils sont spécifiques à quelques langages.

Accessoirement, et c'est très subjectif, ils ne clarifient pas beaucoup le code.

0