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

让人想犯罪 __ 提交于 2019-11-26 03:55:36

问题


The following statement throws java.lang.ArithmeticException: / by zero as obvious.

System.out.println(0/0);

because the literal 0 is considered to be an int literal and divide by zero is not allowed in integer arithmetic.

The following case however doesn\'t throw any exception like java.lang.ArithmeticException: / by zero.

int a = 0;
double b = 6.199;
System.out.println((b/a));

It displays Infinity.

The following statement produces NaN (Not a Number) with no exception.

System.out.println(0D/0); //or 0.0/0, or 0.0/0.0 or 0/0.0 - floating point arithmetic.

In this case, both of the operands are considered to be double.


Similarly, the following statements don\'t throw any exception.

double div1 = 0D/0; //or 0D/0D
double div2 = 0/0D; //or 0D/0D

System.out.printf(\"div1 = %s : div2 = %s%n\", div1, div2);
System.out.printf(\"div1 == div2 : %b%n\", div1 == div2);
System.out.printf(\"div1 == div1 : %b%n\", div1 == div1);
System.out.printf(\"div2 == div2 : %b%n\", div2 == div2);
System.out.printf(\"Double.NaN == Double.NaN : %b%n\", Double.NaN == Double.NaN);
System.out.printf(\"Float.NaN == Float.NaN : %b%n\", Float.NaN == Float.NaN);

They produce the following output.

div1 = NaN : div2 = NaN
div1 == div2 : false
div1 == div1 : false
div2 == div2 : false
Double.NaN == Double.NaN : false
Float.NaN == Float.NaN : false

They all return false. Why is this operation (division by zero) allowed with floating point or double precision numbers?


By the way, I can understand that floating point numbers (double precision numbers) have their values that represent positive infinity, negative infinity, not a number (NaN)...


回答1:


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.




回答2:


It's that way because that's how IEEE 754 defined it.

Division by a floating point 0.0 yields NaN or +/-Inf, depending on whether the numerator is 0 or not.

Division by an integer 0 is not covered by IEEE 754, and generates an exception - there's no other way of indicating the error because an int can't represent NaN or Inf.

Generating an exception is similar to the (software) INT generated by a division by zero on x86 microprocessors.




回答3:


To Infinity and Beyond

class DoubleDivision {

    public static void main(String[] args) {
        System.out.println(5.0/0.0);
    }
}

The above code, and the snippets you mentioned gives infinity.

Why Java uses Doubles to represent decimals. Binary cannot fully represent a number, it can only represent an approximation and therefore, neither can Java’s double.

Imagine a number incredibly close to zero. If you know calculus, imagine a limit at zero. The variable would be approaching zero to some imaginably tiny distance but never equal exactly. You can imagine that, right? Well, suppose that number is needs so much precision for Java to represent, it gives up and calls it 0.0 because it does not have a good alternative. That’s what is happening here. Any regular number divided by a super close number to zero is basically, infinity. Try it: 5 / (10^-100).

Also refer to section : Special Floating-Point Values at Math Errors for more info :)

Related question : why does 1/0 give error but 1.0/0/0 give inf

UPDATE: INT does not have an infinity and NaN value in set whereas float does have a infinity and NaN value. (According to IEEE 754 standards that java follows)




回答4:


When there is a divide by zero, the computer can not create a representation of the result as a number. The computer needs to signal that the result is not a number.

For floating point values it can produce a special not-a-number sentinel value, because there are some 32-bit (for float) and 64-bit (for double) bit patterns that do not represent a number, and thus can be interpreted as not-a-number (NaN).

For integer values using the common twos-complement scheme (as Java requires), all 32-bit (for int) and 64-bit (for long) bit patterns represent a number. So the computer can not report the problem using a sentinel. It must report the problem "out of band" in some manner. Throwing an exception is the out of band method chosen for Java.




回答5:


Java follows the IEEE 754 standard which defines values to return by default in the case of a division by zero. http://en.wikipedia.org/wiki/IEEE_754#Exception_handling

Division by zero (an operation on finite operands gives an exact infinite result, e.g., 1/0 or log(0)) (returns ±infinity by default).




回答6:


import java.util.Scanner;

public class Division {

    public static void main(String[] args) {
        int a, b;
        float result;

        Scanner input = new Scanner(System.in);
        System.out.println("Enter value for a : ");
        a = input.nextInt();

        System.out.println("Enter value for b : ");
        b = input.nextInt();

        try {
            /* here we used "if clause" because result will be in float
             note: Here result is in float, so JVM Cant Catch Exception.
             if we Try to Divide with Zero with Float Values It gives Output as
             Divided by Zero is Infinity */
            if (b != 0) {
                result = (float) a / b;
                System.out.println("Result of " + a + " divided by " + b + " is : " + result);
            } else // here result will be in integer so Jvm can easily Catch The Exception
            {
                result = a / b;
            }
        } catch (ArithmeticException e) {
            System.out.println("Sorry Division By Zero Is Not Possible");
        }
    }
}

/* Ouput :
Enter value for a :2
Enter value for b : 7
Result of 2 divided by 7 is : 0.2857143 */

 /* Ouput :
Enter value for a : 16
Enter value for b : 0
Sorry Division By Zero Is Not Possible */


来源:https://stackoverflow.com/questions/12954193/why-does-division-by-zero-with-floating-point-or-double-precision-numbers-not

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!