openMSX
FixedPoint.hh
Go to the documentation of this file.
1#ifndef FIXEDPOINT_HH
2#define FIXEDPOINT_HH
3
4#include "narrow.hh"
5#include "serialize.hh"
6#include <cmath>
7#include <cstdint>
8
9namespace openmsx {
10
15template<unsigned FRACTION_BITS_>
17public:
20 static constexpr unsigned FRACTION_BITS = FRACTION_BITS_;
21
22private:
25 static constexpr int ONE = 1 << FRACTION_BITS;
26
29 static constexpr float INV_ONE_F = 1.0f / ONE;
30
33 static constexpr double INV_ONE_D = 1.0 / ONE;
34
38 static constexpr int FRACTION_MASK = ONE - 1;
39
40public:
45 [[nodiscard]] static constexpr FixedPoint create(int value) {
46 return FixedPoint(value, CreateRawTag{});
47 }
48
51 constexpr FixedPoint() = default;
52
53 // Conversion to fixed point:
54
55 explicit constexpr FixedPoint(int i) : value(i << FRACTION_BITS) {}
56 explicit constexpr FixedPoint(unsigned i) : value(i << FRACTION_BITS) {}
57 explicit FixedPoint(float f) : value(narrow_cast<int>(lrintf(f * ONE))) {}
58 explicit FixedPoint(double d) : value(narrow_cast<int>(lrint (d * ONE))) {}
59
60 [[nodiscard]] static constexpr FixedPoint roundRatioDown(unsigned n, unsigned d) {
61 return create(narrow_cast<int>((static_cast<uint64_t>(n) << FRACTION_BITS) / d));
62 }
63
64 [[nodiscard]] static constexpr int shiftHelper(int x, int s) {
65 return (s >= 0) ? (x >> s) : (x << -s);
66 }
67 template<unsigned BITS2>
68 explicit constexpr FixedPoint(FixedPoint<BITS2> other)
69 : value(shiftHelper(other.getRawValue(), BITS2 - FRACTION_BITS)) {}
70
71 // Conversion from fixed point:
72
77 [[nodiscard]] constexpr int toInt() const {
78 return value >> FRACTION_BITS;
79 }
80
84 [[nodiscard]] constexpr float toFloat() const {
85 return narrow_cast<float>(value) * INV_ONE_F;
86 }
87
91 [[nodiscard]] constexpr double toDouble() const {
92 return narrow_cast<double>(value) * INV_ONE_D;
93 }
94
101 [[nodiscard]] constexpr float fractionAsFloat() const {
102 return narrow_cast<float>(value & FRACTION_MASK) * INV_ONE_F;
103 }
104
111 [[nodiscard]] constexpr double fractionAsDouble() const {
112 return narrow_cast<double>(value & FRACTION_MASK) * INV_ONE_D;
113 }
114
115 // Various arithmetic:
116
121 [[nodiscard]] constexpr int divAsInt(FixedPoint other) const {
122 return value / other.value;
123 }
124
129 [[nodiscard]] constexpr FixedPoint floor() const {
130 return create(value & ~FRACTION_MASK);
131 }
132
137 [[nodiscard]] constexpr FixedPoint fract() const {
138 return create(value & FRACTION_MASK);
139 }
140
145 [[nodiscard]] constexpr unsigned fractAsInt() const {
146 return value & FRACTION_MASK;
147 }
148
149 // Arithmetic operators:
150
151 [[nodiscard]] constexpr friend FixedPoint operator+(FixedPoint x, FixedPoint y) {
152 return create(x.value + y.value);
153 }
154 [[nodiscard]] constexpr friend FixedPoint operator-(FixedPoint x, FixedPoint y) {
155 return create(x.value - y.value);
156 }
157 [[nodiscard]] constexpr friend FixedPoint operator*(FixedPoint x, FixedPoint y) {
158 return create(int(
159 (static_cast<int64_t>(x.value) * y.value) >> FRACTION_BITS));
160 }
161 [[nodiscard]] constexpr friend FixedPoint operator*(FixedPoint x, int y) {
162 return create(x.value * y);
163 }
164 [[nodiscard]] constexpr friend FixedPoint operator*(int x, FixedPoint y) {
165 return create(x * y.value);
166 }
171 [[nodiscard]] constexpr friend FixedPoint operator/(FixedPoint x, FixedPoint y) {
172 return create(int(
173 (static_cast<int64_t>(x.value) << FRACTION_BITS) / y.value));
174 }
175 [[nodiscard]] constexpr friend FixedPoint operator/(FixedPoint x, int y) {
176 return create(x.value / y);
177 }
178 [[nodiscard]] constexpr friend FixedPoint operator<<(FixedPoint x, int y) {
179 return create(x.value << y);
180 }
181 [[nodiscard]] constexpr friend FixedPoint operator>>(FixedPoint x, int y) {
182 return create(x.value >> y);
183 }
184
185 // Comparison operators:
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:16
static constexpr FixedPoint create(int value)
Create new fixed point object from given representation.
Definition: FixedPoint.hh:45
constexpr friend FixedPoint operator-(FixedPoint x, FixedPoint y)
Definition: FixedPoint.hh:154
constexpr void operator-=(FixedPoint other)
Definition: FixedPoint.hh:193
static constexpr FixedPoint roundRatioDown(unsigned n, unsigned d)
Definition: FixedPoint.hh:60
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:121
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:20
constexpr friend FixedPoint operator*(FixedPoint x, int y)
Definition: FixedPoint.hh:161
constexpr double fractionAsDouble() const
Returns the fractional part of this fixed point number as a double.
Definition: FixedPoint.hh:111
constexpr FixedPoint(unsigned i)
Definition: FixedPoint.hh:56
constexpr double toDouble() const
Returns the double value that corresponds to this fixed point number.
Definition: FixedPoint.hh:91
constexpr friend FixedPoint operator/(FixedPoint x, FixedPoint y)
Divides two fixed point numbers.
Definition: FixedPoint.hh:171
constexpr friend FixedPoint operator*(FixedPoint x, FixedPoint y)
Definition: FixedPoint.hh:157
constexpr friend FixedPoint operator>>(FixedPoint x, int y)
Definition: FixedPoint.hh:181
constexpr FixedPoint fract() const
Returns the fractional part of this value.
Definition: FixedPoint.hh:137
constexpr int toInt() const
Returns the integer part (rounded down) of this fixed point number.
Definition: FixedPoint.hh:77
constexpr friend FixedPoint operator*(int x, FixedPoint y)
Definition: FixedPoint.hh:164
constexpr FixedPoint(int i)
Definition: FixedPoint.hh:55
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:84
FixedPoint(double d)
Definition: FixedPoint.hh:58
static constexpr int shiftHelper(int x, int s)
Definition: FixedPoint.hh:64
constexpr unsigned fractAsInt() const
Returns the fractional part of this value as an integer.
Definition: FixedPoint.hh:145
constexpr float fractionAsFloat() const
Returns the fractional part of this fixed point number as a float.
Definition: FixedPoint.hh:101
constexpr friend FixedPoint operator<<(FixedPoint x, int y)
Definition: FixedPoint.hh:178
constexpr FixedPoint(FixedPoint< BITS2 > other)
Definition: FixedPoint.hh:68
constexpr friend FixedPoint operator+(FixedPoint x, FixedPoint y)
Definition: FixedPoint.hh:151
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:175
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:129
This file implemented 3 utility functions:
Definition: Autofire.cc:9
constexpr To narrow_cast(From &&from) noexcept
Definition: narrow.hh:21