알고리즘 문제를 풀거나 프로그램을 작성하다 보면 특정 데이터 타입이 표현할 수 있는 최솟값 또는 최댓값을 직접 사용해야 하는 경우가 종종 있습니다. 하지만 이렇게 큰 숫자들을 일일이 암기하는 것은 매우 어렵습니다. 이를 위해 C++에서는 각 데이터 타입의 최소·최대 범위를 나타내는 매크로를 제공하고 있습니다. 다만 부호 없는(unsigned) 타입은 최솟값이 항상 0이므로 별도의 최솟값 매크로가 존재하지 않습니다.
C++ 데이터 타입별 범위 및 매크로
| 데이터 타입 | 범위 | 최솟값 매크로 | 최댓값 매크로 |
|---|---|---|---|
| char | -128 ~ +127 | CHAR_MIN | CHAR_MAX |
| signed char | -128 ~ +127 | SCHAR_MIN | SCHAR_MAX |
| unsigned char | 0 ~ 255 | ----- | UCHAR_MAX |
| short int | -32768 ~ +32767 | SHRT_MIN | SHRT_MAX |
| unsigned short int | 0 ~ 65535 | ----- | USHRT_MAX |
| int | -2147483648 ~ +2147483647 | INT_MIN | INT_MAX |
| unsigned int | 0 ~ 4294967295 | ----- | UINT_MAX |
| long int | -2147483648 ~ +2147483647 | LONG_MIN | LONG_MAX |
| unsigned long int | 0 ~ 18446744073709551615 | ----- | ULONG_MAX |
| long long int | -9223372036854775808 ~ +9223372036854775807 | LLONG_MIN | LLONG_MAX |
| unsigned long long int | 0 ~ 18446744073709551615 | ----- | ULLONG_MAX |
| float | 1.17549e-38 ~ 3.40282e+38 | FLT_MIN | FLT_MAX |
| float(음수) | -1.17549e-38 ~ -3.40282e+38 | -FLT_MIN | -FLT_MAX |
| double | 2.22507e-308 ~ 1.79769e+308 | DBL_MIN | DBL_MAX |
| double(음수) | -2.22507e-308 ~ -1.79769e+308 | -DBL_MIN | -DBL_MAX |
정수 계열 타입의 매크로는 <limits.h>(C++ 스타일 헤더는 <climits>)에, 실수 계열 타입의 매크로는 <float.h>(C++ 스타일 헤더는 <cfloat>)에 정의되어 있습니다. 참고로 위 표의 범위는 일반적인 32비트/64비트 환경 기준이며, 운영체제나 컴파일러에 따라 long 계열 타입의 실제 크기는 달라질 수 있습니다.
또 한 가지 주의할 점은 실수 타입의 FLT_MIN과 DBL_MIN이 '가장 작은(음의 큰) 값'이 아니라 '표현 가능한 가장 작은 양수'를 의미한다는 것입니다. 따라서 음수 영역의 경계값이 필요할 때는 -FLT_MIN, -DBL_MIN 형태로 활용해야 합니다.
예제 코드
#include<iostream>
#include<limits.h> // 정수·문자 계열 매크로
#include<float.h> // 실수(float, double) 계열 매크로
using namespace std;
int main() {
cout << "char Range: (" << CHAR_MIN <<", " <<CHAR_MAX << ")\n";
cout << "short char Range: (" << SCHAR_MIN <<", " <<SCHAR_MAX << ")\n";
cout << "unsigned char Range: (" << 0 <<", " <<UCHAR_MAX << ")\n";
cout << "short int Range: (" << SHRT_MIN <<", " <<SHRT_MAX << ")\n";
cout << "unsigned short int Range: (" << 0 <<", " <<USHRT_MAX << ")\n";
cout << "int Range: (" << INT_MIN <<", " <<INT_MAX << ")\n";
cout << "unsigned int Range: (" << 0 <<", " <<UINT_MAX << ")\n";
cout << "long int Range: (" << LONG_MIN <<", " <<LONG_MAX << ")\n";
cout << "unsigned long int Range: (" << 0 <<", " <<ULONG_MAX << ")\n";
cout << "long long int Range: (" << LLONG_MIN <<", " <<LLONG_MAX << ")\n";
cout << "unsigned long long int Range: (" << 0 <<", " <<ULLONG_MAX << ")\n";
cout << "float Range: (" << FLT_MIN <<", " <<FLT_MAX << ")\n";
cout << "float(negative) Range: (" << -FLT_MIN <<", " <<-FLT_MAX << ")\n";
cout << "double Range: (" << DBL_MIN <<", " <<DBL_MAX << ")\n";
cout << "double(negative) Range: (" << -DBL_MIN <<", " <<-DBL_MAX << ")";
}
실행 결과
char Range: (-128, 127)
short char Range: (-128, 127)
unsigned char Range: (0, 255)
short int Range: (-32768, 32767)
unsigned short int Range: (0, 65535)
int Range: (-2147483648, 2147483647)
unsigned int Range: (0, 4294967295)
long int Range: (-2147483648, 2147483647)
unsigned long int Range: (0, 4294967295)
long long int Range: (-9223372036854775808, 9223372036854775807)
unsigned long long int Range: (0, 18446744073709551615)
float Range: (1.17549e-038, 3.40282e+038)
float(negative) Range: (-1.17549e-038, -3.40282e+038)
double Range: (2.22507e-308, 1.79769e+308)
double(negative) Range: (-2.22507e-308, -1.79769e+308)
이처럼 표준 매크로를 활용하면 각 데이터 타입의 표현 범위를 손쉽게 확인할 수 있습니다. 변수 초기화 시 극단값 설정, 오버플로우 방지 조건 검사, 알고리즘 문제에서의 초기 최솟값·최댓값 지정 등 다양한 상황에서 유용하게 사용할 수 있으니, 숫자를 직접 하드코딩하기보다 매크로를 사용하는 습관을 들이는 것이 좋습니다.