61 inline s32 fixmulf(s32 a, s32 b)
69 inline s32 fixmul(s32 a, s32 b)
71 return (s32)(((int64_t)a * b) >> p);
76 inline int fixdiv(s32 a, s32 b)
79 return (s32)((((s64)a) << p) / b);
92 x.halves.h = a >> (
sizeof(s32) * 8 - p);
93 return (s32)(x.a / b);
98 inline u32 CountLeadingZeros(u32 x)
102 if (x & 0xffff0000) {
133 inline int fixinv(s32 a)
144 static const uint16_t rcp_tab[] = {
145 0x8000, 0x71c7, 0x6666, 0x5d17, 0x5555, 0x4ec4, 0x4924, 0x4444
148 s32 exp = detail::CountLeadingZeros(a);
149 x = ((s32)rcp_tab[(a>>(28-exp))&0x7]) << 2;
158 x = fixmul<(32-q)>(x,((2<<(32-q)) - fixmul<q>(a,x)));
159 x = fixmul<(32-q)>(x,((2<<(32-q)) - fixmul<q>(a,x)));
170 float fix2float(s32 f)
172 return (
float)f / (1 << p);
176 s32 float2fix(
float f)
178 return (s32)(f * (1 << p));
183 s32 fixrsqrt16(s32 a);
184 s32 fixsqrt16(s32 a);
193 FXP() : intValue(0) {}
194 FXP(u32 i) : intValue(i << p) {}
195 FXP(s32 i) : intValue(i << p) {}
196 FXP(
float f) : intValue(float2fix<p>(f)) {}
197 FXP(
double f) : intValue(float2fix<p>((
float)f)) {}
199 FXP& operator += (
FXP r) { intValue += r.intValue;
return *
this; }
200 FXP& operator -= (
FXP r) { intValue -= r.intValue;
return *
this; }
201 FXP& operator *= (
FXP r) { intValue = fixmul<p>(intValue, r.intValue);
return *
this; }
202 FXP& operator /= (
FXP r) { intValue = fixdiv<p>(intValue, r.intValue);
return *
this; }
204 FXP& operator ++ () { *
this += 1;
return *
this; }
205 FXP operator ++ (
int) {
const FXP val = *
this; ++ *
this;
return val; }
207 FXP& operator -- () { *
this -= 1;
return *
this; }
208 FXP operator -- (
int) {
const FXP val = *
this; -- *
this;
return val; }
210 FXP& operator *= (s32 r) { intValue *= r;
return *
this; }
211 FXP& operator /= (s32 r) { intValue /= r;
return *
this; }
213 FXP operator - ()
const {
FXP x; x.intValue = -intValue;
return x; }
214 FXP operator + (
FXP r)
const {
FXP x = *
this; x += r;
return x;}
215 FXP operator - (
FXP r)
const {
FXP x = *
this; x -= r;
return x;}
216 FXP operator * (
FXP r)
const {
FXP x = *
this; x *= r;
return x;}
217 FXP operator / (
FXP r)
const {
FXP x = *
this; x /= r;
return x;}
219 bool operator == (
FXP r)
const {
return intValue == r.intValue; }
220 bool operator != (
FXP r)
const {
return !(*
this == r); }
221 bool operator < (
FXP r)
const {
return intValue < r.intValue; }
222 bool operator > (
FXP r)
const {
return intValue > r.intValue; }
223 bool operator <= (
FXP r)
const {
return intValue <= r.intValue; }
224 bool operator >= (
FXP r)
const {
return intValue >= r.intValue; }
226 FXP operator + (s32 r)
const {
FXP x = *
this; x += r;
return x;}
227 FXP operator - (s32 r)
const {
FXP x = *
this; x -= r;
return x;}
228 FXP operator * (s32 r)
const {
FXP x = *
this; x *= r;
return x;}
229 FXP operator / (s32 r)
const {
FXP x = *
this; x /= r;
return x;}
231 s32 asInt()
const {
return intValue; }
232 float toFloat()
const {
return fix2float<p>(intValue); }
233 double toDouble()
const {
return (
double) fix2float<p>(intValue); }
236 void Print(FILE * f) {
241 }
else val = intValue;
242 fprintf(f,
"%d.", val >> p);
243 for (
int i = 0; i <
"011122233344445556667777888999:::"[p]-
'0'; ++i) {
246 fputc((val>>p)+
'0',f);
261 inline FXP<p> operator - (s32 a, FXP<p> b)
265 inline FXP<p> operator * (s32 a, FXP<p> b)
269 inline FXP<p> operator / (s32 a, FXP<p> b)
270 { FXP<p> r(a); r /= b;
return r; }
276 inline FXP<p> Sin(FXP<p> a);
279 inline FXP<p> Cos(FXP<p> a);
282 inline FXP<p> Sqrt(FXP<p> a);
285 inline FXP<p> Rsqrt(FXP<p> a);
288 inline FXP<p> Inv(FXP<p> a);
291 inline FXP<p> Abs(FXP<p> a)
294 r.intValue = a.intValue > 0 ? a.intValue : -a.intValue;
301 inline FXP<16> Sin(FXP<16> a)
304 r.intValue = fixsin16(a.intValue);
309 inline FXP<16> Cos(FXP<16> a)
312 r.intValue = fixcos16(a.intValue);
318 inline FXP<16> Sqrt(FXP<16> a)
321 r.intValue = fixsqrt16(a.intValue);
326 inline FXP<16> Rsqrt(FXP<16> a)
329 r.intValue = fixrsqrt16(a.intValue);
334 inline FXP<16> Inv(FXP<16> a)
337 r.intValue = fixinv<16>(a.intValue);
343 inline FXP<p> multiply_accumulate(
349 for (
int i = 0; i < count; ++i)
350 result += static_cast<s64>(a[i].intValue) * b[i].intValue;
352 r.intValue =
static_cast<s32
>(result >> p);