Skip to content

pawel2000pl/fixed_point

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Library for fixed point operations with alternative specialized math modules.

Template dedicated for RISC-V 32 IM.

There are two math modules:

  • taylormath which is based mostly on taylor series
  • polyapprox which is based on cubic Hermite interpolator

Usage

Files

All library files can be found in src/lib/. Just copy the files and include them.
Additionally taylormath need to be linked with its cpp file.
The library works with C++:

  • std-c++23
  • std-c++20
  • std-c++17
  • std-c++11 if you are not going to use constexpr functionalities (they works but not everywhere)

Fixedpoint

The fixedpoint template has the following prototype:

template<typename T, typename TC=typename make_fast_int<T>::type, unsigned frac_bits=sizeof(T)*4-1> class fixedpoint;
  • T - integer type for calculations.
  • TC - integer type for multiplication and division. By default it is fast type of the T (on 64-bits systems it is usually int64 / uint64)
  • frac_bits - number - where to put the fraction point.

There are predefinied types:

  • Standard types (the fastest TC with at least T size)

    • signed

      • fixed8 - signed 8 bit T, fast 8 bit type for TC, 3 fraction bits
      • fixed16 - signed 16 bit T, fast 16 bit type for TC, 7 fraction bits
      • fixed32 - signed 32 bit T, fast 32 bit type for TC, 15 fraction bits
      • fixed64 - signed 64 bit T, fast 64 bit type for TC, 31 fraction bits
    • unsigned

      • ufixed8 - unsigned 8 bit T, fast 8 bit type for TC, 3 fraction bits
      • ufixed16 - unsigned 16 bit T, fast 16 bit type for TC, 7 fraction bits
      • ufixed32 - unsigned 32 bit T, fast 32 bit type for TC, 15 fraction bits
      • ufixed64 - unsigned 64 bit T, fast 64 bit type for TC, 31 fraction bits
  • Accurate types (TC two times larger than T - except [u]int64)

    • signed

      • fixed8_a - signed 8 bit T, fast 16 bit type for TC, 3 fraction bits
      • fixed16_a - signed 16 bit T, fast 32 bit type for TC, 7 fraction bits
      • fixed32_a - signed 32 bit T, fast 64 bit type for TC, 15 fraction bits
      • fixed64_a - signed 64 bit T, fast 64 bit type for TC, 31 fraction bits
    • unsigned

      • ufixed8_a - unsigned 8 bit T, fast 16 bit type for TC, 3 fraction bits
      • ufixed16_a - unsigned 16 bit T, fast 32 bit type for TC, 7 fraction bits
      • ufixed32_a - unsigned 32 bit T, fast 64 bit type for TC, 15 fraction bits
      • ufixed64_a - unsigned 64 bit T, fast 64 bit type for TC, 31 fraction bits
  • Simple types (same size of T and TC)

    • signed

      • fixed8_s - signed 8 bit T, 8 bit type for TC, 3 fraction bits
      • fixed16_s - signed 16 bit T, 16 bit type for TC, 7 fraction bits
      • fixed32_s - signed 32 bit T, 32 bit type for TC, 15 fraction bits
      • fixed64_s - signed 64 bit T, 64 bit type for TC, 31 fraction bits
    • unsigned

      • ufixed8_s - unsigned 8 bit T, 8 bit type for TC, 3 fraction bits
      • ufixed16_s - unsigned 16 bit T, 16 bit type for TC, 7 fraction bits
      • ufixed32_s - unsigned 32 bit T, 32 bit type for TC, 15 fraction bits
      • ufixed64_s - unsigned 64 bit T, 64 bit type for TC, 31 fraction bits
  • Other types (based on std::size_t)

    • signed

      • fixed_t - signed std::size_t for T, fast signed std::size_t for TC, sizeof(std::size_t) * 4 - 1 fraction bits;
    • unsigned

      • ufixed_t - unsigned std::size_t for T, fast unsigned std::size_t for TC, sizeof(std::size_t) * 4 - 1 fraction bits;

Conversions from IEEE754

Results of conversion from IEEE754 might be incorrect due to reading the numbers binary. Always check results on the new target. In case of any errors use FIXED_POINT_IEEE754_ALWAYS_MULTIPLICATE macro.

Taylormath

Each template takes a type which is used for calculations. It can be deduced by a compiler, but to avoid mistakes and calculating on too accuracy (and slower) type it is advised to fill the template parameter, f.e:

std::cout << taylor::exp<fixed32_f>(x) << "\n";
std::cout << taylor::asin<fixed32_f>(x) << "\n";
std::cout << taylor::cos<fixed32_f>(x) << "\n";
std::cout << taylor::sqrt<fixed32_f>(x) << "\n";

Taylormath calculates until increasing accuracy is not possible, so the more accurate type, the more time is needed to calculate a function result.

Polyapprox

This is a class which allows to create an approximation (functional). There is required at least one template parameter (Storable) which is used for storage parameters and calculating the value of the approximation.
The second (optional) template parameter static_part_count is a number of parts of the approximation. For 0 the class uses std::vector and number of parts can be set dynamically. For values greater than 0 the class uses std::array and the number of parts cannot be changed. The constructor / fit method / create static function takes the following parameters:

  • src - functional of a source function
  • part_count - number of divisions of the source function on a given range - parameter exists only if static_part_count > 0
  • range_min - minimal value of the range
  • range_max - maximal value of the range
  • dx - step for deriverates (default 1e-3)

The constructor, fit method and create static function are templates. The only parameter is a type which will be used for calculating parameters for the approximation.

Test results

Speed comparision (microseconds per 100000 operations on ESP32C3@160MHz)

Read ArduinoFixedPointTest/tests.h to see details.

typelibraryadditionsubtractionmultiplicationdivisionsinsqrtasinlogexp
fixed32_staylormath698169171069826436169572143301522276453157267850
fixed32_ataylormath69566923138461059952841644703347881201136635357140
fixed64taylormath132401321220769114558841901772750197750328644291441286
fixed32_spolyapprox6963692410696264345314052686540725268452913
fixed32_apolyapprox69576923138451059977107869839710546978371193
fixed64polyapprox132501321220766114554108361108048109319107843109227
floatcmath101470105847874111343072048567682605268468521902722035009
doublecmath11884012131615095725626730584731248267423675433617663026707
floattaylormath10148410584787406134307271276736791057189580120533404208784
doubletaylormath118830121316150958256267585896516485806350599864871466210290869

Taylormath and Polyapprox accuracy

Differences with double and cmath as reference.
Polyapprox uses 31-points in test cases.

Taylormath Polyapprox
asin taylor plot asin polyapprox plot
cos taylor plot cos polyapprox plot
sin taylor plot sin polyapprox plot
log taylor plot log polyapprox plot
exp taylor plot exp polyapprox plot
sqrt taylor plot sqrt polyapprox plot

Taylormath iterations

asin taylor iterations plot cos taylor iterations plot sin taylor iterations plot log taylor iterations plot exp taylor iterations plot sqrt taylor iterations plot

About

Template for fixed-point operations with a simplified math library (dedicated for RISC-V IM).

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published