fixpt.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #ifndef FIXEDPOINT_H_
  2. #define FIXEDPOINT_H_
  3. #include "util.h"
  4. #ifndef FIXPT_SIZE
  5. /* Q10.5 */
  6. # define FIXPT_SIZE 24
  7. # define FIXPT_SHIFT 6
  8. #endif
  9. #ifndef FIXPTFLOAT_SIZE
  10. # define FIXPTFLOAT_SIZE 32
  11. #endif
  12. #if FIXPT_SIZE == 8
  13. # define FIXPTBIG_SIZE 16
  14. typedef int8_t fixpt_t;
  15. typedef int16_t fixpt_big_t;
  16. #elif FIXPT_SIZE == 16
  17. # define FIXPTBIG_SIZE 24
  18. typedef int16_t fixpt_t;
  19. typedef int24_t fixpt_big_t;
  20. #elif FIXPT_SIZE == 24
  21. # define FIXPTBIG_SIZE 32
  22. typedef int24_t fixpt_t;
  23. typedef int32_t fixpt_big_t;
  24. #elif FIXPT_SIZE == 32
  25. # define FIXPTBIG_SIZE 64
  26. typedef int32_t fixpt_t;
  27. typedef int64_t fixpt_big_t;
  28. #else
  29. # error "Invalid FIXPT_SIZE"
  30. #endif
  31. #define FIXPT_MAX ((fixpt_t)((1ULL << (FIXPT_SIZE - 1U)) - 1U))
  32. #define FIXPT_MIN ((fixpt_t)(-FIXPT_MAX))
  33. #define FIXPTBIG_MAX ((fixpt_t)((1ULL << (FIXPTBIG_SIZE - 1U)) - 1U))
  34. #define FIXPTBIG_MIN ((fixpt_t)(-FIXPTBIG_MAX))
  35. #if FIXPTFLOAT_SIZE == 32
  36. typedef float fixptfloat_t;
  37. #elif FIXPTFLOAT_SIZE == 64
  38. typedef double fixptfloat_t;
  39. #else
  40. # error "Invalid FIXPTFLOAT_SIZE"
  41. #endif
  42. fixpt_big_t fixpt_inflate(fixpt_t a);
  43. fixpt_t fixpt_deflate(fixpt_big_t a);
  44. #define FLOAT_TO_FIXPT_BIG(f) ((fixpt_big_t)( \
  45. ((f) < 0.0) ? \
  46. (fixpt_big_t)(((f) * (fixptfloat_t)(1L << FIXPT_SHIFT)) - 0.5) \
  47. : \
  48. (fixpt_big_t)(((f) * (fixptfloat_t)(1L << FIXPT_SHIFT)) + 0.5) \
  49. ))
  50. #define FLOAT_TO_FIXPT(f) ((fixpt_t)FLOAT_TO_FIXPT_BIG(f))
  51. static alwaysinline fixpt_big_t float_to_fixpt_big(fixptfloat_t f)
  52. {
  53. return (fixpt_big_t)FLOAT_TO_FIXPT_BIG(f);
  54. }
  55. static alwaysinline fixpt_t float_to_fixpt(fixptfloat_t f)
  56. {
  57. return fixpt_deflate(float_to_fixpt_big(f));
  58. }
  59. static alwaysinline fixptfloat_t fixpt_big_to_float(fixpt_big_t p)
  60. {
  61. return (fixptfloat_t)p / (fixptfloat_t)(1L << FIXPT_SHIFT);
  62. }
  63. static alwaysinline fixptfloat_t fixpt_to_float(fixpt_t p)
  64. {
  65. return fixpt_big_to_float(fixpt_inflate(p));
  66. }
  67. #define INT_TO_FIXPT_BIG(i) ((fixpt_big_t)((int32_t)(i) << FIXPT_SHIFT))
  68. #define INT_TO_FIXPT(i) ((fixpt_t)INT_TO_FIXPT_BIG(i))
  69. fixpt_big_t _do_int32_to_fixpt_big(int32_t i);
  70. #define int_to_fixpt_big(i) choose_expr(is_constant(i), \
  71. INT_TO_FIXPT_BIG(i), \
  72. _do_int32_to_fixpt_big(i))
  73. fixpt_t _do_int32_to_fixpt(int32_t i);
  74. #define int_to_fixpt(i) choose_expr(is_constant(i), \
  75. INT_TO_FIXPT(i), \
  76. _do_int32_to_fixpt(i))
  77. int32_t fixpt_big_to_int(fixpt_big_t p);
  78. int32_t fixpt_to_int(fixpt_t p);
  79. /* Get the integer part of a fixpt_t.
  80. */
  81. int32_t fixpt_get_int_part(fixpt_t p);
  82. /* Get the decimal fractional part of a fixpt_t.
  83. */
  84. uint32_t fixpt_get_dec_fract(fixpt_t p, uint8_t nr_digits);
  85. /* Calculate: a + b
  86. */
  87. fixpt_big_t fixpt_big_add(fixpt_big_t a, fixpt_big_t b);
  88. /* Calculate: a - b
  89. */
  90. fixpt_big_t fixpt_big_sub(fixpt_big_t a, fixpt_big_t b);
  91. /* Calculate: a * b
  92. */
  93. fixpt_big_t fixpt_big_mul(fixpt_big_t a, fixpt_big_t b);
  94. /* Calculate: a / b
  95. */
  96. fixpt_big_t fixpt_big_div(fixpt_big_t a, fixpt_big_t b);
  97. /* Calculate: (a * b) / c
  98. */
  99. fixpt_big_t fixpt_big_mul_div(fixpt_big_t a, fixpt_big_t b, fixpt_big_t c);
  100. /* Calculate: a + b
  101. */
  102. fixpt_t fixpt_add(fixpt_t a, fixpt_t b);
  103. /* Calculate: a - b
  104. */
  105. fixpt_t fixpt_sub(fixpt_t a, fixpt_t b);
  106. /* Calculate: a * b
  107. */
  108. fixpt_t fixpt_mul(fixpt_t a, fixpt_t b);
  109. /* Calculate: a / b
  110. */
  111. fixpt_t fixpt_div(fixpt_t a, fixpt_t b);
  112. /* Calculate: (a * b) / c
  113. */
  114. fixpt_t fixpt_mul_div(fixpt_t a, fixpt_t b, fixpt_t c);
  115. /* Calculate: -a
  116. */
  117. fixpt_t fixpt_neg(fixpt_t a);
  118. /* Calculate: Absolute value of a
  119. */
  120. fixpt_t fixpt_abs(fixpt_t a);
  121. /* Calculate: a + b, limited to lo_lim, hi_lim
  122. */
  123. fixpt_t fixpt_add_limited(fixpt_t a, fixpt_t b,
  124. fixpt_t lo_lim, fixpt_t hi_lim);
  125. /* Limit a to lo_lim, hi_lim */
  126. fixpt_t fixpt_clamp(fixpt_t a,
  127. fixpt_t lo_lim, fixpt_t hi_lim);
  128. #endif /* FIXEDPOINT_H_ */