Waarom wordt er van de waarde afgetrokken door naar een Float te roepen?

Ik heb een geval waarin ik wat wiskunde op een Float-object aan het doen ben en wanneer ik er_i op roep, wordt het met één verminderd.

value = 0.29 * 100
value.to_i
=> 28

Ik weet dat drijvende-komma-getallen onnauwkeurige weergaven zijn, maar dit is meer dan ik zou verwachten. Wat is er aan de hand en hoe kan ik dit voorkomen?

Ik gebruik robijn 1.8.7 (het gebeurt ook in 1.8.6).

0
Wanneer zullen mensen de drijvende-kommawaarden met grote precisie begrijpen wanneer ze worden omgezet in gehele getallen?
toegevoegd de auteur Richard J. Ross III, de bron
Wat verwachtte je dat er zou gebeuren?
toegevoegd de auteur Andrew Grimm, de bron
Ik verwachtte 29 als resultaat.
toegevoegd de auteur brainimus, de bron
Nou ja, #rond toch.
toegevoegd de auteur DigitalRoss, de bron
In dit geval wilt u mogelijk value.ceil gebruiken
toegevoegd de auteur Dan Heberden, de bron

2 antwoord

(0.29 * 100).round
 => 29 

Niet alle drijvende-kommagetallen zijn onnauwkeurig. 29 is exact, 0,25 is exact, maar 0,29 is dat niet. Als zelfs één bit 50 bits rechts van de komma mist, retourneert de standaardtruncatieconversie het volgende lagere gehele getal.

En dat is waarom #rond bestaat.

6
toegevoegd

Een snelle check in irb onthult dat 0,29 * 100 evalueert naar 28.999 ... . Het aanroepen van Float # to_i doet de rest en eindigt met 28.

3
toegevoegd
Hoe zie je dat het evalueert naar 28.999 ... ?
toegevoegd de auteur brainimus, de bron
Ik doe dat en ik krijg 29.0 niet 28.999 ... vandaar waarom ik zou denken dat ik 29 zou teruggeven.
toegevoegd de auteur brainimus, de bron
Ahh ... Dat produceerde 28.99999999999999644729 .
toegevoegd de auteur brainimus, de bron
Je start irb op, je voert 0,29 * 100 in, je drukt op enter en het vertelt je de waarde van de expressie.
toegevoegd de auteur Dominik Honnef, de bron
Probeer dan in plaats daarvan "%. 20f"% (0.29 * 100) te gebruiken. Het is mogelijk dat het de waarde voor uitvoer in sommige versies afrondt bij gebruik van gewone Float # inspect
toegevoegd de auteur Dominik Honnef, de bron