Forum de mathématiques - Bibm@th.net
Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
Pages : 1
Discussion fermée
#1 17-03-2021 12:36:17
- Mouss
- Membre
- Inscription : 23-04-2020
- Messages : 105
Égalité fausse sur python
Bonjour,
Pouvez vous m'expliquer pourquoi python me revois faux qd je tape ceci 0.8+0.1==0.9 ??
Je lai testé à plusieur reprises et je ne comprends pas pourquoi il me renvoie faux.
Merci davance pour votre aide !
Hors ligne
#2 17-03-2021 13:12:50
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 17 385
Re : Égalité fausse sur python
Re,
Bizarre :moi, j'obtiens : True !
>>> 0.8+0.1
0.9
>>> 0.8+0.1==0.9
True
Cela dit :
>>> 0.1+0.2
0.30000000000000004
>>> 0.1+0.2==0.3
False
>>> 0.3-0.1
0.19999999999999998
>>> 0.3-0.1==0.2
False
Le soucis viennent de la représentation des nombres à virgule flottante :
https://www.alloschool.com/assets/docum … atique.pdf
Alors comment puis-je calculer le nombre d'or avec 20000 décimales avec la certitude d'un résultat exact ?
Grâce à l'import de la classe du module decimal : from decimal import Decimal...
@+
Dernière modification par yoshi (17-03-2021 14:10:05)
En ligne
#3 18-03-2021 08:51:47
- Mouss
- Membre
- Inscription : 23-04-2020
- Messages : 105
Re : Égalité fausse sur python
Merci pour votre reponse.
Ce que je comprends cest que les nombres à virgules sont converti dans une autre base pour etre calculer cest pour cela que ça provoque des approximations ?
Pouvez vous m'expliquer le from decimal import Decimal? Je ne lai jamais vu.
Hors ligne
#4 18-03-2021 10:23:20
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 17 385
Re : Égalité fausse sur python
RE,
Ce que je comprends c'est que les nombres à virgules sont converti dans une autre base pour etre calculer cest pour cela que ça provoque des approximations ?
Oui, tout calcul se fait sur des nombres convertis préalablement en base 2 (y compris sur des entiers).
Et certaines parties décimales ne peuvent avoir qu'une représentation approchée en base 2.
On peut aussi contourner la difficulté en travaillant sur des entiers...
Exemple
$0.3-0.1=\dfrac{3}{10}-\dfrac{1}{10}=\dfrac{3-1}{10}$
Maintenant, je fais le calcul via Python :
>>> (3-1)/10==0.2
True...
Voici un programme de calcul de la racine carrée de n'importe quel nombre via la méthode de Heron d'Alexandrie, méthode très rapide (j'obtiens 1000 décimales de $\sqrt 2$ en 0,2 s de $\sqrt 5$ en 0,3 s...
Il faut savoir que ce module n'utilise des nombres entiers que si ils sont au préalable convertis via le module...
#!/usr/bin/env python
# coding: utf-8 -*-
from time import time
from decimal import Decimal as D,getcontext
from math import sqrt
def rac(n,prc):
getcontext().prec=prc+2 # j'augmente la précision voulue de deux chiffres
E=int(sqrt(n))
u=D(E) # Pour ne pas être trop loin de la racine cherchée
q=D(E-1)
epsilon=D(1)/D((10**prc))
i=0
while abs(q)>D(2)*epsilon:
u=(u**2+D(n))/(u*D(2))
q=abs(D(n)/u-u)
i+=1 # nombre d'itérations
return u,i
debut=time()
radicande = 23 # nombre dont vous recherchez la racine carrée
precision = 1000 # Précision souhaitée
u,i=rac(radicande,precision)
print ("Racine cherchée :")
print (u)
print("\nNombre d'Itérations :", i)
print("Effectuées en :",time()-debut,"s")
Résultat pour n=23 :
$\sqrt{23}\approx$
Racine cherchée :
4.79583152331271954159743806416269391999670704190412934648530911444825723590746408249219144643691886061747456324573686513392890392123026548884578379433407966472756967165349434397843456141679872131511991288956318804496411324593925718459496039453926004356146460202152486503532934363086274731937668011877025054737708513330390377209044326617801501683353583041507048640179476745410479188046578554656176617568524450576465389711253958587404330061941137473609109976350633040762876386724156939220008934770208711136596906907199086147225883297177382377130761938137969415630879846048845235697699904403054843252893229055723971617115677679931080384284966690265902454607543365705389368190995394922917929701618373910486985696906813382207089327462650974689848248251780374958486007566141408136373358153770838158951145430274685568051513345253992884803582656451880775953716880018678299314916241332339317904053586692241762254198364109657285849855689315725368519280220902818742895694442815625085979762977950595104103407877523
Je demande u**2, pour voir :
>>> u**2
>>> u**2
Decimal('23.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
Adaptation de la méthode de Heron d'Alexandrie à la racine cubique :
from time import time
from decimal import Decimal as D,getcontext
def cherche_u0(n):
Cubes=[1, 8, 27, 64, 125, 216, 343, 512, 729,1000]
lg=len(str(n))
if lg>3:
fin=lg%3+3*(lg%3==0)
mant,expo=int(str(n)[:fin]),int(len(str(n)[fin:]))//3
else:
mant,expo=n,0
for i,cube in enumerate(Cubes):
if cube>mant:
return i*10**expo
def rac(n,prc):
u=D(cherche_u0(n)) # Pour ne pas être trop loin de la racine cherchée
u0,i=u,0
epsilon=D(1)/(10**prc)
while True:
u=(D(2)*u+n/(u*u))/D(3)
ecart=abs(u0-u)
if ecart<epsilon:
break
i+=1
u0=u
return u,i
debut=time()
radicande = 33856758 # nombre dont vous recherchez la racine cubiquee
precision = 2000 # Précision souhaitée
getcontext().prec=precision+2
u,i=rac(radicande,precision)
print()
print ("Racine cherchée :")
print (u)
print("\nNombre d'Itérations :", i)
print("Effectuées en :",time()-debut,"s")
Résultat avec 2000 décimales :
$\sqrt[3]{33856758 }\approx$
323.5055902434679379226053589200945035623181652483002642788976952283690739883962106530362675397364095473103538731570046507352909307871123959942871217640562136673513051824765310417739361237581506843073397149533743767595318838198675285721453886147287359209956105616074511267891951947394196028600841967426498700575181519066158400071515460404382462609681913232187583258792907469578863857062691675343118500214476371705333836413375239460093233205996709286054254766711240159947884663606054826925754273249699431986469981958185037385479606985666899924869501206085062461822711019904253654383352993956438108717732313589596397026137828181777675725953927012241509327305079763711388286744434051749776044184621875213951597110931707886702054050678236369899753802409178814537079845190451192859339661480828601763799791369209626093227614172615070499174942937747438053962990070199828384337714699939986479116594660416894203054225863702827723720065585733316945466652477019454866296904169700617863197667209177787927556374350507124060559862582736590484489367705247737538533265279741784481203553320732106661208948235472834748542598197121506243147982886821056258879959237326778694213193375694495037504161642192003009611377336902460348708820460052501152790133309969774440854917726403179833698245579046319498564321913784145409407916903972102192305753302863101446754623531909336404059342966182538434424070263066859031462508133629333720804260097025417404103747354379999904499045258566159855291432626252672637826572300811831704462475483990763755609870468954691435318636556727057781527952925400038338199839423636111599882764656166730316228985632700138705443140026470506609930137750647541822227245335099206414112121089876004641063035042977118945271083975191965141033857331230519687557524719887644514528304960898906129163992133761235159140873309120467713461719137651194900058319262148027880798832541610587719264629014103345190676908734507754745907815792716870414402830887895378370865224679666994994340936399176750526942665310146035041204
Nombre d'Itérations : 11
Effectuées en : 0.05100274085998535 s
Et si je demande u**3
>>> u**3
>>> u**3
Decimal('33856758.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
Les calculs sont justes...
https://docs.python.org/fr/3/library/decimal.html
Connais-tu le module fractions ?
from fractions import Fraction as F
print (F1,2)-F(1,3)+F(1,4)-F(1,5)+F(1,6)
23/60
print (F(3,2)-F(1,3)+F(1,4)-F(3,5)+F(1,6))
59/60
Il contient aussi le calcul du PGCD
>>> from fractions import gcd
>>> gcd(5544,7392)
1848
@+
En ligne
#5 18-03-2021 14:43:36
- Mouss
- Membre
- Inscription : 23-04-2020
- Messages : 105
Re : Égalité fausse sur python
Je commence tout juste sur python donc du coup je nai pas tout tout compris, ce que je comprends cest que le fonction Decimal accepte que la valeur soit approximative ? C'est comme la fonction isclose()?
Jai une autre question, est ce que nombres flottant et nombres réels cest la meme chose?
Merci davance pour votre aide
Hors ligne
#6 18-03-2021 19:16:09
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 17 385
Re : Égalité fausse sur python
Bonsoir,
Non, la fonction Decimal calcule avec la précision souhaitée parce qu'elle contourne le problème des nombres en virgule flottante par un format spécial...
Il me semble avoir lu que l'astuce pour ce faire est d'utiliser les fonctions continues : https://fr.wikipedia.org/wiki/Fraction_continue
est-ce que nombres flottant et nombres réels cest la meme chose?
On parle de nombres écrits en virgule flottante ; pour passer d'un entier à un nombre en virgule flottante on utilise la fonction Python float() :
>>> print (float(2))
2.0
>>> print(type(3.5))
<class 'float'>
La racine carrée de 4 est un entier : 2
Pourtant :
>>> type(sqrt(4))
<class 'float'>
Pourquoi ? Parce que la racine carrée, par défaut, donne le résultat sous la forme d'un nombre en virgule flottante...
Mais Python "sait" que c'est en réalité un entier... Il suffit de lui poser la question pour voir :
>>> print(\sqrt(4).is_integer())
True
Comment cela se fait-il ?
Et bien 2 ou 2. 0 c'est juste une affaire de représentation.
Si tu demandes à Python quel est le type de 2.0 il te dit que c'est un nombre en virgule flottante parce qu'il y a le point décimal...
C'est normal. L'ensemble des entiers naturels est inclus dans l'ensemble des nombres décimaux relatifs :
$\mathbb N \subset \mathbb D$
Un réel est un nombre à virgule, donc $\sqrt 3$ qui est un réel pour Python est un "flottant" parce qu'il a une virgule et des chiffres autres que 0 après...
Python ne connaît que 2 types de nombres int et float (ce n'est pas tout à vrai : il sait aussi manipuler (et donc reconnaître les nombres complexe --> programme TS))
Heron d'Alexandrie.
Si tu es en 1ere, tu as peut-être vu les suites.
Quoi qu'il en soit la page wiki est bien faite : https://fr.wikipedia.org/wiki/M%C3%A9th … H%C3%A9ron
Avec ça, tu comprendras mieux ce qui est fait dans mon script de calcul de racine carrée...
Ce n'est que récemment qu'une personne a demandé de l'aire pour un exercice de calcul de la racine cubique, l'énoncé était incomplet : j'avais laissé tomber, puis j'ai repris en relisant la page du wiki pour les racines carrées et j'ai fini par reconstituer l'énoncé correct..
Pour la racine cubique, on ne parle plus d'aire d'un carré mais de volume d'un cube....
Et je me suis empressé d'adapter mon script racine carrée pour qu'il me donne la racine cubique...
@+
[EDIT] J'oubliais isclose(a,b).
Tu auras True si $|a-b|\leqslant 10^{-9}$ c'est dans la doc...
Rien à voir avec getcontext() qui par défaut offre 28 chiffres décimaux.
Si j'en veux plus je suis obligé de spécifier la précision (prec) voulue, par ex : getcontext().prec=1000
Dernière modification par yoshi (18-03-2021 21:22:57)
En ligne
Pages : 1
Discussion fermée







