Erreur étrange avec flottants

Erreur étrange avec flottants - Python - Programmation

Marsh Posté le 29-04-2006 à 15:51:28    

Salut,
 
J'ai écrit une fonction magnetize qui doit magnetiser un point sur une grille.
 

Code :
  1. class Point:
  2.         def __init__(self, x, y):
  3.                 self.x = float(x)
  4.                 self.y = float(y)
  5.         def magnetize(self, grid_width):
  6.                 (a,b) = self.x.__divmod__(grid_width)
  7.                 if b <= grid_width/2:
  8.                         self.x = a * grid_width
  9.                 else:
  10.                         self.x = (a+1) * grid_width
  11.                 (a,b) = self.y.__divmod__(grid_width)
  12.                 if b <= grid_width/2:
  13.                         self.y = a * grid_width
  14.                 else:
  15.                         self.y = (a+1) * grid_width


Après plusieurs tests concluant en voici un dont je ne comprends pas l'orgine de l'erreur :  

Code :
  1. >>> p = Point(1.7,2.5)
  2. >>> p.magnetize(0.8)
  3. >>> print p                   
  4. x = 1.600000  y = 2.400000
  5. >>> p == Point(1.6, 2.4)
  6. False
  7. >>> print p.y - 2.4
  8. 4.4408920985e-16

Reply

Marsh Posté le 29-04-2006 à 15:51:28   

Reply

Marsh Posté le 29-04-2006 à 16:07:12    

et bien c'est juste que c'est comme ça. le résultat est tout à fait correct. surcharge __eq__ pour prendre en compte une certain approximation.
 
http://www.wldelft.nl/soft/d3d/intro/misc/goldberg.pdf

Reply

Marsh Posté le 29-04-2006 à 16:13:57    

0. Quel est l'intérêt de passer par x.__divmod__(y) quand il y a une fonction divmod(x, y) built-in?
1. Tu n'as pas donné l'intégralité de la classe, tu n'as pas donné la méthode __str__ de Point que tu as définie, elle te permettrait pourtant de savoir où est le "problème"
2. As tu surdéfini __eq__?
3. affiche p.x et p.y après avoir utilisé magnetize, tu vas très vite voir où est le problème
4. http://cch.loria.fr/documentation/ [...] ldberg.pdf
5. help(decimal.Decimal)

Taz a écrit :

et bien c'est juste que c'est comme ça. le résultat est tout à fait correct. surcharge __eq__ pour prendre en compte une certain approximation.


Ou bien alors il passe par le point 5 :o


Message édité par masklinn le 29-04-2006 à 16:20:26

---------------
I mean, true, a cancer will probably destroy its host organism. But what about the cells whose mutations allow them to think outside the box, and replicate and expand beyond their wildest dreams by throwing away the limits imposed by overbearing genetic r
Reply

Marsh Posté le 29-04-2006 à 16:25:56    

1. Oups j'avais pas vu  
2. Non  
3. Bah non, justement on voit pas de différence (troncature auto)
4. Merci pour la doc ;)
5. Je vais plutôt surdéfinir __eq__
 
Merci à tous les deux

Reply

Marsh Posté le 29-04-2006 à 16:31:28    


Dans la mesure où par défaut __eq__ teste sur l'identité, tu ne pouvais donc de toute façon pas avoir une réalisation de ton test d'égalité [:spamafote]  

fafounet a écrit :

3. Bah non, justement on voit pas de différence (troncature auto)


Ben j'aimerais bien connaître tes réglages, parce que moi je la vois la différence [:petrus75]

Code :
  1. >>> 1.6
  2. 1.6000000000000001
  3. >>> 2.4
  4. 2.3999999999999999
  5. >>> a, b = divmod(2.5, 0.8)
  6. >>> a
  7. 3.0
  8. >>> b
  9. 0.099999999999999867
  10. >>> a*0.8
  11. 2.4000000000000004
  12. >>>


fafounet a écrit :

5. Je vais plutôt surdéfinir __eq__


Il faut le surdéfinir en testant sur un epsilon dans ce cas, donner simplement (self.x == other.x and self.y == other.y) ne passera pas si tu restes en floating point (avec Decimal ça marcherait par contre, c'est du Fixed Point)


Message édité par masklinn le 29-04-2006 à 16:32:22

---------------
I mean, true, a cancer will probably destroy its host organism. But what about the cells whose mutations allow them to think outside the box, and replicate and expand beyond their wildest dreams by throwing away the limits imposed by overbearing genetic r
Reply

Marsh Posté le 29-04-2006 à 16:36:33    

OK c'est pasque j'utilisais print que cela ne m'affichait pas tout.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed