Float#negative? reports negative zero as not negative
Is this intended behaviour?
irb(main):001:0> neg_zero = -0.0 => -0.0 irb(main):002:0> neg_zero.negative? => false irb(main):003:0> neg_zero < 0 => false
It happens because
< 0. My understanding of IEEE floating point is that negative zero is not less than zero, but I think it should still report as negative.
Updated by chrisseaton (Chris Seaton) 6 months ago
My suggestion is that
Float#negative?(neg_zero) == true and
Float#positive?(pos_zero) == false.
We can't get rid of negative zero - it's a standard part of floating point numbers as implemented by the hardware. It's also useful in some applications.
Updated by Eregon (Benoit Daloze) 6 months ago
chrisseaton (Chris Seaton) wrote in #note-5:
then another option could be to add a new predicate
Float#negative_zero?- that would allow people to differentiate as needed.
Interesting, I thought
equal? would work for that (it does on TruffleRuby) but it does not on CRuby 2.6.6:
 pry(main)> 0.0.equal?(0.0) => true  pry(main)> -0.0.equal?(-0.0) => false
I guess it's a result of implementing Float as tagged (flonum) but only for a subset of Float:
 pry(main)> a=-0.0 => -0.0  pry(main)> a.equal?(a) => true
== do not differentiate 0.0 and -0.0.
One way to test for -0.0 seems
(-f).equal?(0.0) but that's kind of brittle as it relies on 0.0 being a flonum on CRuby.
I tend to agree that
0.0.positive? == -0.0.negative? and since
0.positive? => false then both as
false seems to make sense (essentially they are the same as
> 0 and
Updated by marcandre (Marc-Andre Lafortune) 6 months ago
AFAIK, the only way to check for
1.0 / var == -Float::INFINITY
I find it difficult to discuss what need to be done about any of this as I do not know of the use cases for
-0.0; without them it seems very theoretical.
Updated by sawa (Tsuyoshi Sawada) 6 months ago
Ruby or IEEE 754 seem to regard
0.0 not as 0 in the mathematical sense, but as (something like) negative and positive infinitesimal. Taking this into account, I started to think
0.0.positive? should both be
Regarding the fact that
-0.0 == 0.0 is true, I think it should be understood as '
0.0' rather than '
0.0'. Then it would not contradict with the above. Floating point numbers are approximated numbers to begin with, so it does not make much sense to talk about their exact identity. Hence it makes sense to regard
Float#== to mean 'close enough' rather than 'exactly the same'.