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

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
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

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
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