Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Ca commence mal.

12 réponses
Avatar
G-raison
Bonjour,

J'ai deux ou trois petits programmes que j'ai dans un vieux langage que
j'aimerai mettre en Python. (je ne suis pas trop programmeur...)
Pour étudier ce langage j'ai téléchargé et imprimé un
fichier .pdf :"Apprendre à programmer avec Python" de Gérard Swinnen. (370
pages!)

Là, il y a un truc qui me chagrine.
C'est écrit ça :
a,b=7.3,12
y=3*a+b/5
Et là ça me donne :
y=23.899999999999999 (??!!)

Pourquoi ça ne donne pas y=24.3?
Et pourquoi a=7.2999999999999998 alors que j'avais écrit 7.3?

Ce n'est pas la peine que j'aille plus loin si ça c'est faux.
(Ca se trouve l'explication est donné plus loin mais je n'en suis pas encore
là.)

--
@+
gr

10 réponses

1 2
Avatar
Méta-MCI \(MVP\)
Bonsoir !

Essaie :

a,b=7.3,12.0
y=3.0*a+b/5.0
print y

Explication : flottant versus entier


@+

Michel Claveau
Avatar
G-raison
Méta-MCI (MVP) wrote:

Bonsoir !


Bonsoir.

Explication : flottant versus entier


C'est bon, ça fonctionne!:-)

J'aurais pu comprendre ça quelques pages avant, mais je ne pensais pas que
pour une opération aussi simple il fallait mettre un ".0" à tous les
chiffres.
D'autant plus que j'avais cru que si au moins une valeur était de
type "réel" (là : 7.3...) tout serait de type réel.

En tout cas merci.

--
@+
gr

Avatar
Méta-MCI \(MVP\)
Re !

Effectivement, il n'y en a pas besoin partout (mais, au bon endroit,
oui). C'était juste pour accentuer l'explication.

@-salutations

MCI
Avatar
NicolasP
Bonsoir !


Bonsoir.
Bonjour,


D'autant plus que j'avais cru que si au moins une valeur était de
type "réel" (là : 7.3...) tout serait de type réel.

a,b=7.3,12

y=3*a+b/5

donc :
a = 7.3 (un flottant)
b = 12 (un entier)
y = (3*a) + (b/5) (car la multiplication et la division sont des opérateurs plus "prioritaires" que l'addition)
3*a = 21.9 est évalué en premier (en flottant)
b/5 = 2 est évalué en second (en entier car l'opération n'est dépendante d'aucune autre)
3*a + b/5 = 3*7.3 + 2 = 3*7.3 + 2.0 = 23.9 est évalué en dernier (et là, tout est fait en flottant. Le résultat de la division est transformé en flottant mais pas recalculé. La troncature reste)
Au final l'affichage donne 23.8999999999999999 à cause de la précision des nombres flottants.
Pour éviter les erreurs de précision, en Python, il y a le type decimal. Mais gare aux temps de calcul...

Nicolas


Avatar
G-raison
NicolasP wrote:


Bonjour,


Bonjour,

Pour éviter les erreurs de précision, en
Python, il y a le type decimal. Mais gare aux temps de calcul...


Ah merci aussi pour ces précisions.
Le temps de calcul dans le cas de mes petits programmes, ne devait pas trop
me déranger.

Bon, j'va voir tout ça. ;-)

Nicolas


--
@+
gr

Avatar
Cémoi
Bonsoir,

il me semble que toutes les explications données dans ce fil de
discussion sont erronées.
En effet Python spécifie que lorsqu'il est en présence d'opérations
binaires avec des types d'opérandes hétérogènes il "élargit" l'opérande
du plus petit type au type de l'autre [1]. Aucune restriction n'existe
concernant la position des opérandes.
Si je reprend ce qu'a tenté de faire G-raison au début de la discussion
je dirai qu'il confond sans doute ce qui est retourné en demandant
directement à l'interpréteur d'afficher la valeur et ce qui est retourné
via l'instruction print.

Dans mon interpréteur interactif Python 2.5.1, voilà ce que ça donne [2]:

Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit
(Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.

a, b = 7.3, 12
y = 3 * a + b / 5
print y
23.9



y
23.899999999999999








Bon, c'est peut-être moi qui ai tout faux, mais si ça peut faire avancer
le schmilblick...
Il me semble que des informations complémentaires sont données si on
s'intéresse aux fonctions repr() et str() ou aux méthodes spéciales
__repr__() et __str__(), mais je n'ai pas retrouvé le passage que je
cherchais.
J'essaierai de compléter la discussion avec quelques infos précises sur
la précision des nombres en virgule flottante dès que j'aurai un peu
plus de temps.
En espérant que G-raison persévèrera avec Python qui est un langage
fabuleux.

HTH !
Bonne soirée,

Laurent

[1] Python 2.5.1 Lybrary Reference/ chapitre 3.4. Numeric Types -- int,
float, long, complex

Python fully supports mixed arithmetic: when a binary arithmetic
operator has operands of different numeric types, the operand with the
``narrower'' type is widened to that of the other, where plain integer
is narrower than long integer is narrower than floating point is
narrower than complex. Comparisons between numbers of mixed type use the
same rule.

[2] PEP8 est passée par là ;o)

NicolasP wrote:


Bonjour,


Bonjour,

Pour éviter les erreurs de précision, en
Python, il y a le type decimal. Mais gare aux temps de calcul...


Ah merci aussi pour ces précisions.
Le temps de calcul dans le cas de mes petits programmes, ne devait pas trop
me déranger.

Bon, j'va voir tout ça. ;-)

Nicolas






Avatar
NicolasP
Bonsoir,
Bonjour,



il me semble que toutes les explications données dans ce fil de
discussion sont erronées.
Toutes les informations fausses... Rien que ça.


En effet Python spécifie que lorsqu'il est en présence d'opérations
binaires avec des types d'opérandes hétérogènes il "élargit" l'opérande
du plus petit type au type de l'autre [1]. Aucune restriction n'existe
concernant la position des opérandes.
Il me semble que l'interprétation du précepte de base est un peu abusive.

Ce qui est confirmé par le résultat de l'opération.

Si je reprend ce qu'a tenté de faire G-raison au début de la discussion
je dirai qu'il confond sans doute ce qui est retourné en demandant
directement à l'interpréteur d'afficher la valeur et ce qui est retourné
via l'instruction print.
L'instruction print fait effectivement une "traduction" de la valeur réelle.

Il n'empêche que 23.8999... est la vraie valeur du résultat.

Un exemple tout simple : Tape 0.3 dans l'interpréteur interactif de Python.
Là, ça parait pas évident que le résultat ne soit pas exactement celui que l'on veut.
Essayons maintenant avec 1/3.0
Résultat : 0.333333....
Encore une fois, le résultat est tronqué. Mais on comprend bien que l'on ne peut pas faire autrement.
Il faudrait un nombre infini de chiffres pour noter correctement le résultat.

Attention : Ce n'est pas python qui est responsable de la troncature. C'est le codage utilisé pour les nombres flottants qui est responsable de la troncature.
Et c'est valable quelque soit le langage informatique utilisé.


Dans mon interpréteur interactif Python 2.5.1, voilà ce que ça donne [2]:

Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit
(Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
a, b = 7.3, 12
y = 3 * a + b / 5
print y
23.9



y
23.899999999999999




Bon, c'est peut-être moi qui ai tout faux,
Il semblerait...


mais si ça peut faire avancer
le schmilblick...
Il me semble que des informations complémentaires sont données si on
s'intéresse aux fonctions repr() et str() ou aux méthodes spéciales
__repr__() et __str__(), mais je n'ai pas retrouvé le passage que je
cherchais.
J'essaierai de compléter la discussion avec quelques infos précises sur
la précision des nombres en virgule flottante dès que j'aurai un peu
plus de temps.
Je ne ferai pas un cours sur le nombres en virgule flottante, d'autant plus que c'est déjà expliqué ici :

http://fr.wikipedia.org/wiki/Nombre_flottant

En espérant que G-raison persévèrera avec Python qui est un langage
fabuleux.
Ca, c'est VRAI.



HTH !
Bonne soirée,
Bonne journée


Laurent


Nicolas




Avatar
Laurent Pointal
[zip]
Un exemple tout simple : Tape 0.3 dans l'interpréteur interactif de Python.
Là, ça parait pas évident que le résultat ne soit pas exactement celui
que l'on veut.
Essayons maintenant avec 1/3.0 Résultat : 0.333333.... Encore une fois,
le résultat est tronqué. Mais on comprend bien que l'on ne peut pas
faire autrement.
Il faudrait un nombre infini de chiffres pour noter correctement le
résultat.

Attention : Ce n'est pas python qui est responsable de la troncature.
C'est le codage utilisé pour les nombres flottants qui est responsable
de la troncature. Et c'est valable quelque soit le langage informatique
utilisé.


C'est même plus large que l'informatique - en base 10, sur un bête
papier on ne peut pas représenter le nombre décimal correspondant à 1/3
(infinité de décimales, d'ailleurs je me demande si cette
caractéristique n'en fait pas un nombre qui n'appartient pas à
l'ensemble des nombres décimaux, les cours de math sont loin).

Suivant la base choisir les nombres posant problèmes changent, mais le
problème reste.

D'où les fractions...

[zip]

Avatar
kib


C'est même plus large que l'informatique - en base 10, sur un bête
papier on ne peut pas représenter le nombre décimal correspondant à 1/3
(infinité de décimales, d'ailleurs je me demande si cette
caractéristique n'en fait pas un nombre qui n'appartient pas à
l'ensemble des nombres décimaux, les cours de math sont loin).



C'est un rationnel, càd qu'il peut s'écrire sous la forme p/q, p et q
étant entiers avec q non nul.

Un décimal est un rationnel (il s'écrit a/b ou b est un puissance de 10,
donc 1,10,100,1000, etc.), mais l'inverse n'est pas toujours vrai, comme
le montre 1/3.

Pour Python, on peut toujours se faire une classe fraction, il en existe
de multiples implémentations trouvables un peu partout.

Avatar
G-raison
Cémoi wrote:

Bonsoir,


Bonsoir,

En espérant que G-raison persévèrera avec Python qui est un langage
fabuleux.


Oh mais que oui, que je vais persévérer avec ce langage.
Il ressemble beaucoup à ce que je connais un peu, seulement il faut que
j'aille dans l'ordre des choses.

Avant de recoder mes programmes, je vais lire les 370 pages du fichier pdf
que j'ai imprimé. (la lecture directement à l'écran, ce n'est pas
génial...)

Le choix d'un langage informatique est très dure à prendre.
On verra bien si je perds mon temps. (ceci dit, je ne crois pas)

--
@+
gr

1 2