실수형 자료형에서도 오버플로우와 언더플로우가 있는건 당연하고 그 내용도 이해했으나
왜 최소값에서 나눌때 10이 아니라
#include <stdio.h> #include <float.h> // 실수 자료형의 양수 최솟값, 최댓값이 정의된 헤더 파일 int main() { float num1 = FLT_MIN; // float의 양수 최솟값 float num2 = FLT_MAX; // float의 양수 최댓값 // float의 양수 최솟값을 100000000.0으로 나누면 아주 작은 수가 되면서 언더플로우 발생 num1 = num1 / 100000000.0f; // float의 양수 최댓값에 1000.0을 곱하면 저장할 수 있는 범위를 넘어서므로 오버플로우 발생 num2 = num2 * 1000.0f; printf("%e %e\n", num1, num2); // 0.000000e+00 inf: 실수의 언더플로우는 0 // 오버플로우는 무한대가 됨 return 0; }100000000.0f를 나눠야하나요?
그냥 예시인가 싶어서 10으로 나눠봐도 언더플로우가 일어나지 않더라구요.
오버플로우는 10만 곱해도 바로 나던데
헤더에서 정의된 값이 잘못된건가요?
아니면 비주얼 스튜디오가 표준이랑 다른 컴파일러를 사용해서 더 float 최대값이 더 낮은건가요?
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