2014-09-12 4 views
2

고정 소수점 환경에서 산술 연산이 어떻게 처리되는지 혼란 스럽습니다. 코드의 라인을 다음과 같은 고려 :정수 오버플로는 C에서 어떻게 작동합니까?

/* unsigned short is 16 bit.*/ 
unsigned short x = 1000; 
unsigned short res; 

/* Case1: The following yields correct result in res */ 
res = (x*544/100); 

/* Case2: The following yields wrong result in res*/ 
res = (x*544); /* expected overflow here */ 
res = res/100; 

그래서, 내 질문은 : 그 이유 경우 2 개 수율 잘못된 결과를 볼 수 있습니다. 그러나 - 올바른 결과를 얻는 경우 1에서 컴파일러는 무엇을 수행합니까? - 사례 1에서 산술 연산이 본질적으로 똑같지 않습니까? 이것을 제외하고는 두 문장으로 나뉩니다. - 다른 컴파일러에서 다른 동작을 기대할 수 있습니까?

+1

는 수학는 16 비트 짧은 놓여져 INT-크기 '변수', 아마도 이러한보다 큰 16 비트, 및 (16 비트에 맞지 않음) 후 최종 결과가 이루어되고 . 2의 경우 수학은 'int'에서 여전히 수행되지만 첫 번째 할당은 16 비트에 맞지 않으므로 res에 대한 첫 번째 할당 중에 잘게됩니다. –

답변

5

이것은 일반적인 산술 변환에 의한 곱셈의 피연산자에 적용되는 후 짧은이 계산의 목적을 위해보다 큰 정수 형태로 승격하고 짧은 변환되게 분할에 과제물

섹션의 draft C99 standard6.5.5곱하기 연산자는 말한다 :

일반적인 산술 변환이 피연산자에서 수행됩니다. 우리는 필요

또한 정수 형에게 INT이있을 것이다, 544100 상수 있습니다, 우리는 왜 질문 what are default integer values?에서에 대한 자세한 내용을 확인할 수 있습니다.

우리는 다음 6.3.1.8일반적인 산술 변환 섹션으로 이동 할 수 있고 우리가 말하는 단락에 결국 :

그렇지 않으면, 정수 프로모션은 두 피연산자에서 수행됩니다.

우리는 다음과 같은 규칙에 결국 : 그런 다음 다음과 같은 규칙이 승격 된 피연산자에 적용되는 부호있는 정수 유형 피연산자의 유형이 이 모두를 대표 할 수있는 경우,

그렇지 않으면 부호없는 정수 유형 오퍼랜드의 타입의 값은 다음의 부호없는 정수 유형 오퍼랜드는 부호있는 정수 타입 피연산자의 유형 변환된다.

warning: conversion to 'short unsigned int' from 'int' may alter its value [-Wconversion] 
res = (x*544/100); 
    ^

이 당신이 올바른을 부르는 무엇을 리드 :

그래서 계산의 결과는 -Wcoversion 플래그 gcc하지만 의외로하지 clang 경고를 생성을 사용하여 INT

입니다 첫 번째 경우에 결과는 모든 계산은 초에 INT로 수행되기 때문에 당신은 res에 다시 할당하고 값이 짧은에 맞는 값으로 변환되기 때문에 OND 경우에는 곱셈의 중간 결과를 잃게됩니다. 케이스 (1)에

-3

프로그램은 제 우측 과제 다음 양수인 계산 값 산출한다. 예에서

그것은 그렇게 res 실제로 저장할 수 할당 전에 값을 계산한다.

res = (x*544);은 큰 값을 저장할 수 없으므로 오버 플로우됩니다.

결론적으로 컴파일러를 지정하기 전에 은 공백이 아닌을 전달하면 상관하지 않습니다.

+0

임의 정밀도 산술이란? – Deduplicator

관련 문제