programing

두 개의 int를 나누면 double에 할당 될 때 올바른 값이 생성되지 않는 이유는 무엇입니까?

nasanasas 2020. 9. 5. 10:01
반응형

두 개의 int를 나누면 double에 할당 될 때 올바른 값이 생성되지 않는 이유는 무엇입니까?


다음 스 니펫에서 어떻게

int a = 7;
int b = 3;
double c = 0;
c = a / b;

c예상대로 2.3333이 아닌 2의 값을 갖게됩니다. 경우 ab복식이다, 대답은 2.333로 전환 않습니다. 그러나 확실히 c이미 double 이기 때문에 정수로 작업해야 했습니까?

그래서 어떻게 int/int=double작동하지 않습니까?


이것은 정수 나눗셈 버전을 사용하고 있기 때문입니다.이 버전 operator/은 2 int초를 사용하고 int. double를 반환하는 버전 을 사용하려면 s double중 하나 이상을 int명시 적으로 double.

c = a/(double)b;

여기있어:

a) 두 개의 ints를 나누면 항상 정수 나누기가 수행됩니다. 따라서 a/b귀하의 경우 결과 int.

ab유지 하고 싶지만 int완전히 나누려면 그중 하나 이상을 이중으로 캐스팅해야합니다 : (double)a/b또는 a/(double)b또는 (double)a/(double)b.

b) cA는 double그래서 수 수락int assignement의 값을 다음은 int자동으로 변환된다 double및 할당 c.

c) 할당시, 오른쪽에있는 표현식 =먼저 계산 된 다음 (위의 규칙 (a)에 따라, 왼쪽에있는 변수에 관계없이 =) 다음= (에 따라) 왼쪽에있는 변수에 할당됩니다. b) 위). 나는 이것이 그림을 완성한다고 믿는다.


아주 적은 예외 (하나만 생각할 수 있음)를 제외하고 C ++는 표현식 자체에서 표현식 (또는 하위 표현식)의 전체 의미를 결정합니다. 표현의 결과로 무엇을하든 상관 없습니다. 귀하의 경우에는 표현 a / b에서 a double가 보이지 않습니다 . 모든 것이입니다 int. 따라서 컴파일러는 정수 나누기를 사용합니다. 결과를 얻은 후에 만 ​​무엇을할지 고려하고 double.


두 개의 정수를 나누면 결과는 double로 저장한다는 사실에 관계없이 정수가됩니다.


cdouble변수이지만 할당되는 int값은 두 ints 의 나눗셈에서 발생하므로 "정수 나눗셈"(나머지 삭제)을 제공 하므로 값 입니다. 그래서 라인에서 일어나는 c=a/b일은

  1. a/b 평가되어 임시 유형을 만듭니다. int
  2. 임시 값은 c유형으로 변환 한 후 할당됩니다 double.

의 값은 a/b컨텍스트를 참조하지 않고 결정됩니다 (에 할당 double).


/연산자는 정수 나눗셈 또는 부동 소수점 나눗셈에 사용할 수 있습니다. 두 개의 정수 피연산자를 제공하므로 정수 나눗셈을 수행하고 결과는 double에 저장됩니다.


C ++ 언어에서 subexpresison의 결과는 주변 컨텍스트의 영향을받지 않습니다 (일부 예외가 있음). 이것은 언어가주의 깊게 따르는 원칙 중 하나입니다. 표현식 c = a / b에는 a / b해당 하위 표현식 외부의 모든 항목과 독립적으로 해석되는 독립 하위 표현식이 포함됩니다. 언어는 나중에 결과를 double. a / b정수 나눗셈입니다. 다른 것은 중요하지 않습니다. 이 원칙은 언어 사양의 많은 부분에서 따를 것입니다. 이것이 C ++ (및 C)가 작동하는 방식을 결정합니다.

위에서 언급 한 예외의 한 예는 함수 오버로딩이있는 상황에서 함수 포인터 할당 / 초기화입니다.

void foo(int);
void foo(double);

void (*p)(double) = &foo; // automatically selects `foo(fouble)`

이것은 할당 / 초기화의 왼쪽이 오른쪽의 동작에 영향을 미치는 하나의 컨텍스트입니다. (또한 배열 참조 초기화는 유사한 동작의 또 다른 예인 배열 유형 붕괴를 방지합니다.) 다른 모든 경우에 오른쪽은 왼쪽을 완전히 무시합니다.


이것은 기술적으로 언어에 따라 다르지만 거의 모든 언어가이 주제를 동일하게 취급합니다. 표현식의 두 데이터 유형간에 유형 불일치가있는 경우 대부분의 언어는 =사전 정의 된 규칙 세트에 따라의 한쪽에있는 데이터를 다른쪽에있는 데이터와 일치 시키려고합니다 .

동일한 유형 (정수, double 등)의 두 숫자를 나눌 때 결과는 항상 동일한 유형이됩니다 (따라서 'int / int'는 항상 int가됩니다).

이 경우 분수 데이터가 이미 손실 된 경우 계산 후double var = integer result 정수 결과를 double로 캐스팅합니다 . (대부분의 언어는 예외 나 오류를 발생시키지 않고 유형 부정확성을 방지하기 위해이 캐스팅을 수행합니다.)

결과를 두 배로 유지하려면 다음과 같은 상황을 만들고 싶을 것입니다. double var = double result

이를 수행하는 가장 쉬운 방법은 방정식의 오른쪽에있는 표현식을 강제로 이중으로 변환하는 것입니다.

c = a/(double)b

정수와 double을 나누면 정수가 double로 캐스트됩니다 (수학을 수행 할 때 컴파일러는 종종 데이터 손실을 방지하기 위해 가장 특정한 데이터 유형으로 "업 캐스트"됩니다).

After the upcast, a will wind up as a double and now you have division between two doubles. This will create the desired division and assignment.

AGAIN, please note that this is language specific (and can even be compiler specific), however almost all languages (certainly all the ones I can think of off the top of my head) treat this example identically.

참고URL : https://stackoverflow.com/questions/7571326/why-does-dividing-two-int-not-yield-the-right-value-when-assigned-to-double

반응형