Divide by Zero: Infinite, NaN, or Zero Division Error? [closed]
Why isn't 1/0 == Inf
in every language? Is that not the most mathematically correct response?
All the languages I'm familiar with are capable of expressing both Infinite and NaN values, so why would they choose to throw an error or return NaN instead? Is it just to make life harder for scientific application developers? ;-)
Update: We should maybe close this question because I incorrectly thought that 1f/0f == Float.NaN
in Java. But I was wrong: it does correctly return Float.Infinity
. That was my main confusion; the fact that some languages throw errors instead is understandable, so long as no language returns NaN.
Apart from the fact that 1 / 0 == inf is mathematically highly questionable, the simple reason why it doesn’t work in most programming languages is that 1 / 0
performs an integer division almost universally (exceptions exist).
The result is an integer, and there is simply no way of encoding “infinity” in an integer. There is for floating point numbers, which is why a floating-point division will actually yield an infinite value in most languages.
The same is true for NaN: while the IEEE floating point standard defines a bit pattern that represents a NaN value, integers don’t have such a value; thus such values simply cannot be represented as an integer.
Is that not the most mathematically correct response?
No, because in mathematics, division by zero is simply undefined and infinity is commonly not a value (or not a single value).
The reason that not all languages/libraries return NaN is that (a) zero-division is often the result of a programmer error, since it shouldn't occur at all in mathematically rigorous algorithms, and (b) processors might handle it by going into an exception state, so transforming to NaN would require handling such states, meaning division becomes even more expensive than it already is (compared to, say, summing).
Whilst the limit of 1 / n
will tend towards infinity as n approaches zero (from the positive direction) the reason that 1 / 0 <> Inf
is that 1 / 0 is undefined (by mathematical definition!).
Why the trolling? But I'll bite. This may vary on the way you build up your operators but the most conventional way to define division is just the functional inverse of multiplication. That is to say c = a/b is defined as c being the unique number such that c*b = a.
Now consider c = 1/0. Is there a unique c such that c*0 = 1? Certainly not within R or C. What if we introduce infinity? You could have a special case that says that 0*Infinity = 1. But then you break a bunch of nice properties of the multiplication operator. That is we would like 2*(0*Infinity) = 2*1 = 2. But we also want the associative property. So (2*0)*Infinity = 0*Infinity = 1.
In general a Field can not be extended to have a multiplicative inverse of 0 in anyway that preserves the properties you want.
That said, I assume you introduced the classic 1/0 = Infinity just to troll. Next question, how come languages don't recognize that 0.9 repeater does not equal 1.
How about 0/0
or -1/0
? What if you made a mistake? It is not a good idea to signal the program zero division with an Inf
result.
In a Java interactions pane, I see this.
Welcome to DrJava. Working directory is /Users/morrison/Desktop/PhotoPuzzle
> int top = 1;
> int bottom = 0;
> top/bottom
java.lang.ArithmeticException: / by zero
> double topFloat = 1;
> double bottomFloat = 0;
> topFloat/bottomFloat
Infinity
>
Floating point numbers are inexact and can be very close to zero. Making an integer zero is probably seen as a programmer goof. These are likely the two distinct behaviors you see.
Floating point operations can detect several exceptional conditions and react in a couple of different ways:
- Setting a status flag that can be later tested.
- Immediately generating a trap.
The first mode of operation allows high performance, while the second mode allows immediate notification of possibly erronous operations.
IEEE 754 defines some sane values for the result of operations that raise exceptions (e.g: dividend finite nonzero number and divisor zero → correctly signed INFINITY; 0/0 → Quiet NaN).
The IEEE 754 intention with traps, is that there would be user mode handlers that could inspect the operation, the operands (for Invalid Operation and Divide by Zero exception) or result (for Overflow, Underflow and Inexact exceptions) and exception flags and return a new user-defined result.
In reality, some languages don't even support accessing the exception status flags, let alone set trap handlers.
Even C provides very primitive support for trap handlers, C99 doesn't even define a portable way to set trapping mode, requiring e.g: passing some implementation-defined value to fesetenv()
. Implementations will typically raise a SIGFPE, and the user will typically need to access CPU-dependent state to implement a IEEE-754-like trap handler.
Because while 1 / 0
may at times be approximated as INF
or some other like value, it's not formally defined as such. On the same front is 10 / 0 < 20 / 0
? or 0 / 0
.
Division a | b
by itself isn't defined for b = 0
. Therefore implementations of this operation map this case to a special value, to express this concept.
精彩评论