Arduino Filters master
Filter library for Arduino
FixedPoint.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <AH/STL/cmath>
4#include <AH/STL/cstdint>
5#include <AH/STL/limits>
6#include <AH/STL/type_traits>
7
8#include <AH/Error/Error.hpp>
9
10template <class T>
12 using type = void;
13};
14
15template <>
16struct DoubleWidthInt<uint8_t> {
17 using type = uint16_t;
18};
19
20template <>
21struct DoubleWidthInt<int8_t> {
22 using type = int16_t;
23};
24
25template <>
26struct DoubleWidthInt<uint16_t> {
27 using type = uint32_t;
28};
29
30template <>
31struct DoubleWidthInt<int16_t> {
32 using type = int32_t;
33};
34
35template <>
36struct DoubleWidthInt<uint32_t> {
37 using type = uint64_t;
38};
39
40template <>
41struct DoubleWidthInt<int32_t> {
42 using type = int64_t;
43};
44
47
49template <class T>
51
63template <class T, uint8_t N, class T2 = DoubleWidthInt_t<T>>
65 public:
67 constexpr static T one = 1 << N;
68
70 FixedPoint() : val(0) {}
71
73 template <class U>
74 FixedPoint(U f) : val(std::llrint(f * one)) {}
75
77 static constexpr FixedPoint raw(T t) {
78 FixedPoint res;
79 res.val = t;
80 return res;
81 }
82
85 // if (rhs.val > 0 &&
86 // this->val > std::numeric_limits<T>::max() - rhs.val) {
87 // ERROR("Integer overflow", 0x0FF0);
88 // return raw(std::numeric_limits<T>::max());
89 // }
90 // if (rhs.val < 0 &&
91 // this->val < std::numeric_limits<T>::min() - rhs.val) {
92 // ERROR("Integer underflow", 0x0FF1);
93 // return raw(std::numeric_limits<T>::min());
94 // }
95 return raw(static_cast<T>(
96 static_cast<typename std::make_unsigned<T>::type>(this->val) +
97 static_cast<typename std::make_unsigned<T>::type>(rhs.val)));
98 }
99
102 // return raw(this->val - rhs.val);
103 return *this + -rhs;
104 }
105
107 FixedPoint operator-() const { return raw(-this->val); }
108
111 return raw(div_N(T2(this->val) * T2(rhs.val)));
112 }
113
115 T2 operator*(T2 rhs) const { return div_N(T2(this->val) * T2(rhs)); }
116
119 if (rhs.val == one)
120 return raw(this->val);
121 return raw(T2(this->val) * one / rhs.val);
122 }
123
125 static T div_N(T2 val) {
126 static_assert(std::is_unsigned<T2>::value || (-97 * 2) >> 1 == -97,
127 "Negative signed right shift incorrect");
128 int neg = val < 0 ? 1 : 0;
129 return (val + (1 << (N - 1)) - neg) >> N;
130 }
131
132 explicit operator long double() const { return (long double)val / one; }
133 explicit operator double() const { return (double)val / one; }
134 explicit operator float() const { return (float)val / one; }
135
136 private:
138};
139
141template <class T, uint8_t N, class T2>
143 return rhs * lhs;
144}
145
147template <class T, uint8_t N, class T2>
149 return rhs * lhs;
150}
151
152#ifndef ARDUINO
153
154#include <iosfwd>
155
157template <class T, class T2, uint8_t N>
158std::ostream &operator<<(std::ostream &os, FixedPoint<T, N, T2> fp) {
159 return os << double(fp);
160}
161
162#else
163
165
167template <class T, uint8_t N, class T2>
168Print &operator<<(Print &os, FixedPoint<T, N, T2> fp) {
169 return os << double(fp);
170}
171
172#endif
173
174
Very basic fixed-point integer implementation.
Definition: FixedPoint.hpp:64
FixedPoint()
Default constructor.
Definition: FixedPoint.hpp:70
FixedPoint operator/(FixedPoint rhs) const
Division.
Definition: FixedPoint.hpp:118
FixedPoint operator-() const
Invert.
Definition: FixedPoint.hpp:107
FixedPoint operator+(FixedPoint rhs) const
Addition.
Definition: FixedPoint.hpp:84
static constexpr T one
Fixed-point representation of the number one.
Definition: FixedPoint.hpp:67
FixedPoint operator*(FixedPoint rhs) const
Multiplication.
Definition: FixedPoint.hpp:110
static constexpr FixedPoint raw(T t)
Convert a raw integer representation to fixed point type.
Definition: FixedPoint.hpp:77
FixedPoint(U f)
Initialize U from a numeric value.
Definition: FixedPoint.hpp:74
static T div_N(T2 val)
Divide the given integer by .
Definition: FixedPoint.hpp:125
FixedPoint operator-(FixedPoint rhs) const
Subtraction.
Definition: FixedPoint.hpp:101
T2 operator*(T2 rhs) const
Multiplication with normal integer.
Definition: FixedPoint.hpp:115
Array< decltype(T1{} *T2{}), N1 > operator*(ArraySlice< T1, N1, Reverse1, Const1 > a, T2 b)
Slice * Scalar.
Definition: Array.hpp:495
typename DoubleWidthInt< T >::type DoubleWidthInt_t
Get the integer type that has twice the number of bits as the given type.
Definition: FixedPoint.hpp:50
Print & operator<<(Print &os, Quaternion e)
Printing.
Definition: Quaternion.cpp:28
Definition: vector.cpp:5