Numeri float

Non mi è particolarmente chiaro il discorso alle differenze tra i numeri
floating point calcolati e non.
Ovvero:
1.9 è un numero e ci siamo
1.8 + 0.1 è diverso

irb(main):023:0> 1.8 + 0.1
=> 1.9000000000000001

e va bene
Su un testo leggo la seguente frase condita da esempio:

Note that the difference between the two numbers
is preciselyFloat::EPSILON:
Float::EPSILON # => 2.22044604925031e-16
(1.8 + 0.1) - 1.9 # => 2.22044604925031e-16

però se prendo altri numeri la cosa cambia:

irb(main):020:0> (2.2 + 0.1) - 2.3
=> 4.440892098500626e-16
irb(main):021:0> (42.2 + 0.1) -42.3
=> 7.105427357601002e-15

Insomma, senza passare di lenti BigDecimal, qual è la strada migliore
per verificare l’uguaglianza tra
2.2 + 0.1 e 2.3?

Grazie in anticipo.

On Saturday, August 10, 2013 at 3:18 PM, Renato L. wrote:

Su un testo leggo la seguente frase condita da esempio:
irb(main):021:0> (42.2 + 0.1) -42.3


Ml mailing list
[email protected] (mailto:[email protected])
http://lists.ruby-it.org/mailman/listinfo/ml

Sia minitest che rspec usano metodi simili tra loro: controllare che il
valore sia in un range ristretto, denominato delta:
Minitest:

Rspec:
https://www.relishapp.com/rspec/rspec-expectations/v/2-14/docs/built-in-matchers/be-within-matcher

Federico

Ciao ,
Non basterebbe la funzione round per effettuare la comparazione ?

(2.2 + 0.1).round(2) == 2.3.round(2)

Daniele.

Il giorno 10 agosto 2013 15:27, Federico R.
<[email protected]

ha scritto:

All’Euruko di questo anno Xavier N. ha fatto un talk su questo tipo
di problemi, se vuoi trovi il video e le slide del video a questo
indirizzo NameBright - Coming Soon.
Forse può toglierti qualche dubbio e darti qualche idea.

Il problema che 0.1 non ha una rappresentazione binaria finita;
analogamente a 1/3 che non ha una rappresentazione decimale finita.

L’unica maniera corretta in generale di verificare l’uguaglianza fra
numeri
in virgola mobile a meno di un piccolo delta, come giustamente ha
scritto
Federico. Si verifica cio che sia

abs(x-y) < epsilon

2013/8/10 Renato L. [email protected]

Per ora me la sono cavata con una porcheria di questo tipo:

irb(main):019:0> ((2.2 + 0.1) - 2.3).abs < 0.00000000001
=> true

non un gran che…