A fixed-point math library is what you need. My preferred solution for this is Anthony Williams' fixed-Point math C++ library. Because it is in C++ and defines a fixed
class with extensive function and operator overloading, it can largely be used simply by replacing float
or double
in your existing code with fixed
. It uses int64_t
as the underlying integer data type, with 34 integer bits and 28 fractional bits (34Q28), so is good for about 8 decimal places and a wider range than int32_t
.
If your compiler supports C++, you can still essentially write your code using the essentially C subset if you prefer, using C++ only to support this library.
On 32bit ARM this library performs about 5 times faster than software-floating point and is comparable in performance to ARM's VFP unit for C code.
Note that the sqrt()
function in this library has poor precision performance for very small values as it looses lower-order bits in intermediate calculations that can be preserved. It can be improved by replacing it with the code the version I presented in this question.
There are no doubt C libraries for fixed-point math but they will lack the simplicity and convenience of a "real" fixed-point data type provided by this library, and this library has a complete set of standard library math function equivalents, while many fixed point solutions just provide basic arithmetic operators.