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.