FR_Math

A C language fixed-point math library for embedded systems.

FR_Math is a compact, integer-only fixed-point math library built for systems where floating point is too slow, too big, or unavailable. Designed for embedded targets ranging from legacy 16 MHz 68k processors to modern Cortex-M and RISC-V cores, it provides a full suite of math primitives — trigonometry, logarithms, roots, transforms, and signal generators — while remaining deterministic, portable, and small. Unlike traditional fixed-point libraries, FR_Math lets the caller choose the binary point per operation, trading precision and range explicitly instead of locking into a single format.

Measured accuracy

Errors below are measured at Q16.16 (s15.16). All functions accept any radix — Q16.16 is just the reference point for the table. See the TDD report for sweeps at radixes 8, 12, 16, and 24.

FunctionMax errorNote
sin / cos5 LSB (~7.7e-5)Exact at 0, 90, 180, 270
sqrt≤ 0.5 LSBRound-to-nearest
log2≤ 4 LSB65-entry mantissa table
pow2≤ 1 LSB (integers exact)65-entry fraction table
ln, log10≤ 4 LSBVia FR_MULK28 from log2
hypot (exact)≤ 0.5 LSB64-bit intermediate
hypot_fast (4-seg)0.34%Shift-only, no multiply
hypot_fast8 (8-seg)0.10%Shift-only, no multiply

What’s in the box

AreaFunctions
ArithmeticFR_ADD, FR_SUB, FR_DIV, FR_DIV32, FR_MOD, FR_FixMuls, FR_FixMulSat, FR_CHRDX
UtilityFR_MIN, FR_MAX, FR_CLAMP, FR_ABS, FR_SGN
Trig (integer deg)FR_Sin, FR_Cos, FR_Tan, FR_SinI, FR_CosI, FR_TanI
Trig (radian/BAM)fr_sin, fr_cos, fr_tan, fr_sin_bam, fr_cos_bam, fr_sin_deg, fr_cos_deg
Inverse trigFR_atan, FR_atan2, FR_asin, FR_acos
Log / expFR_log2, FR_ln, FR_log10, FR_pow2, FR_EXP, FR_POW10, FR_EXP_FAST, FR_POW10_FAST, FR_MULK28
RootsFR_sqrt, FR_hypot, FR_hypot_fast, FR_hypot_fast8
Wave generatorsfr_wave_sqr, fr_wave_pwm, fr_wave_tri, fr_wave_saw, fr_wave_tri_morph, fr_wave_noise
Envelopefr_adsr_init, fr_adsr_trigger, fr_adsr_release, fr_adsr_step
2D transformsFR_Matrix2D_CPT (mul, add, sub, det, inv, setrotate, XFormPtI, XFormPtI16)
Formatted outputFR_printNumD, FR_printNumF, FR_printNumH, FR_numstr

Every function is covered by the TDD characterization suite in the repo.

Why fixed-point, in 2026?

Most application code today has an FPU and can use float freely. But there are still large, interesting corners where fixed-point pays off:

FR_Math is engineered for these use cases. It does not try to be a generic float replacement.

Quick taste

#include "FR_math.h"

#define R 16  /* work at radix 16 (s15.16) throughout */

s32 pi    = FR_NUM(3, 14159, 5, R);       /* pi at radix 16             */
s32 c45   = FR_CosI(45);                  /* cos 45 deg = 0.7071 (s15.16) */
s32 root2 = FR_sqrt(I2FR(2, R), R);       /* sqrt(2)    = 1.4142        */
s32 lg    = FR_log2(I2FR(1000, R), R, R); /* log2(1000) ~ 9.97          */
s32 ex    = FR_EXP(I2FR(1, R), R);        /* e^1        ~ 2.7183        */

See Getting Started for a complete walkthrough, or jump straight to the Fixed-Point Primer if you want to understand how the radix notation works first.

Comparison

FeaturelibfixmathCMSIS-DSPFR_Math
Fixed formatQ16.16 onlyQ31 / Q15Any radix
Angle inputRadians (Q16.16)Radians (float)BAM (u16), degrees, or radians
Exact cardinal anglesNoN/AYes
Multiply-free optionNoNoYes (e.g. FR_EXP_FAST, FR_hypot_fast)
Wave generatorsNoNo6 shapes + ADSR
DependenciesNoneARM onlyNone
Code size (Cortex-M0, -Os)2.4 KB~40 KB+4.2 KB

Sizes measured with arm-none-eabi-gcc -mcpu=cortex-m0 -mthumb -Os. libfixmath covers trig/sqrt/exp in Q16.16 only; FR_Math includes log/ln/log10, wave generators, ADSR, print helpers, and variable radix. CMSIS-DSP estimate is for the math function subset only. See docker/build_sizes.sh for the build script.

History

FR_Math has been in service since 2000, originally built for graphics transforms on 16 MHz 68k Palm Pilots (it shipped inside Trumpetsoft’s Inkstorm), then ported forward to ARM, x86, MIPS, RISC-V, and various 8/16-bit embedded targets. v2.0.2 is the current release with a full test suite, bit-exact numerical specification, and CI on every push.

License

BSD-2-Clause. Use it freely in open source or commercial projects.