The following macros should be used when dealing with 20.12 fixed point numbers. Addition and Substraction work the same way as with integers and don't need extra macros therefore.
The variable type to work with 20.12 fixed point numbers is a 32bit signed integer. HEL Library exclusively uses the sfp32
datatype for fixed point numbers.
Because an integer uses the most significant bit as sign, you actually only have 19 bits for the decimal part. These are numbers in range from 0 to 524288. If you convert a value greater than this into the 20.12 fixed point format and storing it in a 32bit datatype, you get wrong results.
For more information about fixed point math, I recommend the TONC: Fixed Point Math tutorial written by Cearn (TONC tutorials).
#define FIXED_DIV | ( | Number, | |||
Denom | ) |
Divide two fixed point 20.12 values.
The FIXED_DIV divides the two fixed point 20.12 values specified by Number
and Denom
.
Denom
isn't a constant. The debug library displays an assertion in such case.__builtin_constant_p
built-in function to check if Denom
is a constant and known at compile-time. In case it is, FIXED_DIV will not perform a divide, by multiply Number
by the reciprocal of Denom
.#define FIXED_DIVSAFE | ( | Number, | |||
Denom | ) |
Divide two fixed point 20.12 values (div by zero safe).
The FIXED_DIV divides the two fixed point 20.12 values specified by Number
and Denom
. If Denom
is zero, it returns 0x7FFFFFFF.
Denom
is not known at compile-time.__builtin_constant_p
built-in function to check if Denom
is a constant and known at compile-time. In case it is, FIXED_DIV will not perform a divide, by multiply Number
by the reciprocal of Denom
.#define FIXED_FROMFLOAT | ( | Value | ) |
Convert a float value into fixed point 20.12 format.
#define FIXED_FROMINT | ( | Value | ) |
Convert an integer into fixed point 20.12 format.
The FIXED_FROMINT macro generates a 20.12 fixed point number from the number specified by Value
.
#define FIXED_MUL | ( | A, | |||
B | ) |
Multiply two fixed point 20.12 values.
The FIXED_MUL macro multiplies two fixed point 20.12 numbers.
mull
and umull
instructions). These instructions are available in ARM mode only. If you compile in THUMB mode, a div function defined in libgcc is used instead, which is a lot slower. This shouldn't be a problem if you use HAM compile-chain/makefile-system, since all source files are compiled in ARM mode in this case. Thanks to Cearn for the information. #define FIXED_ONE |
1
in fixed point 20.12
The FIXED_ONE define represents 1
(One) in fixed point 20.12 format.
#define FIXED_PI |
PI
in fixed point 20.12
The FIXED_PI define represents PI
(3.14159) in fixed point 20.12 format.
#define FIXED_TOFLOAT | ( | Value | ) |
Convert a float value into a fixed point 20.12.
The FIXED_TOFLOAT macro generates a float value from the fixed point 20.12 number specified by Value
.
#define FIXED_TOINT | ( | Value | ) |
Convert a fixed point 20.12 value into an integer.
The FIXED_TOINT macro generates an integer from the fixed point 20.12 number specified by Value
.
#define FIXED_TRUNC | ( | _Value | ) |
Truncate a fixed point 20.12 value.
The FIXED_TRUNC macro generates the number specified by Value
without fraction part. 99.8 becomes 99 and -99.2 becomes -100.