Routines for performing 32bit fixed-point maths. More...
Classes | |
class | Fix |
Fixed point arithmetic functions. More... | |
Typedefs | |
typedef int32_t | fix |
typedef uint32_t | ufix |
typedef fix | fixangle |
Routines for performing 32bit fixed-point maths.
This code is targeted at CPUs without hardware support for division or floating point. It has been optimised for ARM CPUs but should be suitable for other RISC architecures.
A type representing a 32bit fixed-point number. The binary point lies between bits 15 and 16.
To convert between floating point and fixed point representations, numbers need scaling by 2 to-the-power-of 16 (65536) e.g.
fix x; float f; // to convert f into x... x = (double)f*65536.0l; // to convert x into f... f = (double)x/65536.0l;
Note, values are cast using (double)
here to persuade the compiler to use double precision floating point arithmetic. This avoids loosing precision as single floats only have 24 significant bits, (less that the 32 bits in a fix
number).
To convert between int and fixed point types, shift values by 16.
fix x; int i; // to convert i into x... x = i<<16; // to convert x into i (rounding towards minus infinity)... i = x>>16; // to convert x into i (rounding towards nearest integer)... i = ((x>>15)+1)>>1;
Conversions described above may produce results which overflow the range which can be represented by fixed point numbers. To detect this, check the range of values before they are converted into fixed point...
fix x; float f; // convert f into x... float temp = (double)f*65536.0l; if((double)-2147483648.0<=temp && temp<=(double)2147483647.0) x = temp; else printf("Number conversion overflow!");
or...
fix x; int i; // convert i into x... if(-0x8000<=i && i<=0x7fff) x = i<<16; else printf("Number conversion overflow!");
A type representing a 32bit unsigned fixed-point number. The binary point lies between bits 15 and 16.
For convertsion into/from fixed point format, see fix. Note, valid input range fo unsigned values is 0..0xffff for integers, and 0..0xffffffff for the 'temp' value in the floating point conversion.
A 32bit fixed-point value representing an angle. Values are scaled by a factor of 1/(2*PI), i.e. a value of 1.0 (0x10000) represents a full circle.
To convert angles between floating point and fixed point representations, numbers need scaling as for fix, but with the scaling factor reduced by 2*PI. E.g.
#define PI 3.1415926535897932384626433832795l fixangle a; double f; // to convert f into a... a = (double)f*65536.0l/(2.0l*PI); // to convert a into f... f = (double)a/65536.0l*(2.0l*PI);
This treats f
as an angle in radians, (the usual units for angles in mathematics and computer functions). If you want to use values in degrees, replace 2.0l*PI
with 360.0l
.