As I said, I think it's legitimate to hypothesize about different floating-point arithmetic, also in the context of Rust. A lot of languages come with their own numeric types that aren't tied to what the processor does. Consider Python:
>>> 2**1000
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376
I don't want to promote introducing any of that in Rust, changing behavior of f64
, or anything like that, but I find it interesting to think about alternative rules (as it also helps understanding the current rules better).
(And I don't consider the original post to be a rant.)
I still like NaNs, but I'd like to understand the proposal better.
@tczajka, basically you propose that in your model returning any result is legitimate that would be contained in an interval when using interval arithmetic? I'm not familiar with the latter. Why would [0.0, 0.0] / [0.0, 0.0] be [−∞, +∞]? Because [−∞, +∞] * [0.0, 0.0] = [0.0, 0.0], I guess. But no, correct would be: [−huge, +huge] * [0.0, 0.0] with |huge| < ∞. Or am I wrong? (Really not sure here.)
Thus (within the model of integer arithmetic, if I understand it right), I'd say the following doesn't make sense:
Instead, 0.0 / 0.0 could give 0.0, because 0.0 is one possible solution to the equation x × 0.0 = 0.0. This would also be average (and median) of all possible solutions when using finite floating-point representation.
But how about 1.0 / 0.0? Here −∞ and +∞ would be possible solutions, so an interval containing all solutions would be [−∞, +∞]. But finite numbers are no solution. So not sure what to do here.
Given these considerations, how would you answer the following questions (as of now):
- Can 0.0 / 0.0 be infinite? Or wouldn't 0.0 / 0.0 = 0.0 be a better choice?
- Should −0.0 and +0.0 be distinguished?
- Should −∞ and +∞ be distinguished, and if we don't distinguish them, how do they compare to other numbers?
Anyway, setting sqrt(−1) = 0 doesn't make sense in any case, I think, as 0² is not −1. I'd rather say sqrt(−1) = −∞ (because dsqrt(x)/dx = ∞ for x = 0)
.
I would propose (for this hypothetical arithmetic):
- 0.0 / 0.0 = 0.0
- 1.0 / +0.0 = +∞
- 1.0 / −0.0 = −∞
- sqrt(∞) = ln(∞) = ∞
- ln(1) = 0
- sqrt(0) = 0
- ln(0) = −∞
- sqrt(−1) = ln(−1) = −∞
- sqrt(−∞) = ln(−∞) = −∞
- sin(−∞) = sin(+∞) = 0.0
- cos(−∞) = cos(+∞) = 0.0