问题
I\'m just curious, why in IEEE-754
any non zero float number divided by zero results in infinite value? It\'s a nonsense from the mathematical perspective. So I think that correct result for this operation is NaN.
Function f(x) = 1/x is not defined when x=0, if x is a real number. For example, function sqrt is not defined for any negative number and sqrt(-1.0f) if IEEE-754
produces a NaN
value. But 1.0f/0 is Inf
.
But for some reason this is not the case in IEEE-754
. There must be a reason for this, maybe some optimization or compatibility reasons.
So what\'s the point?
回答1:
It's a nonsense from the mathematical perspective.
Yes. No. Sort of.
The thing is: Floating-point numbers are approximations. You want to use a wide range of exponents and a limited number of digits and get results which are not completely wrong. :)
The idea behind IEEE-754 is that every operation could trigger "traps" which indicate possible problems. They are
- Illegal (senseless operation like sqrt of negative number)
- Overflow (too big)
- Underflow (too small)
- Division by zero (The thing you do not like)
- Inexact (This operation may give you wrong results because you are losing precision)
Now many people like scientists and engineers do not want to be bothered with writing trap routines. So Kahan, the inventor of IEEE-754, decided that every operation should also return a sensible default value if no trap routines exist.
They are
- NaN for illegal values
- signed infinities for Overflow
- signed zeroes for Underflow
- NaN for indeterminate results (0/0) and infinities for (x/0 x != 0)
- normal operation result for Inexact
The thing is that in 99% of all cases zeroes are caused by underflow and therefore in 99% of all times Infinity is "correct" even if wrong from a mathematical perspective.
回答2:
I'm not sure why you would believe this to be nonsense.
The simplistic definition of a / b
, at least for non-zero b
, is the unique number of b
s that has to be subtracted from a
before you get to zero.
Expanding that to the case where b
can be zero, the number that has to be subtracted from any non-zero number to get to zero is indeed infinite, because you'll never get to zero.
Another way to look at it is to talk in terms of limits. As a positive number n
approaches zero, the expression 1 / n
approaches "infinity". You'll notice I've quoted that word because I'm a firm believer in not propagating the delusion that infinity is actually a concrete number :-)
NaN
is reserved for situations where the number cannot be represented (even approximately) by any other value (including the infinities), it is considered distinct from all those other values.
For example, 0 / 0
(using our simplistic definition above) can have any amount of b
s subtracted from a
to reach 0. Hence the result is indeterminate - it could be 1, 7, 42, 3.14159 or any other value.
Similarly things like the square root of a negative number, which has no value in the real plane used by IEEE754 (you have to go to the complex plane for that), cannot be represented.
回答3:
In mathematics, division by zero is undefined because zero has no sign, therefore two results are equally possible, and exclusive: negative infinity or positive infinity (but not both).
In (most) computing, 0.0 has a sign. Therefore we know what direction we are approaching from, and what sign infinity would have. This is especially true when 0.0 represents a non-zero value too small to be expressed by the system, as it frequently the case.
The only time NaN would be appropriate is if the system knows with certainty that the denominator is truly, exactly zero. And it can't unless there is a special way to designate that, which would add overhead.
回答4:
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 asx->0
is either plus or minus infinity, or it's undefined. Ifg(x)
takes both signs in the neighborhood ofx==0
, then the limit is undefined (left and right limits don't agree). Ifg(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.
来源:https://stackoverflow.com/questions/14682005/why-does-division-by-zero-in-ieee754-standard-results-in-infinite-value