/[projet1]/users/mmu_man/demos/viendez/fpmath_16_16.h
Defence Force logotype

Contents of /users/mmu_man/demos/viendez/fpmath_16_16.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 862 - (show annotations)
Fri Sep 21 10:08:26 2012 UTC (7 years, 8 months ago) by mmu_man
File MIME type: text/plain
File size: 3897 byte(s)
Add sources for my 'viendez' microAlchimie2 invitro released at VIP2012.

1 // C Header File
2 // Created 20/08/2007; 02:24:15
3
4 #if defined(__GNU_C__) || defined(__TIGCC_ENV__)
5 #define _A_PACKED __attribute__ ((packed))
6 #else
7 #define _A_PACKED
8 #endif
9
10 typedef union {
11 struct {
12 int16 m; // magnitude (integral) part
13 uint16 f; //fractional part
14 };
15 int32 data;
16 } fpfloat _A_PACKED;
17 typedef int32 _fp_full_t;
18
19 extern void __fp_init(void);
20
21 #define COS_TABLE_SH (8)
22 #define COS_TABLE_SZ (1<<COS_TABLE_SH)
23 // stuff the cos and sin tables together
24 #define COSSIN_TABLE_SZ (COS_TABLE_SZ + COS_TABLE_SZ / 4)
25 extern fpfloat __fp_sin_table[COSSIN_TABLE_SZ];
26 extern fpfloat *__fp_cos_table;
27
28 #define FPINLINE static inline
29
30 #define NO64 1
31
32
33
34 //#define FPPI ((fpfloat){(int32)(PI * (float)((int32)1 << 16))})
35 #define FPPI ((fpfloat)(int32)(M_PI * (float)(((int32)1) << 16)))
36 #define FPHALF_PI ((fpfloat)(int32)(M_PI_2 * (float)(((int32)1) << 16)))
37 #define FPTWO_PI ((fpfloat)(int32)(2 * M_PI * (float)(((int32)1) << 16)))
38 #define FPZERO ((fpfloat){{(int16)0,(int16)0}})
39 #define FPONE ((fpfloat){{(int16)1,(int16)0}})
40
41
42 FPINLINE int fp_to_int(fpfloat f)
43 {
44 return f.m;
45 }
46
47 FPINLINE fpfloat int_to_fp(int i)
48 {
49 fpfloat f = {{i, 0}};
50 return f;
51 }
52
53 #define fp_to_float(f) ((float)(f.data) / (float)((int32)1 << 16))
54 #define float_to_fp(f) ((fpfloat)(int32)(f * (float)((int32)1 << 16)))
55
56 #define fplt(a,b) ((a).data<(b).data)
57 #define fple(a,b) ((a).data<=(b).data)
58 #define fpgt(a,b) ((a).data>(b).data)
59 #define fpge(a,b) ((a).data>=(b).data)
60 #define fpeq(a,b) ((a).data==(b).data)
61 #define fpne(a,b) ((a).data!=(b).data)
62
63 FPINLINE fpfloat fpadd(fpfloat a, fpfloat b)
64 {
65 //return (fpfloat) ( (*(int32*)&a) + (*(int32*)&b) );
66 return (fpfloat) ( (a.data) + (b.data) );
67 }
68
69 FPINLINE fpfloat fpaddi(fpfloat a, int b)
70 {
71 a.m += b;
72 return (a);
73 }
74
75 FPINLINE fpfloat fpsub(fpfloat a, fpfloat b)
76 {
77 return (fpfloat) ( (a.data) - (b.data) );
78 }
79
80 FPINLINE fpfloat fpmul(fpfloat a, fpfloat b)
81 {
82 #ifndef NO64
83 int64 big = (int64)a.data * (int64)b.data;
84 fpfloat ret;
85 ret.data = big >> 16;
86 #else
87 fpfloat ret;
88 // it's wrong...
89 ret.data = (a.data >> 8) * (b.data >> 8);
90 #endif
91 /* if (big > 0)
92 ret.data = big >> 16;
93 else
94 ret.data = -((-big) >> 16);*/
95 //XXX
96 return ret;
97 }
98
99 FPINLINE fpfloat fpdiv(fpfloat a, fpfloat b)
100 {
101 fpfloat ret;
102 int64 big;
103 if (fpeq(b, FPZERO))
104 return a;
105 big = (((int64)a.data) << 16) / (int64)b.data;
106 ret.data = big;
107 /* if (big > 0)
108 ret.data = big >> 16;
109 else
110 ret.data = -((-big) >> 16);*/
111 //XXX
112 return ret;
113 }
114
115 FPINLINE fpfloat fpcos(fpfloat a)
116 {
117 int index;
118 //a.data %= v.data; // restrict to 2*pi
119 /*while (fpge(a, FPTWO_PI))
120 a = fpsub(a, FPTWO_PI);
121 while (fplt(a, FPZERO))
122 a = fpadd(a, FPTWO_PI);*/
123 //a.data = a.data % (uint32)v.data;// -- doesn't seem to work !?
124 //index = a.data * (COS_TABLE_SZ) / v.data;
125 index = (a.data << COS_TABLE_SH) / (FPTWO_PI).data;
126 index &= ((1<<COS_TABLE_SH)-1);
127 // safety
128 ASSERTF(index >= 0, "%d", index);
129 ASSERTF(index < COS_TABLE_SZ, "%d", index);
130 //index = min(COS_TABLE_SZ, index);
131 //index = max(0, index);
132 return __fp_cos_table[index];
133 }
134
135 FPINLINE fpfloat fpsin(fpfloat a)
136 {
137 //return fpcos(fpsub(FPHALF_PI, a));
138 //fpfloat v = FPTWO_PI;
139 int index;
140 //index = ((FPHALF_PI).data - a.data) * (COS_TABLE_SZ) / (FPTWO_PI).data;
141 index = (a.data << (COS_TABLE_SH)) / (FPTWO_PI).data;
142 index &= ((1<<COS_TABLE_SH)-1);
143 // safety
144 ASSERTF(index >= 0, "%d", index);
145 ASSERTF(index < COS_TABLE_SZ, "%d", index);
146 //index = min(COS_TABLE_SZ, index);
147 //index = max(0, index);
148 return __fp_sin_table[index];
149 }
150
151 // faster trigo for integer angle:
152 // 0 -> 0 rad; 256 -> 2PI rad
153 FPINLINE fpfloat fpcosB(int a)
154 {
155 return __fp_cos_table[a & ((1<<COS_TABLE_SH)-1)];
156 }
157
158 FPINLINE fpfloat fpsinB(int a)
159 {
160 return __fp_sin_table[a & ((1<<COS_TABLE_SH)-1)];
161 }
162

  ViewVC Help
Powered by ViewVC 1.1.26