openMSX
FixedPoint.hh
Go to the documentation of this file.
1#ifndef FIXEDPOINT_HH
2#define FIXEDPOINT_HH
3
4#include "serialize.hh"
5#include <cmath>
6#include <cstdint>
7
8namespace openmsx {
9
14template<unsigned FRACTION_BITS_>
16public:
19 static constexpr unsigned FRACTION_BITS = FRACTION_BITS_;
20
21private:
24 static constexpr int ONE = 1 << FRACTION_BITS;
25
28 static constexpr float INV_ONE_F = 1.0f / ONE;
29
32 static constexpr double INV_ONE_D = 1.0 / ONE;
33
37 static constexpr int FRACTION_MASK = ONE - 1;
38
39public:
44 [[nodiscard]] static constexpr FixedPoint create(int value) {
45 return FixedPoint(value, CreateRawTag{});
46 }
47
50 constexpr FixedPoint() = default;
51
52 // Conversion to fixed point:
53
54 explicit constexpr FixedPoint(int i) : value(i << FRACTION_BITS) {}
55 explicit constexpr FixedPoint(unsigned i) : value(i << FRACTION_BITS) {}
56 explicit FixedPoint(float f) : value(lrintf(f * ONE)) {}
57 explicit FixedPoint(double d) : value(lrint (d * ONE)) {}
58
59 [[nodiscard]] static constexpr FixedPoint roundRatioDown(unsigned n, unsigned d) {
60 return create((static_cast<uint64_t>(n) << FRACTION_BITS) / d);
61 }
62
63 [[nodiscard]] static constexpr int shiftHelper(int x, int s) {
64 return (s >= 0) ? (x >> s) : (x << -s);
65 }
66 template<unsigned BITS2>
67 explicit constexpr FixedPoint(FixedPoint<BITS2> other)
68 : value(shiftHelper(other.getRawValue(), BITS2 - FRACTION_BITS)) {}
69
70 // Conversion from fixed point:
71
76 [[nodiscard]] constexpr int toInt() const {
77 return value >> FRACTION_BITS;
78 }
79
83 [[nodiscard]] constexpr float toFloat() const {
84 return value * INV_ONE_F;
85 }
86
90 [[nodiscard]] constexpr double toDouble() const {
91 return value * INV_ONE_D;
92 }
93
100 [[nodiscard]] constexpr float fractionAsFloat() const {
101 return (value & FRACTION_MASK) * INV_ONE_F;
102 }
103
110 [[nodiscard]] constexpr double fractionAsDouble() const {
111 return (value & FRACTION_MASK) * INV_ONE_D;
112 }
113
114 // Various arithmetic:
115
120 [[nodiscard]] constexpr int divAsInt(FixedPoint other) const {
121 return value / other.value;
122 }
123
128 [[nodiscard]] constexpr FixedPoint floor() const {
129 return create(value & ~FRACTION_MASK);
130 }
131
136 [[nodiscard]] constexpr FixedPoint fract() const {
137 return create(value & FRACTION_MASK);
138 }
139
144 [[nodiscard]] constexpr unsigned fractAsInt() const {
145 return value & FRACTION_MASK;
146 }
147
148 // Arithmetic operators:
149
150 [[nodiscard]] constexpr friend FixedPoint operator+(FixedPoint x, FixedPoint y) {
151 return create(x.value + y.value);
152 }
153 [[nodiscard]] constexpr friend FixedPoint operator-(FixedPoint x, FixedPoint y) {
154 return create(x.value - y.value);
155 }
156 [[nodiscard]] constexpr friend FixedPoint operator*(FixedPoint x, FixedPoint y) {
157 return create(int(
158 (static_cast<int64_t>(x.value) * y.value) >> FRACTION_BITS));
159 }
160 [[nodiscard]] constexpr friend FixedPoint operator*(FixedPoint x, int y) {
161 return create(x.value * y);
162 }
163 [[nodiscard]] constexpr friend FixedPoint operator*(int x, FixedPoint y) {
164 return create(x * y.value);
165 }
170 [[nodiscard]] constexpr friend FixedPoint operator/(FixedPoint x, FixedPoint y) {
171 return create(int(
172 (static_cast<int64_t>(x.value) << FRACTION_BITS) / y.value));
173 }
174 [[nodiscard]] constexpr friend FixedPoint operator/(FixedPoint x, int y) {
175 return create(x.value / y);
176 }
177 [[nodiscard]] constexpr friend FixedPoint operator<<(FixedPoint x, int y) {
178 return create(x.value << y);
179 }
180 [[nodiscard]] constexpr friend FixedPoint operator>>(FixedPoint x, int y) {
181 return create(x.value >> y);
182 }
183
184 // Comparison operators:
185 [[nodiscard]] constexpr bool operator== (const FixedPoint&) const = default;
186 [[nodiscard]] constexpr auto operator<=>(const FixedPoint&) const = default;
187
188 // Arithmetic operators that modify this object:
189
190 constexpr void operator+=(FixedPoint other) {
191 value += other.value;
192 }
193 constexpr void operator-=(FixedPoint other) {
194 value -= other.value;
195 }
196
200 constexpr void addQuantum() {
201 value += 1;
202 }
203
204 // Should only be used by other instances of this class
205 // templatized friend declarations are not possible in c++
206 [[nodiscard]] constexpr int getRawValue() const {
207 return value;
208 }
209
210 template<typename Archive>
211 void serialize(Archive& ar, unsigned /*version*/)
212 {
213 ar.serialize("value", value);
214 }
215
216private:
217 struct CreateRawTag {};
218 constexpr FixedPoint(int raw_value, CreateRawTag)
219 : value(raw_value) {}
220
221 int value = 0;
222};
223
224} // namespace openmsx
225
226#endif // FIXEDPOINT_HH
A fixed point number, implemented by a 32-bit signed integer.
Definition: FixedPoint.hh:15
static constexpr FixedPoint create(int value)
Create new fixed point object from given representation.
Definition: FixedPoint.hh:44
constexpr bool operator==(const FixedPoint &) const =default
constexpr friend FixedPoint operator-(FixedPoint x, FixedPoint y)
Definition: FixedPoint.hh:153
constexpr void operator-=(FixedPoint other)
Definition: FixedPoint.hh:193
static constexpr FixedPoint roundRatioDown(unsigned n, unsigned d)
Definition: FixedPoint.hh:59
constexpr int divAsInt(FixedPoint other) const
Returns the result of a division between this fixed point number and another, rounded towards zero.
Definition: FixedPoint.hh:120
static constexpr unsigned FRACTION_BITS
Number of fractional bits (export template parameter as a constant so that external code can use it m...
Definition: FixedPoint.hh:19
constexpr friend FixedPoint operator*(FixedPoint x, int y)
Definition: FixedPoint.hh:160
constexpr double fractionAsDouble() const
Returns the fractional part of this fixed point number as a double.
Definition: FixedPoint.hh:110
constexpr FixedPoint(unsigned i)
Definition: FixedPoint.hh:55
constexpr double toDouble() const
Returns the double value that corresponds to this fixed point number.
Definition: FixedPoint.hh:90
constexpr friend FixedPoint operator/(FixedPoint x, FixedPoint y)
Divides two fixed point numbers.
Definition: FixedPoint.hh:170
constexpr friend FixedPoint operator*(FixedPoint x, FixedPoint y)
Definition: FixedPoint.hh:156
constexpr friend FixedPoint operator>>(FixedPoint x, int y)
Definition: FixedPoint.hh:180
constexpr FixedPoint fract() const
Returns the fractional part of this value.
Definition: FixedPoint.hh:136
constexpr int toInt() const
Returns the integer part (rounded down) of this fixed point number.
Definition: FixedPoint.hh:76
constexpr friend FixedPoint operator*(int x, FixedPoint y)
Definition: FixedPoint.hh:163
constexpr FixedPoint(int i)
Definition: FixedPoint.hh:54
constexpr int getRawValue() const
Definition: FixedPoint.hh:206
constexpr float toFloat() const
Returns the float value that corresponds to this fixed point number.
Definition: FixedPoint.hh:83
FixedPoint(double d)
Definition: FixedPoint.hh:57
static constexpr int shiftHelper(int x, int s)
Definition: FixedPoint.hh:63
constexpr unsigned fractAsInt() const
Returns the fractional part of this value as an integer.
Definition: FixedPoint.hh:144
constexpr float fractionAsFloat() const
Returns the fractional part of this fixed point number as a float.
Definition: FixedPoint.hh:100
constexpr friend FixedPoint operator<<(FixedPoint x, int y)
Definition: FixedPoint.hh:177
constexpr FixedPoint(FixedPoint< BITS2 > other)
Definition: FixedPoint.hh:67
constexpr friend FixedPoint operator+(FixedPoint x, FixedPoint y)
Definition: FixedPoint.hh:150
constexpr void addQuantum()
Increase this value with the smallest possible amount.
Definition: FixedPoint.hh:200
constexpr friend FixedPoint operator/(FixedPoint x, int y)
Definition: FixedPoint.hh:174
void serialize(Archive &ar, unsigned)
Definition: FixedPoint.hh:211
constexpr FixedPoint()=default
Creates a zero-initialized fixed point object.
constexpr auto operator<=>(const FixedPoint &) const =default
constexpr void operator+=(FixedPoint other)
Definition: FixedPoint.hh:190
constexpr FixedPoint floor() const
Returns this value rounded down.
Definition: FixedPoint.hh:128
This file implemented 3 utility functions:
Definition: Autofire.cc:9
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:127