IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Calcul scientifique Python Discussion :

Calcul d'un grand nombre de décimal


Sujet :

Calcul scientifique Python

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2019
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2019
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Calcul d'un grand nombre de décimal
    Bonjour,

    Mon but est d'effectuer une certaine division, à savoir 1/0.9144 (pour des raisons peu importantes ici), mais j'aimerai obtenir un GRAND nombre de décimales exactes, au alentour de 400 ou plus.

    Le problème: la division basique de python ne me donne que 16 chiffres significatifs, du moins trop peu pour moi. J'ai alors eu l'idée pour obtenir ces décimales de coder la division euclidienne moi même, et de l'appliquer à quelque chose comme 1e400 divisé par 9144, puis de mettre la virgule ou il faut le moment venu.

    Oui mais: je crois que mon programme est correct, pourtant, pour deux valeurs du numérateur (1e200 et 1e250 par exemple), il semble que les chiffres au delà du seizième changent, ce qui ne devrait pas être le cas. Ci joint une photo du programme: (implémentation classique, surement mal foutu par mon manque de talent mais fonctionnelle de la division euclidienne me semble il)
    Nom : Yard.png
Affichages : 813
Taille : 59,4 Ko
    Y'a t'il une raison obscure à cette limitation, que mon maigre niveau d'algorithmique et d'informatique m'a fait louper?

    Merci de vos réponses et happy coding!

  2. #2
    Membre expérimenté

    Homme Profil pro
    linux, pascal, HTML
    Inscrit en
    Mars 2002
    Messages
    649
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : linux, pascal, HTML
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2002
    Messages : 649
    Points : 1 493
    Points
    1 493
    Billets dans le blog
    1
    Par défaut
    Bonjour,
    cela serait plus simple si tu faisais un copier coller du code entre deux balises CODE le # sur l'éditeur

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2019
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2019
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    D'accord, voilà:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    def n(r,b):
       n=0
       while 10**n*b < r:
          n += 1 
       if n == 0: return 0
       else: return n-1 
     
    def c(r,b,n):
       c=0
       while 10**n*b*c < r:
          c+=1
       if c == 0: return 
       else: return c-1
     
    def div(a,b):
       q = 0 
       r = a
       while r > b:
          m = n(r,b)
          d = c(r,b,m)
          q += 10**m*d
          r -= 10**m*b*d
       return q,r

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Tu n'exploites pas ce que Python sait faire déjà.

    La division entière (//)fonctionne très bien. Voilà ton résultat avec 1000 chiffres:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    print(10**1003//9144)
    1093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440
    Mais ce qu'on obtient ici est un entier. Si tu dois enchaîner d'autres calculs, il faut continuer en entier. Tu ne peux insérer un point décimal que pour un affichage, parce qu'il faudra convertir avant ce nombre entier en chaine de caractères (str(...)).

    Il existe aussi le module "decimal" (https://docs.python.org/fr/3/library...module-decimal) qui permet de faire des calculs avec le nombre de chiffres significatifs (y compris avec décimales) qu'on veut:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from decimal import getcontext, Decimal
    getcontext().prec = 1000
    print(Decimal(1)/(Decimal(9144)/Decimal(10000))) # 1/0.9144
    1.093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440069991251093613298337707786526684164479440
    Tu vois que le résultat est identique en chiffres trouvés, mais il y a un point décimal, et d'autres calculs peuvent être enchainés.

    Il faut cependant apprendre à utiliser ce module décimal, parce qu'il y a des effets qu'on ne comprend pas tout de suite. Par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    print(Decimal(1)/Decimal(0.9144)) # 1/0.9144
    1.093613298337707797786561187067634719818706412919076038716131075198890225702988479195774126789035671568160960730582382304242645549206456944723416025547005762331191436600660217289465436927961494084486021147203291835454096685609228525720927459471391810617818371166591758508104636790821242296675075833324080834345102166518103886508578032178445515224974674941730438471027123887191913908851046849553930614941415344972171942959863984616356664201544580410488445744194691084278836289070041026671273779053484929692233611608142073449222292710730011169920291641420853597733804472477553369327830846505726227028091591605134150464127605416662219517915912705189453879221916760722508822597370366365956683497247315945269461174833133467160581877386054350118805725427055351054899032631159984456674954666689942485383107111687675525442215107855446880180497354371917088666691343843531663641000617831450858003321317712951641442970237984803906676059310513576336542640640706029976289975445224891040091859750626599671416797852
    On voit que le résultat est faux après la 16ème décimales, et c'est normal: avec Decimal(0.9144), on demande la conversion d'un float de 16 décimales en un nombre de 1000 décimales, ce qui, en général, ne tombe pas juste. Ce n'est pas une erreur de calcul, c'est lié à la façon dont les nombres réels (type "float" en Python correspondant au "double" en C) sont codés en mémoire dans un nombre limité d'octets (8).

    Il vaut mieux en conséquence demander à ce que le module "decimal" fasse lui-même les calculs à partir d'entiers: d'où le (Decimal(9144)/Decimal(10000)) qui donne le bon résultat.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

Discussions similaires

  1. [Toutes versions] Automatiser un calcul dans un grand nombre de fichiers
    Par fanfanus dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 22/11/2016, 13h31
  2. calcul du plus grand nombre
    Par bernards111 dans le forum Général Python
    Réponses: 23
    Dernier message: 13/05/2011, 14h53
  3. Réponses: 14
    Dernier message: 05/10/2010, 16h26
  4. Calcul Grand nombre
    Par Thesum4113 dans le forum C#
    Réponses: 3
    Dernier message: 08/01/2008, 18h14
  5. Réponses: 14
    Dernier message: 18/11/2005, 15h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo