음.. 뭔가 쓰려고 하니까 민망하긴 하지만 나색기 이런것도 까먹었음을 만천하에 공표하는 느낌으로다가 이제 안까먹어야지.
쓸데없이 오밤중에 새벽에 min heap을 구현하겠답시고 열심히 구현을 하다가 구현에서 이상한것도 아니고 쓸데없는것에서 이상한 것을 발견하였다.
무한대를 $2^{31}$ 로 정의하고 싶어서, 다음과 같이 define
을 했었다.
#define INF 1<<31
그래. 당연히 $1<<31$은 $2^{31}$과 계산 결과가 같다.
그럼 여기서 문제.
INF - 1 의 값으로는 어떤 것이 나올까?
자 여기서 솔직히 이미 바닥나버린 양심이지만 바닥까지 긁어 모은 양심을 걸고 아 뭐야 당연히 $2^{31}-1$ 이지! 한 사람 나오세요.
저랑 동지입니다.^^
자 정답은 $2^{31 - 1} = 2^{30}$이다. ㄴㅇㄱ
상상도 못한 정체
define
은 약간 의역(?) 코딩에서도 의역이 있었나 을 하자면 아 1<<31 맨날 쓰기 귀찮은데 INF라고 쓸게 걍! 이런 느낌이다.
따라서.. 만약
printf("%d", INF - 1);
이라고 썼을 경우, 이는
printf("%d", 1<<31 -1);
이 되는 것이다.
심지어 비트 연산자의 우선 순위보다 덧셈, 뺄셈의 우선 순위가 한 단계 더 높다. 따라서 뺄셈이 먼저 계산되기 때문에 쟤는 결국
printf("%d, 1<<30);
이 되는 것이다........
이거 모르고 이것저것 아래와 같이 출력해 보다가 INF_4
출력하고 깨달음을 얻음^^..
// #define INF 1<<31
printf("INF = %lld\nINF - 1 = %lld\n", INF, INF -1);
// #define INF_2 1<<30
printf("\nINF_2 = %lld\nINF_2 - 1 = %lld\n", INF_2, INF_2 -1);
// #define INF_3 2147483648
printf("\nINF_3 = %lld\nINF_3 - 1 = %lld\n", INF_3, INF_3 -1);
// #define INF_4 1<<3
printf("\nINF_4 = %lld\nINF_4 - 1 = %lld\n", INF_4, INF_4 -1);
/* 출력결과
INF = 2147483648
INF - 1 = 1073741824
INF_2 = 1073741824
INF_2 - 1 = 536870912
INF_3 = 2147483648
INF_3 - 1 = 2147483647
INF_4 = 8
INF_4 - 1 = 4
*/
까먹지 말아야지... 눈물주룩
아니 근데 그럼 $2^{31}$을 애초에 define 할 때 부터 쓰고 싶으면 대체 어떻게 써야 잘 썼다고 할 수 있는 것인가?
2147483648를 외우고 다닐 수도 없고.. pow 함수같은것도 못 쓸 것이고..
지나가다 아시는 분 계시면 댓글 부탁드립니다...
오늘 랩실에서 이 문제를 @mttw2820에게 물어보았다.
결과적으로는 어제 대충 깃허브에서 찾아봤던 내용으로 해결이 되었다.
#define
을 할 때, data type을 suffix로 명시하면 된다.
// signed int 1을 31만큼 left shift -> overflow
#define INF 1<<31
// unsigned int 1을 31만큼 left shift -> overflow 발생 안함
#define INF_2 1U<<31
어제
오늘 새벽에
해보면서 위의 INF
처럼 명시한 후, (INF)-1
을 해보려고 했는데 편집기 linter가 뭐라고 뭐라고 잔소리하길래 귀찮아서 안읽고 잤는데, 맽튜가 듣고 해 보더니 그거 int
범위 overflow 때문에 난 오류같다고 얘기를 해 줬다.
그래서 어제 열심히 이것저것 뒤져보다가 생각난 suffix data type을 명시해놓고 left shift를 했더니 잘 되더라.. 라는 후문.
위에서 정의한 INF_2
는 overflow같은게 발생 안해서 (INF_2)-1
이렇게 써도 뭐 문제가 없이 생각했던 대로 잘 돌아간다.
suffix data type은 매우 여러 가지의 것들이 있다.
저 대신 정리한 사람이 많으니.. 링크를 걸어두겠어요..
그럼 이만 문제 해결 끝
'잡다한 지식 > CS 베이스' 카테고리의 다른 글
[프로그래밍언어론] 객체지향 프로그래밍 언어의 특징 (0) | 2021.03.26 |
---|---|
[Data Structure] Heap (0) | 2021.03.19 |
정수 범위 무한대 입력 방법 (0) | 2021.03.19 |
[Data Structure] Priority Queue (우선순위 큐) (0) | 2021.03.19 |
row-major (행 우선), column-major(열 우선)가 왜 중요한가? (1) | 2021.03.19 |