2012년 3월 17일 토요일

부동소수점

부동소숫점이란 소숫점의 위치가 고정되어 있지 않고 떠 다닌다는 의미입니다. 다음과 같이 말이죠.

3.14 == 0.314*10 == 314./100
4 바이트(32 비트) 실수인 float 형을 기준으로 실수 표현을 설명합니다.

32 비트 중,
첫번째 1 비트(±)는 부호를 나타내고,
그 다음 8 비트(e)는 지수를 나타내는데, 실제 지수에 127을 더한 값으로 표현합니다.
나머지 23 비트(m)는 1.??? 다음의 수소 자리를 나타냅니다.


±
e
m
0
00000000
00000000000000000000000000000


e-127
±1.m * 2


3.5
= 3 + 0.5
= 112 + 0.12 = 11.12

정규화하면,
= 1.112 * 2^1
= +1.112 * 2^(100000002-011111112)
± : 0 (+)
e : 100000002 (128)
m : 112 (0.5+0.25)
=> 0 10000000 11000000000000000000000

결국
3.5 = 1.75 * 2 = (1+0.75 )*2 = (1.+0.5+0.25)*2 = 1.112 * 2
/**

2.3 = 2 + 1/4 + 1/8 + 1/32 + 1/64 + 1/ 512 + 1/1024...

= 10.0100110011001100110011(2)

정규화(1.???로 만들기)하면,

1.00100110011001100110011(2) * 2^1

± = 0(+)
e = 100 0000 0(2) = 128
m = 001 0011 0011 0011 0011 0011(2)

--------------------------------------------------
= 0100 0000 0001 0011 0011 0011 0011 0011(2)
= 4 0 1 3 3 3 3 3(16)*/

#include <stdio.h>

union F {
float f;
struct {
unsigned m:23;
unsigned e:8;
unsigned s:1;
};
char c[4];
};

void printb(float f)
{
unsigned *d = (unsigned*)&f;
int i;

for(i=0; i < 32; i++) {
putchar((*d&0x80000000)?'1':'0');
*d <<= 1;
}
putchar('\n');
}

int main()
{
union F v;
v.f = 2.3F;

printb(v.f);
printf("%d %d %d\n",v.s,v.e,v.m);
printf("%2x %2x %2x %2x\n",v.c[3],v.c[2],v.c[1],v.c[0]); // little-endian
}


댓글 없음:

댓글 쓰기