programing

내부 분할:1/3의 결과가 0인 이유는 무엇입니까?

bestcode 2022. 9. 3. 13:20
반응형

내부 분할:1/3의 결과가 0인 이유는 무엇입니까?

난 이 코드를 쓰고 있었어:

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

결과는 0 입니다.이 문제는 왜, 어떻게 해결하면 좋을까요?

2개의 오퍼랜드(1과 3)는 정수이므로 정수 연산(여기서는 나눗셈)이 사용됩니다.결과 변수를 이중으로 선언하면 분할 암묵적인 변환이 발생합니다.

정수 나눗셈은 물론 0을 향해 반올림된 진정한 나눗셈 결과를 반환합니다.0.333...(프로세서는 실제로는 반올림을 하지 않지만, 그래도 그렇게 생각할 수 있습니다.)

, 양쪽 오퍼랜드(숫자)가 플로트로서 주어지는 경우는, 3.0과 1.0, 또는 최초의 부동 소수점 산술이 사용되고 있기 때문에,0.333....

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

중 는 '네'가 합니다.float ★★★★★★★★★★★★★★★★★」double.

할 수.1.0/3 »1.0블입니니다다

쓸 수 요.(double)을 바꾸다intdouble.

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

으로 합니다.double

double g = 1.0/3.0

가 "Java"에 정수 합니다.1 ★★★★★★★★★★★★★★★★★」3정수 상수로 입력했기 때문입니다.

정수 나눗셈을 하고 있기 때문입니다.

@Noldorin이 말했듯이 두 연산자가 정수일 경우 정수 나눗셈이 사용됩니다.

0.333333333은 정수로 표시할 수 없으므로 정수 부분(0)만 결과에 할당됩니다.

연산자 중 하나가 다음 값인 경우doublefloat부동 소수점 산술이 실행됩니다.하지만 이렇게 하면 동일한 문제가 발생합니다.

int n = 1.0 / 3.0;

가장 쉬운 해결책은 이것만 하는 것이다.

double g = (double) 1 / 3;

1.0/3.0을 입력하지 않았기 때문에 Java가 Integer division이라고 가정했기 때문에 수동으로 두 배의 데이터 타입으로 변환할 수 있습니다.변환을 좁혀도 마찬가지입니다.이를 캐스트 연산자라고 합니다.여기서는 피연산자를 하나만 캐스팅하고, 이는 정수 분할을 피하기에 충분합니다(0을 향해 반올림).

결과는 0 입니다.이 문제는 왜, 어떻게 해결하면 좋을까요?

TL;DR

다음을 수행하여 해결할 수 있습니다.

double g = 1.0/3.0; 

또는

double g = 1.0/3; 

또는

double g = 1/3.0; 

또는

double g = (double) 1 / 3;

다음 중 마지막 옵션은 예를 들어 변수를 사용할 때 필요합니다.int a = 1, b = 3; double g = (double) a / b;.

보다 완전한 답변

이중 g = 1/3;

, 「 」가 됩니다.0

  • 우선 배당 < 제수;
  • 모두 입니다.int, 「」가 됩니다.int(5.6.2. JLS)는 다음과 같은 부동소수점 값을 나타낼 수 없습니다.0.333333...
  • "정수 분할이 0을 향해 반올림" 15.17.2 JLS

★★★★double g = 1.0/3.0; ★★★★★★★★★★★★★★★★★」double g = ((double) 1) / 3; 일?

5장부터. 전환프로모션:

변환 컨텍스트 중 하나는 + 또는 *와 같은 숫자 연산자의 오퍼랜드입니다.이러한 오퍼랜드의 변환 프로세스를 수치 승격이라고 합니다.이진 연산자의 경우 한 피연산자에 대해 선택된 변환은 부분적으로 다른 피연산자 식의 유형에 따라 달라질 수 있다는 점에서 프로모션은 특별합니다.

★★★★★★★★★★★★★★★★★」5.6.2. Binary Numeric Promotion

연산자가 오퍼랜드 쌍에 바이너리 수치 프로모션을 적용하는 경우, 각 오퍼랜드 쌍은 숫자 유형으로 변환할 수 있는 값을 나타내야 합니다.다음 규칙이 순서대로 적용됩니다.

피연산자가 기준형일 경우 언박스 변환(55.1.8)된다.

확장 프리미티브 변환('5.1.2)은 다음 규칙에 따라 어느 한쪽 또는 양쪽 오퍼랜드를 변환하기 위해 적용됩니다.

어느 하나의 피연산자가 double 유형인 경우 다른 피연산자는 double로 변환됩니다.

그렇지 않으면 어느 피연산자가 플로트 유형이면 다른 피연산자는 플로트로 변환됩니다.

그렇지 않으면 어느 하나의 오퍼랜드가 long 유형일 경우 다른 오퍼랜드는 long으로 변환됩니다.

그렇지 않으면 두 오퍼랜드가 int 유형으로 변환됩니다.

를 사용해야 합니다.

double g=1.0/3;

또는

double g=1/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에서 설명한 바와 같이 다음과 같습니다.

시프트 연산자 이외의 정수 연산자가 적어도 1종류의 긴 피연산자를 가지고 있는 경우에는 64비트 정밀도로 연산을 실시하고, 그 수치 연산자의 결과는 긴 종류이다.다른 피연산자가 길지 않은 경우 먼저 숫자 승진을 통해 길이가 긴 피연산자(5 5.1.5)로 넓어진다( if 5.6).

또한 JLS를 번역하는 최선의 방법은 항상 예시입니다.

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

그렇지 않으면 32비트 정밀도로 연산이 이루어지며, 수치 연산자의 결과는 int형이다.어느 하나의 오퍼랜드가 int가 아닌 경우 먼저 숫자 프로모션을 통해 int를 입력하도록 확장됩니다.

short + int -> int + int -> int

의 Eclipse를 해도 Eclipse를 한 예.short는 않을 입니다. :s는 그렇게 간단하지 않습니다.

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

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

이를 위해서는 정밀도가 떨어질 수 있는 주물이 필요합니다.

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

수치 연산자에 대한 오퍼랜드 중 적어도 하나가 타입 더블일 경우 64비트 부동소수점 연산을 사용하여 연산이 실행되며, 수치 연산자의 결과는 타입 더블 값이다.다른 피연산자가 더블이 아닌 경우, 먼저 숫자 승진을 통해 더블 타입( (5.6)으로 넓어진다.

그래서 프로모션은 두 배로 진행됩니다.

그리고 정수와 부동값이 혼합되면 다음과 같이 부동값이 됩니다.

바이너리 연산자에 대한 오퍼랜드 중 적어도1개가 부동소수점 타입일 경우 다른 오퍼랜드가 적분인 경우에도 동작은 부동소수점 연산입니다.

는 이진 되지만 " 연산자"는 " 연산자는 "할당 연산자"입니다+=

간단한 작업 예시로 이를 입증할 수 있습니다.

int i = 1;
i += 1.5f;

그 이유는 여기서 암묵적인 캐스팅이 이루어지기 때문에, 이것은 다음과 같이 실행될 것입니다.

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

을 합니다.그 는 0.1은 3 은 0 。 써야 요.1.0 ★★★★★★★★★★★★★★★★★」3.0.

나는 이 일을 했다.

double g = 1.0/3.0;
System.out.printf("%gf", g);

이중 계산을 수행할 때는 0.0을 사용합니다.그렇지 않으면 Java는 정수 사용을 가정합니다.계산에서 이중 값을 사용하는 경우 출력은 이중 값이 됩니다.가 모두 정수일 경우 출력은 정수입니다.

대신 "double g=1.0/3.0;"을 수행하십시오.

(1/3)은 정수 나눗셈을 의미하기 때문에 이 나눗셈에서 10진수를 얻을 수 없습니다.이 문제를 해결하려면 다음을 사용합니다.

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이 모두 int이기 때문에 결과는 반올림되지 않고 잘립니다.그래서 너는 분수를 무시하고 도매만 가져간다.

이를 피하려면 숫자 1 또는 숫자 3 중 적어도 하나를 10진수 형식으로 1.0 및/또는 3.0으로 지정합니다.

이것을 시험해 보세요.

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

내 코드는:

System.out.println("enter weight: ");
int weight = myObj.nextInt();

System.out.println("enter height: ");
int height = myObj.nextInt();

double BMI = weight / (height *height)
System.out.println("BMI is: " + BMI);

사용자가 weight(Numerator) = 5 및 height(Dominator) = 7을 입력하면 BMI는 0이 됩니다.여기서 Democator > Numerator는 인터거(5/7 = 0.71)를 반환하므로 결과는 0(10진수치 없음)이 됩니다.

해결책:

옵션 1:

doubleouble  BMI = (double) weight / ((double)height * (double)height);

옵션 2:

double  BMI = (double) weight / (height * height);

많은 회답에는 이 내용이 기재되어 있지 않은 것을 알 수 있었습니다만, 또한1.0 * 1 / 3부동 소수점 나눗셈을 얻습니다.이 기능은 변수 뒤에 0.0을 추가할 수 없는 변수가 있는 경우에 더 유용합니다.

import java.io.*;

public class Main {
    public static void main(String[] args) {
        int x = 10;
        int y = 15;
        System.out.println(1.0 * x / y);
    }
}

다른 많은 사람들은 진짜 문제를 지적하지 못하고 있습니다.

정수만 연산하면 연산 결과가 정수로 캐스트됩니다.

따라서 정수로 표시될 수 있는 부동 소수점 결과가 잘립니다(소수점 부분 제외).

질문하신 캐스팅(타이프캐스팅/타이프 변환)은 무엇입니까?

언어의 구현에 따라 다르지만 위키피디아는 상당히 포괄적인 관점을 가지고 있습니다.또한 강압에 대해서도 언급하고 있습니다.이것은 질문에 답하는 중요한 정보입니다.

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

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

반응형