nuclear@25: #ifndef FIXED_POINT_H_ nuclear@25: #define FIXED_POINT_H_ nuclear@25: nuclear@25: #include "inttypes.h" nuclear@25: nuclear@25: #ifdef DBG_USE_FLOAT nuclear@25: typedef float fixed; nuclear@25: #else nuclear@25: typedef int32_t fixed; nuclear@25: #endif nuclear@25: nuclear@25: /* valid choices for DECIMAL_BITS nuclear@25: * 8: for fixed point 24:8 nuclear@25: * 16: for fixed point 16:16 nuclear@25: */ nuclear@25: #define DECIMAL_BITS 16 nuclear@25: nuclear@25: #if DECIMAL_BITS == 8 nuclear@25: #define FIXED_SHIFT 8 nuclear@25: #define FLT_SCALE 256.0f nuclear@25: #define FRAC_MASK 0xff nuclear@25: #else /* DECIMAL_BITS == 16 */ nuclear@25: #define FIXED_SHIFT 16 nuclear@25: #define FLT_SCALE 65536.0f nuclear@25: #define FRAC_MASK 0xffff nuclear@25: #endif /* DECIMAL_BITS */ nuclear@25: nuclear@25: /*extern const fixed fixed_zero; nuclear@25: extern const fixed fixed_one; nuclear@25: extern const fixed fixed_half; nuclear@25: extern const fixed fixed_tenth; nuclear@25: extern const fixed fixed_255;*/ nuclear@25: nuclear@25: #ifdef DBG_USE_FLOAT nuclear@25: /* ------- debug mode, use floating point -------- */ nuclear@25: #define FIXED_INT_PART(n) ((int)(n)) nuclear@25: #define FIXED_FRAC_PART(n) ((n) > 0.0f ? (FIXED_INT_PART(n) - (n)) : (FIXED_INT_PART(n) + (n))) nuclear@25: #define FIXED_ROUND(n) FIXED_INT_PART((n) >= 0.0 ? (n) + 0.5f : (n) - 0.5f) nuclear@25: nuclear@25: #define FIXED_TO_FLOAT(n) (n) nuclear@25: #define FLOAT_TO_FIXED(n) (n) nuclear@25: #define INT_TO_FIXED(n) ((float)(n)) nuclear@25: nuclear@25: #define FIXED_EPSILON (1e-6) nuclear@25: nuclear@25: #else /* ---- really fixed point ---- */ nuclear@25: nuclear@25: #define FIXED_INT_PART(n) ((n) >> FIXED_SHIFT) nuclear@25: #define FIXED_FRAC_PART(n) ((n) & FRAC_MASK) nuclear@25: #define FIXED_ROUND(n) FIXED_INT_PART((n) >= 0 ? (n) + fixedf(0.5) : (n) - fixedf(0.5)) nuclear@25: /*#define FIXED_ROUND(n) FIXED_INT_PART(n)*/ nuclear@25: nuclear@25: #define FIXED_TO_FLOAT(n) (float)((n) / FLT_SCALE) nuclear@25: #define FLOAT_TO_FIXED(n) (fixed)((n) * FLT_SCALE) nuclear@25: #define INT_TO_FIXED(n) (fixed)((n) << FIXED_SHIFT) nuclear@25: nuclear@25: #define FIXED_EPSILON (1) nuclear@25: nuclear@25: #endif nuclear@25: nuclear@25: nuclear@25: #define fixed_int(n) FIXED_INT_PART(n) nuclear@25: #define fixed_frac(n) FIXED_FRAC_PART(n) nuclear@25: #define fixed_float(n) FIXED_TO_FLOAT(n) nuclear@25: #define fixed_round(n) FIXED_ROUND(n) nuclear@25: nuclear@25: #define fixedf(n) FLOAT_TO_FIXED(n) nuclear@25: #define fixedi(n) INT_TO_FIXED(n) nuclear@25: nuclear@25: #define fixed_add(n1, n2) ((n1) + (n2)) nuclear@25: #define fixed_sub(n1, n2) ((n1) - (n2)) nuclear@25: nuclear@25: nuclear@25: nuclear@25: #ifdef DBG_USE_FLOAT nuclear@25: nuclear@25: #define fixed_mul(n1, n2) ((n1) * (n2)) nuclear@25: #define fixed_div(n1, n2) ((n1) / (n2)) nuclear@25: nuclear@25: #define fixed_sin(x) (fixed)sin(x) nuclear@25: #define fixed_cos(x) (fixed)cos(x) nuclear@25: nuclear@25: #else nuclear@25: nuclear@25: #if DECIMAL_BITS == 8 nuclear@25: #define fixed_mul(n1, n2) (fixed)((n1) * (n2) >> FIXED_SHIFT) nuclear@25: #define fixed_div(n1, n2) (((n1) << FIXED_SHIFT) / (n2)) nuclear@25: #else nuclear@27: #define fixed_div(n1, n2) (((n2) >> 8) ? (((n1) << 8) / ((n2) >> 8)) : (n1)) nuclear@25: #define fixed_mul(n1, n2) (((n1) >> 8) * ((n2) >> 8)) nuclear@25: #endif /* DECIMAL_BITS */ nuclear@25: nuclear@25: #ifdef __cplusplus nuclear@25: extern "C" { nuclear@25: #endif nuclear@25: nuclear@25: fixed fixed_sin(fixed angle); nuclear@25: fixed fixed_cos(fixed angle); nuclear@25: nuclear@25: #ifdef __cplusplus nuclear@25: } nuclear@25: #endif nuclear@25: nuclear@25: #endif nuclear@25: nuclear@25: #endif /* FIXED_POINT_H_ */