2009-12-22 5 views
2

Est-ce que Ruby a un bug dans son arrondissement? Pourquoi faut-il se comporte comme ceci:Arrondi incohérent dans Ruby?

>> [1.14, 1.15, 1.16].map{|x| "%.1f" % x} 
=> ["1.1", "1.1", "1.2"] 
>> [1.4, 1.5, 1.6].map{|x| "%.0f" % x} 
=> ["1", "2", "2"] 

comme, pourquoi 1,15 arrondi à 1,1 obtenir, mais 1,5 obtient arrondie à 2? À tout le moins, n'est-ce pas incompatible? le comportement est le même dans ruby ​​1.9.1 et ruby ​​1.8.7.

+0

duplication possible de [Pourquoi sprl de Perl ne arrondit pas correctement les nombres à virgule flottante?] (Http://stackoverflow.com/questions/1651671/why-does-perls-sprintf-not-round-floating-point-numbers- correctement) –

Répondre

2

Vous utilisez des nombres à virgule flottante. Les nombres à virgule flottante ne sont pas précis. Voir http://en.wikipedia.org/wiki/IEEE_754-2008 pour une introduction dans la norme. La version courte est: N'utilisez JAMAIS des flotteurs pour quelque chose où vous avez besoin de précision de quelque façon que ce soit!

1

Il est utile de rappeler et aussi tout à fait ironique de contempler, mais les nombres à virgule flottante ne représentent que exactement : (a) quelques fractions ou (b) tous les entiers. Donc, pour avoir une représentation exacte, une fraction doit être composée de puissances (négatives) de deux. Ainsi, les fractions suivantes sont les seuls entre .01 et .99 qui sont exactement représentés:

0.25 
0.50 
0.75 

En d'autres termes, FP est parfaitement exact lorsqu'ils traitent avec des entiers. Allez comprendre.

+0

Cela ne semble pas correct. Vous devriez obtenir une réponse exacte pour tous les exposants négatifs qui peuvent être représentés dans la mantisse (ce que Wikipédia me dit s'appelle maintenant le "significand" - doit être arrivé après que je suis allé à l'école). Donc '2 ** 1/n' devrait fonctionner pour tout' n' qui peut tenir dans la mantisse. Non? – zetetic

+0

devrait se lire "pour tout résultat qui peut tenir dans la mantisse" – zetetic

+0

Presque, mais seulement lorsque * n * est une puissance de deux. Ainsi, une fraction composée d'un ou plusieurs termes de * 1/2, 1/4, 1/8, 1/16, 1/32 *, ... peut être représentée exactement. – DigitalRoss