NOTE:
I re-wrote this following a valuable comment from @Cubic.
I think the correct answer to this has to come from calculus and the notion of limits. Consider the limit of f(x)/g(x)
as x->0
under the assumption that g(0) == 0
. There are two broad cases that are interesting here:
- If
f(0) != 0
, then the limit as x->0
is either plus or minus infinity, or it's undefined. If g(x)
takes both signs in the neighborhood of x==0
, then the limit is undefined (left and right limits don't agree). If g(x)
has only one sign near 0, however, the limit will be defined and be either positive or negative infinity. More on this later.
- If
f(0) == 0
as well, then the limit can be anything, including positive infinity, negative infinity, a finite number, or undefined.
In the second case, generally speaking, you cannot say anything at all. Arguably, in the second case NaN
is the only viable answer.
Now in the first case, why choose one particular sign when either is possible or it might be undefined? As a practical matter, it gives you more flexibility in cases where you do know something about the sign of the denominator, at relatively little cost in the cases where you don't. You may have a formula, for example, where you know analytically that g(x) >= 0
for all x
, say, for example, g(x) = x*x
. In that case the limit is defined and it's infinity with sign equal to the sign of f(0)
. You might want to take advantage of that as a convenience in your code. In other cases, where you don't know anything about the sign of g
, you cannot generally take advantage of it, but the cost here is just that you need to trap for a few extra cases - positive and negative infinity - in addition to NaN
if you want to fully error check your code. There is some price there, but it's not large compared to the flexibility gained in other cases.
Why worry about general functions when the question was about "simple division"? One common reason is that if you're computing your numerator and denominator through other arithmetic operations, you accumulate round-off errors. The presence of those errors can be abstracted into the general formula format shown above. For example f(x) = x + e
, where x
is the analytically correct, exact answer, e
represents the error from round-off, and f(x)
is the floating point number that you actually have on the machine at execution.