5

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?

The Governor
  • 1,152
  • 1
  • 12
  • 28

5 Answers5

8

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

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
7

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.

rgettman
  • 176,041
  • 30
  • 275
  • 357
  • 2
    1/0 equating infinity is not mathematically correct. You can't divide by zero and mathematics doesn't discriminate between real numbers and rational numbers when it comes to arithmetic. – Rapptz Aug 30 '13 at 22:52
  • One way to intuit this is that floating points are approximations. So `1.0 / 0.0` can be thought of as "a number really close to 1, divided by a number really close to 0." The result is "a really big number," which is approximated by `Infinity`. This is all very wishy-washy and imprecise, but it gets at the intuition. Note that `1 / Double.MIN_VALUE` is also `Infinity` (`Double.MIN_VALUE` being the smallest positive number that a `Double` can represent.) – yshavit Aug 30 '13 at 22:55
  • @Rapptz Yes, you're right, I guess I typed it too fast. Corrected. – rgettman Aug 30 '13 at 22:56
  • 3
    @yshavit This is a very dangerous intuition to rely on, because the key to understanding other aspects of IEEE 754 floating-point is that floating-point numbers are not “approximations”, they exactly represent specific values. This is an important enough notion that this floating-point expert bothered to list your misconception as “common misconception (2)” and the truth as “An FP number only represents itself (a rational)” when explaining it to non-expert intensive users of floating-point. http://lipforge.ens-lyon.fr/www/crlibm/documents/cern.pdf – Pascal Cuoq Aug 30 '13 at 23:12
  • 1
    It's generally better to think of `/` as "approximately division" than to think of `double` values as approximations of a real number. – Louis Wasserman Aug 30 '13 at 23:14
  • Fair enough points. That mis-categorization (which is everywhere, btw!) has bothered me in the past, so I really shouldn't have propagated it. @LouisWasserman has a better way of phrasing it. – yshavit Aug 31 '13 at 00:08
6

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.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
0

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.

progrenhard
  • 2,333
  • 2
  • 14
  • 14
0

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).

supercat
  • 77,689
  • 9
  • 166
  • 211