float 자료형은 소수부가 23비트이므로 2의 -23승보다 작은 정밀도의 값을 나타낼 수 없습니다.
정밀도의 한계 내에서 표현할 수 있는 값을 정규화된 값(normalized value)이라 합니다. 그림 8-1에 따르면 float는 더 큰 범위의 값도 표현할 수 있지만, 정밀도의 한계를 벗어나게 됩니다. 이처럼 정밀도의 한계를 벗어나는 값을 비정규화된 값, 즉 비정상 값(denormalized number or subnormal number)라고 부릅니다.
https://ko.wikipedia.org/wiki/비정상_값
유효범위를 벗어나 정밀도는 보장할 수 없지만, float 타입에서 가장 작은 값은 FLT_TRUE_MIN으로 정의되어 있습니다.
printf("%e\n", FLT_TRUE_MIN);
으로 확인할 수 있습니다.
printf("%e\n", FLT_TRUE_MIN/2.0f);
2로만 나누어도 바로 언더플로우가 발생해서 0으로 출력되는 것을 볼 수 있습니다.
따라서 FLT_MIN은 -38승, FLT_MIN_TRUE는 -45승입니다. 때문에 FLT_MIN에서 언더플로우를 발생하게 하려면 최소 8승 이상의 값으로 나누어야 합니다. 즉, 100000000 이상의 수로 나누어야 합니다. 이게 예제에서 100000000.0f로 나눈 이유입니다.
유효범위 이내이고 정밀도를 보장할 수 있는 최솟값은 FLT_MIN으로 정의되어 있습니다.
FLT_TRUE_MIN은 ANSI C11부터 지원합니다. 따라서 ANSI C11을 지원하지 않는 컴파일러에서는 FLT_TRUE_MIN을 사용할 수 없습니다. FLT_TRUE_MIN도 float.h에 정의되어 있습니다.
마찬가지로 double 타입도 DBL_TRUE_MIN이 정의되어 있습니다.
이는 컴파일러의 차이가 아니라 2진수로 수를 표시하는 컴퓨터의 구조적인 문제입니다. 따라서 이와 관련된 자세한 내용은 컴퓨터 구조에서 학습하게 됩니다.
데이비드 페터슨 교수의 책이 전 세계적으로 유명합니다.
이 책의 3장을 보시면 자세히 설명되어 있습니다.
--------------
CHAPTER 3 컴퓨터 연산
3.1 서론
3.2 덧셈과 뺄셈
3.3 곱셈
3.4 나눗셈
3.5 부동소수점
3.6 병렬성과 산술연산: 서브워드 병렬성
3.7 실례: x86의 SSE와 AVX
3.8 더 빠르게: 서브워드 병렬성과 행렬 곱셈
3.9 오류 및 함정
3.10 결론
3.11 역사적 고찰 및 참고문헌
3.12 연습문제
--------------
컴퓨터 구조는 컴퓨터 공학과 2-3학년 전공 수업으로 배우게 됩니다.
이와 같은 수 표현의 체계나 한계점은 프로그래밍 언어나 컴파일러와 관계가 없습니다. 2진수로 수를 표기하는 방식 때문에 발생하는 문제입니다.
부동소수점 표기 형식은 IEEE 754로 표준화되어 있습니다. 이에 대해서는 다음 항목을 참고하세요.
https://ko.wikipedia.org/wiki/IEEE_754