This library provides two fixed-point arithmetic types, fix32 and fix64, which are header-only and templated to allow users to specify the number of fractional bits. These types offer a balance between the precision of floating-point numbers and the performance and determinism of integer arithmetic.
This library is intendet to be used for Microcontrollers that do not have a hardware floating-point unit and offer a performant alternative to the software implementations of float
and double
. Disclaimer: Modern PC processors have very efficient floating-point units with great pipelining and will probably not see a performance increase. However, you may still want to use a fixed-point precision in some cases because of math. For example, when you want to calculate a fast moving-average by accumulating the differences of inputs and outputs, instead of summing over the whole buffer. Floating-point types may introduce drift due to numerical errors, whereas fixed-point types will be numerically stable/accurate.
- C++14: Supported
- Fixed-Point Arithmetic: Perform arithmetic operations with fixed precision.
- Templated Fractional Bits: Specify the number of fractional bits at compile-time for flexibility.
- Support for Various Data Types: Construct fixed-point numbers from integers and floating-point numbers.
- Stream Output: Output fixed-point numbers to streams.
- Comparison and Arithmetic Operators: Includes all standard comparison and arithmetic operators.
To use the fix32 and fix64 types in your project, include the corresponding header files and specify the number of fractional bits. Below are examples of how to use these types. Example for fix32
fix32<8> a = 3.1415926535897932f; // 24 integer bits, 8 fractional bits
fix32<8> b = 1.5f;
fix32<8> c = a + b;
std::cout << "Result: " << c << std::endl; // Output> Result: 4.640
Example for fix64
fix64<42> a = 3.1415926535897932; // 16 integer bits, 48 fractional bits
fix64<42> b = 1.5;
fix64<42> c = a * b;
std::cout << "Result: " << c << std::endl; // Output> Result: 4.742
std::cout << "Result: ";
print(std::cout, c, 8) << std::endl; // Output> Result: 4.74218380
fix32() = default;
fix32(const fix32&) = default;
fix32(int32_t number);
fix32(uint32_t number);
fix32(float num);
fix32(double num);
template<size_t other_frac_bits> fix32(const fix32<other_frac_bits>& other);
static fix32 reinterpret(int32_t number);
friend fix32 operator+ (fix32 lhs, fix32 rhs);
friend fix32 operator- (fix32 a);
friend fix32 operator- (fix32 lhs, fix32 rhs);
friend fix32 operator* (fix32 lhs, fix32 rhs);
template<typename Integer> friend fix32 operator* (fix32 lhs, Integer rhs);
template<typename Integer> friend fix32 operator* (Integer lhs, fix32 rhs);
friend fix32 operator/ (fix32 lhs, fix32 rhs);
template<typename Integer> friend fix32 operator/ (fix32 lhs, Integer rhs);
fix32& operator+= (fix32 rhs);
fix32& operator-= (fix32 rhs);
fix32& operator*= (fix32 rhs);
fix32& operator/= (fix32 rhs);
friend bool operator== (fix32 lhs, fix32 rhs);
friend bool operator!= (fix32 lhs, fix32 rhs);
friend bool operator< (fix32 lhs, fix32 rhs);
friend bool operator> (fix32 lhs, fix32 rhs);
friend bool operator<= (fix32 lhs, fix32 rhs);
friend bool operator>= (fix32 lhs, fix32 rhs);
friend Stream& print(Stream& stream, fix32 f, size_t significant_places_after_comma=3);
template<class Stream> friend Stream& operator<<(Stream& stream, fix32 f);
fix64() = default;
fix64(const fix64&) = default;
fix64(int64_t number);
fix64(uint64_t number);
fix64(float num);
fix64(double num);
template<size_t other_frac_bits> fix64(const fix64<other_frac_bits>& other);
static fix32 reinterpret(int64_t number);
friend fix64 operator+ (fix64 lhs, fix64 rhs);
friend fix64 operator- (fix64 a);
friend fix64 operator- (fix64 lhs, fix64 rhs);
friend fix64 operator* (fix64 lhs, fix64 rhs);
template<typename Integer> friend fix64 operator* (fix64 lhs, Integer rhs);
template<typename Integer> friend fix64 operator* (Integer lhs, fix64 rhs);
friend fix64 operator/ (fix64 lhs, fix64 rhs);
template<typename Integer> friend fix64 operator/ (fix64 lhs, Integer rhs);
fix64& operator+= (fix64 rhs);
fix64& operator-= (fix64 rhs);
fix64& operator*= (fix64 rhs);
fix64& operator/= (fix64 rhs);
friend bool operator== (fix64 lhs, fix64 rhs);
friend bool operator!= (fix64 lhs, fix64 rhs);
friend bool operator< (fix64 lhs, fix64 rhs);
friend bool operator> (fix64 lhs, fix64 rhs);
friend bool operator<= (fix64 lhs, fix64 rhs);
friend bool operator>= (fix64 lhs, fix64 rhs);
friend Stream& print(Stream& stream, fix64 f, size_t significant_places_after_comma=3);
template<class Stream> friend Stream& operator<<(Stream& stream, fix64 f);
This library is header-only, so you can simply include the header files in your project.
Copy fix32.hpp and fix64.hpp to your project's include directory. Include the headers in your source files where needed.
This project is licensed under the MIT License. See the LICENSE file for details. Author