Skip to content

bastian2001/Fixed-Point-int

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fixed Point int

This library implements signed fixed point integer classes – fix32 (16.16) and fix64 (32.32) – that can be used to accelerate math functions on microcontrollers, or generally anywhere in a C++ application.

The code is currently only targeting an RP2350 and unless you, yes you, decide to change that, it will likely stay like that. The 4 basic maths functions (+-*/) as well as bit shifting, abs etc. are not dependent on the RP2350 hardware, but stuff like trigonometric functions or sqrt currently require the RP2xxx interpolator. Porting for the RP2040 is easy, about 10 lines max (if any, there just needs to be a polyfill for the __clz (count leading zeroes) intrinsic), but other targets will require polyfills for the interpolator. Also doable, but the speed gains will be lower and effort for porting slightly higher.

This repo mostly exists for me, so that I have quick and easy access to the functions in my projects using PlatformIO.

Note

Going forward, when I am referring to fix32 AND fix64, I will just call it fix for simplicity. If something only applies to one of the types, I will call it fix32 or fix64.

Usage

  1. Somehow install it in your project, e.g. by adding this repo to your lib_deps in PlatformIO or downloading and adding the ZIP to your Arduino project.
  2. Declare fix numbers the same way you would normally declare ints or floats. The operators are overridden, so you can just use these numbers like any other types. a = b * c and so on, you know.
  3. You can also use ints, floats etc. in your operations as long as the fix is the first (fix + int works, but int + fix does not). If you need that (for things like 1 / a, write fix(1) / a)

Reference

See here to learn which functions and math operations exist.

I need/can help

Despite this being a project that I primarily maintain for myself, I would/do enjoy it if others take a use from it (otherwise I wouldn't spend 2h writing documentation).

If you need help, just file an issue. I'll do my best to explain the inner workings of this library.

If you want to port this over to another microcontroller or otherwise expand this library, feel free to open a PR with the necessary changes. Keep in mind to use sensible defines so that your changes don't affect other microcontrollers.

Application notes

  • Fixed points have a fixed precision (as in: step) for all calculations. Let's call it eps. For fix32, eps is 1/65536, and for fix64, eps is 2^-32 (roughly 1/4bn). This why they are called fixed. Floats and doubles have a precision that is relative to the magnitude of the number. Their decimal point (actually binary but whatever) slides (floats). This makes floats slower to compute but usually more versatile.
  • There are min and max values for fixed point ints. You can find them at FIX32_MIN (-32768), FIX32_MAX (+32768 - eps), FIX64_MIN (-2^31, roughly -2bn) and FIX64_MAX (+2^31 - eps, roughly +2bn).
  • There are also constants available for Pi etc: FIX_PI, FIX_PI_2, FIX_PI_4, FIX_3PI_4, FIX_2_PI, FIX_1_PI, FIX_TWOPI, FIX_SQRTPI, FIX_SQRT2, FIX_SQRT1_2, FIX_E, FIX_LOG2E, FIX_LOG10E, FIX_LN2, FIX_LN10
  • When assigning values, they are always rounded towards 0 to the nearest available fix step.
  • The RP2350 has an FPU. During my testing, I found that this library is still faster, but loses quite a bit of its advantage compared to back when I used it on an RP2040. The biggest advantages come in the trigonometric functions and sqrt and when using the raw values with other interpolation methods.
  • All of the basics are coded in a way that the compiler inlines them. This has two advantages:
    1. Faster: The CPU does not need to jump into and out of a function
    2. Constants and constexpr: The compiler automatically does as much as possible during compilation so that stuff like fix32 a = b * 2.3 does not actually do any floating point math on the microcontroller (given b is fix, too). The literal 2.3 is automatically converted to a fix at compile time!
  • Overflow: Because it is all implemented using ints, overflow happens the same way as with normal ints. If you write fix32 a = 32769, it will actually assign a value of -32767. Similarly with additions etc.
  • fix64 cannot be divided by another fix64. Please convert the values to fix32, floats, doubles, whatever you want. Implementing this would require dividing a 96 bit value by a 64 bit value. No clue how to do that, and, honestly speaking, this is a very rare case.

Examples

There are none, haha. But you can check out my flight controller where I use them extensively.

About

Fixed Point math library that uses the interpolator to accelerate math functions even further on the RP2350.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors