#pragma once #include /* * Generic fixed-point helpers. * * Example for Q4.12 using int16_t: * typedef int16_t q4_12_t; * #define Q4_12_FRAC_BITS 12 * q4_12_t a = FIXED_FROM_INT(3, Q4_12_FRAC_BITS); * q4_12_t b = FIXED_FROM_RATIO_T(int16_t, 1, 2, Q4_12_FRAC_BITS); * q4_12_t c = FIXED_MUL_T(int16_t, a, b, Q4_12_FRAC_BITS); * * Example for Q16.16 using int32_t: * typedef int32_t q16_16_t; * #define Q16_16_FRAC_BITS 16 */ #define FIXED_ONE(frac_bits) ((int32_t)1 << (frac_bits)) #define FIXED_HALF(frac_bits) (FIXED_ONE(frac_bits) >> 1) #define FIXED_FRACTION_MASK(frac_bits) (FIXED_ONE(frac_bits) - 1) #define FIXED_PI(frac_bits) FIXED_FROM_RATIO(355, 113, frac_bits) #define FIXED_HALF_PI(frac_bits) (FIXED_PI(frac_bits) >> 1) #define FIXED_FROM_INT(value, frac_bits) ((value) << (frac_bits)) #define FIXED_TO_INT(value, frac_bits) ((value) >> (frac_bits)) #define FIXED_FRACTION(value, frac_bits) ((value) & FIXED_FRACTION_MASK(frac_bits)) #define FIXED_ABS(value) ((value) < 0 ? -(value) : (value)) #define FIXED_MIN(a, b) ((a) < (b) ? (a) : (b)) #define FIXED_MAX(a, b) ((a) > (b) ? (a) : (b)) #define FIXED_CLAMP(value, min_value, max_value) \ ((value) < (min_value) ? (min_value) : ((value) > (max_value) ? (max_value) : (value))) #define FIXED_MUL(a, b, frac_bits) \ ((int32_t)(((int64_t)(a) * (int64_t)(b)) >> (frac_bits))) #define FIXED_DIV(numerator, denominator, frac_bits) \ ((denominator) == 0 ? 0 : (int32_t)(((int64_t)(numerator) << (frac_bits)) / (denominator))) #define FIXED_FROM_RATIO(numerator, denominator, frac_bits) \ ((denominator) == 0 ? 0 : (int32_t)(((int64_t)(numerator) << (frac_bits)) / (denominator))) #define FIXED_LERP(a, b, t, frac_bits) \ ((a) + FIXED_MUL((b) - (a), (t), (frac_bits))) #define FIXED_MUL_T(type, a, b, frac_bits) \ ((type)(((int64_t)(a) * (int64_t)(b)) >> (frac_bits))) #define FIXED_DIV_T(type, numerator, denominator, frac_bits) \ ((denominator) == 0 ? (type)0 : (type)(((int64_t)(numerator) << (frac_bits)) / (denominator))) #define FIXED_FROM_RATIO_T(type, numerator, denominator, frac_bits) \ ((denominator) == 0 ? (type)0 : (type)(((int64_t)(numerator) << (frac_bits)) / (denominator))) int32_t fixed_sqrt(int32_t value, uint8_t frac_bits); int32_t fixed_inv_sqrt(int32_t value, uint8_t frac_bits); int32_t fixed_atan2(int32_t y, int32_t x, uint8_t frac_bits); int32_t fixed_asin(int32_t value, uint8_t frac_bits);