29#include <EASTL/functional.h>
38namespace FixedPointInternals {
41int32_t
dDiv(int32_t a, int32_t
b,
unsigned scale);
69template <
unsigned precisionBits = 12, std::
integral T =
int32_t,
unsigned Scale = 1 << precisionBits>
70 requires((precisionBits > 0) && (precisionBits < 32) && ((sizeof(T) == 4) || (sizeof(T) == 2) || sizeof(T) == 1))
72 using
signedUpType = std::conditional<sizeof(T) == 4,
int64_t,
int32_t>::type;
73 using
unsignedUpType = std::conditional<sizeof(T) == 4, u
int64_t, u
int32_t>::type;
74 using upType = std::conditional<std::is_
signed<T>::value,
signedUpType,
unsignedUpType>::type;
85 T raw() const { return value; }
91 static constexpr
unsigned scale = Scale;
98 explicit constexpr FixedPo
int(T
integer, T fraction) : value(
integer * scale + fraction) {
99 static_assert(sizeof(FixedPo
int) == sizeof(T));
112 consteval FixedPo
int(
long double ld) {
113 bool negative = ld < 0;
114 T
integer = negative ? -ld : ld;
115 T fraction = ld * scale -
integer * scale + (negative ? -0.5 : 0.5);
116 value =
integer * scale + fraction;
119 constexpr FixedPo
int() : value(0) {}
120 constexpr FixedPo
int(const FixedPo
int&) = default;
121 constexpr FixedPo
int(FixedPo
int&&) = default;
122 constexpr FixedPo
int& operator=(const FixedPo
int&) = default;
125 constexpr FixedPo
int(T raw, Raw) : value(raw) {}
131 template <
unsigned otherPrecisionBits = 12, std::
integral U =
int32_t>
132 explicit FixedPoint(FixedPoint<otherPrecisionBits, U> other) {
133 if constexpr (precisionBits == otherPrecisionBits) {
134 value = T(other.value);
135 }
else if constexpr (precisionBits > otherPrecisionBits) {
136 value = T(other.value << (precisionBits - otherPrecisionBits));
137 }
else if constexpr (precisionBits < otherPrecisionBits) {
138 value = T(other.value >> (otherPrecisionBits - precisionBits));
158 template <
size_t factor = 1>
159 constexpr T integer()
const {
160 if constexpr (std::is_signed<T>::value) {
162 return T(
value - scale / (2 * factor)) / T(scale / factor);
165 return T(
value + scale / (2 * factor)) / T(scale / factor);
168 template <std::
integral U>
169 constexpr U integer()
const {
170 if constexpr (std::is_signed<T>::value) {
172 return U((
value - scale / 2) / scale);
175 return U(
value + scale / 2) / U(scale);
189 template <std::
integral U = T>
190 constexpr U floor()
const {
191 if constexpr (std::is_signed<T>::value) {
193 return U(
value - scale + 1) / U(scale);
196 return U(
value) / U(scale);
210 template <std::
integral U = T>
211 constexpr U ceil()
const {
212 if constexpr (std::is_signed<T>::value) {
214 return U(
value) / U(scale);
217 return U(
value + scale - 1) / U(scale);
232 void print(
const eastl::function<
void(
char)>& charPrinter)
const {
234 if constexpr (std::is_signed<T>::value) {
243 constexpr FixedPoint abs()
const {
244 FixedPoint
ret = *
this;
245 if constexpr (std::is_signed<T>::value) {
253 constexpr FixedPoint operator+(FixedPoint other)
const {
254 FixedPoint
ret = *
this;
255 ret.value += other.value;
259 template <std::
integral U>
260 constexpr FixedPoint operator+(U other)
const {
261 FixedPoint
ret = *
this;
262 ret.value += other * scale;
266 constexpr FixedPoint operator-(FixedPoint other)
const {
267 FixedPoint
ret = *
this;
268 ret.value -= other.value;
272 template <std::
integral U>
273 constexpr FixedPoint operator-(U other)
const {
274 FixedPoint
ret = *
this;
275 ret.value -= other * scale;
279 constexpr FixedPoint operator*(FixedPoint other)
const {
288 template <std::
integral U>
289 constexpr FixedPoint operator*(U other)
const {
290 FixedPoint
ret = *
this;
295 constexpr FixedPoint operator/(FixedPoint other)
const {
297 if constexpr (
sizeof(T) == 4) {
298 if constexpr (std::is_signed<T>::value) {
300 }
else if constexpr (!std::is_signed<T>::value) {
303 }
else if constexpr (
sizeof(T) < 4) {
312 template <std::
integral U>
313 constexpr FixedPoint operator/(U other)
const {
314 FixedPoint
ret = *
this;
319 constexpr FixedPoint operator-()
const {
320 FixedPoint
ret = *
this;
325 constexpr FixedPoint& operator+=(FixedPoint other) {
326 value += other.value;
330 template <std::
integral U>
331 constexpr FixedPoint& operator+=(U other) {
332 value += other * scale;
336 constexpr FixedPoint& operator-=(FixedPoint other) {
337 value -= other.value;
341 template <std::
integral U>
342 constexpr FixedPoint& operator-=(U other) {
343 value -= other * scale;
347 constexpr FixedPoint& operator*=(FixedPoint other) {
355 template <std::
integral U>
356 constexpr FixedPoint& operator*=(U other) {
361 constexpr FixedPoint& operator/=(FixedPoint other) {
362 if constexpr (
sizeof(T) == 4) {
363 if constexpr (std::is_signed<T>::value) {
365 }
else if constexpr (!std::is_signed<T>::value) {
368 }
else if constexpr (
sizeof(T) == 2) {
377 template <std::
integral U>
378 constexpr FixedPoint& operator/=(U other) {
383 auto operator<=>(
const FixedPoint& other)
const =
default;
385 constexpr FixedPoint operator<<(
unsigned shift)
const {
386 FixedPoint
ret = *
this;
391 constexpr FixedPoint operator>>(
unsigned shift)
const {
392 FixedPoint
ret = *
this;
397 constexpr FixedPoint& operator<<=(
unsigned shift) {
402 constexpr FixedPoint& operator>>=(
unsigned shift) {
413 FixedPoint
ret = *
this;
424 FixedPoint
ret = *
this;
429 constexpr bool operator!()
const {
return value == 0; }
432template <
unsigned precisionBits = 12, std::integral T = int32_t,
unsigned scale = 1 << precisionBits,
433 std::integral U = int32_t>
434constexpr FixedPoint<precisionBits, T, scale> operator+(U a, FixedPoint<precisionBits, T, scale>
b) {
438template <
unsigned precisionBits = 12, std::integral T = int32_t,
unsigned scale = 1 << precisionBits,
439 std::integral U = int32_t>
440constexpr FixedPoint<precisionBits, T, scale> operator-(U a, FixedPoint<precisionBits, T, scale>
b) {
444template <
unsigned precisionBits = 12, std::integral T = int32_t,
unsigned scale = 1 << precisionBits,
445 std::integral U = int32_t>
446constexpr FixedPoint<precisionBits, T, scale> operator*(U a, FixedPoint<precisionBits, T, scale>
b) {
450template <
unsigned precisionBits = 12, std::integral T = int32_t,
unsigned scale = 1 << precisionBits,
451 std::integral U = int32_t>
452constexpr FixedPoint<precisionBits, T, scale> operator/(U a, FixedPoint<precisionBits, T, scale>
b) {
453 FixedPoint<precisionBits, T, scale>
ret;
454 if constexpr (
sizeof(T) == 4) {
455 if constexpr (std::is_signed<T>::value || std::is_signed<U>::value) {
456 ret.value = FixedPointInternals::dDiv(a * FixedPoint<precisionBits, T>::scale,
b.raw(), scale);
457 }
else if constexpr (!std::is_signed<T>::value && !std::is_signed<U>::value) {
458 ret.value = FixedPointInternals::iDiv(a * FixedPoint<precisionBits, T>::scale,
b.raw(), scale);
460 }
else if constexpr (
sizeof(T) == 2) {
461 ret.value = a * FixedPoint<precisionBits, T>::scale /
b.raw();
466namespace fixed_point_literals {
474consteval FixedPoint<>
operator""_fp(
long double value) {
return value; }
uint32_t t
Definition cop0.c:79
uint32_t iDiv(uint64_t rem, uint32_t base, unsigned scale)
Definition fixed-point.cpp:29
int32_t dDiv(int32_t a, int32_t b, unsigned scale)
Definition fixed-point.cpp:59
void printInt(uint32_t value, const eastl::function< void(char)> &, unsigned scale)
Definition fixed-point.cpp:72
Definition cdrom-loader.hh:39
psyqo::AdvancedPad::Pad & operator++(psyqo::AdvancedPad::Pad &pad)
Definition advancedpad.hh:253
psyqo::AdvancedPad::Pad & operator--(psyqo::AdvancedPad::Pad &pad)
Definition advancedpad.hh:265
char b[9]
Definition string.c:47
static int value
Definition syscalls.h:534
static int ret
Definition syscalls.h:72
void uint32_t(classId, spec)