Sean Russell <ser / germane-software.com> writes:

> Paul Duncan wrote:
> 
> > Neither 0/0 nor 0.0/0.0 are defined.  You can't test the equality of
> > infinite values, and you can't test the equality of NaNs either.  That
> > doesn't have anything to do with the underlying logic; that's basic
> > mathematics.
> 
> They're very clearly defined, and they're defined differently.  0/0 is 
> defined, ispo facto, to be an error.  0.0/0.0 returns an Object of type 
> Float, who's value is "NaN".  You can even do operations with this:

In mathematics, 0/0 is clearly defined to be an undefined
operation, as is 0.0/0.0. Computer follows the rule for 0/0, but it
cannot follow the rule for 0.0/0.0 because, as Sean Russell pointed
out, of its limitation.

Mathematics(0.0) != Computer(0.0) simply because the former has an
infinite precision and the later is clearly limited in its
precision. So, 2/3 != 1.0 - 1/3 in computer.

If you want Computer(0.0/0.0) to return an error, just like 0/0 does,
then, first, you have to be able to make the computer do 2/3 == 1.0
- 1/3.

Russell is right that this is an implementation issue because at least
there is one software, Mathlab (the one by Stephen Wofram), that can
do 0.0/0.0 == 0/0 and 2/3 == 1 - 1/3 properly. However this is achieved
by some trickery and a price. First of all, mathlab never computes the
result of 0.0/0.0 nor 0/0 nor 2/3 nor 1/3. It uses symbolic
computation, just like what humans do. In the case of 2/3 =? 1 - 1/3,
it turns it into 2/3 =? 3/3 - 1/3 and perform separate _integer_
operations on both the numerator and denominator. In the case of
0.0/0.0 =? 0/0, it performs cross member operation, turning it into:
0.0/0 =? 0.0/0. The form on the LHS is similar to the form to the RHS,
so LHS is equal to RHS.

Clearly, symbolic computation is complicated. It is _unrealistic_ to
expect this algorithm to be implemented within CPU due to its
complexity and resource consumption (processing power, memory,
etc). It is also unreasonable to expect ruby to implement this as ruby
is a generic programming language, not a mathematician's best friend
like Mathlab.

>         0/0 != 0/0.0

But it is! 0/0 is not 0/0.0. Symbolic computation is flawed. In the
example of 0.0/0.0 =? 0/0, the actual, mathematically result is
undefined. 0.0/0.0 is an undefined operation and 0/0 is also an
undefined operation. But here in lies the subtle point: one undefined
does not equal to another undefined. So, ruby/CPU got this correct by
coincidence.

I lied when I said Mathlab can equate 0.0/0.0 with 0/0. It was a bug
in a version before 1995. They have since corrected it (adding this
special case into their table of 'invalid' operations).

>         (-1/0.0) * 100 => "-Infinity"
>         (-1/0.0) * (1/0.0) => "-Infinity"

If one undefined operation does not equal to another undefined, then
is one infinity equal to another infinity? They are not related, but
they share the same answer: no.

So, mathematically, lim x->0[(-1/x) * 100] != lim x->0[(-1/x) *
(1/x)]. In this case, ruby is wrong because this should be false:

irb(main):005:0>  (-1/0.0) * 100 == (-1/0.0) * (1/0.0)
true

> I don't see how this can be rationalized except by an appeal to "that's the 
> way it has to be because of how computers work".

But since ruby is a general programming language, it serves two
different population: those who care about the mathematical
correctness of a calculation (slow) and those who don't (fast). If
ruby implements mathematically correct calculation, the people who
don't care about it (or who are constrained by time) will suffer
because of the slowness of the calculation. However, if ruby stays the
way it is now, the people who need mathematically correct calculation
can always write code to do that, just like Mathlab.

YS.