29#include <EASTL/functional.h>
38namespace FixedPointInternals {
51 res =
static_cast<uint64_t
>(high) << 32;
52 rem -=
static_cast<uint64_t
>(high * base) << 32;
55 while (
static_cast<int64_t
>(
b) > 0 &&
b < rem) {
72constexpr int32_t
dDiv(int32_t a, int32_t
b,
unsigned scale) {
82 return iDiv(a,
b, scale) *
s;
110template <
unsigned precisionBits = 12, std::
integral T =
int32_t,
unsigned Scale = 1 << precisionBits>
111 requires((precisionBits > 0) && (precisionBits < 32) && ((sizeof(T) == 4) || (sizeof(T) == 2) || sizeof(T) == 1))
113 using
signedUpType = std::conditional<sizeof(T) == 4,
int64_t,
int32_t>::type;
114 using
unsignedUpType = std::conditional<sizeof(T) == 4, u
int64_t, u
int32_t>::type;
115 using upType = std::conditional<std::is_
signed<T>::value,
signedUpType,
unsignedUpType>::type;
126 T raw() const { return value; }
132 static constexpr
unsigned scale = Scale;
139 explicit constexpr FixedPo
int(T
integer, T fraction) : value(
integer * scale + fraction) {
140 static_assert(sizeof(FixedPo
int) == sizeof(T));
153 consteval FixedPo
int(
long double ld) {
154 bool negative = ld < 0;
155 T
integer = negative ? -ld : ld;
156 T fraction = ld * scale -
integer * scale + (negative ? -0.5 : 0.5);
157 value =
integer * scale + fraction;
160 constexpr FixedPo
int() : value(0) {}
161 constexpr FixedPo
int(const FixedPo
int&) = default;
162 constexpr FixedPo
int(FixedPo
int&&) = default;
163 constexpr FixedPo
int& operator=(const FixedPo
int&) = default;
166 constexpr FixedPo
int(T raw, Raw) : value(raw) {}
172 template <
unsigned otherPrecisionBits = 12, std::
integral U =
int32_t>
173 explicit FixedPoint(FixedPoint<otherPrecisionBits, U> other) {
174 if constexpr (precisionBits == otherPrecisionBits) {
175 value = T(other.value);
176 }
else if constexpr (precisionBits > otherPrecisionBits) {
177 value = T(other.value << (precisionBits - otherPrecisionBits));
178 }
else if constexpr (precisionBits < otherPrecisionBits) {
179 value = T(other.value >> (otherPrecisionBits - precisionBits));
199 template <
size_t factor = 1>
200 constexpr T integer()
const {
201 if constexpr (std::is_signed<T>::value) {
203 return T(
value - scale / (2 * factor)) / T(scale / factor);
206 return T(
value + scale / (2 * factor)) / T(scale / factor);
209 template <std::
integral U>
210 constexpr U integer()
const {
211 if constexpr (std::is_signed<T>::value) {
213 return U((
value - scale / 2) / scale);
216 return U((
value + scale / 2) / scale);
230 template <std::
integral U = T>
231 constexpr U floor()
const {
232 if constexpr (std::is_signed<T>::value) {
234 return U(
value - scale + 1) / U(scale);
237 return U(
value) / U(scale);
251 template <std::
integral U = T>
252 constexpr U ceil()
const {
253 if constexpr (std::is_signed<T>::value) {
255 return U(
value) / U(scale);
258 return U(
value + scale - 1) / U(scale);
273 void print(
const eastl::function<
void(
char)>& charPrinter)
const {
275 if constexpr (std::is_signed<T>::value) {
284 constexpr FixedPoint abs()
const {
285 FixedPoint
ret = *
this;
286 if constexpr (std::is_signed<T>::value) {
294 constexpr FixedPoint operator+(FixedPoint other)
const {
295 FixedPoint
ret = *
this;
296 ret.value += other.value;
300 template <std::
integral U>
301 constexpr FixedPoint operator+(U other)
const {
302 FixedPoint
ret = *
this;
303 ret.value += other * scale;
307 constexpr FixedPoint operator-(FixedPoint other)
const {
308 FixedPoint
ret = *
this;
309 ret.value -= other.value;
313 template <std::
integral U>
314 constexpr FixedPoint operator-(U other)
const {
315 FixedPoint
ret = *
this;
316 ret.value -= other * scale;
320 constexpr FixedPoint operator*(FixedPoint other)
const {
329 template <std::
integral U>
330 constexpr FixedPoint operator*(U other)
const {
331 FixedPoint
ret = *
this;
336 constexpr FixedPoint operator/(FixedPoint other)
const {
338 if constexpr (
sizeof(T) == 4) {
339 if constexpr (std::is_signed<T>::value) {
341 }
else if constexpr (!std::is_signed<T>::value) {
344 }
else if constexpr (
sizeof(T) < 4) {
353 template <std::
integral U>
354 constexpr FixedPoint operator/(U other)
const {
355 FixedPoint
ret = *
this;
360 constexpr FixedPoint operator-()
const {
361 FixedPoint
ret = *
this;
366 constexpr FixedPoint& operator+=(FixedPoint other) {
367 value += other.value;
371 template <std::
integral U>
372 constexpr FixedPoint& operator+=(U other) {
373 value += other * scale;
377 constexpr FixedPoint& operator-=(FixedPoint other) {
378 value -= other.value;
382 template <std::
integral U>
383 constexpr FixedPoint& operator-=(U other) {
384 value -= other * scale;
388 constexpr FixedPoint& operator*=(FixedPoint other) {
396 template <std::
integral U>
397 constexpr FixedPoint& operator*=(U other) {
402 constexpr FixedPoint& operator/=(FixedPoint other) {
403 if constexpr (
sizeof(T) == 4) {
404 if constexpr (std::is_signed<T>::value) {
406 }
else if constexpr (!std::is_signed<T>::value) {
409 }
else if constexpr (
sizeof(T) == 2) {
418 template <std::
integral U>
419 constexpr FixedPoint& operator/=(U other) {
424 auto operator<=>(
const FixedPoint& other)
const =
default;
426 constexpr FixedPoint operator<<(
unsigned shift)
const {
427 FixedPoint
ret = *
this;
432 constexpr FixedPoint operator>>(
unsigned shift)
const {
433 FixedPoint
ret = *
this;
438 constexpr FixedPoint& operator<<=(
unsigned shift) {
443 constexpr FixedPoint& operator>>=(
unsigned shift) {
454 FixedPoint
ret = *
this;
465 FixedPoint
ret = *
this;
470 constexpr bool operator!()
const {
return value == 0; }
473template <
unsigned precisionBits = 12, std::integral T = int32_t,
unsigned scale = 1 << precisionBits,
474 std::integral U = int32_t>
475constexpr FixedPoint<precisionBits, T, scale> operator+(U a, FixedPoint<precisionBits, T, scale>
b) {
479template <
unsigned precisionBits = 12, std::integral T = int32_t,
unsigned scale = 1 << precisionBits,
480 std::integral U = int32_t>
481constexpr FixedPoint<precisionBits, T, scale> operator-(U a, FixedPoint<precisionBits, T, scale>
b) {
485template <
unsigned precisionBits = 12, std::integral T = int32_t,
unsigned scale = 1 << precisionBits,
486 std::integral U = int32_t>
487constexpr FixedPoint<precisionBits, T, scale> operator*(U a, FixedPoint<precisionBits, T, scale>
b) {
491template <
unsigned precisionBits = 12, std::integral T = int32_t,
unsigned scale = 1 << precisionBits,
492 std::integral U = int32_t>
493constexpr FixedPoint<precisionBits, T, scale> operator/(U a, FixedPoint<precisionBits, T, scale>
b) {
494 FixedPoint<precisionBits, T, scale>
ret;
495 if constexpr (
sizeof(T) == 4) {
496 if constexpr (std::is_signed<T>::value || std::is_signed<U>::value) {
497 ret.value = FixedPointInternals::dDiv(a * FixedPoint<precisionBits, T>::scale,
b.raw(), scale);
498 }
else if constexpr (!std::is_signed<T>::value && !std::is_signed<U>::value) {
499 ret.value = FixedPointInternals::iDiv(a * FixedPoint<precisionBits, T>::scale,
b.raw(), scale);
501 }
else if constexpr (
sizeof(T) == 2) {
502 ret.value = a * FixedPoint<precisionBits, T>::scale /
b.raw();
507namespace fixed_point_literals {
515consteval FixedPoint<>
operator""_fp(
long double value) {
return value; }
uint32_t t
Definition cop0.c:79
uint8_t b
Definition gte-depthcue.c:39
constexpr uint32_t iDiv(uint64_t rem, uint32_t base, unsigned scale)
Definition fixed-point.hh:42
void printInt(uint32_t value, const eastl::function< void(char)> &, unsigned scale)
Definition fixed-point.cpp:30
constexpr int32_t dDiv(int32_t a, int32_t b, unsigned scale)
Definition fixed-point.hh:72
psyqo::AdvancedPad::Pad & operator++(psyqo::AdvancedPad::Pad &pad)
Definition advancedpad.hh:255
psyqo::AdvancedPad::Pad & operator--(psyqo::AdvancedPad::Pad &pad)
Definition advancedpad.hh:267
char * s
Definition string.c:48
static int value
Definition syscalls.h:535
static int ret
Definition syscalls.h:73
void uint32_t(classId, spec)