DEMO.DESIGN
Frequently Asked Questions
 
оглавление | demo party в ex-СССР | infused bytes e-mag | новости от ib/news | другие проекты | письмо | win koi lat

следующий фpагмент (2)
Вычисления с фиксиpованной точкой. A good example should explain this. Say you are working on a machine with 32-bit registers (or using a language that has 32-bit integers) and you want to use these 32 bits to represent approximations to real numbers. Depending on the magnitude and desired precision of the numbers you are using you dedicate a certain number of the low order bits to storing the "fractional" portion of the number and the remaining high order bits to the "whole" portion of the number. Say you wish to use 16 bits for fractional part and 16 bits for the whole part. What you actually store for the number f is f*2^16 rounded to the nearest integer. For instance PI would be stored as round(3.14159... * 2^16) = 205887 = 3243F (base 16) 0000 0000 0000 0011 0010 0100 0011 1111 ------------------- ------------------- | |_______ fraction (0.14159...) |_____ whole (3) Now you can use all the integer operators that are supplied to perform your fixed point arithmetic, making observations like the following: a*2^16 + b*2^16 = (a + b)*2^16 (add two fixed points) i * a*2^16 = (i*a)*2^16 (integer times fixed point) a*2^16 x b*2^16 = (a*b)*2^32 (multiply two fixed points -- watch for overflow!) sqrt(a*2^16) = sqrt(a)*2^8 (square root of fixed point) etc... Fixed point is perfect for certain problems (e.g. I implemented an entire rasterization library and fixed point arithmetic was all I ever needed for manipulating real values; Donald Knuth rasterizes all his fonts using only fixed points -- he calls them scaled integers, which is what they are). [...] [Anton Petrusevich] Задумано под Watcom C++ 32бит. Пpи изменении BASE надо менять количество бит в q_div. === Cut === #ifndef __386__ #error "Must 386+!" #endif #include <stdlib.h> #define BASE 1024 #pragma inline_depth 200 #pragma inline_recursion on extern "C" int q_div(int,int); #pragma aux q_div= "cdq "\ "shld edx,eax,10"\ "shl eax,10"\ "idiv ebx"\ parm [eax] [ebx] modify [edx] value [eax]; class fixed { public: int data; fixed(){} fixed(int a) { data=a*BASE; } fixed(int a,int b) { data=a*BASE+b; } fixed operator+(int a){ return fixed(a,data); } fixed operator-(int a){ return fixed(0,data-a*BASE); } fixed operator-(fixed f){ return fixed(0,data-f.data); } fixed operator+(fixed f){ return fixed(0,data+f.data); } fixed operator*(int a){ return fixed(0,data*a); } fixed operator*(fixed f){ int d,c; d=f.data%BASE; c=f.data/BASE; return fixed(0,data*c+data*d/BASE); } fixed operator/(int a){ return fixed(0,data/a); } fixed operator/(fixed f){ return fixed(0,q_div(data,f.data)); } fixed& operator+=(fixed f){ data+=f.data; return *this; } fixed& operator-=(fixed f){ data-=f.data; return *this; } fixed& operator/=(fixed f){ ldiv_t r=ldiv(data,f.data); data=r.quot*BASE+r.rem*BASE/f.data; return *this; } fixed& operator*=(fixed f){ int a,b; a=f.data/BASE;b=f.data%BASE; data=data*a+data*b/BASE; return *this; } fixed& operator+=(int a){ data+=a*BASE; return *this; } fixed& operator-=(int a){ data-=a*BASE; return *this; } fixed& operator/=(int a){ data/=a; return *this; } fixed& operator*=(int a){ data*=a; return *this; } fixed operator++(){ return *this+=1; } fixed operator++(int){ fixed a=*this; *this+=1; return a; } fixed operator--(){ return *this-=1; } fixed operator--(int){ fixed a=*this; *this-=1; return a; } friend fixed operator+(int a,fixed f){ return fixed(a,f.data); } friend fixed operator-(int a,fixed f){ return fixed(0,a*BASE-f.data); } friend fixed operator*(int a,fixed f){ return fixed(0,f.data*a); } friend fixed operator/(int a,fixed f){ ldiv_t r=ldiv(a*BASE,f.data); return fixed(r.quot,r.rem*BASE/f.data); } operator int(){ return (data+BASE/2)/BASE; } fixed& operator =(int a) { data=a*BASE; return *this; } int integer(){ return data/BASE; } int remainder(){ return data%BASE; } }; inline fixed sin(int angle) { extern s_tbl[]; angle%=360; return (angle<0)?fixed(0,-s_tbl[-angle]):fixed(0,s_tbl[angle]); } inline fixed cos(int angle) { extern c_tbl[]; angle=angle < 0 ? angle=-angle:angle; angle%=360; return fixed(0,c_tbl[angle]); } === Cut === Пpимеp использования fixed point. === Cut === #include <graph.h> #include <conio.h> #include "fixed.h" void circ(short x,short y,short rad,char col) { fixed f,rx; _setcolor(col); for (rx=0,f=rad;rx<=f;rx++ ) { int tx=int(rx),tf=int(f); _setpixel(tx+x,tf+y); _setpixel(tf+x,tx+y); _setpixel(x-tx,tf+y); _setpixel(x-tf,tx+y); _setpixel(tx+x,y-tf); _setpixel(tf+x,y-tx); _setpixel(x-tx,y-tf); _setpixel(x-tf,y-tx); f-=rx/f; } } void main() { _setvideomode(_VRES16COLOR); getch(); _ellipse(_GBORDER,120,40,520,440); getch(); circ(320,240,200,8); getch(); _setvideomode(3); } === Cut ===

Всего 1 фpагмент(а/ов) |пpедыдущий фpагмент (1)

Если вы хотите дополнить FAQ - пожалуйста пишите.

design/collection/some content by Frog,
DEMO DESIGN FAQ (C) Realm Of Illusion 1994-2000,
При перепечатке материалов этой страницы пожалуйста ссылайтесь на источник: "DEMO.DESIGN FAQ, http://www.enlight.ru/demo/faq".