18 #ifndef INCLUDED_FIXED
19 #define INCLUDED_FIXED
28 #define USE_FIXED_OVERFLOW_CHECKS
34 #define FIXED_MUL_I64_I32_I32(a, b) (__emul((a), (b)))
36 #define FIXED_MUL_I64_I32_I32(a, b) ((i64)(a) * (i64)(b))
40 #ifndef USE_FIXED_OVERFLOW_CHECKS
42 #define CheckSignedSubtractionOverflow(type, left, right, overflowWarning, underflowWarning)
43 #define CheckSignedAdditionOverflow(type, left, right, overflowWarning, underflowWarning)
44 #define CheckCastOverflow(var, targetType, overflowWarning, underflowWarning)
45 #define CheckU32CastOverflow(var, targetType, overflowWarning)
46 #define CheckUnsignedAdditionOverflow(result, operand, overflowWarning)
47 #define CheckUnsignedSubtractionOverflow(result, operand, overflowWarning)
48 #define CheckNegationOverflow(var, type, overflowWarning)
49 #define CheckMultiplicationOverflow(type, left, right, overflowWarning, underflowWarning)
50 #define CheckDivisionOverflow(type, left, right, overflowWarning)
52 #else // USE_FIXED_OVERFLOW_CHECKS
54 #define CheckSignedSubtractionOverflow(type, left, right, overflowWarning, underflowWarning) \
55 if(left > 0 && right < 0 && left > std::numeric_limits<type>::max() + right) \
56 debug_warn(overflowWarning); \
57 else if(left < 0 && right > 0 && left < std::numeric_limits<type>::min() + right) \
58 debug_warn(underflowWarning);
60 #define CheckSignedAdditionOverflow(type, left, right, overflowWarning, underflowWarning) \
61 if(left > 0 && right > 0 && std::numeric_limits<type>::max() - left < right) \
62 debug_warn(overflowWarning); \
63 else if(left < 0 && right < 0 && std::numeric_limits<type>::min() - left > right) \
64 debug_warn(underflowWarning);
66 #define CheckCastOverflow(var, targetType, overflowWarning, underflowWarning) \
67 if(var > std::numeric_limits<targetType>::max()) \
68 debug_warn(overflowWarning); \
69 else if(var < std::numeric_limits<targetType>::min()) \
70 debug_warn(underflowWarning);
72 #define CheckU32CastOverflow(var, targetType, overflowWarning) \
73 if(var > (u32)std::numeric_limits<targetType>::max()) \
74 debug_warn(overflowWarning);
76 #define CheckUnsignedAdditionOverflow(result, operand, overflowWarning) \
77 if(result < operand) \
78 debug_warn(overflowWarning);
80 #define CheckUnsignedSubtractionOverflow(result, left, overflowWarning) \
82 debug_warn(overflowWarning);
84 #define CheckNegationOverflow(var, type, overflowWarning) \
85 if(value == std::numeric_limits<type>::min()) \
86 debug_warn(overflowWarning);
88 #define CheckMultiplicationOverflow(type, left, right, overflowWarning, underflowWarning) \
89 i64 res##left = (i64)left * (i64)right; \
90 CheckCastOverflow(res##left, type, overflowWarning, underflowWarning)
92 #define CheckDivisionOverflow(type, left, right, overflowWarning) \
93 if(right == -1) { CheckNegationOverflow(left, type, overflowWarning) }
95 #endif // USE_FIXED_OVERFLOW_CHECKS
100 return (
T)(value >= 0 ? value + 0.5f : value - 0.5f);
103 template <
typename T>
106 return (
T)(value >= 0 ? value + 0.5 : value - 0.5);
114 template<
typename T, T max_t,
int total_bits,
int int_bits,
int fract_bits_,
int fract_pow2>
145 float scaled = n * fract_pow2;
146 return CFixed(round_away_from_zero<T>(scaled));
153 double scaled = n * fract_pow2;
154 return CFixed(round_away_from_zero<T>(scaled));
163 return (
float)
value / (float)fract_pow2;
169 return value / (double)fract_pow2;
254 CheckCastOverflow(result,
T, L
"Overflow in CFixed::operator/(CFixed n)", L
"Underflow in CFixed::operator/(CFixed n)")
276 if (n.
value > 0 && t < 0)
278 else if (n.
value < 0 && t > 0)
295 CheckCastOverflow(t,
T, L
"Overflow in CFixed::Multiply(CFixed n)", L
"Underflow in CFixed::Multiply(CFixed n)")
313 CheckCastOverflow(t,
T, L
"Overflow in CFixed::Multiply(CFixed n)", L
"Underflow in CFixed::Multiply(CFixed n)")
346 template<
typename T, T max_t,
int total_bits,
int int_bits,
int fract_bits_,
int fract_pow2>
347 struct numeric_limits<
CFixed<
T, max_t, total_bits, int_bits, fract_bits_, fract_pow2> >
351 static const bool is_specialized =
true;
369 #endif // INCLUDED_FIXED
CFixed< T, max_t, total_bits, int_bits, fract_bits_, fract_pow2 > fixed
A simple fixed-point number class.
bool operator>(CFixed n) const
Numeric comparison.
#define FIXED_MUL_I64_I32_I32(a, b)
CFixed_15_16 fixed
Default fixed-point type used by the engine.
CFixed operator-() const
Negate a CFixed.
CFixed & operator+=(CFixed n)
Add a CFixed. Might overflow.
CFixed operator+(CFixed n) const
Add a CFixed. Might overflow.
CFixed & operator-=(CFixed n)
Subtract a CFixed. Might overflow.
T GetInternalValue() const
#define CheckSignedSubtractionOverflow(type, left, right, overflowWarning, underflowWarning)
CFixed operator%(CFixed n) const
Mod by a fixed. Must not have n == 0. Result has the same sign as n.
int ToInt_RoundToZero() const
void SetInternalValue(T n)
CFixed< i32,(i32) 0x7fffffff, 32, 15, 16, 65536 > CFixed_15_16
A fixed-point number class with 1-bit sign, 15-bit integral part, 16-bit fractional part...
CFixed operator/(int n) const
Divide by an integer. Must not have n == 0. Cannot overflow unless n == -1.
T round_away_from_zero(float value)
CFixed Multiply(CFixed n) const
Multiply by a CFixed.
float ToFloat() const
Convert to float. May be lossy - float can't represent all values.
#define CheckNegationOverflow(var, type, overflowWarning)
u32 isqrt64(u64 n)
64-bit integer square root.
bool operator>=(CFixed n) const
Numeric comparison.
static CFixed FromString(const CStr8 &s)
#define CheckDivisionOverflow(type, left, right, overflowWarning)
#define T(string_literal)
CFixed operator*(int n) const
Multiply by an integer. Might overflow.
int ToInt_RoundToNegInfinity() const
double ToDouble() const
Convert to double. Won't be lossy - double can precisely represent all values.
#define CheckSignedAdditionOverflow(type, left, right, overflowWarning, underflowWarning)
CFixed MulDiv(CFixed m, CFixed d) const
Compute this*m/d.
static CFixed FromInt(int n)
CFixed operator-(CFixed n) const
Subtract a CFixed. Might overflow.
bool IsZero() const
Returns true if the number is precisely 0.
bool operator<(CFixed n) const
Numeric comparison.
CStr8 ToString() const
Returns the shortest string such that FromString will parse to the correct value. ...
#define CheckMultiplicationOverflow(type, left, right, overflowWarning, underflowWarning)
bool operator!=(CFixed n) const
Inequality.
bool operator<=(CFixed n) const
Numeric comparison.
static CFixed FromFloat(float n)
void sincos_approx(CFixed_15_16 a, CFixed_15_16 &sin_out, CFixed_15_16 &cos_out)
Compute sin(a) and cos(a).
CFixed Square() const
Multiply the value by itself.
CFixed operator/(CFixed n) const
Divide by a CFixed. Must not have n.IsZero(). Might overflow.
int ToInt_RoundToNearest() const
bool operator==(CFixed n) const
Equality.
CFixed_15_16 atan2_approx(CFixed_15_16 y, CFixed_15_16 x)
Inaccurate approximation of atan2 over fixed-point numbers.
static CFixed FromDouble(double n)
int ToInt_RoundToInfinity() const
#define CheckCastOverflow(var, targetType, overflowWarning, underflowWarning)