#include <iostream>
using namespace std;

static const int fix_factor = 4096; // 2의 12승
static const int fix_shift = 12; // 쉬프트 값

int main()
{
 // 부동 -> 고정
 double a = 3.245;
 int fix_a = (int)(a*fix_factor);

 // 정수 -> 고정소수
 int b = 10;
 int fix_b = b << fix_shift;

 // 고정소수 -> 부동소수
 double c = (double)fix_a / fix_factor;

 // 고정소수 -> 정수로
 int d = fix_b >> fix_shift;

 printf(" a(3.245) = %d(0x%8X)\n b(10) = %d(0x%8X)\n c(double) = %f(0x%8X)\n d(고정소수를 정수변환) = %d(0x%8X)\n",a,a,b,b,c,c,d,d);

 // 덧셈, 뺄셈
 int plus = fix_a + fix_b;
 int minus = fix_a - fix_b;

 // 곱셈
 int multi = (fix_a * fix_b) >> fix_shift;

 // 나눗셈
 int div = (fix_a << fix_shift) / fix_b;

 printf("\n고정소수점 %d(%0.3f)와 %d(%d)끼리의 연산\n", fix_a, a, fix_b, b);
 printf("+ : %d, - : %d, * : %d, / : %d\n", plus, minus, multi, div);

 printf("fix_factor 만큼 나누기\n");
 printf("+ : %d, - : %d, * : %d, / : %d\n",
  plus / fix_factor , minus / fix_factor, multi / fix_factor, div / fix_factor);

 printf("fix_shiht 만큼 밀기\n");
 printf("+ : %d, - : %d, * : %d, / : %d\n",
  plus >> fix_shift , minus >> fix_shift, multi >> fix_shift, div >> fix_shift);
}

그러니까 32비트열에
xxxxxxxxxxxx.oooooooooooooooooooo
과 같이 임의 의 소수점을 찍어서 거기에 숫자 넣어서 처음부터 계산하는게 아니고

float 나 double 값을 곱셈해서 쉬프트를 시킨후 계산만 정수 연산부를 사용하는 것임.
대부분 cpu는... 정수 연산이 부동 소수점 연산보다 빠르니.. 이게 좋을꺼 같다.

만약, 아예 비트를 쪼개서 정수부, 소수부로 나누어서 계산하고 싶다면..
typedef unsigned int fint;
typedef unsigned char u8;
typedef unsigned short u16;

#define make_fint(i,f)  (fint)(f | i << 20)   // int를 부동소수점 마냥 쓰기
#define get_int(i)   (fint)(i >> 20)    // 정수부분 가져오기
#define get_float(f)  (fint)((f << 12) >> 12)  // 소수점 아래 부분 가져오기
#define get_upper(a)  (fint)(a >> 20)    // 소수점끼리 연산으로 정수로 올라온 숫자 가져오기

이렇게 하고.. 각각 연산에 적당한 함수를 만들어준뒤, 그 함수를 통해서 연산을 해야 할것이다.
이건.. 좀 빡센듯;;

'C/C++언어' 카테고리의 다른 글

LEX & YACC  (0) 2008.06.07
Lex와 Yacc의 사용법 강좌  (0) 2008.06.07
코드 최적화  (0) 2008.05.09
[알고리즘]고정소수점(fixed point) 연산  (0) 2008.05.09
음 고정소수점 만들기..  (0) 2008.05.09

+ Recent posts