Plasma Engine  2.0
Loading...
Searching...
No Matches
FixedPoint_inl.h
1#pragma once
2
3#include <Foundation/Math/Math.h>
4
5template <plUInt8 DecimalBits>
7{
8 m_iValue = iVal << DecimalBits;
9 return *this;
10}
11
12template <plUInt8 DecimalBits>
14{
15 m_iValue = (plInt32)plMath::Round(fVal * (1 << DecimalBits));
16 return *this;
17}
18
19template <plUInt8 DecimalBits>
21{
22 m_iValue = (plInt32)plMath::Round(fVal * (1 << DecimalBits));
23 return *this;
24}
25
26template <plUInt8 DecimalBits>
28{
29 return (plInt32)(m_iValue >> DecimalBits);
30}
31
32template <plUInt8 DecimalBits>
34{
35 return (float)((double)m_iValue / (double)(1 << DecimalBits));
36}
37
38template <plUInt8 DecimalBits>
40{
41 return ((double)m_iValue / (double)(1 << DecimalBits));
42}
43
44template <plUInt8 DecimalBits>
46{
47 // lhs and rhs are in N:M format (N Bits for the Integer part, M Bits for the fractional part)
48 // after multiplication, it will be in 2N:2M format
49
50 const plInt64 TempLHS = m_iValue;
51 const plInt64 TempRHS = rhs.m_iValue;
52
53 plInt64 TempRes = TempLHS * TempRHS;
54
55 // the lower DecimalBits Bits are nearly of no concern (we throw them away anyway), except for the upper most Bit
56 // that is Bit '(DecimalBits - 1)' and its Bitmask is therefore '(1 << (DecimalBits - 1))'
57 // If that Bit is set, then the lowest DecimalBits represent a value of more than '0.5' (of their range)
58 // so '(TempRes & (1 << (DecimalBits - 1))) ' is either 0 or 1 depending on whether the lower DecimalBits Bits represent a value larger than 0.5 or
59 // not we shift that Bit one to the left and add it to the original value and thus 'round up' the result
60 TempRes += ((TempRes & (1 << (DecimalBits - 1))) << 1);
61
62 TempRes >>= DecimalBits; // result format: 2N:M
63
64 // the upper N Bits are thrown away during conversion from 64 Bit to 32 Bit
65 m_iValue = (plInt32)TempRes;
66}
67
68template <plUInt8 DecimalBits>
70{
71 plInt64 TempLHS = m_iValue;
72 const plInt64 TempRHS = rhs.m_iValue;
73
74 TempLHS <<= 31;
75
76 plInt64 TempRes = TempLHS / TempRHS;
77
78 // same rounding concept as in multiplication
79 TempRes += ((TempRes & (1 << (31 - DecimalBits - 1))) << 1);
80
81 TempRes >>= (31 - DecimalBits);
82
83 // here we throw away the upper 32 Bits again (not needed anymore)
84 m_iValue = (plInt32)TempRes;
85}
86
87
88template <plUInt8 DecimalBits>
90{
92 res += rhs;
93 return res;
94}
95
96template <plUInt8 DecimalBits>
98{
100 res -= rhs;
101 return res;
102}
103
104template <plUInt8 DecimalBits>
106{
108 res *= rhs;
109 return res;
110}
111
112template <plUInt8 DecimalBits>
114{
116 res /= rhs;
117 return res;
118}
119
120
121template <plUInt8 DecimalBits>
122plFixedPoint<DecimalBits> operator*(const plFixedPoint<DecimalBits>& lhs, plInt32 rhs)
123{
125 ret *= rhs;
126 return ret;
127}
128
129template <plUInt8 DecimalBits>
130plFixedPoint<DecimalBits> operator*(plInt32 lhs, const plFixedPoint<DecimalBits>& rhs)
131{
133 ret *= lhs;
134 return ret;
135}
136
137template <plUInt8 DecimalBits>
138plFixedPoint<DecimalBits> operator/(const plFixedPoint<DecimalBits>& lhs, plInt32 rhs)
139{
141 ret /= rhs;
142 return ret;
143}
Implements fixed point arithmetic for fractional values.
Definition FixedPoint.h:23
double ToDouble() const
Implicit conversion to double.
Definition FixedPoint_inl.h:39
const plFixedPoint< DecimalBits > & operator=(plInt32 iVal)
Assignment from an integer.
Definition FixedPoint_inl.h:6
void operator*=(const plFixedPoint< DecimalBits > &rhs)
*= operator
Definition FixedPoint_inl.h:45
plInt32 ToInt() const
Implicit conversion to int (the fractional part is dropped).
Definition FixedPoint_inl.h:27
float ToFloat() const
Implicit conversion to float.
Definition FixedPoint_inl.h:33
void operator/=(const plFixedPoint< DecimalBits > &rhs)
/= operator
Definition FixedPoint_inl.h:69
PL_ALWAYS_INLINE double Round(double f)
Rounds f to the next integer.
Definition MathDouble_inl.h:35