Voil=E0, je rencontre un probl=E8me ennuyeux en ce moment avec
l'utilisation des float dans python lorsque je convertis des chiffres
initialement au format =AB string =BB (r=E9cup=E9r=E9s dans un fichier
texte) et que je les convertis en float pour entamer une =E9tape de
calculs : python semble convertir les chiffres qui lui sont fournis
en arrondis hasardeux.
Exemple : 51.3 deviendra 51.299999999999997 (lorsqu'il est inscrit
dans une liste) ou 51.3000000000000001 alors qu'il affichera bien
51.3 sur la console si on lui demande la valeur existante dans
ma_liste[128] par exemple.
A la rigueur, =E7=E0 ne pose pas trop de probl=E8mes si on se base sur 1
chiffre significatif et qu'on r=E9sout des =AB op=E9rations simples =BB
sur peu de valeurs. Cependant =E7=E0 deviens vite critique qu'on traite
=E0 l'inverse beaucoup de donn=E9es et des calculs plus =AB complexes =BB
(carr=E9s, exponentielles, proba, etc.) J'ai fais des tests m=EAme sur
des choses toutes b=EAtes comme les moyenne !
Exemple :
#---------------------------------------------------------------------------
import os, sys, string, re, math
#on cree un fichier avec des valeurs, peu importe...
fic=3Dopen('mon_fichier.txt','w')
for x in range(0,50000):
v=3D(x+1.2)/math.sqrt((x+1.2)/9)
fic.write(str(round((x+1.2)/math.sqrt((x+1.2)/9),1))+'\n')
fic.close()
#une fonction pour obtenir la moyenne
def moyenne(liste):
somme=3D0
for element in liste[:-1]:
element=3Dfloat(element)
somme+=3Delement
return somme/len(liste)
#on recupere dans une liste tous les nombres du fichier
def scan(fic):
tab=3D[]
fic=3Dopen(fic,"r")
while 1:
line=3Dfic.readline()
tab.append(line[:-1])
if not line:
break
fic.close()
return tab
Python donne pour moyenne la valeur suivante : 447.214
R (logiciel statistique) donne la valeur suivante : 447.223
Excel.... Donne la m=EAme valeur : 447.223
Est-ce qu'il s'agit d'un vrai probl=E8me ?
Est-ce que =E7=E0 veux dire qu'on ne peux pas vraiment faire de calculs
scientifiques avec python ?
ou bien ai-je loup=E9 un =E9pisode ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
rafi
Sylvain wrote:
Bonjour à tous,
bonjour
Est-ce qu'il s'agit d'un vrai problème ? Est-ce que çà veux dire qu'on ne peux pas vraiment faire de calculs scientifiques avec python ? ou bien ai-je loupé un épisode ?
les floats sont des floats, c'est à dire des valeurs arondies par rapport à une représentation informatisée
utiliser le package décimal est peut ête la solution à ton problème (que je n'ai jamais utilisé)
mes 2 cents
-- rafi
"Imagination is more important than knowledge." (Albert Einstein)
Sylvain wrote:
Bonjour à tous,
bonjour
Est-ce qu'il s'agit d'un vrai problème ?
Est-ce que çà veux dire qu'on ne peux pas vraiment faire de calculs
scientifiques avec python ?
ou bien ai-je loupé un épisode ?
les floats sont des floats, c'est à dire des valeurs arondies par
rapport à une représentation informatisée
utiliser le package décimal est peut ête la solution à ton problème (que
je n'ai jamais utilisé)
mes 2 cents
--
rafi
"Imagination is more important than knowledge."
(Albert Einstein)
Est-ce qu'il s'agit d'un vrai problème ? Est-ce que çà veux dire qu'on ne peux pas vraiment faire de calculs scientifiques avec python ? ou bien ai-je loupé un épisode ?
les floats sont des floats, c'est à dire des valeurs arondies par rapport à une représentation informatisée
utiliser le package décimal est peut ête la solution à ton problème (que je n'ai jamais utilisé)
mes 2 cents
-- rafi
"Imagination is more important than knowledge." (Albert Einstein)
Sylvain
les floats sont des floats, c'est à dire des valeurs arondies par rapport à une représentation informatisée
C'est vrai, mais çà n'explique pas totalementles différences de calcul observées :
1- Quand on passe directement des float générés par python en arguments de la fonction moyenne, j'obtiens la moyenne de ~447,210.
2- Quand je fais exactement le même calcul cette fois-ci en récupérant les valeurs float dans un fichier texte, la moyenne est de : ~447,214
Pourquoi d'autres logiciels eux aussi gérant les mêmes arrondis (avec du langage comme du c ou du c++ derrière), ne font pas les mêmes erreurs d'approximation (moyD7,223) ?
utiliser le package décimal est peut ête la solution à ton problè me (que je n'ai jamais utilisé)
Ce serait pas mal... Je vais y jetter un coup d'oeil. Merci :)
les floats sont des floats, c'est à dire des valeurs arondies par
rapport à une représentation informatisée
C'est vrai, mais çà n'explique pas totalementles différences de
calcul observées :
1- Quand on passe directement des float générés par python en
arguments de la fonction moyenne, j'obtiens la moyenne de ~447,210.
2- Quand je fais exactement le même calcul cette fois-ci en
récupérant les valeurs float dans un fichier texte, la moyenne est de
: ~447,214
Pourquoi d'autres logiciels eux aussi gérant les mêmes arrondis (avec
du langage comme du c ou du c++ derrière), ne font pas les mêmes
erreurs d'approximation (moy=447,223) ?
utiliser le package décimal est peut ête la solution à ton problè me (que
je n'ai jamais utilisé)
Ce serait pas mal... Je vais y jetter un coup d'oeil.
Merci :)
les floats sont des floats, c'est à dire des valeurs arondies par rapport à une représentation informatisée
C'est vrai, mais çà n'explique pas totalementles différences de calcul observées :
1- Quand on passe directement des float générés par python en arguments de la fonction moyenne, j'obtiens la moyenne de ~447,210.
2- Quand je fais exactement le même calcul cette fois-ci en récupérant les valeurs float dans un fichier texte, la moyenne est de : ~447,214
Pourquoi d'autres logiciels eux aussi gérant les mêmes arrondis (avec du langage comme du c ou du c++ derrière), ne font pas les mêmes erreurs d'approximation (moyD7,223) ?
utiliser le package décimal est peut ête la solution à ton problè me (que je n'ai jamais utilisé)
Ce serait pas mal... Je vais y jetter un coup d'oeil. Merci :)
#on recupere dans une liste tous les nombres du fichier def scan(fic): tab=[] fic=open(fic,"r") while 1: line=fic.readline() tab.append(line[:-1]) if not line: break fic.close() [...]
ou bien ai-je loupé un épisode ?
50000 != 50001 !!!
Votre test de fin de fichier devrait être avant le 'append'...
-- Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
#on recupere dans une liste tous les nombres du fichier
def scan(fic):
tab=[]
fic=open(fic,"r")
while 1:
line=fic.readline()
tab.append(line[:-1])
if not line:
break
fic.close()
[...]
ou bien ai-je loupé un épisode ?
50000 != 50001 !!!
Votre test de fin de fichier devrait être avant le 'append'...
--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
#on recupere dans une liste tous les nombres du fichier def scan(fic): tab=[] fic=open(fic,"r") while 1: line=fic.readline() tab.append(line[:-1]) if not line: break fic.close() [...]
ou bien ai-je loupé un épisode ?
50000 != 50001 !!!
Votre test de fin de fichier devrait être avant le 'append'...
-- Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
rafi
Sylvain wrote:
les floats sont des floats, c'est à dire des valeurs arondies par rapport à une représentation informatisée C'est vrai, mais çà n'explique pas totalementles différences de
calcul observées :
1- Quand on passe directement des float générés par python en arguments de la fonction moyenne, j'obtiens la moyenne de ~447,210.
2- Quand je fais exactement le même calcul cette fois-ci en récupérant les valeurs float dans un fichier texte, la moyenne est de : ~447,214
une explication potentielle: le float est un arrondi dont l'affichage est aussi un arrondi. donc lorsqu'on le stocke dans un fichier on doit faire une approximation de la valeur mémoire et donc "on perd un peu de la valeur des nombres". cela ne me surprends donc pas que le passage par un fichier texte implique des problèmes de calcul. il faudrait peut être mieux sauvegarder les nombres dans un fichier binaire?
Pourquoi d'autres logiciels eux aussi gérant les mêmes arrondis (avec du langage comme du c ou du c++ derrière), ne font pas les mêmes erreurs d'approximation (moyD7,223) ?
je ne sais as
Merci :)
avec plaisir
mes derniers 2 cents
-- rafi
"Imagination is more important than knowledge." (Albert Einstein)
Sylvain wrote:
les floats sont des floats, c'est à dire des valeurs arondies par
rapport à une représentation informatisée
C'est vrai, mais çà n'explique pas totalementles différences de
calcul observées :
1- Quand on passe directement des float générés par python en
arguments de la fonction moyenne, j'obtiens la moyenne de ~447,210.
2- Quand je fais exactement le même calcul cette fois-ci en
récupérant les valeurs float dans un fichier texte, la moyenne est de
: ~447,214
une explication potentielle: le float est un arrondi dont l'affichage
est aussi un arrondi. donc lorsqu'on le stocke dans un fichier on doit
faire une approximation de la valeur mémoire et donc "on perd un peu de
la valeur des nombres". cela ne me surprends donc pas que le passage par
un fichier texte implique des problèmes de calcul. il faudrait peut être
mieux sauvegarder les nombres dans un fichier binaire?
Pourquoi d'autres logiciels eux aussi gérant les mêmes arrondis (avec
du langage comme du c ou du c++ derrière), ne font pas les mêmes
erreurs d'approximation (moyD7,223) ?
je ne sais as
Merci :)
avec plaisir
mes derniers 2 cents
--
rafi
"Imagination is more important than knowledge."
(Albert Einstein)
les floats sont des floats, c'est à dire des valeurs arondies par rapport à une représentation informatisée C'est vrai, mais çà n'explique pas totalementles différences de
calcul observées :
1- Quand on passe directement des float générés par python en arguments de la fonction moyenne, j'obtiens la moyenne de ~447,210.
2- Quand je fais exactement le même calcul cette fois-ci en récupérant les valeurs float dans un fichier texte, la moyenne est de : ~447,214
une explication potentielle: le float est un arrondi dont l'affichage est aussi un arrondi. donc lorsqu'on le stocke dans un fichier on doit faire une approximation de la valeur mémoire et donc "on perd un peu de la valeur des nombres". cela ne me surprends donc pas que le passage par un fichier texte implique des problèmes de calcul. il faudrait peut être mieux sauvegarder les nombres dans un fichier binaire?
Pourquoi d'autres logiciels eux aussi gérant les mêmes arrondis (avec du langage comme du c ou du c++ derrière), ne font pas les mêmes erreurs d'approximation (moyD7,223) ?
je ne sais as
Merci :)
avec plaisir
mes derniers 2 cents
-- rafi
"Imagination is more important than knowledge." (Albert Einstein)
Hervé Cauwelier
Pourquoi d'autres logiciels eux aussi gérant les mêmes arrondis (avec du langage comme du c ou du c++ derrière), ne font pas les mêmes erreurs d'approximation (moyD7,223) ?
Parce qu'ils savent que les fonctions standard sont trop approximatives et implémentent les leurs, comme le fait le nouveau module decimal.
Cette question revient tellement souvent que je doute que tu ais cherché. Le grand classique est les gens qui demandent pourquoi Python calcul faux. C'était un titre de FAQ, de mémoire.
http://python.org/doc/2.4/whatsnew/node9.html
-- Hervé Cauwelier http://www.oursours.net/
Pourquoi d'autres logiciels eux aussi gérant les mêmes arrondis (avec
du langage comme du c ou du c++ derrière), ne font pas les mêmes
erreurs d'approximation (moyD7,223) ?
Parce qu'ils savent que les fonctions standard sont trop approximatives
et implémentent les leurs, comme le fait le nouveau module decimal.
Cette question revient tellement souvent que je doute que tu ais
cherché. Le grand classique est les gens qui demandent pourquoi Python
calcul faux. C'était un titre de FAQ, de mémoire.
Pourquoi d'autres logiciels eux aussi gérant les mêmes arrondis (avec du langage comme du c ou du c++ derrière), ne font pas les mêmes erreurs d'approximation (moyD7,223) ?
Parce qu'ils savent que les fonctions standard sont trop approximatives et implémentent les leurs, comme le fait le nouveau module decimal.
Cette question revient tellement souvent que je doute que tu ais cherché. Le grand classique est les gens qui demandent pourquoi Python calcul faux. C'était un titre de FAQ, de mémoire.
Parce qu'ils savent que les fonctions standard sont trop approximatives et implémentent les leurs, comme le fait le nouveau module decimal.
Les erreurs d'arrondis n'expliquent pas tout... En tous cas pas une erreur aussi importante ;-)
-- Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
JBB
Bonjour à tous,
Voilà, je rencontre un problème ennuyeux en ce moment avec l'utilisation des float dans python lorsque je convertis des chiffres initialement au format « string » (récupérés dans un fichier texte) et que je les convertis en float pour entamer une étape de calculs : python semble convertir les chiffres qui lui sont fournis en arrondis hasardeux.
Exemple : 51.3 deviendra 51.299999999999997 (lorsqu'il est inscrit dans une liste) ou 51.3000000000000001 alors qu'il affichera bien 51.3 sur la console si on lui demande la valeur existante dans ma_liste[128] par exemple.
Ca c'est le probleme des float. Il y a quasiment systematiquement une
approximation. Mais d'ailleurs ce n'est pas forcement un probleme. Dans la 'vraie' vie un float est toujours une aproximation. Si je dis que je pese 65 kg c'est une approximation, je pese surement 65,xxxxxxxxxxxxxxxxxxxxxxx.... kg. Et si je fais 7km tous les matins il manque aussi des chiffres apres la virgule.
A la rigueur, çà ne pose pas trop de problèmes si on se base sur 1 chiffre significatif et qu'on résout des « opérations simples » sur peu de valeurs. Cependant çà deviens vite critique qu'on traite à l'inverse beaucoup de données et des calculs plus « complexes » (carrés, exponentielles, proba, etc.) J'ai fais des tests même sur des choses toutes bêtes comme les moyenne !
Exemple :
#--------------------------------------------------------------------------- import os, sys, string, re, math
#on cree un fichier avec des valeurs, peu importe... fic=open('mon_fichier.txt','w') for x in range(0,50000): v=(x+1.2)/math.sqrt((x+1.2)/9) fic.write(str(round((x+1.2)/math.sqrt((x+1.2)/9),1))+'n') fic.close()
J'ai executé ton exemple.
#une fonction pour obtenir la moyenne def moyenne(liste): somme=0 for element in liste[:-1]: element=float(element) somme+=element print len(liste)
return somme/len(liste)
et là au surprise 'liste' contient 50001 elements: les 50000 valeurs
plus une chaine vide (la ligne vide en fin de fichier, probablement rajoutée par fic.close() ).
Comme la fonction float renvoie 0 pour la chaine vide, la somme est bonne , mais le diviseur est mauvais. Si tu divise par 50000 tu trouve la bonne valeur ( 447.222962) .
Il n'y a donc pas de miracle ou d'erreur de python. L'erreur vient de toi. Les float sont ce qu'ils sont, mais marchent tres bien pour ce pourquoi ils sont faits.
#on recupere dans une liste tous les nombres du fichier def scan(fic): tab=[] fic=open(fic,"r") while 1: line=fic.readline() tab.append(line[:-1]) if not line: break fic.close() return tab
Python donne pour moyenne la valeur suivante : 447.214 R (logiciel statistique) donne la valeur suivante : 447.223 Excel.... Donne la même valeur : 447.223
Est-ce qu'il s'agit d'un vrai problème ? Est-ce que çà veux dire qu'on ne peux pas vraiment faire de calculs scientifiques avec python ? ou bien ai-je loupé un épisode ?
Help !!!
Merci d'avance.
Sylvain
Bonjour à tous,
Voilà, je rencontre un problème ennuyeux en ce moment avec
l'utilisation des float dans python lorsque je convertis des chiffres
initialement au format « string » (récupérés dans un fichier
texte) et que je les convertis en float pour entamer une étape de
calculs : python semble convertir les chiffres qui lui sont fournis
en arrondis hasardeux.
Exemple : 51.3 deviendra 51.299999999999997 (lorsqu'il est inscrit
dans une liste) ou 51.3000000000000001 alors qu'il affichera bien
51.3 sur la console si on lui demande la valeur existante dans
ma_liste[128] par exemple.
Ca c'est le probleme des float. Il y a quasiment systematiquement une
approximation.
Mais d'ailleurs ce n'est pas forcement un probleme. Dans la 'vraie' vie
un float est toujours une aproximation. Si je dis que je pese 65 kg
c'est une approximation, je pese surement 65,xxxxxxxxxxxxxxxxxxxxxxx....
kg. Et si je fais 7km tous les matins il manque aussi des chiffres apres
la virgule.
A la rigueur, çà ne pose pas trop de problèmes si on se base sur 1
chiffre significatif et qu'on résout des « opérations simples »
sur peu de valeurs. Cependant çà deviens vite critique qu'on traite
à l'inverse beaucoup de données et des calculs plus « complexes »
(carrés, exponentielles, proba, etc.) J'ai fais des tests même sur
des choses toutes bêtes comme les moyenne !
Exemple :
#---------------------------------------------------------------------------
import os, sys, string, re, math
#on cree un fichier avec des valeurs, peu importe...
fic=open('mon_fichier.txt','w')
for x in range(0,50000):
v=(x+1.2)/math.sqrt((x+1.2)/9)
fic.write(str(round((x+1.2)/math.sqrt((x+1.2)/9),1))+'n')
fic.close()
J'ai executé ton exemple.
#une fonction pour obtenir la moyenne
def moyenne(liste):
somme=0
for element in liste[:-1]:
element=float(element)
somme+=element
print len(liste)
return somme/len(liste)
et là au surprise 'liste' contient 50001 elements: les 50000 valeurs
plus une chaine vide (la ligne vide en fin de fichier, probablement
rajoutée par fic.close() ).
Comme la fonction float renvoie 0 pour la chaine vide, la somme est
bonne , mais le diviseur est mauvais. Si tu divise par 50000 tu trouve
la bonne valeur ( 447.222962) .
Il n'y a donc pas de miracle ou d'erreur de python. L'erreur vient de toi.
Les float sont ce qu'ils sont, mais marchent tres bien pour ce pourquoi
ils sont faits.
#on recupere dans une liste tous les nombres du fichier
def scan(fic):
tab=[]
fic=open(fic,"r")
while 1:
line=fic.readline()
tab.append(line[:-1])
if not line:
break
fic.close()
return tab
Python donne pour moyenne la valeur suivante : 447.214
R (logiciel statistique) donne la valeur suivante : 447.223
Excel.... Donne la même valeur : 447.223
Est-ce qu'il s'agit d'un vrai problème ?
Est-ce que çà veux dire qu'on ne peux pas vraiment faire de calculs
scientifiques avec python ?
ou bien ai-je loupé un épisode ?
Voilà, je rencontre un problème ennuyeux en ce moment avec l'utilisation des float dans python lorsque je convertis des chiffres initialement au format « string » (récupérés dans un fichier texte) et que je les convertis en float pour entamer une étape de calculs : python semble convertir les chiffres qui lui sont fournis en arrondis hasardeux.
Exemple : 51.3 deviendra 51.299999999999997 (lorsqu'il est inscrit dans une liste) ou 51.3000000000000001 alors qu'il affichera bien 51.3 sur la console si on lui demande la valeur existante dans ma_liste[128] par exemple.
Ca c'est le probleme des float. Il y a quasiment systematiquement une
approximation. Mais d'ailleurs ce n'est pas forcement un probleme. Dans la 'vraie' vie un float est toujours une aproximation. Si je dis que je pese 65 kg c'est une approximation, je pese surement 65,xxxxxxxxxxxxxxxxxxxxxxx.... kg. Et si je fais 7km tous les matins il manque aussi des chiffres apres la virgule.
A la rigueur, çà ne pose pas trop de problèmes si on se base sur 1 chiffre significatif et qu'on résout des « opérations simples » sur peu de valeurs. Cependant çà deviens vite critique qu'on traite à l'inverse beaucoup de données et des calculs plus « complexes » (carrés, exponentielles, proba, etc.) J'ai fais des tests même sur des choses toutes bêtes comme les moyenne !
Exemple :
#--------------------------------------------------------------------------- import os, sys, string, re, math
#on cree un fichier avec des valeurs, peu importe... fic=open('mon_fichier.txt','w') for x in range(0,50000): v=(x+1.2)/math.sqrt((x+1.2)/9) fic.write(str(round((x+1.2)/math.sqrt((x+1.2)/9),1))+'n') fic.close()
J'ai executé ton exemple.
#une fonction pour obtenir la moyenne def moyenne(liste): somme=0 for element in liste[:-1]: element=float(element) somme+=element print len(liste)
return somme/len(liste)
et là au surprise 'liste' contient 50001 elements: les 50000 valeurs
plus une chaine vide (la ligne vide en fin de fichier, probablement rajoutée par fic.close() ).
Comme la fonction float renvoie 0 pour la chaine vide, la somme est bonne , mais le diviseur est mauvais. Si tu divise par 50000 tu trouve la bonne valeur ( 447.222962) .
Il n'y a donc pas de miracle ou d'erreur de python. L'erreur vient de toi. Les float sont ce qu'ils sont, mais marchent tres bien pour ce pourquoi ils sont faits.
#on recupere dans une liste tous les nombres du fichier def scan(fic): tab=[] fic=open(fic,"r") while 1: line=fic.readline() tab.append(line[:-1]) if not line: break fic.close() return tab
Python donne pour moyenne la valeur suivante : 447.214 R (logiciel statistique) donne la valeur suivante : 447.223 Excel.... Donne la même valeur : 447.223
Est-ce qu'il s'agit d'un vrai problème ? Est-ce que çà veux dire qu'on ne peux pas vraiment faire de calculs scientifiques avec python ? ou bien ai-je loupé un épisode ?
Help !!!
Merci d'avance.
Sylvain
bug
Oui, il y a un problème dans ta boucle, voici la procédure scan réécrite (plus pythonesque) :
def scan(fic): fic=open(fic,"r") tab=[ line[:-1] for line in fic.readlines()] fic.close() return tab
et sinon il y a aussi un problème dans ta fonction moyenne, tu ne prends pas tout le monde (surement pour éviter le pb de la fonction scan)
def moyenne(liste): somme=0 for element in liste: element=float(element) somme+=element return somme/len(liste)
Résultat : 447.222962 comme dans Excel !
Oui, il y a un problème dans ta boucle, voici la procédure scan
réécrite (plus pythonesque) :
def scan(fic):
fic=open(fic,"r")
tab=[ line[:-1] for line in fic.readlines()]
fic.close()
return tab
et sinon il y a aussi un problème dans ta fonction moyenne, tu ne
prends pas tout le monde (surement pour éviter le pb de la fonction
scan)
def moyenne(liste):
somme=0
for element in liste:
element=float(element)
somme+=element
return somme/len(liste)
Oui, il y a un problème dans ta boucle, voici la procédure scan réécrite (plus pythonesque) :
def scan(fic): fic=open(fic,"r") tab=[ line[:-1] for line in fic.readlines()] fic.close() return tab
et sinon il y a aussi un problème dans ta fonction moyenne, tu ne prends pas tout le monde (surement pour éviter le pb de la fonction scan)
def moyenne(liste): somme=0 for element in liste: element=float(element) somme+=element return somme/len(liste)
Résultat : 447.222962 comme dans Excel !
JBB
Bonjour à tous,
Voilà, je rencontre un problème ennuyeux en ce moment avec l'utilisation des float dans python lorsque je convertis des chiffres initialement au format « string » (récupérés dans un fichier texte) et que je les convertis en float pour entamer une étape de calculs : python semble convertir les chiffres qui lui sont fournis en arrondis hasardeux.
Exemple : 51.3 deviendra 51.299999999999997 (lorsqu'il est inscrit dans une liste) ou 51.3000000000000001 alors qu'il affichera bien 51.3 sur la console si on lui demande la valeur existante dans ma_liste[128] par exemple.
Ca c'est le probleme des float. Il y a quasiment systematiquement une
approximation. Mais d'ailleurs ce n'est pas forcement un probleme. Dans la 'vraie' vie un float est toujours une aproximation. Si je dis que je pese 65 kg c'est une approximation, je pese surement 65,xxxxxxxxxxxxxxxxxxxxxxx.... kg. Et si je fais 7km tous les matins il manque aussi des chiffres apres la virgule.
A la rigueur, çà ne pose pas trop de problèmes si on se base sur 1 chiffre significatif et qu'on résout des « opérations simples » sur peu de valeurs. Cependant çà deviens vite critique qu'on traite à l'inverse beaucoup de données et des calculs plus « complexes » (carrés, exponentielles, proba, etc.) J'ai fais des tests même sur des choses toutes bêtes comme les moyenne !
#on cree un fichier avec des valeurs, peu importe... fic=open('mon_fichier.txt','w') for x in range(0,50000): v=(x+1.2)/math.sqrt((x+1.2)/9) fic.write(str(round((x+1.2)/math.sqrt((x+1.2)/9),1))+'n') fic.close()
J'ai executé ton exemple.
#une fonction pour obtenir la moyenne def moyenne(liste): somme=0 for element in liste[:-1]: element=float(element) somme+=element
print len(liste)
return somme/len(liste)
et là au surprise 'liste' contient 50001 elements: les 50000 valeurs
plus une chaine vide (la ligne vide en fin de fichier, probablement rajoutée par fic.close() ). Effectivement comme l'a dit Paulc'est à cause du append avant le break .
Comme la fonction float renvoie 0 pour la chaine vide, la somme est bonne , mais le diviseur est mauvais. Si tu divise par 50000 tu trouve la bonne valeur ( 447.222962) .
Il n'y a donc pas de miracle ou d'erreur de python. L'erreur vient de toi. Les float sont ce qu'ils sont, mais marchent tres bien pour ce pourquoi ils sont faits.
#on recupere dans une liste tous les nombres du fichier def scan(fic): tab=[] fic=open(fic,"r") while 1: line=fic.readline() tab.append(line[:-1]) if not line: break fic.close() return tab
Python donne pour moyenne la valeur suivante : 447.214 R (logiciel statistique) donne la valeur suivante : 447.223 Excel.... Donne la même valeur : 447.223
Est-ce qu'il s'agit d'un vrai problème ? Est-ce que çà veux dire qu'on ne peux pas vraiment faire de calculs scientifiques avec python ? ou bien ai-je loupé un épisode ?
Help !!!
Merci d'avance.
Sylvain
Bonjour à tous,
Voilà, je rencontre un problème ennuyeux en ce moment avec
l'utilisation des float dans python lorsque je convertis des chiffres
initialement au format « string » (récupérés dans un fichier
texte) et que je les convertis en float pour entamer une étape de
calculs : python semble convertir les chiffres qui lui sont fournis
en arrondis hasardeux.
Exemple : 51.3 deviendra 51.299999999999997 (lorsqu'il est inscrit
dans une liste) ou 51.3000000000000001 alors qu'il affichera bien
51.3 sur la console si on lui demande la valeur existante dans
ma_liste[128] par exemple.
Ca c'est le probleme des float. Il y a quasiment systematiquement une
approximation.
Mais d'ailleurs ce n'est pas forcement un probleme. Dans la 'vraie' vie
un float est toujours une aproximation. Si je dis que je pese 65 kg
c'est une approximation, je pese surement 65,xxxxxxxxxxxxxxxxxxxxxxx....
kg. Et si je fais 7km tous les matins il manque aussi des chiffres apres
la virgule.
A la rigueur, çà ne pose pas trop de problèmes si on se base sur 1
chiffre significatif et qu'on résout des « opérations simples »
sur peu de valeurs. Cependant çà deviens vite critique qu'on traite
à l'inverse beaucoup de données et des calculs plus « complexes »
(carrés, exponentielles, proba, etc.) J'ai fais des tests même sur
des choses toutes bêtes comme les moyenne !
#on cree un fichier avec des valeurs, peu importe...
fic=open('mon_fichier.txt','w')
for x in range(0,50000):
v=(x+1.2)/math.sqrt((x+1.2)/9)
fic.write(str(round((x+1.2)/math.sqrt((x+1.2)/9),1))+'n')
fic.close()
J'ai executé ton exemple.
#une fonction pour obtenir la moyenne
def moyenne(liste):
somme=0
for element in liste[:-1]:
element=float(element)
somme+=element
print len(liste)
return somme/len(liste)
et là au surprise 'liste' contient 50001 elements: les 50000 valeurs
plus une chaine vide (la ligne vide en fin de fichier, probablement
rajoutée par fic.close() ).
Effectivement comme l'a dit Paulc'est à cause du append avant le break .
Comme la fonction float renvoie 0 pour la chaine vide, la somme est
bonne , mais le diviseur est mauvais. Si tu divise par 50000 tu trouve
la bonne valeur ( 447.222962) .
Il n'y a donc pas de miracle ou d'erreur de python. L'erreur vient de toi.
Les float sont ce qu'ils sont, mais marchent tres bien pour ce pourquoi
ils sont faits.
#on recupere dans une liste tous les nombres du fichier
def scan(fic):
tab=[]
fic=open(fic,"r")
while 1:
line=fic.readline()
tab.append(line[:-1])
if not line:
break
fic.close()
return tab
Python donne pour moyenne la valeur suivante : 447.214
R (logiciel statistique) donne la valeur suivante : 447.223
Excel.... Donne la même valeur : 447.223
Est-ce qu'il s'agit d'un vrai problème ?
Est-ce que çà veux dire qu'on ne peux pas vraiment faire de calculs
scientifiques avec python ?
ou bien ai-je loupé un épisode ?
Voilà, je rencontre un problème ennuyeux en ce moment avec l'utilisation des float dans python lorsque je convertis des chiffres initialement au format « string » (récupérés dans un fichier texte) et que je les convertis en float pour entamer une étape de calculs : python semble convertir les chiffres qui lui sont fournis en arrondis hasardeux.
Exemple : 51.3 deviendra 51.299999999999997 (lorsqu'il est inscrit dans une liste) ou 51.3000000000000001 alors qu'il affichera bien 51.3 sur la console si on lui demande la valeur existante dans ma_liste[128] par exemple.
Ca c'est le probleme des float. Il y a quasiment systematiquement une
approximation. Mais d'ailleurs ce n'est pas forcement un probleme. Dans la 'vraie' vie un float est toujours une aproximation. Si je dis que je pese 65 kg c'est une approximation, je pese surement 65,xxxxxxxxxxxxxxxxxxxxxxx.... kg. Et si je fais 7km tous les matins il manque aussi des chiffres apres la virgule.
A la rigueur, çà ne pose pas trop de problèmes si on se base sur 1 chiffre significatif et qu'on résout des « opérations simples » sur peu de valeurs. Cependant çà deviens vite critique qu'on traite à l'inverse beaucoup de données et des calculs plus « complexes » (carrés, exponentielles, proba, etc.) J'ai fais des tests même sur des choses toutes bêtes comme les moyenne !
#on cree un fichier avec des valeurs, peu importe... fic=open('mon_fichier.txt','w') for x in range(0,50000): v=(x+1.2)/math.sqrt((x+1.2)/9) fic.write(str(round((x+1.2)/math.sqrt((x+1.2)/9),1))+'n') fic.close()
J'ai executé ton exemple.
#une fonction pour obtenir la moyenne def moyenne(liste): somme=0 for element in liste[:-1]: element=float(element) somme+=element
print len(liste)
return somme/len(liste)
et là au surprise 'liste' contient 50001 elements: les 50000 valeurs
plus une chaine vide (la ligne vide en fin de fichier, probablement rajoutée par fic.close() ). Effectivement comme l'a dit Paulc'est à cause du append avant le break .
Comme la fonction float renvoie 0 pour la chaine vide, la somme est bonne , mais le diviseur est mauvais. Si tu divise par 50000 tu trouve la bonne valeur ( 447.222962) .
Il n'y a donc pas de miracle ou d'erreur de python. L'erreur vient de toi. Les float sont ce qu'ils sont, mais marchent tres bien pour ce pourquoi ils sont faits.
#on recupere dans une liste tous les nombres du fichier def scan(fic): tab=[] fic=open(fic,"r") while 1: line=fic.readline() tab.append(line[:-1]) if not line: break fic.close() return tab
Python donne pour moyenne la valeur suivante : 447.214 R (logiciel statistique) donne la valeur suivante : 447.223 Excel.... Donne la même valeur : 447.223
Est-ce qu'il s'agit d'un vrai problème ? Est-ce que çà veux dire qu'on ne peux pas vraiment faire de calculs scientifiques avec python ? ou bien ai-je loupé un épisode ?
Help !!!
Merci d'avance.
Sylvain
JBB
Oui, il y a un problème dans ta boucle, voici la procédure scan réécrite (plus pythonesque) :
def scan(fic): fic=open(fic,"r") tab=[ line[:-1] for line in fic.readlines()] fic.close() return tab
ou alors
def scan(fic): tab=[ float(line) for line in open(fic,"r") if len(string.strip(line))>0] return tab
et tu as directement un tableau de float avec tous les lignes vides filtrées
et sinon il y a aussi un problème dans ta fonction moyenne, tu ne prends pas tout le monde (surement pour éviter le pb de la fonction scan)
def moyenne(liste): somme=0 for element in liste: element=float(element) somme+=element return somme/len(liste)
Résultat : 447.222962 comme dans Excel !
Oui, il y a un problème dans ta boucle, voici la procédure scan
réécrite (plus pythonesque) :
def scan(fic):
fic=open(fic,"r")
tab=[ line[:-1] for line in fic.readlines()]
fic.close()
return tab
ou alors
def scan(fic):
tab=[ float(line) for line in open(fic,"r") if len(string.strip(line))>0]
return tab
et tu as directement un tableau de float avec tous les lignes vides filtrées
et sinon il y a aussi un problème dans ta fonction moyenne, tu ne
prends pas tout le monde (surement pour éviter le pb de la fonction
scan)
def moyenne(liste):
somme=0
for element in liste:
element=float(element)
somme+=element
return somme/len(liste)