7
votes

Comment compter de 0,0001 à 1 en rubis?

Je veux compter de 0,0001 à 1 avec 0,0001 pas dans Ruby. J'ai écrit ce code mais il entre dans une boucle infinie. L'interprète fait une mauvaise somme.

0.0001
0.0002
0.00030000000000000003
0.0004
0.0005
0.0006000000000000001
0.0007000000000000001
0.0008000000000000001
0.0009000000000000002
0.0010000000000000002


2 commentaires

Fait intéressant, cela ne se produit pas sur Jruby.


La réponse de Gioele est clairement meilleure que celle que vous avez marquée comme correcte.


6 Réponses :


1
votes

plutôt que x! = 1.0 , mettre x <1,0 . Cela sera au moins sûr que votre boucle se termine.

Un système binaire comme ceux qui exécutent tous nos ordinateurs modernes ne peuvent (facilement) représenter des fractions, en particulier celles qui ne peuvent pas être représentées avec précision en décimal. C'est là que le nombre étrange se trouve lorsque vous devriez avoir .0003 . C'est un artefact de la manière dont les nombres sont représentés en interne.

Certaines langues sont meilleures pour traiter des chiffres et de la précision que d'autres, de sorte que la précision des nombres compte, vous devez soit utiliser une langue différente, utilisez une bibliothèque qui gère le nombre de choses pour vous (chiffres significatifs et tout ce que ), ou vous devez le gérer vous-même avec l'arrondi approprié, etc. à chaque étape.


2 commentaires

Oui ça marche. Mais que faire si je veux un résultat précis? Et pourquoi 0,0005 + 0,0001 est égal à 0,0006000000000000001 à Ruby?


En raison de la façon dont les œuvres de numéro flottant: regardez flottant-point-gui.de



16
votes

Essayez ceci:

0.0001.step(1, 0.0001).each { |i| puts i }


1 commentaires

Merci! Cela fait le travail :)



2
votes

Le problème est que les nombres réels de rubis ne sont pas représentés exactement en raison du stockage et de la manipulation binaire. Je ferais ce xxx


2 commentaires

Merci! :) Je viens de commencer à programmer. Je ne savais pas ça! :)


Juste pour clarifier, cela ne se limite pas à Ruby, c'est un problème de point flottant.



0
votes

Les numéros de points flottants ne sont pas exactement précis Article de point flottant Wikipedia .

Si vous devez avoir des x nettoyés, je vous recommande d'utiliser un entier et de la division de 1000 avant d'utiliser la valeur. Si vous ne vous souciez pas des petits bits de bruit, tout ira bien avec la modification de votre temps X! = 1,0 à tandis que x <1,0


3 commentaires

Je suis d'accord. En général, en utilisant des entiers pour les opérations (si possible), puis la conversion à la fin donnera des résultats plus précis.


Binaire commun représentations de nombres de points flottants (par exemple, IEEE 754) ne sont pas exacts.


Michael, dis-tu que le calcul est fiable mais la sortie est le problème?




0
votes
1.step(10000, 1).each { |x| puts "%f" % (x / 10000.0).round(4) }

0 commentaires