deepstone

annotate src/fixedp.h @ 40:1fa939507d8b

fast floating point->int conversion
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 15 Sep 2017 05:00:37 +0300
parents dcfe615c4c5f
children
rev   line source
nuclear@25 1 #ifndef FIXED_POINT_H_
nuclear@25 2 #define FIXED_POINT_H_
nuclear@25 3
nuclear@25 4 #include "inttypes.h"
nuclear@25 5
nuclear@25 6 #ifdef DBG_USE_FLOAT
nuclear@25 7 typedef float fixed;
nuclear@25 8 #else
nuclear@25 9 typedef int32_t fixed;
nuclear@25 10 #endif
nuclear@25 11
nuclear@25 12 /* valid choices for DECIMAL_BITS
nuclear@25 13 * 8: for fixed point 24:8
nuclear@25 14 * 16: for fixed point 16:16
nuclear@25 15 */
nuclear@25 16 #define DECIMAL_BITS 16
nuclear@25 17
nuclear@25 18 #if DECIMAL_BITS == 8
nuclear@25 19 #define FIXED_SHIFT 8
nuclear@25 20 #define FLT_SCALE 256.0f
nuclear@25 21 #define FRAC_MASK 0xff
nuclear@25 22 #else /* DECIMAL_BITS == 16 */
nuclear@25 23 #define FIXED_SHIFT 16
nuclear@25 24 #define FLT_SCALE 65536.0f
nuclear@25 25 #define FRAC_MASK 0xffff
nuclear@25 26 #endif /* DECIMAL_BITS */
nuclear@25 27
nuclear@25 28 /*extern const fixed fixed_zero;
nuclear@25 29 extern const fixed fixed_one;
nuclear@25 30 extern const fixed fixed_half;
nuclear@25 31 extern const fixed fixed_tenth;
nuclear@25 32 extern const fixed fixed_255;*/
nuclear@25 33
nuclear@40 34 static __inline long cround64(double val)
nuclear@40 35 {
nuclear@40 36 val += 6755399441055744.0;
nuclear@40 37 return *(long*)&val;
nuclear@40 38 }
nuclear@40 39
nuclear@25 40 #ifdef DBG_USE_FLOAT
nuclear@25 41 /* ------- debug mode, use floating point -------- */
nuclear@25 42 #define FIXED_INT_PART(n) ((int)(n))
nuclear@25 43 #define FIXED_FRAC_PART(n) ((n) > 0.0f ? (FIXED_INT_PART(n) - (n)) : (FIXED_INT_PART(n) + (n)))
nuclear@25 44 #define FIXED_ROUND(n) FIXED_INT_PART((n) >= 0.0 ? (n) + 0.5f : (n) - 0.5f)
nuclear@25 45
nuclear@25 46 #define FIXED_TO_FLOAT(n) (n)
nuclear@25 47 #define FLOAT_TO_FIXED(n) (n)
nuclear@25 48 #define INT_TO_FIXED(n) ((float)(n))
nuclear@25 49
nuclear@25 50 #define FIXED_EPSILON (1e-6)
nuclear@25 51
nuclear@25 52 #else /* ---- really fixed point ---- */
nuclear@25 53
nuclear@25 54 #define FIXED_INT_PART(n) ((n) >> FIXED_SHIFT)
nuclear@25 55 #define FIXED_FRAC_PART(n) ((n) & FRAC_MASK)
nuclear@25 56 #define FIXED_ROUND(n) FIXED_INT_PART((n) >= 0 ? (n) + fixedf(0.5) : (n) - fixedf(0.5))
nuclear@25 57 /*#define FIXED_ROUND(n) FIXED_INT_PART(n)*/
nuclear@25 58
nuclear@25 59 #define FIXED_TO_FLOAT(n) (float)((n) / FLT_SCALE)
nuclear@25 60 #define FLOAT_TO_FIXED(n) (fixed)((n) * FLT_SCALE)
nuclear@25 61 #define INT_TO_FIXED(n) (fixed)((n) << FIXED_SHIFT)
nuclear@25 62
nuclear@25 63 #define FIXED_EPSILON (1)
nuclear@25 64
nuclear@25 65 #endif
nuclear@25 66
nuclear@25 67
nuclear@25 68 #define fixed_int(n) FIXED_INT_PART(n)
nuclear@25 69 #define fixed_frac(n) FIXED_FRAC_PART(n)
nuclear@25 70 #define fixed_float(n) FIXED_TO_FLOAT(n)
nuclear@25 71 #define fixed_round(n) FIXED_ROUND(n)
nuclear@25 72
nuclear@25 73 #define fixedf(n) FLOAT_TO_FIXED(n)
nuclear@25 74 #define fixedi(n) INT_TO_FIXED(n)
nuclear@25 75
nuclear@25 76 #define fixed_add(n1, n2) ((n1) + (n2))
nuclear@25 77 #define fixed_sub(n1, n2) ((n1) - (n2))
nuclear@25 78
nuclear@25 79
nuclear@25 80
nuclear@25 81 #ifdef DBG_USE_FLOAT
nuclear@25 82
nuclear@25 83 #define fixed_mul(n1, n2) ((n1) * (n2))
nuclear@25 84 #define fixed_div(n1, n2) ((n1) / (n2))
nuclear@25 85
nuclear@25 86 #define fixed_sin(x) (fixed)sin(x)
nuclear@25 87 #define fixed_cos(x) (fixed)cos(x)
nuclear@25 88
nuclear@25 89 #else
nuclear@25 90
nuclear@25 91 #if DECIMAL_BITS == 8
nuclear@25 92 #define fixed_mul(n1, n2) (fixed)((n1) * (n2) >> FIXED_SHIFT)
nuclear@25 93 #define fixed_div(n1, n2) (((n1) << FIXED_SHIFT) / (n2))
nuclear@25 94 #else
nuclear@27 95 #define fixed_div(n1, n2) (((n2) >> 8) ? (((n1) << 8) / ((n2) >> 8)) : (n1))
nuclear@25 96 #define fixed_mul(n1, n2) (((n1) >> 8) * ((n2) >> 8))
nuclear@25 97 #endif /* DECIMAL_BITS */
nuclear@25 98
nuclear@25 99 #ifdef __cplusplus
nuclear@25 100 extern "C" {
nuclear@25 101 #endif
nuclear@25 102
nuclear@25 103 fixed fixed_sin(fixed angle);
nuclear@25 104 fixed fixed_cos(fixed angle);
nuclear@25 105
nuclear@25 106 #ifdef __cplusplus
nuclear@25 107 }
nuclear@25 108 #endif
nuclear@25 109
nuclear@25 110 #endif
nuclear@25 111
nuclear@25 112 #endif /* FIXED_POINT_H_ */