FLT_MAX에 더해서 float에 overflow를 나게 하는 최솟값?

raymundo의 이미지

다른 곳에서 질문글을 보면서 잠깐 해봤는데 제 계산과 실제 결과가 달라서요, 딱 2배 차이가 나고 있습니다. (사실 근소한 오차는 더 있을지도)

제 계산:

1)

FLX_MAX는 7F 7F FF FF - 이건 코드로로 확인 가능

0111 1111 0111 1111 1111 1111 1111 1111

0: 부호
1111 1110: 지수(254-127 = 2^127승)
1...1(23자리): 가수

2)

부동소수점의 덧셈은, 지수를 두 수 중 큰 쪽에 맞추고(작은 쪽은 그만큼 가수의 소숫점이 이동), 그 상태에서 가수부를 더한 후, 다시 가수가 1.m 형태가 되도록 정규화

3)

따라서 구하려는 X는, 지수를 2^127에 맞췄을 때 가수가 0.000 0000 0000 0000 0000 0001 (2^-23)이 되는 값
= 2^(-23) * 2^127
= 1.0 * 2^104

따라서 저는 답이 2의 104승일 거라고 생각했는데... 실제로는 2^103만 더해도 오버플로우가 발생합니다.

#include <stdio.h>
#include <float.h>
 
int main(void)
{
    float x = FLT_MAX;
 
    printf("%g\n", x);     // 3.40282e+38
    x += 1.0141204782936E31;  // 2^103, powf( 2, 103 ) 을 해도 같은 결과
    printf("%g\n", x);    // inf
}

딱 한 자리가 달라지니 제가 저 가수 쉬프팅할 때 한 칸 잘못 세었나 싶은데 아무리 세어봐도 맞아 보이는데요.

어디서 틀렸을까요?

익명 사용자의 이미지

rounding 때문인거 같네요. IEEE754에서는 기본적으로 짝수로 반올림합니다. 다음의 코드를 보세요.

float x = powf(2, 127);  // 7f 00 00 00
x += powf(2, 103); // 7f 00 00 00
x += powf(2, 104); // 7f 00 00 01
x += powf(2, 103); // 7f 00 00 02

raymundo의 이미지

아하 그 생각을 못했네요. 감사합니다.

좋은 하루 되세요!