Algorithms/C, C++

Overflow / Underflow

esmJK 2019. 10. 9. 03:07

조금 더 자세히 들어가 왜 타입 캐스팅을 잘못하면 오버플로우가 나는지에 대해 알아보도록 한다. 

 

먼저, 이진법에서 음수를 어떻게 활용하는지를 파악하는 것이 중요하다. 

2진법에서는 음수를 표현하기 위해 '보수' (complement)의 개념을 활용한다. 

 

Most Significant Bit (가장 왼쪽에 있는 비트)가 부호를 나타내기 위한 비트이다. 

 

 

5 00000101  
Signed Magnitude 10000101 

+0 과 -0 존재

10000000

00000000

1's Complement 

1의 보수

11111010 

+0과 -0 존재 

11111111

00000000

2's Complement

2의 보수

11111011

Unique Value of 0

 

 

2의 보수의 표현범위는 다음과 같다 

 

8비트 : -128 ... 127

16비트 : -32768 ... 32767

 

언더플로우가 일어날 때:

예를 들어16비트(=2바이트)에서 양수의 표현범위는 0111111111111111인데, 1을 더하면 1000000000000000(음수)이 된다. Sign Bit에 1이 있기 때문이다. 따라서 1000000000000001 (=십진수로 -32767) 이 2의 보수로 표현할 수 있는 가장 작은 음수이다. 이보다 더 작은 수를 16비트에서 다루게 되면 언더플로우가 나타난다 

 

오버플로우는 다음 예를 참고한다. 

 

8비트 2's complement 에서 127 + 1 은 128이 되지 못한다

Sign Bit 가 1이 되었으므로 더이상 양수가 아니게 된다.

 

코드를 짤 때 각 자료형이 몇 바이트를 가지는 지를 (1바이트 = 8비트) 출력해보면 다음과 같다. 잘 참고해 오버플로우나 언더플로우가 일어나지 않도록 한다.

#include <stdio.h>
#include <stdlib.h>
#include <float.h>

/* This program prints Helo World in the String */
int main(void) {
	printf("sizeof(char) is %d \n", sizeof(char));
	printf("sizeof(short) is %d \n", sizeof(short));
	printf("sizeof(int) is %d \n", sizeof(int));
	printf("sizeof(long) is %d \n", sizeof(long));
	printf("sizeof(long long ) is %d \n", sizeof(long long));
	printf("sizeof(float) is %d \n", sizeof(float));
	printf("sizeof(double) is %d \n", sizeof(double));
	printf("sizeof(long double) is %d \n", sizeof(long double));
	
	printf("int ranges from %d to %d \n", INT_MIN, INT_MAX);
	printf("double ranges from %e to %e\n", DBL_MIN, DBL_MAX);

	system("pause");
}

 

 

이제 큰 타입에서 작은 타입으로 갈 때 왜 쓰레기값이 나오는 지 알 수 있다. 예를 들어 4바이트에서 2바이트로 간다고 할 때, 데이터 손실이 날 수 있기 때문이다. 형변환과 자료형의 범위에 조금 더 익숙해지기 위해 다른 형변환 예제를 살펴보도록 한다. 

 

#include <stdio.h>
#include <stdlib.h>

int main() {

	short width;
	int height; 
	float area;
	double total;
	int length;
	short num1, num2, sum;
	
	width = (short)10;
	height = 5;
	area = 100.0F;

	total = area + width * height; //3번의 형변환 발생 
	printf("Total is %.1f\n", total);

	length = 3.14;
	printf("Length is %d.\n", length);

	length = (int)3.14;
	printf("Length is %d\n", length);

	num1 = (short)10;
	num2 = (short)20;

	printf("sizeof(num1 + num2) is %d.\n", sizeof(num1 + num2)); //Int 형의 덧셈이기 때문에 4바이트가 나옴
	printf("sizeof(a - A) is %d.\n", sizeof('a' - 'A')); 

	sum = num1 + num2;
	printf("sizeof sum is %d\n", sizeof(sum));

	system("pause");
	return 0;
}

 

'Algorithms > C, C++' 카테고리의 다른 글

C++ 자주 쓰이는 기능 요약  (0) 2021.01.06
Function  (0) 2019.10.13
Type Casting (형변환)  (0) 2019.10.05
#문법 - 전처리기  (0) 2019.08.19
#오류 - 쓰기용으로 열 수 없습니다  (0) 2019.08.19