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
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)
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 isfasttype of theT(on 64-bits systems it is usuallyint64/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 forTC, 3 fraction bits - fixed16 - signed 16 bit
T, fast 16 bit type forTC, 7 fraction bits - fixed32 - signed 32 bit
T, fast 32 bit type forTC, 15 fraction bits - fixed64 - signed 64 bit
T, fast 64 bit type forTC, 31 fraction bits
- fixed8 - signed 8 bit
-
unsigned
- ufixed8 - unsigned 8 bit
T, fast 8 bit type forTC, 3 fraction bits - ufixed16 - unsigned 16 bit
T, fast 16 bit type forTC, 7 fraction bits - ufixed32 - unsigned 32 bit
T, fast 32 bit type forTC, 15 fraction bits - ufixed64 - unsigned 64 bit
T, fast 64 bit type forTC, 31 fraction bits
- ufixed8 - unsigned 8 bit
-
-
Accurate types (TC two times larger than T - except [u]int64)
-
signed
- fixed8_a - signed 8 bit
T, fast 16 bit type forTC, 3 fraction bits - fixed16_a - signed 16 bit
T, fast 32 bit type forTC, 7 fraction bits - fixed32_a - signed 32 bit
T, fast 64 bit type forTC, 15 fraction bits - fixed64_a - signed 64 bit
T, fast 64 bit type forTC, 31 fraction bits
- fixed8_a - signed 8 bit
-
unsigned
- ufixed8_a - unsigned 8 bit
T, fast 16 bit type forTC, 3 fraction bits - ufixed16_a - unsigned 16 bit
T, fast 32 bit type forTC, 7 fraction bits - ufixed32_a - unsigned 32 bit
T, fast 64 bit type forTC, 15 fraction bits - ufixed64_a - unsigned 64 bit
T, fast 64 bit type forTC, 31 fraction bits
- ufixed8_a - unsigned 8 bit
-
-
Simple types (same size of T and TC)
-
signed
- fixed8_s - signed 8 bit
T, 8 bit type forTC, 3 fraction bits - fixed16_s - signed 16 bit
T, 16 bit type forTC, 7 fraction bits - fixed32_s - signed 32 bit
T, 32 bit type forTC, 15 fraction bits - fixed64_s - signed 64 bit
T, 64 bit type forTC, 31 fraction bits
- fixed8_s - signed 8 bit
-
unsigned
- ufixed8_s - unsigned 8 bit
T, 8 bit type forTC, 3 fraction bits - ufixed16_s - unsigned 16 bit
T, 16 bit type forTC, 7 fraction bits - ufixed32_s - unsigned 32 bit
T, 32 bit type forTC, 15 fraction bits - ufixed64_s - unsigned 64 bit
T, 64 bit type forTC, 31 fraction bits
- ufixed8_s - unsigned 8 bit
-
-
Other types (based on
std::size_t)-
signed
- fixed_t - signed
std::size_tforT, fast signedstd::size_tforTC,sizeof(std::size_t) * 4 - 1fraction bits;
- fixed_t - signed
-
unsigned
- ufixed_t - unsigned
std::size_tforT, fast unsignedstd::size_tforTC,sizeof(std::size_t) * 4 - 1fraction bits;
- ufixed_t - unsigned
-
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.
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.
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 functionpart_count- number of divisions of the source function on a given range - parameter exists only ifstatic_part_count > 0range_min- minimal value of the rangerange_max- maximal value of the rangedx- 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.
Read ArduinoFixedPointTest/tests.h to see details.
| type | library | addition | subtraction | multiplication | division | sin | sqrt | asin | log | exp |
|---|---|---|---|---|---|---|---|---|---|---|
| fixed32_s | taylormath | 6981 | 6917 | 10698 | 26436 | 169572 | 143301 | 522276 | 453157 | 267850 |
| fixed32_a | taylormath | 6956 | 6923 | 13846 | 105995 | 284164 | 470334 | 788120 | 1136635 | 357140 |
| fixed64 | taylormath | 13240 | 13212 | 20769 | 114558 | 841901 | 772750 | 1977503 | 2864429 | 1441286 |
| fixed32_s | polyapprox | 6963 | 6924 | 10696 | 26434 | 53140 | 52686 | 54072 | 52684 | 52913 |
| fixed32_a | polyapprox | 6957 | 6923 | 13845 | 105997 | 71078 | 69839 | 71054 | 69783 | 71193 |
| fixed64 | polyapprox | 13250 | 13212 | 20766 | 114554 | 108361 | 108048 | 109319 | 107843 | 109227 |
| float | cmath | 101470 | 105847 | 87411 | 134307 | 2048567 | 682605 | 2684685 | 2190272 | 2035009 |
| double | cmath | 118840 | 121316 | 150957 | 256267 | 3058473 | 1248267 | 4236754 | 3361766 | 3026707 |
| float | taylormath | 101484 | 105847 | 87406 | 134307 | 2712767 | 3679105 | 7189580 | 12053340 | 4208784 |
| double | taylormath | 118830 | 121316 | 150958 | 256267 | 5858965 | 16485806 | 35059986 | 48714662 | 10290869 |
Differences with double and cmath as reference.
Polyapprox uses 31-points in test cases.
| Taylormath | Polyapprox |
|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |

















