[Maxima] Résultat étrange pour une simple soustraction

Tout ce qui concerne les différents logiciels mathématiques (Matlab, Maxima, Scilab, R, Maple, Mathematica, ...) et les calculatrices scientifiques.
Règles du forum
Merci d'éviter le style SMS dans vos messages et de penser à utiliser la fonction Recherche avant de poster un message. Pour joindre des fichiers à vos messages, consulter ce sujet.
> Penser à utiliser les balises Code pour poster du code.
> Préciser le nom du logiciel concerné dans le titre de votre message.

[Maxima] Résultat étrange pour une simple soustraction

Messagepar MB » Lundi 01 Janvier 2007, 15:55

Bonjour, en utilisant Maxima, je constate que :

Code: Tout sélectionner
17.64-15.84;


retourne le résultat suivant :

Code: Tout sélectionner
1.800000000000001


Je ne parviens pas à l'expliquer ...
MB (Pas d'aide en Message Privé)
Merci d'utiliser $\LaTeX$ (voir ici) et d'éviter le style SMS pour la lisibilité des messages.
MB
Administrateur
 
Messages: 6885
Inscription: Samedi 28 Mai 2005, 13:23
Localisation: Créteil
Statut actuel: Actif et salarié | Enseignant

Publicité

Messagepar Arnaud » Lundi 01 Janvier 2007, 16:05

Erreur d'arrondis à mon avis.

Même problème en java ici : http://www.geogebra.org/forum/viewtopic.php?t=1350

J'ai déjà vu des calculatrices de grandes marques qui plantaient les résultats sur des additions de fractions simples.
Arnaud

Un peu d'info - Pyromaths
LaTeX - Exemples de formules LaTeX

Pas d'aide en MP (non plus)
Arnaud
Modérateur
 
Messages: 7115
Inscription: Lundi 28 Août 2006, 12:18
Localisation: Allemagne
Statut actuel: Actif et salarié | Enseignant

Messagepar kojak » Lundi 01 Janvier 2007, 16:06

C'est encore plus rigolo quand tu changes la précision..... le résultat change....
Par défaut la précision serait à 16, si je comprends bien... Si tu la diminues, ça a l'air de coller...
kojak
Modérateur
 
Messages: 10397
Inscription: Samedi 18 Novembre 2006, 19:50
Statut actuel: Actif et salarié | Enseignant

Messagepar MB » Lundi 01 Janvier 2007, 16:19

Arnaud a écrit:Erreur d'arrondis à mon avis.


Il me faudrait des détails sur l'algorithme utilisé pour effectuer une soustraction (de nombres décimaux) mais je me demande bien pourquoi il a besoin de faire des arrondis. D'autant que le nombre de décimales de ces décimaux est bien faible (bien inférieur au digit limite de Maxima en tout cas).
MB (Pas d'aide en Message Privé)
Merci d'utiliser $\LaTeX$ (voir ici) et d'éviter le style SMS pour la lisibilité des messages.
MB
Administrateur
 
Messages: 6885
Inscription: Samedi 28 Mai 2005, 13:23
Localisation: Créteil
Statut actuel: Actif et salarié | Enseignant

Messagepar gigiair » Lundi 01 Janvier 2007, 16:46

MB a écrit:
Arnaud a écrit:Erreur d'arrondis à mon avis.


Il me faudrait des détails sur l'algorithme utilisé pour effectuer une soustraction (de nombres décimaux) mais je me demande bien pourquoi il a besoin de faire des arrondis. D'autant que le nombre de décimales de ces décimaux est bien faible (bien inférieur au digit limite de Maxima en tout cas).

AMHA les calculs en interne sont en binaire. La perte de précision se fait à cause de la conversion décimal->binaire qui en général n'est pas exacte.
--
JJR.
gigiair
Exa-utilisateur
 
Messages: 2398
Inscription: Samedi 08 Juillet 2006, 19:56
Localisation: Saint Bonnet Elvert
Statut actuel: Actif et salarié

Messagepar MB » Lundi 01 Janvier 2007, 17:04

gigiair a écrit:AMHA les calculs en interne sont en binaire. La perte de précision se fait à cause de la conversion décimal->binaire qui en général n'est pas exacte.


De toute façon il y a bien un problème quelque part c'est sûr.
Mais les décimaux ne doivent pas spécialement être bien différents des entiers (couple d'entiers au pire). En tout cas, ça ne fait pas très sérieux, surtout pour un logiciel de calcul formel.

Sinon :

Code: Tout sélectionner
7.64-5.84;


donne bien

Code: Tout sélectionner
1.8


Mais :

Code: Tout sélectionner
8.64-6.84;


donne

Code: Tout sélectionner
1.800000000000001


Par contre, en forçant un peu l'usage des fractions :

Code: Tout sélectionner
float(864/100-684/100);


donne bien

Code: Tout sélectionner
1.8


Je pense que ce genre de bug pourrait être corrigé tout de même. :P
MB (Pas d'aide en Message Privé)
Merci d'utiliser $\LaTeX$ (voir ici) et d'éviter le style SMS pour la lisibilité des messages.
MB
Administrateur
 
Messages: 6885
Inscription: Samedi 28 Mai 2005, 13:23
Localisation: Créteil
Statut actuel: Actif et salarié | Enseignant

Messagepar Arnaud » Lundi 01 Janvier 2007, 17:48

Ce que dit gigiair est juste, est c'est à mon avis le problème le plus récurrent en info : la conversion dans un autre type de données.

Il y a certaines valeurs qui passent et d'autres non, pour des raisons qui m'échappent, et ça peut devenir un véritable casse-tête pour un programmeur de déceler l'origine d'une telle erreur.

En déclarant le type de données dans ton calcul, tu peux ainsi éviter les erreurs, mais ça devient vite lourd...
Arnaud

Un peu d'info - Pyromaths
LaTeX - Exemples de formules LaTeX

Pas d'aide en MP (non plus)
Arnaud
Modérateur
 
Messages: 7115
Inscription: Lundi 28 Août 2006, 12:18
Localisation: Allemagne
Statut actuel: Actif et salarié | Enseignant

Messagepar gigiair » Lundi 01 Janvier 2007, 19:36

Maxima ne calcule pas les valeurs en virgules flottantes. Il passe à Lisp et effectue la troncature correspondant à la précision demandée.
La valeur renvoyée par Lisp est 1.8000000000000007 ce qui est arrondi à 1.800000000000001 quand fpprec=16.
Je pense que Lisp code les flottants en binaire sur un nombre d'octets fixes, et je pense qu'il doit utiliser bêtement les bibliothèques C standard. Il faudrait demander à quelqu'un qui connaît, mais je ne trouve pas ça très intéressant. En tout cas, c'est sûr que ce n'est pas un bug.
Il est un peu illogique de demander à un calculateur symbolique de calculer en virgule flottante, puisque par définition ce calcul est approché.
Toutes les calculatrices (en virgules flottantes) ont un $\epsilon$ qui est la plus grande valeur telle que $1+\epsilon-1=0$.
Dans le cas de Maxima, on peut vérifier que

$$0.11102230246\times10^{-15}\leqslant\epsilon\leqslant0.11102230247\times10^{-15}$$


C'est de l'ordre de grandeur du $\epsilon$ des calculatrices de poche. On peut demander d'effectuer les calculs en bigfloat pour plus de précision, mais le problème subsistera toujours.
--
JJR
gigiair
Exa-utilisateur
 
Messages: 2398
Inscription: Samedi 08 Juillet 2006, 19:56
Localisation: Saint Bonnet Elvert
Statut actuel: Actif et salarié

Messagepar Arnaud » Lundi 01 Janvier 2007, 19:58

C'est intéressant, mais je n'ai pas compris pourquoi l'erreur est présente pour $8.64-6.84$ et pas pour $7.64-5.84$.

Il est un peu illogique de demander à un calculateur symbolique de calculer en virgule flottante, puisque par définition ce calcul est approché.


Oui, tout à fait;
Sur le lien que je donne au-dessus, on a l'exemple d'un prof qui veut faire une activité avec ses élèves, basée sur le fait que le minimum d'une fonction est 21.
Erreur, le programme donne 20, c'est tout de même gênant pour une utilisation ultérieure de cette valeur et pour l'intégrité de l'exercice.
Bon tu me diras : geogebra n'est pas réellement un calculateur.
Arnaud

Un peu d'info - Pyromaths
LaTeX - Exemples de formules LaTeX

Pas d'aide en MP (non plus)
Arnaud
Modérateur
 
Messages: 7115
Inscription: Lundi 28 Août 2006, 12:18
Localisation: Allemagne
Statut actuel: Actif et salarié | Enseignant

Messagepar MB » Lundi 01 Janvier 2007, 19:58

Tu as retrouver comment la valeur renvoyée par Lisp ? (d'où vient ce 7 ?)

Il est en effet fort possible que ce genre de problème vienne des bibliothèques génériques de C. Je signale que Maple ne fait pas cette erreur (ni même les calculatrices bas de gamme).

C'est peut être pas un bug, mais je pense que la méthode utilisée par Maxima pour ce genre de calculs n'est pas bonne. Il semble qu'il ferait mieux de ne pas faire appel à Lips.
MB (Pas d'aide en Message Privé)
Merci d'utiliser $\LaTeX$ (voir ici) et d'éviter le style SMS pour la lisibilité des messages.
MB
Administrateur
 
Messages: 6885
Inscription: Samedi 28 Mai 2005, 13:23
Localisation: Créteil
Statut actuel: Actif et salarié | Enseignant

Messagepar MB » Lundi 01 Janvier 2007, 20:36

Pour une explication détaillée de la méthode d'addition (et de soustraction) en virgule flottante, cette page est bien faite.
En effet, c'est tout à fait approximatif, même pour des nombres qui ne nécessiteraient pas un arrondi.

D'après ce site, on devrait trouver $8.64-6.84=1.8000002$ et $7.64-5.84=1.7999997$.
MB (Pas d'aide en Message Privé)
Merci d'utiliser $\LaTeX$ (voir ici) et d'éviter le style SMS pour la lisibilité des messages.
MB
Administrateur
 
Messages: 6885
Inscription: Samedi 28 Mai 2005, 13:23
Localisation: Créteil
Statut actuel: Actif et salarié | Enseignant

Messagepar Arnaud » Lundi 01 Janvier 2007, 20:51

Ok, merci MB :wink:
Arnaud

Un peu d'info - Pyromaths
LaTeX - Exemples de formules LaTeX

Pas d'aide en MP (non plus)
Arnaud
Modérateur
 
Messages: 7115
Inscription: Lundi 28 Août 2006, 12:18
Localisation: Allemagne
Statut actuel: Actif et salarié | Enseignant

Messagepar gigiair » Mardi 02 Janvier 2007, 08:08

MB a écrit:Pour une explication détaillée de la méthode d'addition (et de soustraction) en virgule flottante, cette page est bien faite.
En effet, c'est tout à fait approximatif, même pour des nombres qui ne nécessiteraient pas un arrondi.

D'après ce site, on devrait trouver $8.64-6.84=1.8000002$ et $7.64-5.84=1.7999997$.


Maxima est programmé en clisp.
La représentation des nombres est beaucoup plus complexe en informatique qu'en mathématique.
voici celle de clisp:
http://fr.wikipedia.org/wiki/Common_Lisp#Nombres
le clisp de maxima a un type supplémentaire : bigfloat, flottants dont la précision est fixée par la valeur de fpprec
bfloat(x) convertit x en un bigfloat.
Pour saisir une constante en bigfloat, il suffit d'ajouter b suivi de l'exposant.
par exemple, 1 est un entier 1e0 ou 1d0 sont des float, 1b0 est un bigfloat.
Pour que le résultat de ton opération soit calculé en bigfloat, il aurait fallu taper
8.64b0-6.84b0;
1.8b0.
Ce qui est plutôt rassurant.

----------
en clisp,
(- 8.64s0 6.84s0) renvoie 1.79999s0 (type short -float)
(- 8.64e0 6.84e0) renvoie 1.8000002 (type single-float)
(- 8.64d0 6.84d0) renvoie 1.8000000000000007d0 (type double-float)
(- 8.64l0 6.84l0) renvoie 1.8000000000000000002L0 (type long-float)
gnu-clisp n'a pas de bigfloat par défaut
par défaut maxima représente les flottants en double-float.
------

Pour passer en clisp, évaluer sous maxima

Code: Tout sélectionner
to_lisp() ;


Puis pour revenir en mode maxima, évaluer

Code: Tout sélectionner
(to-maxima)


--
JJR.
gigiair
Exa-utilisateur
 
Messages: 2398
Inscription: Samedi 08 Juillet 2006, 19:56
Localisation: Saint Bonnet Elvert
Statut actuel: Actif et salarié

Messagepar MB » Mardi 02 Janvier 2007, 14:38

Merci beaucoup pour ces précisions intéressantes.

gigiair a écrit:le clisp de maxima a un type supplémentaire : bigfloat, flottants dont la précision est fixée par la valeur de fpprec


Apparemment le type LONG-FLOAT est assez similaire. Je trouve ici :

Arbitrary Precision Floats. LONG-FLOATs have variable mantissa length, which is a multiple of 16 (or 32, depending on the word size of the processor). The default length used when LONG-FLOATs are READ is given by the place (EXT:LONG-FLOAT-DIGITS). It can be set by (SETF (EXT:LONG-FLOAT-DIGITS) n), where n is a positive INTEGER. E.g., (SETF (EXT:LONG-FLOAT-DIGITS) 3322) sets the default precision of LONG-FLOATs to about 1000 decimal digits.


Donc à part ça, une DOUBLE-FLOAT semble codé sur 64 bits : 1 (signe) + 52 (mantisse) + 11 (exposant). (voir ici pour la norme IEEE-754 que semble respecter Lisp (à peu près)).

Sur ce lien il était indiqué 52+1 bits pour la mantisse. Voici l'explication :

In describing binary floating-point types, the significand is characterized by a certain width in bits (binary digits). Because the most significant bit is always 1 for normal numbers, this bit is typically not stored and is called the "hidden bit". Depending on the context, the hidden bit may or may not be counted in describing the width of the significand. For example, the same IEEE 754 double precision format is commonly described either as having a 53-bit significand/mantissa (including the hidden bit) or as having a 52-bit significand/mantissa (not including the hidden bit).


Source : Wikipédia.

En tout cas, pour stocker le décimal $6,84$ dans une variable de type FLOAT, il faut commencer par l'écrire sous forme binaire mais avec la virgule. C'est à dire :

$$6,84 = \ds\sum_{k \in \Z} b_k \times 2^k $$



Par exemple, le décimal $2,625$ s'écrit $10,101$ en binaire. Pour calculer la partie décimale, on utilise une méthode par multiplication (voir ici):

Code: Tout sélectionner
0.625   ×   2   =   1.25      1
0.25   ×   2   =   0.5      0
0.5   ×   2   =   1.0      1


Cette méthode ne se termine pas forcément. Ici elle se termine bien car $\dfrac{625}{1000}=\dfrac{5}{8}=\dfrac{5}{2^3}$.

Par contre, pour $6,84 = \dfrac{684}{100} = \dfrac{171}{25}= \dfrac{171}{5^2}$ la procédure ne se termine pas et on tombe forcément sur une approximation de $6,84$.
MB (Pas d'aide en Message Privé)
Merci d'utiliser $\LaTeX$ (voir ici) et d'éviter le style SMS pour la lisibilité des messages.
MB
Administrateur
 
Messages: 6885
Inscription: Samedi 28 Mai 2005, 13:23
Localisation: Créteil
Statut actuel: Actif et salarié | Enseignant

Messagepar gigiair » Mardi 02 Janvier 2007, 22:00

Bon, tout ça ce sont des bonnes nouvelles. Dommage que la doc de maxima soit aussi rébarbative, c'est vraiment un bon logiciel. On pourrait faire de belles économies en l'utilisant dans les classes prépas de préférence à un logiciel payant.
C'était une très bonne question. merci MB.
--
JJR.
gigiair
Exa-utilisateur
 
Messages: 2398
Inscription: Samedi 08 Juillet 2006, 19:56
Localisation: Saint Bonnet Elvert
Statut actuel: Actif et salarié


Retourner vers Logiciels mathématiques

 


  • Articles en relation
    Réponses
    Vus
    Dernier message

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité