본문 바로가기
컴퓨터/C,C++

[C언어 기초] 범위를 넘어가는 수를 저장할때 주의할것 (int 의 합이 long long인경우)

by IT황구 2021. 1. 20.
728x90
반응형

아.. 이거 제목을 어떻게 지을지 너무 고민했다.

아니 이거를 어떻게 설명하지 ...

int a, int b 의 합이 long long 인 경우에

#include<cstdio>
typedef long long ll;
int main()
{
	ll sum;
	int a = 1111111111;
	int b = 1111111111;
	sum = a+b;
	printf("%lld",sum);
 } 

이건 오류가 난다. 왜일까?

분명 범위내에 들어가는 수를 저장한 a와 b를 더해서 그걸 바로 long long에다가 옮겨준것인데..

이걸 인터넷에 어떻게 검색해야할지 몰라서 그냥 직접 까봤다.

리눅스에서

gcc file.c -S -o file.S 를 하면 assembly 코드를 볼 수 있다.

vim file.S 로 파일을 열어보면 인텔 x86-64 아키텍처같은 ..

코드가 나온다.

*참고 : movl 옆에 쓴 a와 b는 스택에 넣었따는 뜻이다. edx 와 eax가 실질적인 변수 레지스터가 된다.

1. a와 b에 값이 할당된다. 앞이 e로 시작하는 레지스터는 32bit 이므로 a와 b 란걸 알 수 있다.

2. 두개를 더하는데 , sum = a+b가 아니고 b = a+b를 먼저 한다. 따라서 여기서 이미 범위를 초과한 값이 저장된다.

3. convert double to quad word 에서 그걸 32bit에서 64bit으로 늘려준다.

movq가 두번이 있는데 내 생각에 값이 큰건 스택으로 옮겼다가 다시 빼는것 같다. (기억이 가물가물 함 복습을 안해서)

위에 11억또한 스택으로 넣었다가 다시 move double 을 보면 알 수 있다.

아무튼!!

4. moveq %rax , %rsi 에서

sum = b (a+b를 한 값) 이 일어나는데...

이러니 쓰레기값이 나올 수 밖에 없다.

====올바르게 long long a, long long b로 한 경우

보면 코드가 똑같다. 64비트로 변환하는 과정이 없을뿐이다.

이미 64비트 연산이라서 오버플로우가 날 일도 없다.

===결론

sum = a + b는 우리 눈에는 이상 없어보이지만

컴퓨터는 a+b를 a나 b에 담아뒀다가 그걸 나중에 옮겨서 sum으로 가져간다.

처음에 배우면서 이거 언제 써먹지 했는데

요번에 좀 요긴하게 써먹었다. 역시 수업을 하는 이유가 다 있는것 같다.

이제 안까먹을듯!!

이만..

 

728x90
반응형