Problème avec les grands nombres ?

Résolu
Phil_1857 -  
yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   -

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

  1. Utilisateur anonyme
     

    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
  2. Phil_1857
     

    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
    1. Utilisateur anonyme
       

      De rien

      0
    2. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       

      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
      1. Utilisateur anonyme > yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention  
         

        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
      2. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588 > Utilisateur anonyme
         

        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