Comparing floating-point values different from 1.0?
(also, greater errors)
I think Float#== as it is is fine. Arguably it could use delta
comparison with Float::EPSILON and leave the exact comparison to eql?
But I'd like it if Float#in_delta(other, delta=Float::EPSILON) was in
core (personally I add it in my libs as Numeric#in_delta).
That default value for delta makes no sense in general if you're using it as
in the above example.
Comparing the absolute difference against a fixed epsilon (especially
Float::EPSILON) isn't normally as interesting as giving a bound for the
relative error, so you'd at least need something like
class Float
def in_rdelta(other, rdelta = 1e-6) # or maybe no default at all?
return true if self == other
d = self.abs > other.abs ? (self - other) / self : (self - other) / other
d.abs <= rdelta
end
end
e = Float::EPSILON # => 2.22044604925031e-16
1.0.in_rdelta(1.000000000000000222, e) # => true
100.0.in_rdelta(100.000000000000021, e) # => true
100.0.in_rdelta(100.000000000000044, e) # => false
1.0.in_rdelta(1.000000000000000322, e) # => true
1.000000000000000322 == 1.000000000000000222 # => true
"%20.18f" % 1.000000000000000322 # => "1.000000000000000222"
# And you'd have to add an extra check if you want a different semantics
# around 0.0:
0.0.in_rdelta(2.22e-16, 0.1) # => false
0.0.in_rdelta(2e-17, 0.99) # => false
0.0.in_rdelta(2e-20, 0.9999) # => false