You can assign a negative sign to a 0.0 float in Ruby because all IEEE 754 floating point numbers have a sign bit to indicate whether the number is positive or negative.
Here are the binary representations of 2.5 and -2.5:
[2.5].pack('f').unpack1('b*')
#=> "00000000000000000000010000000010"
[-2.5].pack('f').unpack1('b*')
#=> "00000000000000000000010000000011"
The last bit is the sign bit. Note that all the other bits are identical.
On the other hand, there is zero with a sign bit of 0:
['00000000000000000000000000000000'].pack('b*').unpack1('f')
#=> 0.0
and zero with a sign bit of 1:
['00000000000000000000000000000001'].pack('b*').unpack1('f')
#=> -0.0
Although 0.0 and -0.0 are numerically equal, they are not identical on the object level:
(0.0).eql?(-0.0) #=> true
(0.0).equal?(-0.0) #=> false
Negative zeros have some special properties.
For instance:
1 / 0.0 #=> Infinity
1 / -0.0 #=> -Infinity
Assigning - explicitly is not the only way to get -0.0. You may also get -0.0 as the result of a basic arithmetic operation:
-1.0 * 0 #=> -0.0