26#define USE_FIXED_OVERFLOW_CHECKS
32#define MUL_I64_I32_I32(a, b)\
34#define SQUARE_U64_FIXED(a)\
35 static_cast<u64>(__emul((a).GetInternalValue(), (a).GetInternalValue()))
37#define MUL_I64_I32_I32(a, b)\
38 static_cast<i64>(a) * static_cast<i64>(b)
39#define SQUARE_U64_FIXED(a)\
40 static_cast<u64>(static_cast<i64>((a).GetInternalValue()) * static_cast<i64>((a).GetInternalValue()))
44#ifndef USE_FIXED_OVERFLOW_CHECKS
46#define CheckSignedSubtractionOverflow(type, left, right, overflowWarning, underflowWarning)
47#define CheckSignedAdditionOverflow(type, left, right, overflowWarning, underflowWarning)
48#define CheckCastOverflow(var, targetType, overflowWarning, underflowWarning)
49#define CheckU32CastOverflow(var, targetType, overflowWarning)
50#define CheckUnsignedAdditionOverflow(result, operand, overflowWarning)
51#define CheckUnsignedSubtractionOverflow(result, operand, overflowWarning)
52#define CheckNegationOverflow(var, type, overflowWarning)
53#define CheckMultiplicationOverflow(type, left, right, overflowWarning, underflowWarning)
54#define CheckDivisionOverflow(type, left, right, overflowWarning)
58#define CheckSignedSubtractionOverflow(type, left, right, overflowWarning, underflowWarning) \
59 if(left > 0 && right < 0 && left > std::numeric_limits<type>::max() + right) \
60 debug_warn(overflowWarning); \
61 else if(left < 0 && right > 0 && left < std::numeric_limits<type>::min() + right) \
62 debug_warn(underflowWarning);
64#define CheckSignedAdditionOverflow(type, left, right, overflowWarning, underflowWarning) \
65 if(left > 0 && right > 0 && std::numeric_limits<type>::max() - left < right) \
66 debug_warn(overflowWarning); \
67 else if(left < 0 && right < 0 && std::numeric_limits<type>::min() - left > right) \
68 debug_warn(underflowWarning);
70#define CheckCastOverflow(var, targetType, overflowWarning, underflowWarning) \
71 if(var > std::numeric_limits<targetType>::max()) \
72 debug_warn(overflowWarning); \
73 else if(var < std::numeric_limits<targetType>::min()) \
74 debug_warn(underflowWarning);
76#define CheckU32CastOverflow(var, targetType, overflowWarning) \
77 if(var > (u32)std::numeric_limits<targetType>::max()) \
78 debug_warn(overflowWarning);
80#define CheckUnsignedAdditionOverflow(result, operand, overflowWarning) \
81 if(result < operand) \
82 debug_warn(overflowWarning);
84#define CheckUnsignedSubtractionOverflow(result, left, overflowWarning) \
86 debug_warn(overflowWarning);
88#define CheckNegationOverflow(var, type, overflowWarning) \
89 if(value == std::numeric_limits<type>::min()) \
90 debug_warn(overflowWarning);
92#define CheckMultiplicationOverflow(type, left, right, overflowWarning, underflowWarning) \
93 i64 res##left = (i64)left * (i64)right; \
94 CheckCastOverflow(res##left, type, overflowWarning, underflowWarning)
96#define CheckDivisionOverflow(type, left, right, overflowWarning) \
97 if(right == -1) { CheckNegationOverflow(left, type, overflowWarning) }
104 return (
T)(value >= 0 ? value + 0.5f : value - 0.5f);
110 return (
T)(value >= 0 ? value + 0.5 : value - 0.5);
118template<
typename T, T max_t,
int total_bits,
int int_bits,
int fract_bits_,
int fract_pow2>
148 return CFixed(
static_cast<int>(
static_cast<unsigned int>(n) <<
fract_bits) / d);
153 if (!std::isfinite(n))
155 float scaled = n * fract_pow2;
156 return CFixed(round_away_from_zero<T>(scaled));
161 if (!std::isfinite(n))
163 double scaled = n * fract_pow2;
164 return CFixed(round_away_from_zero<T>(scaled));
173 return (
float)
value / (float)fract_pow2;
179 return value / (double)fract_pow2;
277 CheckCastOverflow(result,
T, L
"Overflow in CFixed::operator/(CFixed n)", L
"Underflow in CFixed::operator/(CFixed n)")
292 t = std::max((
i64)std::numeric_limits<T>::min(), std::min((
i64)std::numeric_limits<T>::max(), t));
307 if (n.
value > 0 && t < 0)
309 else if (n.
value < 0 && t > 0)
326 CheckCastOverflow(t,
T, L
"Overflow in CFixed::Multiply(CFixed n)", L
"Underflow in CFixed::Multiply(CFixed n)")
344 CheckCastOverflow(t,
T, L
"Overflow in CFixed::Multiply(CFixed n)", L
"Underflow in CFixed::Multiply(CFixed n)")
377template<
typename T, T max_t,
int total_bits,
int int_bits,
int fract_bits_,
int fract_pow2>
378struct numeric_limits<
CFixed<
T, max_t, total_bits, int_bits, fract_bits_, fract_pow2> >
382 static const bool is_specialized =
true;
#define MUL_I64_I32_I32(a, b)
Definition: Fixed.h:37
#define CheckCastOverflow(var, targetType, overflowWarning, underflowWarning)
Definition: Fixed.h:70
T round_away_from_zero(float value)
Definition: Fixed.h:102
CFixed_15_16 atan2_approx(CFixed_15_16 y, CFixed_15_16 x)
Inaccurate approximation of atan2 over fixed-point numbers.
Definition: Fixed.cpp:147
#define CheckNegationOverflow(var, type, overflowWarning)
Definition: Fixed.h:88
#define CheckSignedAdditionOverflow(type, left, right, overflowWarning, underflowWarning)
Definition: Fixed.h:64
void sincos_approx(CFixed_15_16 a, CFixed_15_16 &sin_out, CFixed_15_16 &cos_out)
Compute sin(a) and cos(a).
Definition: Fixed.cpp:187
#define CheckSignedSubtractionOverflow(type, left, right, overflowWarning, underflowWarning)
Definition: Fixed.h:58
CFixed_15_16 fixed
Default fixed-point type used by the engine.
Definition: Fixed.h:370
#define CheckMultiplicationOverflow(type, left, right, overflowWarning, underflowWarning)
Definition: Fixed.h:92
#define CheckDivisionOverflow(type, left, right, overflowWarning)
Definition: Fixed.h:96
u32 isqrt64(u64 n)
64-bit integer square root.
Definition: Sqrt.cpp:23
A simple fixed-point number class.
Definition: Fixed.h:120
CFixed operator-(CFixed n) const
Subtract a CFixed. Might overflow.
Definition: Fixed.h:239
void SetInternalValue(T n)
Definition: Fixed.h:136
static constexpr CFixed FromFraction(int n, int d)
Definition: Fixed.h:146
double ToDouble() const
Convert to double. Won't be lossy - double can precisely represent all values.
Definition: Fixed.h:177
constexpr CFixed Absolute() const
Definition: Fixed.h:315
CStr8 ToString() const
Returns the shortest string such that FromString will parse to the correct value.
Definition: Fixed.cpp:96
constexpr CFixed MultiplyClamp(int n) const
Multiply by an integer. Avoids overflow by clamping to min/max representable value.
Definition: Fixed.h:289
CFixed operator/(int n) const
Divide by an integer. Must not have n == 0. Cannot overflow unless n == -1.
Definition: Fixed.h:297
static CFixed Zero()
Definition: Fixed.h:131
constexpr bool operator<(CFixed n) const
Numeric comparison.
Definition: Fixed.h:221
float ToFloat() const
Convert to float. May be lossy - float can't represent all values.
Definition: Fixed.h:171
static constexpr CFixed FromFloat(float n)
Definition: Fixed.h:151
CFixed()
Definition: Fixed.h:129
constexpr CFixed(T v)
Definition: Fixed.h:124
constexpr CFixed & operator+=(CFixed n)
Add a CFixed. Might overflow.
Definition: Fixed.h:246
constexpr bool operator==(CFixed n) const
Equality.
Definition: Fixed.h:212
constexpr bool operator<=(CFixed n) const
Numeric comparison.
Definition: Fixed.h:218
constexpr CFixed Square() const
Multiply the value by itself.
Definition: Fixed.h:333
constexpr CFixed & operator-=(CFixed n)
Subtract a CFixed. Might overflow.
Definition: Fixed.h:249
constexpr int ToInt_RoundToInfinity() const
Definition: Fixed.h:190
CFixed Multiply(CFixed n) const
Multiply by a CFixed.
Definition: Fixed.h:321
CFixed operator<<(int n) const
Definition: Fixed.h:264
constexpr CFixed Sqrt() const
Definition: Fixed.h:348
constexpr int ToInt_RoundToNearest() const
Definition: Fixed.h:200
CFixed operator-() const
Negate a CFixed.
Definition: Fixed.h:252
CFixed operator/(float n) const
CFixed MulDiv(CFixed m, CFixed d) const
Compute this*m/d.
Definition: Fixed.h:341
constexpr int ToInt_RoundToNegInfinity() const
Definition: Fixed.h:195
constexpr bool operator>=(CFixed n) const
Numeric comparison.
Definition: Fixed.h:224
constexpr bool operator!=(CFixed n) const
Inequality.
Definition: Fixed.h:215
CFixed operator+(CFixed n) const
Add a CFixed. Might overflow.
Definition: Fixed.h:232
CFixed operator/(CFixed n) const
Divide by a CFixed. Must not have n.IsZero(). Might overflow.
Definition: Fixed.h:272
constexpr bool IsZero() const
Returns true if the number is precisely 0.
Definition: Fixed.h:209
T GetInternalValue() const
Definition: Fixed.h:135
static constexpr CFixed FromDouble(double n)
Definition: Fixed.h:159
constexpr CFixed operator%(CFixed n) const
Mod by a fixed. Must not have n == 0. Result has the same sign as n.
Definition: Fixed.h:304
constexpr int ToInt_RoundToZero() const
Definition: Fixed.h:182
@ fract_bits
Definition: Fixed.h:127
T value
Definition: Fixed.h:122
CFixed operator*(float n) const
static constexpr CFixed FromInt(int n)
Definition: Fixed.h:140
constexpr bool operator>(CFixed n) const
Numeric comparison.
Definition: Fixed.h:227
static CFixed Epsilon()
Definition: Fixed.h:132
static CFixed FromString(const CStr8 &s)
Definition: Fixed.cpp:27
CFixed operator*(int n) const
Multiply by an integer. Might overflow.
Definition: Fixed.h:282
static CFixed Pi()
Definition: Fixed.cpp:182
CFixed operator>>(int n) const
Definition: Fixed.h:258
#define ASSERT(expr)
same as ENSURE in debug mode, does nothing in release mode.
Definition: debug.h:305
Definition: ShaderDefines.cpp:31
#define T(string_literal)
Definition: secure_crt.cpp:77
static fixed max()
Definition: Fixed.h:384
static fixed min()
Definition: Fixed.h:383
CFixed< T, max_t, total_bits, int_bits, fract_bits_, fract_pow2 > fixed
Definition: Fixed.h:380
uint64_t u64
Definition: types.h:40
int32_t i32
Definition: types.h:34
int64_t i64
Definition: types.h:35
uint32_t u32
Definition: types.h:39