Why is number divided by zero infinity in Java?

2019-01-26 22:39发布

问题:

Why should the following code in Java

System.out.println(new Integer(1)/ new Double(0));

print 'Infinity' and not undefined. Isn't that mathematically wrong?

回答1:

In mathematics, there are many different structures that support arithmetic. The most prominent ones, such as the natural numbers, the integers, and the real numbers, do not include infinity. In those systems, division by zero is not supported.

Other systems do include at least one infinity. See, for example, the real projective line. It does permit division by zero.

There is only one way to know what is mathematically defined or undefined in a particular system - study that system.

Similarly, whether operations are commutative (a op b == b op a) and/or associative (a op (b op c) == (a op b) op c) depends on the system and the operation.

IEEE 754 binary floating point is a system with a finite set of elements, including two infinities. Addition and multiplication are both commutative but not associative. Java real and double arithmetic are based on it. The Java Language Specification is the only way to know for sure what is or is not defined in Java floating point arithmetic.

Many of the worst errors in using floating point have their basis in assuming that floating point numbers are real numbers, rather than a valid but different system.



回答2:

This is consistent with the IEEE 754 standard on floating-point, which Java follows.



回答3:

No, you can't divide by zero in math, but in Java Infinity is correct for new Integer(1)/ new Double(0). new Integer(0)/ new Double(0) would be undefined (NaN).

Java follows IEEE standards, so for floating point operations such as this, Infinity is correct. Had it been 1/0, an ArithmeticException would have occurred, because in integer division, division by zero is not allowed; there is no int representation for infinity.

Specifically, in the JLS, Section 15.17.2:

[I]f the value of the divisor in an integer division is 0, then an ArithmeticException is thrown.

And

The result of a floating-point division is determined by the rules of IEEE 754 arithmetic:

Division of a zero by a zero results in NaN Division of a nonzero finite value by a zero results in a signed infinity.



回答4:

In short: floating point numbers can represent infinity (or even operations that yield values which aren't numbers) so an operation that results in this (e.g. dividing by 0) is valid.



回答5:

One of the better design decisions in the design of today's floating-point standards was allowing things like division by zero to yield a special sentinel value which indicates that something went out of range, rather than crashing the program. The code which uses the result can then decide to what extent such a sentinel value indicates a major problem or a minor one. For example, a program which is graphing a function may simply omit points where a value can't be computed while plotting the rest.

Rarely will a floating-point number output as its true value. Instead, it will output as some string which is sufficient to identify its value. The sentinel value which is generated when dividing a non-zero number by zero prints out as "Infinity", but that doesn't mean it's mathematically infinity. Rather, it means that it it's the sentinel value which is used to represent a result which is indistinguishable from any other number greater than roughly 2^1024 and should rank greater than any other defined result. Another sentinel value exists for a result which is indistinguishable from any other number less than -(2^1024) and should rank less than any other defined result. A third exists for results which can't be computed but don't fit either category.

The reason for using the same sentinel for computations which exceed 2^1024 and the division of a positive number by zero is that both situations can arise when dividing a very big positive number by a very small one. If the result of such a comparison would be "positive infinity", sorting above everything else, even when dividing by the most infinitesimally small positive number, it should remain when dividing by "half" of that number (which rounds to zero).