1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#ifndef __DAL_FIXED31_32_H__
27#define __DAL_FIXED31_32_H__
28
29#ifndef LLONG_MAX
30#define LLONG_MAX 9223372036854775807ll
31#endif
32#ifndef LLONG_MIN
33#define LLONG_MIN (-LLONG_MAX - 1ll)
34#endif
35
36#define FIXED31_32_BITS_PER_FRACTIONAL_PART 32
37#ifndef LLONG_MIN
38#define LLONG_MIN (1LL<<63)
39#endif
40#ifndef LLONG_MAX
41#define LLONG_MAX (-1LL>>1)
42#endif
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57struct fixed31_32 {
58 long long value;
59};
60
61
62
63
64
65
66
67static const struct fixed31_32 dc_fixpt_zero = { 0 };
68static const struct fixed31_32 dc_fixpt_epsilon = { 1LL };
69static const struct fixed31_32 dc_fixpt_half = { 0x80000000LL };
70static const struct fixed31_32 dc_fixpt_one = { 0x100000000LL };
71
72static const struct fixed31_32 dc_fixpt_pi = { 13493037705LL };
73static const struct fixed31_32 dc_fixpt_two_pi = { 26986075409LL };
74static const struct fixed31_32 dc_fixpt_e = { 11674931555LL };
75static const struct fixed31_32 dc_fixpt_ln2 = { 2977044471LL };
76static const struct fixed31_32 dc_fixpt_ln2_div_2 = { 1488522236LL };
77
78
79
80
81
82
83
84
85
86
87struct fixed31_32 dc_fixpt_from_fraction(long long numerator, long long denominator);
88
89
90
91
92
93static inline struct fixed31_32 dc_fixpt_from_int(int arg)
94{
95 struct fixed31_32 res;
96
97 res.value = (long long) arg << FIXED31_32_BITS_PER_FRACTIONAL_PART;
98
99 return res;
100}
101
102
103
104
105
106
107
108
109
110
111static inline struct fixed31_32 dc_fixpt_neg(struct fixed31_32 arg)
112{
113 struct fixed31_32 res;
114
115 res.value = -arg.value;
116
117 return res;
118}
119
120
121
122
123
124static inline struct fixed31_32 dc_fixpt_abs(struct fixed31_32 arg)
125{
126 if (arg.value < 0)
127 return dc_fixpt_neg(arg);
128 else
129 return arg;
130}
131
132
133
134
135
136
137
138
139
140
141static inline bool dc_fixpt_lt(struct fixed31_32 arg1, struct fixed31_32 arg2)
142{
143 return arg1.value < arg2.value;
144}
145
146
147
148
149
150static inline bool dc_fixpt_le(struct fixed31_32 arg1, struct fixed31_32 arg2)
151{
152 return arg1.value <= arg2.value;
153}
154
155
156
157
158
159static inline bool dc_fixpt_eq(struct fixed31_32 arg1, struct fixed31_32 arg2)
160{
161 return arg1.value == arg2.value;
162}
163
164
165
166
167
168static inline struct fixed31_32 dc_fixpt_min(struct fixed31_32 arg1, struct fixed31_32 arg2)
169{
170 if (arg1.value <= arg2.value)
171 return arg1;
172 else
173 return arg2;
174}
175
176
177
178
179
180static inline struct fixed31_32 dc_fixpt_max(struct fixed31_32 arg1, struct fixed31_32 arg2)
181{
182 if (arg1.value <= arg2.value)
183 return arg2;
184 else
185 return arg1;
186}
187
188
189
190
191
192
193
194static inline struct fixed31_32 dc_fixpt_clamp(
195 struct fixed31_32 arg,
196 struct fixed31_32 min_value,
197 struct fixed31_32 max_value)
198{
199 if (dc_fixpt_le(arg, min_value))
200 return min_value;
201 else if (dc_fixpt_le(max_value, arg))
202 return max_value;
203 else
204 return arg;
205}
206
207
208
209
210
211
212
213
214
215
216static inline struct fixed31_32 dc_fixpt_shl(struct fixed31_32 arg, unsigned char shift)
217{
218 ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) ||
219 ((arg.value < 0) && (arg.value >= ~(LLONG_MAX >> shift))));
220
221 arg.value = arg.value << shift;
222
223 return arg;
224}
225
226
227
228
229
230static inline struct fixed31_32 dc_fixpt_shr(struct fixed31_32 arg, unsigned char shift)
231{
232 bool negative = arg.value < 0;
233
234 if (negative)
235 arg.value = -arg.value;
236 arg.value = arg.value >> shift;
237 if (negative)
238 arg.value = -arg.value;
239 return arg;
240}
241
242
243
244
245
246
247
248
249
250
251static inline struct fixed31_32 dc_fixpt_add(struct fixed31_32 arg1, struct fixed31_32 arg2)
252{
253 struct fixed31_32 res;
254
255 ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) ||
256 ((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value)));
257
258 res.value = arg1.value + arg2.value;
259
260 return res;
261}
262
263
264
265
266
267static inline struct fixed31_32 dc_fixpt_add_int(struct fixed31_32 arg1, int arg2)
268{
269 return dc_fixpt_add(arg1, dc_fixpt_from_int(arg2));
270}
271
272
273
274
275
276static inline struct fixed31_32 dc_fixpt_sub(struct fixed31_32 arg1, struct fixed31_32 arg2)
277{
278 struct fixed31_32 res;
279
280 ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) ||
281 ((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value)));
282
283 res.value = arg1.value - arg2.value;
284
285 return res;
286}
287
288
289
290
291
292static inline struct fixed31_32 dc_fixpt_sub_int(struct fixed31_32 arg1, int arg2)
293{
294 return dc_fixpt_sub(arg1, dc_fixpt_from_int(arg2));
295}
296
297
298
299
300
301
302
303
304
305
306
307struct fixed31_32 dc_fixpt_mul(struct fixed31_32 arg1, struct fixed31_32 arg2);
308
309
310
311
312
313
314static inline struct fixed31_32 dc_fixpt_mul_int(struct fixed31_32 arg1, int arg2)
315{
316 return dc_fixpt_mul(arg1, dc_fixpt_from_int(arg2));
317}
318
319
320
321
322
323struct fixed31_32 dc_fixpt_sqr(struct fixed31_32 arg);
324
325
326
327
328
329static inline struct fixed31_32 dc_fixpt_div_int(struct fixed31_32 arg1, long long arg2)
330{
331 return dc_fixpt_from_fraction(arg1.value, dc_fixpt_from_int(arg2).value);
332}
333
334
335
336
337
338static inline struct fixed31_32 dc_fixpt_div(struct fixed31_32 arg1, struct fixed31_32 arg2)
339{
340 return dc_fixpt_from_fraction(arg1.value, arg2.value);
341}
342
343
344
345
346
347
348
349
350
351
352
353
354
355struct fixed31_32 dc_fixpt_recip(struct fixed31_32 arg);
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370struct fixed31_32 dc_fixpt_sinc(struct fixed31_32 arg);
371
372
373
374
375
376
377
378
379
380struct fixed31_32 dc_fixpt_sin(struct fixed31_32 arg);
381
382
383
384
385
386
387
388
389
390
391
392struct fixed31_32 dc_fixpt_cos(struct fixed31_32 arg);
393
394
395
396
397
398
399
400
401
402
403
404
405
406struct fixed31_32 dc_fixpt_exp(struct fixed31_32 arg);
407
408
409
410
411
412
413
414
415
416
417
418struct fixed31_32 dc_fixpt_log(struct fixed31_32 arg);
419
420
421
422
423
424
425
426
427
428
429
430
431
432static inline struct fixed31_32 dc_fixpt_pow(struct fixed31_32 arg1, struct fixed31_32 arg2)
433{
434 return dc_fixpt_exp(
435 dc_fixpt_mul(
436 dc_fixpt_log(arg1),
437 arg2));
438}
439
440
441
442
443
444
445
446
447
448
449static inline int dc_fixpt_floor(struct fixed31_32 arg)
450{
451 unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
452
453 if (arg.value >= 0)
454 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
455 else
456 return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
457}
458
459
460
461
462
463static inline int dc_fixpt_round(struct fixed31_32 arg)
464{
465 unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
466
467 const long long summand = dc_fixpt_half.value;
468
469 ASSERT(LLONG_MAX - (long long)arg_value >= summand);
470
471 arg_value += summand;
472
473 if (arg.value >= 0)
474 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
475 else
476 return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
477}
478
479
480
481
482
483static inline int dc_fixpt_ceil(struct fixed31_32 arg)
484{
485 unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
486
487 const long long summand = dc_fixpt_one.value -
488 dc_fixpt_epsilon.value;
489
490 ASSERT(LLONG_MAX - (long long)arg_value >= summand);
491
492 arg_value += summand;
493
494 if (arg.value >= 0)
495 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
496 else
497 return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
498}
499
500
501
502
503
504
505
506unsigned int dc_fixpt_u4d19(struct fixed31_32 arg);
507
508unsigned int dc_fixpt_u3d19(struct fixed31_32 arg);
509
510unsigned int dc_fixpt_u2d19(struct fixed31_32 arg);
511
512unsigned int dc_fixpt_u0d19(struct fixed31_32 arg);
513
514unsigned int dc_fixpt_clamp_u0d14(struct fixed31_32 arg);
515
516unsigned int dc_fixpt_clamp_u0d10(struct fixed31_32 arg);
517
518int dc_fixpt_s4d19(struct fixed31_32 arg);
519
520static inline struct fixed31_32 dc_fixpt_truncate(struct fixed31_32 arg, unsigned int frac_bits)
521{
522 bool negative = arg.value < 0;
523
524 if (frac_bits >= FIXED31_32_BITS_PER_FRACTIONAL_PART) {
525 ASSERT(frac_bits == FIXED31_32_BITS_PER_FRACTIONAL_PART);
526 return arg;
527 }
528
529 if (negative)
530 arg.value = -arg.value;
531 arg.value &= (~0LL) << (FIXED31_32_BITS_PER_FRACTIONAL_PART - frac_bits);
532 if (negative)
533 arg.value = -arg.value;
534 return arg;
535}
536
537#endif
538