알고리즘 문제를 풀면서 가끔 어이없는 실수로 인해 시간을 날리기 쉽다. 그 중 내가 가장 많이 했던 실수는 자료형 계산이다. 오류가 뜨진 않지만 값이 달라서 더 짜증나는 실수다. 그래서 가장 많이 하는 실수들의 사례를 가지고 왔다.
1. 예시
#include <bits/stdc++.h>
using namespace std;
const int INF = 21e8;
const long long int INF2 = 21e8;
const float f = 3.56789123;
#define ll long long int
int main()
{
ll a = INF + INF;
ll b = INF + INF2;
printf("%lld\n%lld\n",a, b);
printf("%f, %.5f, %.4f, %d, %d, %f, %f, %llf", f, f, f, f, (int)f, 100000000 + f, (int)100 + f, 100000000 + (double)f);
}
2. 이유
첫 번째로 long long int = int + int이다. 이 때 좌변은 long long int지만 우변의 경우 int범위에서 21억 + 21억을 계산하므로 int범위를 넘어서서 적용된다. 그 다음 줄에서 INF + INF2를 하면 괜찮아 진다. 이를 통해서 아래와 같은 사실을 알 수 있다.
int, long long int, float, double... 등 자료형을 통해 선언하면 정해진 메모리로 변수가 생성된다.
따라서 int + long long int가 된다면 더 큰 영역인 long long int로 확장된다. 하지만 int + int로 범위를 초과하면 음수가 되며 (4비트)(int가르켰던 4비트) 꼴로 long long int가 작동한다.
이러한 현상은 정수와 실수의 연산에서도 일어나는 데, 정수에 실수를 더했음에도 정상적으로 작동하는 것과 안되는 것을 알 수 있다. 그 이유 또한 위의 설명과 같다. 소숫점 아래의 숫자들도 공간을 차지하는 데 연산할 때 그 공간이 충분치 않아 정상적으로 일어나지 않는 것이다. 하지만 공간이 괜찮다면 계산이 정상적으로 일어나는 것을 볼 수 있다.
※ 소수의 경우 부호 비트 / 지수부(정수) / 가수부(소숫점) 으로 나뉜다.
여담으로 float형을 (int)로 하면 버림이고 %.0f하면 반올림이다.
다음 포스팅은 자료의 저장과 보수, 부동소수점에 대해 다뤄보고자 한다.
'코딩 > C, C++' 카테고리의 다른 글
[자료구조] Ordered Linked List 구현하기 (0) | 2024.10.18 |
---|---|
[자료구조] 포인터와 동적 할당, 자료구조 입문하기! (with c언어) (0) | 2024.10.18 |
[C/C++] 자료형의 프로모션(실수 방지!) (0) | 2024.07.10 |
[C/C++] 포인터 완벽 이해 ( 포인터, 배열, 상수, 다중포인터 ) (0) | 2024.06.02 |
[C/C++] 부동소수점 - 컴퓨터는 정확하다며... (0) | 2024.03.30 |