123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- #ifndef FIXEDPOINT_H_
- #define FIXEDPOINT_H_
- #include "util.h"
- #ifndef FIXPT_SIZE
- /* Q10.5 */
- # define FIXPT_SIZE 24
- # define FIXPT_SHIFT 6
- #endif
- #ifndef FIXPTFLOAT_SIZE
- # define FIXPTFLOAT_SIZE 32
- #endif
- #if FIXPT_SIZE == 8
- # define FIXPTBIG_SIZE 16
- typedef int8_t fixpt_t;
- typedef int16_t fixpt_big_t;
- #elif FIXPT_SIZE == 16
- # define FIXPTBIG_SIZE 24
- typedef int16_t fixpt_t;
- typedef int24_t fixpt_big_t;
- #elif FIXPT_SIZE == 24
- # define FIXPTBIG_SIZE 32
- typedef int24_t fixpt_t;
- typedef int32_t fixpt_big_t;
- #elif FIXPT_SIZE == 32
- # define FIXPTBIG_SIZE 64
- typedef int32_t fixpt_t;
- typedef int64_t fixpt_big_t;
- #else
- # error "Invalid FIXPT_SIZE"
- #endif
- #define FIXPT_MAX ((fixpt_t)((1ULL << (FIXPT_SIZE - 1U)) - 1U))
- #define FIXPT_MIN ((fixpt_t)(-FIXPT_MAX))
- #define FIXPTBIG_MAX ((fixpt_t)((1ULL << (FIXPTBIG_SIZE - 1U)) - 1U))
- #define FIXPTBIG_MIN ((fixpt_t)(-FIXPTBIG_MAX))
- #if FIXPTFLOAT_SIZE == 32
- typedef float fixptfloat_t;
- #elif FIXPTFLOAT_SIZE == 64
- typedef double fixptfloat_t;
- #else
- # error "Invalid FIXPTFLOAT_SIZE"
- #endif
- fixpt_big_t fixpt_inflate(fixpt_t a);
- fixpt_t fixpt_deflate(fixpt_big_t a);
- #define FLOAT_TO_FIXPT_BIG(f) ((fixpt_big_t)( \
- ((f) < 0.0) ? \
- (fixpt_big_t)(((f) * (fixptfloat_t)(1L << FIXPT_SHIFT)) - 0.5) \
- : \
- (fixpt_big_t)(((f) * (fixptfloat_t)(1L << FIXPT_SHIFT)) + 0.5) \
- ))
- #define FLOAT_TO_FIXPT(f) ((fixpt_t)FLOAT_TO_FIXPT_BIG(f))
- static alwaysinline fixpt_big_t float_to_fixpt_big(fixptfloat_t f)
- {
- return (fixpt_big_t)FLOAT_TO_FIXPT_BIG(f);
- }
- static alwaysinline fixpt_t float_to_fixpt(fixptfloat_t f)
- {
- return fixpt_deflate(float_to_fixpt_big(f));
- }
- static alwaysinline fixptfloat_t fixpt_big_to_float(fixpt_big_t p)
- {
- return (fixptfloat_t)p / (fixptfloat_t)(1L << FIXPT_SHIFT);
- }
- static alwaysinline fixptfloat_t fixpt_to_float(fixpt_t p)
- {
- return fixpt_big_to_float(fixpt_inflate(p));
- }
- #define INT_TO_FIXPT_BIG(i) ((fixpt_big_t)((int32_t)(i) << FIXPT_SHIFT))
- #define INT_TO_FIXPT(i) ((fixpt_t)INT_TO_FIXPT_BIG(i))
- fixpt_big_t _do_int32_to_fixpt_big(int32_t i);
- #define int_to_fixpt_big(i) choose_expr(is_constant(i), \
- INT_TO_FIXPT_BIG(i), \
- _do_int32_to_fixpt_big(i))
- fixpt_t _do_int32_to_fixpt(int32_t i);
- #define int_to_fixpt(i) choose_expr(is_constant(i), \
- INT_TO_FIXPT(i), \
- _do_int32_to_fixpt(i))
- int32_t fixpt_big_to_int(fixpt_big_t p);
- int32_t fixpt_to_int(fixpt_t p);
- /* Get the integer part of a fixpt_t.
- */
- int32_t fixpt_get_int_part(fixpt_t p);
- /* Get the decimal fractional part of a fixpt_t.
- */
- uint32_t fixpt_get_dec_fract(fixpt_t p, uint8_t nr_digits);
- /* Calculate: a + b
- */
- fixpt_big_t fixpt_big_add(fixpt_big_t a, fixpt_big_t b);
- /* Calculate: a - b
- */
- fixpt_big_t fixpt_big_sub(fixpt_big_t a, fixpt_big_t b);
- /* Calculate: a * b
- */
- fixpt_big_t fixpt_big_mul(fixpt_big_t a, fixpt_big_t b);
- /* Calculate: a / b
- */
- fixpt_big_t fixpt_big_div(fixpt_big_t a, fixpt_big_t b);
- /* Calculate: (a * b) / c
- */
- fixpt_big_t fixpt_big_mul_div(fixpt_big_t a, fixpt_big_t b, fixpt_big_t c);
- /* Calculate: a + b
- */
- fixpt_t fixpt_add(fixpt_t a, fixpt_t b);
- /* Calculate: a - b
- */
- fixpt_t fixpt_sub(fixpt_t a, fixpt_t b);
- /* Calculate: a * b
- */
- fixpt_t fixpt_mul(fixpt_t a, fixpt_t b);
- /* Calculate: a / b
- */
- fixpt_t fixpt_div(fixpt_t a, fixpt_t b);
- /* Calculate: (a * b) / c
- */
- fixpt_t fixpt_mul_div(fixpt_t a, fixpt_t b, fixpt_t c);
- /* Calculate: -a
- */
- fixpt_t fixpt_neg(fixpt_t a);
- /* Calculate: Absolute value of a
- */
- fixpt_t fixpt_abs(fixpt_t a);
- /* Calculate: a + b, limited to lo_lim, hi_lim
- */
- fixpt_t fixpt_add_limited(fixpt_t a, fixpt_t b,
- fixpt_t lo_lim, fixpt_t hi_lim);
- /* Limit a to lo_lim, hi_lim */
- fixpt_t fixpt_clamp(fixpt_t a,
- fixpt_t lo_lim, fixpt_t hi_lim);
- #endif /* FIXEDPOINT_H_ */
|