Why Doesn't Java Throw an Exception When Dividing by 0.0

Why doesn't Java throw an Exception when dividing by 0.0?

The result of division by zero is, mathematically speaking, undefined, which can be expressed with a float/double (as NaN - not a number), it isn't, however, wrong in any fundamental sense.

As an integer must hold a specific numerical value, an error must be thrown on division by zero when dealing with them.

Java division by zero doesnt throw an ArithmeticException - why?

Why can't you just check it yourself and throw an exception if that is what you want.

    try {
for (int i = 0; i < tab.length; i++) {
tab[i] = 1.0 / tab[i];

if (tab[i] == Double.POSITIVE_INFINITY ||
tab[i] == Double.NEGATIVE_INFINITY)
throw new ArithmeticException();
}
} catch (ArithmeticException ae) {
System.out.println("ArithmeticException occured!");
}

Why does division by zero with floating point (or double precision) numbers not throw java.lang.ArithmeticException: / by zero in Java

In short, that's the way it's specified in the IEEE-754 standard, which is what Java's Floating-Point Operations are based on.

Why doesn't division by zero (or overflow, or underflow) stop the program or trigger an error? Why does a standard on numbers include "not-a-number" (NaN)?

The 754 model encourages robust programs. It is intended not only for numerical analysts but also for spreadsheet users, database systems, or even coffee pots. The propagation rules for NaNs and infinities allow inconsequential exceptions to vanish. Similarly, gradual underflow maintains error properties over a precision's range.

When exceptional situations need attention, they can be examined immediately via traps or at a convenient time via status flags. Traps can be used to stop a program, but unrecoverable situations are extremely rare. Simply stopping a program is not an option for embedded systems or network agents. More often, traps log diagnostic information or substitute valid results.

Flags offer both predictable control flow and speed. Their use requires the programmer be aware of exceptional conditions, but flag stickiness allows programmers to delay handling exceptional conditions until necessary.

How should I throw a divide by zero exception in Java without actually dividing by zero?

You should not throw an ArithmeticException. Since the error is in the supplied arguments, throw an IllegalArgumentException. As the documentation says:

Thrown to indicate that a method has been passed an illegal or inappropriate argument.

Which is exactly what is going on here.

if (divisor == 0) {
throw new IllegalArgumentException("Argument 'divisor' is 0");
}

why there is no ArithmeticException( divide by zero) when both values are double?

The "magic" is that Java floating point representations are based on the IEE 754 floating point standard. This has a special value (NaN) that denotes the "indefinite value" that you get when zero is divided by zero. (There are also values that represent positive and negative infinity; e.g. 1.0 / 0.0 gives INF - positive infinity.)

This is covered in the Java Language Specification; see sections §4.2.3 which discusses the representations and §4.2.4 which discusses how arithmetic works.


Note that the same "magic" applies to float, double, Float and Double.

Why doesn't 'd /= d' throw a division by zero exception when d == 0?

C++ does not have a "Division by Zero" Exception to catch. The behavior you're observing is the result of Compiler optimizations:

  1. The compiler assumes Undefined Behavior doesn't happen
  2. Division by Zero in C++ is undefined behavior
  3. Therefore, code which can cause a Division by Zero is presumed to not do so.

    • And, code which must cause a Division by Zero is presumed to never happen
  4. Therefore, the compiler deduces that because Undefined Behavior doesn't happen, then the conditions for Undefined Behavior in this code (d == 0) must not happen
  5. Therefore, d / d must always equal 1.

However...

We can force the compiler to trigger a "real" division by zero with a minor tweak to your code.

volatile int d = 0;
d /= d; //What happens?

So now the question remains: now that we've basically forced the compiler to allow this to happen, what happens? It's undefined behavior—but we've now prevented the compiler from optimizing around this undefined behavior.

Mostly, it depends on the target environment. This will not trigger a software exception, but it can (depending on the target CPU) trigger a Hardware Exception (an Integer-Divide-by-Zero), which cannot be caught in the traditional manner a software exception can be caught. This is definitely the case for an x86 CPU, and most other (but not all!) architectures.

There are, however, methods of dealing with the hardware exception (if it occurs) instead of just letting the program crash: look at this post for some methods that might be applicable: Catching exception: divide by zero. Note they vary from compiler to compiler.

Java not catching/displaying ArithmeticException

The integer division 0/0 would throw an ArithmeticException but this would not happen if any of the operands are floating point numbers.

As Java uses IEEE754 floating point numbers, this division is allowed.

If zero is divided by zero (floating point division), the result is NaN (Not a Number) and this woukd not throw an exception.

If a positive non-zero number is divided by zero (or a negative non-zero) number is divided by negative zero), the result would be Infinity.

If a negative non-zero number is divided by zero (or a positive non-zero number is divided by negative zero), the result would be -Infinity.

When a floating point number is 0.0 as a divisor (in java)

Exact 0 is not a divisor, except in the case of 0/0

Proof:

Let p <> 0 be a number, so that

p / 0 = q

Let's multiply the equation with 0:

p = 0 * q

which is possible if and only if p is 0. But then q can be anything, so dividing a non-zero number with 0 is undefined, while dividing 0 with 0 is ambivalent.

A number infinitely close, but not equal to 0 is a divisor

Proof

Let p -> 0, p <> 0

In this case, dividing a normal q, not 0 number with p, which is extremely close to 0 yields infinity, since you will need to multiply p (which is infinitely close to 0) with infinity to get 1, but in that case you multiply q with infinity as well, hence the result.

0.0 represents a number infinitely close to 0.



Related Topics



Leave a reply



Submit