A comprehensive fixed-point math library written in C++23 and C++17, designed for high precision and efficiency.
fixedmath::func
and function objects in sub namespace fixedmath::fobj
, however You can use namesapce fixedmath{ using namesapce fixedmath::func; }
for getting backward compatibility.fixed_t
type is robust against unintentional type conversions, fostering code correctness.double
) to fixed_t
in basic arithmetic operations, enhancing ease of use without sacrificing precision.fixed_t
and double
types automatically yield a double
result type. Arithmetic operations involving double
are seamlessly elevated to double precision, ensuring accuracy for critical calculations.constexpr
, enabling compile-time evaluations where applicable. This feature significantly reduces runtime overhead and allows for constant expressions.[1]constexpr
, FixedMath simplifies integration into projects. Explore the API interface and implementation details: API Reference | Implementation.FixedMath is committed to delivering precision, efficiency, and ease of use, making it an ideal choice for projects requiring fixed-point arithmetic in a modern C++ environment.
[1] The sqrt
function is always available as constexpr
, utilizing the Abacus algorithm for constant evaluation, alongside the standard std::sqrt
for runtime execution. On windows msvc toolset (not clang-cl) still is not fully compatibile with c++23 and still has nonsense compiletime evaluation errors, for example I had to split consteval function into constant but this change does not has any sense.
At this stage, the code has not been optimized, and the results presented below are based solely on initial implementations focused on code quality. The performance metrics indicate the relative computation times for executing functions across a large dataset of input values, without considering value conversions.
Cortex-A73 - Snapdragon 865+
Tag | Function | Fixed (Clang) | Fixed (GCC) | Float | Double | Status |
---|---|---|---|---|---|---|
0.9.1 | sin | 50 ms | - | 31 ms | 77 ms | - |
0.9.4 | sin | 30 ms | 24 ms | 31 ms | 77 ms | Optimized |
0.9.1 | asin | 124 ms | - | 75 ms | 128 ms | - |
0.9.4 | asin | 63 ms | 54 ms | 75 ms | 127 ms | Optimized |
0.9.1 | tan | 136 ms | - | 104 ms | 206 ms | - |
0.9.4 | tan | 136 ms | 130 ms | 104 ms | 206 ms | - |
0.9.1 | atan | 113 ms | - | 110 ms | 165 ms | - |
0.9.5 | atan | 80 ms | 65 ms | 110 ms | 165 ms | Optimized |
Ryzen 9 - 3900X
Tag | Function | Fixed (Clang) | Fixed (GCC) | Float | Double | Status |
---|---|---|---|---|---|---|
0.9.1 | sin | 27 ms | - | 22 ms | 75 ms | - |
0.9.4 | sin | 20 ms | 18 ms | 21 ms | 74 ms | Optimized |
0.9.1 | asin | 92 ms | - | 58 ms | 106 ms | - |
0.9.4 | asin | 49 ms | 44 ms | 57 ms | 104 ms | Optimized |
0.9.1 | tan | 81 ms | - | 66 ms | 180 ms | - |
0.9.4 | tan | 78 ms | 88 ms | 67 ms | 176 ms | - |
0.9.1 | atan | 90 ms | - | 78 ms | 162 ms | - |
0.9.5 | atan | 64 ms | 55 ms | 77 ms | 161 ms | Optimized |
This library is predominantly header-only, with the exception of tabularized trigonometric functions. Therefore, if you require only the precise trigonometric functions, there is no need for compilation. Simply add fixed_lib/include
to your include path and use #include <fixedmath/fixed_math.hpp>
in your code.
For access to additional, approximate trigonometric functions, the library should be compiled like any standard CMake project. Currently, the project does not offer any specific tuning parameters for CMake.
For projects utilizing CPM (CMake Package Manager) for dependency management, you can easily integrate FixedMath by adding the following lines to your CMakeLists.txt
:
CPMAddPackage(
NAME fixed_math
GITHUB_REPOSITORY arturbac/fixed_math
GIT_TAG v2.0.0
)
find_package(fixed_math REQUIRED)
# optional PCH
target_precompile_headers( fixed_math INTERFACE <fixedmath/fixed_math.hpp>)
The following compilers are confirmed to compile the project in branches
If you encounter any issues, please report it by submitting an issue.
fixed_t
serves as the typename for the fixed-point arithmetic type within this library, supporting common operators such as +
, -
, *
, and more.
#include <fixedmath/fixed_math.hpp>
#include <fixedmath/iostream.h>
using fixedmath::fixed_t;
using fixedmath::operator""_fix;
// fixed and all functionality is constexpr so You can declare constants see features [1]
inline constexpr fixed_t foo_constant{fixedmath::tan(15 * fixedmath::phi / 180)};
constexpr fixed_t my_function(fixed_t value)
{
using namespace fixedmath;
return foo_constant + sin(value) / (1.41_fix - 2 * cos(value) / 4);
}
int main()
{
// converting to/from fixed_t
// construction from other arithmetic types is explicit
fixed_t val1{3.14};
fixed_t val2{3u};
//- there is no implicit assignment from other types
float some_float{3.14f};
fixed_t some_fixed;
some_fixed = fixed_t{some_float};
//- converting to other arithmetic types coud be done with static cast and is explicit
double some_double(some_fixed);
// for constant values postfix operator _fix may be used
some_fixed = some_float * 2.45_fix; // operation with float is promoted to fixed_t
some_double = 4.15 * some_fixed; // operation with double is promoted to double
std::cout << some_double << " " << my_function(some_fixed) << std::endl;
}
To execute the unit tests, simply #include <fixedmath/unittests/compile_time_unit_tests.h>
in any source file of your project. This enables you to validate the functionality at compile time, ensuring the library's reliability.
Alternatively, unit tests can be executed using CMake/CTest with clang. Run ninja test
or make test
commands, depending on your build system, as the tests are included in the default CMake configuration of the source folder. To enable or disable this feature, modify the FIXEDMATH_ENABLE_UNIT_TESTS
option in the CMakeLists.txt
file.
This flexible testing approach ensures that you can easily integrate and verify the functionality of the library within your development workflow.
The development of version 1.0 focused on establishing a robust foundation for fixed-point arithmetic operations, with significant achievements as outlined below:
hypot
) implemented with normalization to prevent overflow and underflow.atan
, atan2
) with an error margin of approximately <= 0.00005.asin
) accuracy of approximately <= 0.0001.Looking forward, the project aims to expand its offerings and improve in several key areas:
Should you encounter any bugs, we encourage you to file an issue through our issue submission form. When reporting a bug, please include sufficient information for reproduction, such as a static_assert(expression)
, along with the compiler version and target architecture if pertinent. We welcome feature requests and contributions; these can be submitted either as issues or pull requests.
The library is freely available to everyone under the terms of the MIT License or the Boost Software License - Version 1.0. For more details, please refer to the LICENSE.md file.