Development Tip

부동 소수점 (또는 배정 밀도) 숫자로 0으로 나누면 Java에서 java.lang.ArithmeticException : / 0으로 처리되지 않는 이유

yourdevel 2020. 12. 30. 19:45
반응형

부동 소수점 (또는 배정 밀도) 숫자로 0으로 나누면 Java에서 java.lang.ArithmeticException : / 0으로 처리되지 않는 이유


다음 문장 java.lang.ArithmeticException: / by zero은 분명합니다.

System.out.println(0/0);

리터럴 0리터럴 로 간주 int되고 정수 산술에서는 0으로 나누기가 허용되지 않기 때문입니다.

다음의 경우는 그러나 하지 않는 등의 예외를 던져 java.lang.ArithmeticException: / by zero.

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

표시됩니다 Infinity.

다음 문은 NaN예외없이 (Not a Number)를 생성합니다 .

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

이 경우 두 피연산자는 모두 double로 간주됩니다.


마찬가지로 다음 문 예외를 발생 시키지 않습니다 .

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

다음 출력을 생성합니다.

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

모두 반환합니다. false.왜이 연산 (0으로 나누기)이 부동 소수점 또는 배정 밀도 숫자로 허용됩니까?


그런데, 나는 부동 소수점 숫자 (배정 밀도 번호)를 나타냅니다 그 값이 있는지 이해할 수있는 양의 무한대 , 음의 무한대를 , 숫자가 아닌 ( NaN) ...


요컨대, Java의 부동 소수점 연산 이 기반으로 하는 IEEE-754 표준에 지정된 방식 입니다.

0으로 나누기 (또는 오버플로 또는 언더 플로)가 프로그램을 중지하거나 오류를 트리거하지 않는 이유는 무엇입니까? 숫자에 대한 표준에 "숫자가 아님"(NaN)이 포함 된 이유는 무엇입니까?

754 모델은 강력한 프로그램을 장려합니다. 수치 분석가뿐만 아니라 스프레드 시트 사용자, 데이터베이스 시스템 또는 커피 포트를위한 것입니다. NaN 및 무한대에 대한 전파 규칙은 중요하지 않은 예외가 사라지도록 허용합니다. 마찬가지로 점진적 언더 플로는 정밀도 범위에서 오류 속성을 유지합니다.

예외적 인 상황에주의가 필요한 경우 트랩을 통해 즉시 또는 상태 플래그를 통해 편리한 시간에 검사 할 수 있습니다. 트랩을 사용하여 프로그램을 중지 할 수 있지만 복구 할 수없는 상황은 극히 드뭅니다. 단순히 프로그램을 중지하는 것은 임베디드 시스템이나 네트워크 에이전트를위한 옵션이 아닙니다. 종종 트랩은 진단 정보를 기록하거나 유효한 결과를 대체합니다.

플래그는 예측 가능한 제어 흐름과 속도를 모두 제공합니다. 이를 사용하려면 프로그래머가 예외적 인 조건을 알고 있어야하지만 플래그 고정 기능을 사용하면 프로그래머가 필요할 때까지 예외적 인 조건 처리를 지연 할 수 있습니다.


IEEE 754가 정의한 방식이기 때문입니다.

부동 소수점 0.0으로 나누면 분자가 0인지 아닌지에 따라 NaN 또는 +/- Inf가 생성됩니다.

이 때문에 오류를 나타내는의 다른 방법이 없다 - 정수 0으로 나누기는 IEEE 754에 포함하고, 예외를 생성하지 않는 int나타낼 수 없습니다 NaN또는 Inf.

예외 INT생성은 x86 마이크로 프로세서에서 0으로 나누기에 의해 생성 된 (소프트웨어)와 유사합니다 .


무한과 그 너머로

class DoubleDivision {

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

위의 코드와 언급 한 스 니펫은 infinity.

Java가 Doubles를 사용 하여 소수를 나타내는 이유 . 바이너리는 숫자를 완전히 나타낼 수 없으며 근사값 만 나타낼 수 있으므로 Java의 두 배가 될 수 없습니다.

0에 매우 가까운 숫자를 상상해보십시오. 미적분을 알고 있다면 한계가 0이라고 상상해보십시오. 변수는 상상할 수있을 정도로 작은 거리에 0에 접근하지만 정확히 같지는 않습니다. 상상할 수 있겠죠? 음, Java가 표현하기 위해 숫자에 너무 많은 정밀도가 필요하다고 가정 0.0하면 좋은 대안이 없기 때문에 포기하고 호출합니다 . 그것이 여기서 일어나는 일입니다. 0에 매우 가까운 숫자로 나눈 일반 숫자는 기본적으로 무한대 입니다. 시도해보십시오 : 5 / (10^-100).

또한 섹션을 참조하십시오 : 특수 부동 소수점 값 에서 수학 오류 추가 정보를 원하시면 :)

관련 질문 : 1/0은 오류를 제공하지만 1.0 / 0 / 0은 inf를 제공하는 이유

업데이트 : 세트에 INT무한대와 NaN이없는 반면 float에는 무한대와 NaN값이 있습니다. (Java가 따르는 IEEE 754 표준에 따름)


0으로 나누면 컴퓨터는 결과를 숫자로 표현할 수 없습니다. 컴퓨터는 결과가 숫자가 아니라는 신호를 보내야합니다.

부동 소수점 값의 경우 숫자를 나타내지 않는 32 비트 (for float) 및 64 비트 (for double) 비트 패턴이 있기 때문에 숫자가 아닌 것으로 해석 될 수 있으므로 특수한 숫자가 아닌 센티널 값 을 생성 할 수 있습니다. -a- 숫자 ( 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.


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


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 */

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

반응형