정수형 데이터 1이 float형으로는 어떻게 되나요?

dltkddyd의 이미지

4바이트의 정수형 데이터 1의 비트구조를 비트연산해서 구해보면 다음과 같습니다.

00000000 00000000 00000000 00000001

그리고 이를 4바이트의 실수형 float으로 해석해서 출력하면 그 값은

0.00000000000000000000001(이진수) X 2^(-127)

이 되죠(여기서 ^은 제곱승을 나타내기 위한 기호입니다.). 왜냐하면 맨 앞부터 1비트는 부호부이고, 8비트는 지수부이며, 나머지 23비트는 가수부이기 때문입니다. 부호부는 양수일 때 0이고, 지수부는 메모리상에서는 0이지만 2^(8-1)-1을 빼면 -127이죠. 그리고 가수부는 맨 끝을 1로 놓으면 위와 같은 결과로 해석이 될 겁니다. 그리고 이 값을 공학용 계산기로 계산하니

0.00000000000000000000001 X 5.877471754E-39 1번

입니다.
그러나 C++의 공용체로 1이라는 데이터를 int형 멤버와 float형 멤버로 공유해 저 위의 결과를 float형 멤버로 출력해보면

1.4013e-45 2번

입니다. 어떤 계산결과가 맞나요? 제 생각으로는 1번인데, 컴퓨터는 계속 2번이라고 하네요. 2번이라면 왜 그렇게 되는지 설명좀 부탁드립니다. 혹시 답변을 위해 소스가 필요하시다면, 올리겠습니다.

gilgil의 이미지

00000000 00000000 00000000 00000001(2진수)를 float 로 보고 분석을 하면

sign / exponent / significand
0 / 0000000 0 / 0000000 00000000 00000001

sign : 0
exponent : -127 (bias 127 빼기)
significand : 100000000000000000000001 (맨 앞에 implicit leading bit 추가)

가 되겠고, 이를 숫자로 표현을 하면

2^(-127) * 1.00000000000000000000001(b)

이것을 사람이 보기 좋게 표현을 하자면 5.87747175 × 10-39 가 되네요.

그런데 C++/Pascal에서는 다음과 같이 출력이 됩니다.

1.4013e-045 (C++)
1.40129846432482E-0045 (Delphi)

음... 4바이트 실수를 표현하는 컴파일러의 오류인가요? 음... ㅠㅠ

익명 사용자의 이미지

implicit leading bit ?? 만 없으면 1.4e-45가 나오는데요..

2^(-127)*0.000000 00000000 00000001
= 2^(-127)*(1/2)^(-22) = 2^(-149) = 1.401298464324817e-45
dltkddyd의 이미지

leading bit라는 것이 가수부의 맨 앞을 의미하는 것인가요? 그리고 그 맨 앞은 소수점 하나 앞 자리를 의미하는 비트인가요?

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

gilgil의 이미지

http://en.wikipedia.org/wiki/Single_precision_floating-point_format

exponent가 0의 값이면
(−1)signbits×2−126 * 0.significandbits 로 계산을 하고

exponent가 1~254의 값이면
(−1)signbits×2exponentbits−127 * 1.significandbits 로 계산을 하고("1."이라는 것이 implicit leading bit를 의미함)

exponent가 255의 값이면
+-infinity이거나 NaN이고.

dltkddyd의 이미지

컴파일의 버그일수도 있나요? 그러면 처음 계산한 값이 맞겠네요.

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

gilgil의 이미지

컴파일러 버그가 아니고 제 실수입니다. -_-;
제일 밑에 답글 달아 놓았음.

익명 사용자의 이미지

subnormal/denormal, gradual underflow 를 찾아보세요

gilgil의 이미지

이러한 규약이 있었군요.
http://download.oracle.com/docs/cd/E19060-01/stud8.compiler/817-0932/ncg_math.html

A. 0 < e < 255 인 경우의 value : (-1)s × 2^(-127) × 1.f (normal numbers)

B. e = 0 이고 f != 0 인 경우의 value : (-1)s × 2^(-126) × 0.f (subnormal numbers) // -127이 아니고 -126 이군요. implicit leading bit도 무시하구...

1(int)를 다시 계산해 보면(A 방식으로 계산하면 안되고 B 방식으로 계산)

sign / exponent / significand
0 / 0000000 0 / 0000000 00000000 00000001

value = 2^(-126) * 0.00000000000000000000001(b)
= 2^(-126) * 2^(-23)
= 2^(-149)
= 1.40129846 × 10-45

좋은 정보 감사. ^^

gilgil의 이미지

비줠씨뿔불, 지뿔뿔로 테스트해 봤습니다. ^^

exponent의 값이 0이냐, 255냐, 아니면 다른 값이냐에 따라서 출력을 다르게 하였습니다.

소스코드 및 실행 예제는 여기에서 --> http://www.gilgil.net/11340