IT

정수 나누기 : 왜 1/3 == 0의 결과입니까?

lottoking 2020. 8. 30. 09:03
반응형

정수 나누기 : 왜 1/3 == 0의 결과입니까?


이 코드를 작성했습니다.

public static void main(String[] args) {
    double g = 1 / 3;
    System.out.printf("%.2f", g);
}

결과는 0입니다.이 이유는 무엇 이며이 문제를 어떻게 해결합니까?


두 피연산자 (1 및 3)는 정수 산술 (여기서 나누기)이 사용됩니다. 결과 변수를 double로 선언하면 나눗셈 나중에 암시 적 변환이 발생합니다 .

물론 정수 나누기는 0으로 반올림 된 나눗셈의 실제 결과를 반환합니다. 따라서 결과는 0.333...여기서 0으로 내림됩니다. (설치는 실제로 반올림을 수행하지 않지만 여전히 그렇게 생각할 수 있습니다.)

또한 피연산자 (숫자)가 모두 실수로 제공 되는 경우에도 유의하십시오 . 3.0 및 1.0 또는 첫 번째 , 부동 소수점 산술이 사용되어 0.333....


1/3 양쪽이 정수 정수 나눗셈을 사용합니다.

이 중 하나 이상이 float또는이 (가) 필요 double합니다.

질문과 같이 소스 코드에 값을 입력하는 경우 다음을 수행 할 수 있습니다 1.0/3. 1.0두 번이다.

곳에서 값 다른을받을 경우 사용할 수 (double)을 설정하는 int으로 double.

int x = ...;
int y = ...;
double value = ((double) x) / y;

명시 적으로 double

double g = 1.0/3.0

이것은 자바의 정수 나눗셈 당신이 사용하기 때문에 발생 1하고 3정수 상수로 입력하기 때문이다.


당신은 선호합니다

double g=1.0/3;

또는

double g=1/3.0;

정수 나누기는 정수를 반환합니다.


정수를 나누고 있기 때문입니다.

@Noldorin이 말했듯이 두 연산자가 모두 정수이면 정수 나누기가 사용됩니다.

결과 0.33333333은 정수로 문헌 수있는 정수 부분 (0) 만 결과에 할당됩니다.

연산자 중 하나가 double/ float이면 부동 소수점 산술이 수행됩니다. 하지만 그렇게하면 동일한 문제가 발생합니다.

int n = 1.0 / 3.0;

1과 3을 정수로 처리하는 결과를 0으로 반올림하여 정수가 처리됩니다.

원하는 결과를 얻으려면 숫자가 다음과 같이 두 배라는 것을 명시 적으로 Java에 알려주십시오.

double g = 1.0/3.0;

1을 부동으로 만들고 부동 분할이 사용합니다.

public static void main(String d[]){
    double g=1f/3;
    System.out.printf("%.2f",g);
}

JAVA에서의 변환은 매우 간단하지만 약간의 이해가 필요합니다. JLS에 설명 된대로 정수 연산 :

시프트 연산자가 아닌 정수 연산자에 long 유형의 피연산자가 하나 이상 있으면 64 비트를 사용하여 연산이 수행되고 숫자 연산자의 결과는 long 유형입니다. 다른 피연산자가 길지 먼저 숫자 승격 (§5.6)에 의해 long을 입력하도록 확장합니다 (§5.1.5).

그리고 예제는 항상 JLS를 번역하는 가장 좋은 방법입니다.)

int + long -> long
int(1) + long(2) + int(3) -> long(1+2) + long(3)

32 비트 용어를 사용하여 연산이 수행되고 숫자 연산자의 결과는 int 유형입니다. 피연산자가 아니면 먼저 숫자 승격을 통해 int를 입력하도록 확장합니다.

short + int -> int + int -> int

이클립스를 사용하여 두 개의 추가하는 것조차 short쉽지 않다는 것을 작은 예제 :

short s = 1;
s = s + s; <- Compiling error

//possible loss of precision
//  required: short
//  found:    int

이를 위해 필요한 것이 수있는 주조가 필요합니다.

부동 소수점 연산자도 마찬가지입니다.

숫자 연산자에 대한 피연산자 중 하나 이상이 double 유형이면 64 비트 부동 소수점 산술을 사용하여 연산이 수행되고 숫자 연산자의 결과는 double 유형 값입니다. 다른 피연산자가 double이 아닌 경우 먼저 숫자 승격 (§5.6)에 의해 double을 입력하도록 확장됩니다 (§5.1.5).

따라서 프로모션은 플로트에서 두 배로 이루어집니다.

그리고 정수와 부동 값을 모두 혼합하면 위에서 말한 것처럼 부동 값이 생성됩니다.

이항 연산자에 대한 피연산자 중 하나 이상이 부동 소수점 유형이면 다른 하나가 정수인 경우에도 연산은 부동 소수점 연산입니다.

이항 연산자에는 해당되지만 "할당 연산자"에는 해당되지 않습니다. +=

간단한 작업 예제만으로도이를 증명할 수 있습니다.

int i = 1;
i += 1.5f;

그 이유는 여기에 암시 적 캐스트가 있기 때문입니다. 이것은 다음과 같이 실행됩니다.

i = (int) i + 1.5f
i = (int) 2.5f
i = 2

1과 3은 정수 상수이므로 Java는 결과가 0 인 정수 나눗셈을 수행합니다. 이중 상수를 작성하려면 1.0을 작성해야합니다 3.0.


가장 쉬운 해결책은 이렇게하는 것입니다.

double g = ((double) 1 / 3);

1.0 / 3.0을 입력하지 않았기 때문에 Java가 정수 나눗셈이라고 가정했기 때문에 수동으로 double 데이터 유형으로 변환하고 변환 범위를 좁히는 것을 의미하더라도 그렇게 할 수 있습니다. 이것을 캐스트 연산자라고합니다.


(1/3)은 정수 나눗셈을 의미하므로이 나눗셈에서 십진수 값을 얻을 수 없습니다. 이 문제를 해결하려면 다음을 사용하십시오.

public static void main(String[] args) {
        double g = 1.0 / 3;
        System.out.printf("%.2f", g);
    }

public static void main(String[] args) {
    double g = 1 / 3;
    System.out.printf("%.2f", g);
}

1과 3은 모두 정수이므로 결과는 반올림되지 않지만 잘립니다. 따라서 분수는 무시하고 정수만 취합니다.

이를 방지하려면 숫자 1 또는 3 중 하나 이상을 십진수 형식 1.0 및 / 또는 3.0으로 지정하십시오.


"double g = 1.0 / 3.0;" 대신.


다른 많은 사람들이 실제 문제를 지적하지 못했습니다.

정수에 대한 연산은 연산 결과를 정수로 캐스트합니다.

이것은 반드시 정수로 표시 될 수 있는 부동 소수점 결과 가 잘릴 것임을 의미합니다 (소수점 부분을 잘라 냄).

캐스트 (타입 캐스팅 / 타입 변환) 란 무엇인가요 ?

언어 구현에 따라 다르지만 Wikipedia는 상당히 포괄적 인 관점을 가지고 있으며 질문에 답하는 데 중요한 정보 인 강제 에 대해서도 이야기 합니다.

http://en.wikipedia.org/wiki/Type_conversion


이것을 시도하십시오 :

public static void main(String[] args) {
    double a = 1.0;
    double b = 3.0;
    double g = a / b;
    System.out.printf(""+ g);
}

참고 URL : https://stackoverflow.com/questions/4685450/int-division-why-is-the-result-of-1-3-0

반응형