<aside> 💡 오버플로우 & 언더플로우

다음 결과는 0이 출력된다

연산의 결과로 자료형보다 큰 수가 나오는 경우를 말함.
자료형의 크기는 변하지 않기 때문에 자리수를 넘은 비트는 버린다
</aside>
-언더플로우 발생<aside> 💡 오버플로우 & 언더플로우
</aside>
<aside> 💡 빼기 연산자에서, 음수를 표현할 수 없는 값 끼리 빼기를 진행하면 무슨 일이 벌어질까?
int num1 = 10;
int num2 = 30;
**uint result = (unit)num1 = (unit)num2;**
그 이유는 음수를 표현할 수 없기에 최대값보다 20이 작은 숫자가 나오는 원리임
0~100까지의 <u>**양수**</u>만 표현할 수 있는 자료형이 있다고 가정하자.
해당 값에 -1이 들어오면, 자료형은 양수만 표현할 수 있기 때문에 언더플로우가 발생하여
최대값보다 1 작은 99값이 출력됨
</aside>
<aside> 💡 2의 보수를 생각하자

<aside> 💡 근데 2의 보수 왜씀?
컴퓨터의 문제는 항상 서로다른 n개의 공간을 어떻게 2진값으로 표현할것인가에 있다
4비트 4자리 가지고 unsigned int로 4를 표현하면 0000 ~ 1111 해서 F(15) 까지 표현 가능
| 0 | 0 | 0 |
|---|---|---|
| 0 | 1 | 1 |
| 1 | 0 | 2 |
| 1 | 1 | 3 |
| 0 | 0 | +0 |
|---|---|---|
| 0 | 1 | +1 |
| 1 | 0 | |
| 1 | 1 | +1 |
→ 3개의 범위밖에 표현을 못함
→ 1110(-6) 에서 0001 을 더하면 1111(-7) 이 되는 문제가…! -5가 되어야 하는데!
→ 양수쪽에 add는 정상작동하는디, 음수쪽은 문제가 많다
-0 ’없는 수 문제’0111 (+7)
1000 (-7)
→ 1000 (-7) 에서 0001 (+1) 을 더하면 1001(-6) 오 잘 작동한다!
→ 하지만, 1110(-1) 에서 0001(+1)을 더하면, 1111(-0) 엥? 뭐냐 이거?
→ 1110(-1) 에서 +1 을 해서 +0이 되어야 하는데, 실제 갭은 +2 를 해야하는 문제가 있다.
→ -1 과 +0 사이에 존재하지 않는 수인 -0이 존재하여 오류가 존재함. 이 문제를 해결하기 위해 2의 보수법이 등장함
왜 2의 보수에선 값을 뒤집고 1을 더할까?
→ 0000을 뒤집으면 1111이 됨. 여기서 1을 더하면 다시 0000이 됨
→ 0001 을 뒤집으면 1110 이 됨. 여기서 1을 더하면 1111이 됨
→ 1과 +0 사이에 갭이 하나만 벌어진다
(1의 보수에선 2개가 벌어져서 문제가 있었음)
2의 보수법 4bit로 표현할 수 있는 범위는 +7 ~ -7 즉 15가지인가..?
그냥 Unsigned로 표현하면 16가지인데 2의 보수법이 15개면 이것도 1의보수랑 다를바없는거 아니냐?
→ NO!!! 2의 보수법에서는 1의 보수와 달리 -0이라는 값이 없기때문에, 값을 하나 더 사용할 수 있는데, 1000 값을 사용할 수 있어 +7 ~ -8 범위까지 표현 가능!
그리고 그냥 더하기(full adder) 써도 값이 멀~쩡함 ㅋㅋ
음수가 없는 양수로 보면 1110 은 12지만,
음수가 있는 양수로 보면 1110 은 -2 다…
</aside>

다음 설명을 도표로 정리하면 다음과 같다
</aside>
#include <stdio.h>
int main(){
int a = 1;
//! 다양한 음수 표현 방법
printf("%d\n",a);
printf("%d\n",-a); //이래도 0는 표시되지만,
printf("%d\n",~a+1); //2의 보수로 포현하여 음수를 표현할 수 있다
//~NOT으로 1의부호를 먼저 만들고 1을 더한것이다
//! 비트부호연산자로구현
for (int i = 0; i < 5; i++)
printf(" %d ",a<<i);
return 0;
}
#include <stdio.h>
int main(){
//!1바이트인 char를 사용하여서 두 값을더해보자
char a = 98;
char b = 74;
char sum = a+b;
//172가 나와야하는데... 1바이트로 쓰니 왜 값이 이상하게 나올까?
printf("%d\n",sum);
/*
0110 0010
+ 0100 1010
1010 1100
(오버 플로우 상태 68p 확인)
앞에 부호가 1이기 때문에, 제대로된 값이 나올 수없다
-> 적절한 자료형을 쓰지 않으면 이러한 문제를 야기할수 있음
엄청나게 큰 수를 더하면 오버플로우 문제가 생기겠지?
항상 오버플로우 체크할 필요가 없다 부호가 다르면 ((-) + (+) or (+) + (-)) 오버플로우가 발생할가능성이 낮아지니까
*/
return 0;
}