Pioneer
Loading...
Searching...
No Matches
fixed.h
Go to the documentation of this file.
1// Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details
2// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3
4#ifndef _FIXED_H
5#define _FIXED_H
6
7#include <SDL_stdinc.h>
8#include <cassert>
9
10template <int FRAC_BITS>
11class fixedf {
12public:
13 static const int FRAC = FRAC_BITS;
14 static const Uint64 MASK = (Uint64(1UL) << FRAC_BITS) - 1;
15
17 v(0) {}
18 // template <int bits>
19 // fixedf(fixedf<bits> f) { *this = f; }
20 constexpr fixedf(Sint64 raw) :
21 v(raw) {}
22 constexpr fixedf(Sint64 num, Sint64 denom) :
23 v((num << FRAC) / denom) {}
24 // ^^ this is fucking shit
25
26 fixedf Abs() const { return fixedf(v >= 0 ? v : -v); }
27 friend fixedf operator+(const fixedf &a, const Sint64 b) { return a + fixedf(b << FRAC); }
28 friend fixedf operator-(const fixedf &a, const Sint64 b) { return a - fixedf(b << FRAC); }
29 friend fixedf operator*(const fixedf &a, const Sint64 b) { return a * fixedf(b << FRAC); }
30 friend fixedf operator/(const fixedf &a, const Sint64 b) { return a / fixedf(b << FRAC); }
31 friend fixedf operator+(const Sint64 a, const fixedf &b) { return fixedf(a << FRAC) + b; }
32 friend fixedf operator-(const Sint64 a, const fixedf &b) { return fixedf(a << FRAC) - b; }
33 friend fixedf operator*(const Sint64 a, const fixedf &b) { return fixedf(a << FRAC) * b; }
34 friend fixedf operator/(const Sint64 a, const fixedf &b) { return fixedf(a << FRAC) / b; }
35 friend bool operator==(const fixedf &a, const Sint64 b) { return a == fixedf(b << FRAC); }
36 friend bool operator==(const Sint64 a, const fixedf &b) { return b == fixedf(a << FRAC); }
37 friend bool operator!=(const fixedf &a, const Sint64 b) { return a != fixedf(b << FRAC); }
38 friend bool operator!=(const Sint64 a, const fixedf &b) { return b != fixedf(a << FRAC); }
39 friend bool operator>=(const fixedf &a, const Sint64 b) { return a >= fixedf(b << FRAC); }
40 friend bool operator>=(const Sint64 a, const fixedf &b) { return b >= fixedf(a << FRAC); }
41 friend bool operator<=(const fixedf &a, const Sint64 b) { return a <= fixedf(b << FRAC); }
42 friend bool operator<=(const Sint64 a, const fixedf &b) { return b <= fixedf(a << FRAC); }
43 friend bool operator>(const fixedf &a, const Sint64 b) { return a > fixedf(b << FRAC); }
44 friend bool operator>(const Sint64 a, const fixedf &b) { return b > fixedf(a << FRAC); }
45 friend bool operator<(const fixedf &a, const Sint64 b) { return a < fixedf(b << FRAC); }
46 friend bool operator<(const Sint64 a, const fixedf &b) { return b < fixedf(a << FRAC); }
47 friend fixedf operator>>(const fixedf &a, const int b) { return fixedf(a.v >> b); }
48 friend fixedf operator<<(const fixedf &a, const int b) { return fixedf(a.v << b); }
49
51 {
52 (*this) = (*this) * a;
53 return (*this);
54 }
55 fixedf &operator*=(const Sint64 a)
56 {
57 (*this) = (*this) * a;
58 return (*this);
59 }
61 {
62 (*this) = (*this) / a;
63 return (*this);
64 }
65 fixedf &operator/=(const Sint64 a)
66 {
67 (*this) = (*this) / a;
68 return (*this);
69 }
71 {
72 (*this) = (*this) + a;
73 return (*this);
74 }
75 fixedf &operator+=(const Sint64 a)
76 {
77 (*this) = (*this) + a;
78 return (*this);
79 }
81 {
82 (*this) = (*this) - a;
83 return (*this);
84 }
85 fixedf &operator-=(const Sint64 a)
86 {
87 (*this) = (*this) - a;
88 return (*this);
89 }
90 fixedf &operator>>=(const int a)
91 {
92 v >>= a;
93 return (*this);
94 }
95 fixedf &operator<<=(const int a)
96 {
97 v <<= a;
98 return (*this);
99 }
100
101 friend fixedf operator-(const fixedf &a) { return fixedf(-a.v); }
102 friend fixedf operator+(const fixedf &a, const fixedf &b) { return fixedf(a.v + b.v); }
103 friend fixedf operator-(const fixedf &a, const fixedf &b) { return fixedf(a.v - b.v); }
104 friend fixedf operator*(const fixedf &a, const fixedf &b)
105 {
106 // 64*64 = (128bit>>FRAC) & ((1<<64)-1)
107 //return fixedf(a.v*b.v >> FRAC);
108 Sint64 hi = 0;
109 Uint64 a0, a1, b0, b1;
110 Uint64 lo = 0;
111 Uint64 oldlo;
112 int isneg = 0;
113 if (a.v < 0) {
114 a0 = (-a.v) & 0xffffffff;
115 a1 = (-a.v) >> 32;
116 isneg = !isneg;
117 } else {
118 a0 = a.v & 0xffffffff;
119 a1 = a.v >> 32;
120 }
121 if (b.v < 0) {
122 b0 = (-b.v) & 0xffffffff;
123 b1 = (-b.v) >> 32;
124 isneg = !isneg;
125 } else {
126 b0 = b.v & 0xffffffff;
127 b1 = b.v >> 32;
128 }
129 Uint64 x;
130 // a0 * b;
131 lo = a0 * b0;
132 oldlo = lo;
133 x = a0 * b1;
134 lo += x << 32;
135 if (lo < oldlo) hi++;
136 oldlo = lo;
137 hi += (x >> 32);
138
139 // a1 * b;
140 x = a1 * b0;
141 lo += x << 32;
142 if (lo < oldlo) hi++;
143 oldlo = lo;
144 hi += x >> 32;
145
146 hi += a1 * b1;
147 Sint64 out = (lo >> FRAC) + ((hi & MASK) << (64 - FRAC));
148 return isneg ? -out : out;
149 }
150 friend fixedf operator/(const fixedf &a, const fixedf &b)
151 {
152 // 128-bit divided by 64-bit, to make sure high bits are not lost
153 Sint64 quotient_hi = a.v >> (64 - FRAC);
154 Uint64 quotient_lo = a.v << FRAC;
155 Sint64 d = b.v;
156 int isneg = 0;
157 Sint64 remainder = 0;
158
159 if (d < 0) {
160 d = -d;
161 isneg = 1;
162 }
163
164 for (int i = 0; i < 128; i++) {
165 Uint64 sbit = (Uint64(1) << 63) & quotient_hi;
166 remainder <<= 1;
167 if (sbit) remainder |= 1;
168 // shift quotient left 1
169 {
170 quotient_hi <<= 1;
171 if (quotient_lo & (Uint64(1) << 63)) quotient_hi |= 1;
172 quotient_lo <<= 1;
173 }
174 if (remainder >= d) {
175 remainder -= d;
176 quotient_lo |= 1;
177 }
178 }
179 return (isneg ? -Sint64(quotient_lo) : quotient_lo);
180 }
181 friend bool operator==(const fixedf &a, const fixedf &b) { return a.v == b.v; }
182 friend bool operator!=(const fixedf &a, const fixedf &b) { return a.v != b.v; }
183 friend bool operator>(const fixedf &a, const fixedf &b) { return a.v > b.v; }
184 friend bool operator<(const fixedf &a, const fixedf &b) { return a.v < b.v; }
185 friend bool operator>=(const fixedf &a, const fixedf &b) { return a.v >= b.v; }
186 friend bool operator<=(const fixedf &a, const fixedf &b) { return a.v <= b.v; }
187
188 /* implicit operator float() bad */
189 inline int ToInt32() const { return int(v >> FRAC); }
190 inline Sint64 ToInt64() const { return v >> FRAC; }
191 inline float ToFloat() const { return v / float(Sint64(1) << FRAC); }
192 inline double ToDouble() const { return v / double(Sint64(1) << FRAC); }
193
194 static fixedf FromDouble(const double val) { return fixedf(Sint64(((val) * double(Sint64(1) << FRAC)))); }
195
196 template <int NEW_FRAC_BITS>
197 operator fixedf<NEW_FRAC_BITS>() const
198 {
199 int shift = NEW_FRAC_BITS - FRAC_BITS;
200 if (shift > 0)
201 return fixedf<NEW_FRAC_BITS>(v << shift);
202 else
203 return fixedf<NEW_FRAC_BITS>(v >> (-shift));
204 }
205
206 static fixedf SqrtOf(const fixedf &a)
207 {
208 /* only works on even-numbered fractional bits */
209 assert(!(FRAC & 1));
210 Uint64 root, remHi, remLo, testDiv, count;
211 root = 0;
212 remHi = 0;
213 remLo = a.v;
214 count = 32 + (FRAC >> 1) - 1;
215 do {
216 remHi = (remHi << 2) | (remLo >> 62);
217 remLo <<= 2;
218 root <<= 1;
219 testDiv = (root << 1) + 1;
220 if (remHi >= testDiv) {
221 remHi -= testDiv;
222 root++;
223 }
224 } while (count-- != 0);
225
226 return (fixedf(root));
227 }
228
229 static fixedf CubeRootOf(const fixedf &a)
230 {
231 /* NR method. XXX very bad initial estimate (we get there in
232 * the end... XXX */
233 fixedf x = a;
234 for (int i = 0; i < 48; i++)
235 x = fixedf(1, 3) * ((a / (x * x)) + 2 * x);
236 return x;
237 }
238
239 Sint64 v;
240};
241
243
244#endif /* _FIXED_H */
double val
Definition PrecalcPath.cpp:40
Definition fixed.h:11
static fixedf CubeRootOf(const fixedf &a)
Definition fixed.h:229
friend fixedf operator+(const fixedf &a, const fixedf &b)
Definition fixed.h:102
fixedf & operator-=(const Sint64 a)
Definition fixed.h:85
friend bool operator<=(const Sint64 a, const fixedf &b)
Definition fixed.h:42
friend fixedf operator+(const Sint64 a, const fixedf &b)
Definition fixed.h:31
friend fixedf operator<<(const fixedf &a, const int b)
Definition fixed.h:48
friend fixedf operator/(const Sint64 a, const fixedf &b)
Definition fixed.h:34
fixedf & operator*=(const Sint64 a)
Definition fixed.h:55
Sint64 v
Definition fixed.h:239
static fixedf SqrtOf(const fixedf &a)
Definition fixed.h:206
friend fixedf operator/(const fixedf &a, const Sint64 b)
Definition fixed.h:30
int ToInt32() const
Definition fixed.h:189
friend bool operator>=(const fixedf &a, const Sint64 b)
Definition fixed.h:39
friend bool operator<(const fixedf &a, const fixedf &b)
Definition fixed.h:184
friend bool operator!=(const fixedf &a, const fixedf &b)
Definition fixed.h:182
friend fixedf operator-(const fixedf &a)
Definition fixed.h:101
friend bool operator>(const fixedf &a, const Sint64 b)
Definition fixed.h:43
constexpr fixedf(Sint64 raw)
Definition fixed.h:20
fixedf & operator<<=(const int a)
Definition fixed.h:95
fixedf & operator>>=(const int a)
Definition fixed.h:90
fixedf & operator/=(const fixedf &a)
Definition fixed.h:60
fixedf & operator-=(const fixedf &a)
Definition fixed.h:80
friend bool operator<(const Sint64 a, const fixedf &b)
Definition fixed.h:46
friend bool operator<=(const fixedf &a, const Sint64 b)
Definition fixed.h:41
friend bool operator==(const fixedf &a, const Sint64 b)
Definition fixed.h:35
friend fixedf operator-(const Sint64 a, const fixedf &b)
Definition fixed.h:32
fixedf & operator+=(const Sint64 a)
Definition fixed.h:75
friend fixedf operator>>(const fixedf &a, const int b)
Definition fixed.h:47
friend bool operator==(const fixedf &a, const fixedf &b)
Definition fixed.h:181
friend bool operator==(const Sint64 a, const fixedf &b)
Definition fixed.h:36
fixedf Abs() const
Definition fixed.h:26
friend fixedf operator/(const fixedf &a, const fixedf &b)
Definition fixed.h:150
float ToFloat() const
Definition fixed.h:191
fixedf()
Definition fixed.h:16
static fixedf FromDouble(const double val)
Definition fixed.h:194
friend fixedf operator-(const fixedf &a, const fixedf &b)
Definition fixed.h:103
static const Uint64 MASK
Definition fixed.h:14
fixedf & operator+=(const fixedf &a)
Definition fixed.h:70
friend bool operator>(const Sint64 a, const fixedf &b)
Definition fixed.h:44
friend fixedf operator+(const fixedf &a, const Sint64 b)
Definition fixed.h:27
constexpr fixedf(Sint64 num, Sint64 denom)
Definition fixed.h:22
fixedf & operator/=(const Sint64 a)
Definition fixed.h:65
friend fixedf operator*(const Sint64 a, const fixedf &b)
Definition fixed.h:33
friend fixedf operator*(const fixedf &a, const fixedf &b)
Definition fixed.h:104
friend bool operator!=(const fixedf &a, const Sint64 b)
Definition fixed.h:37
friend bool operator>=(const fixedf &a, const fixedf &b)
Definition fixed.h:185
static const int FRAC
Definition fixed.h:13
friend bool operator!=(const Sint64 a, const fixedf &b)
Definition fixed.h:38
friend fixedf operator-(const fixedf &a, const Sint64 b)
Definition fixed.h:28
friend bool operator>=(const Sint64 a, const fixedf &b)
Definition fixed.h:40
Sint64 ToInt64() const
Definition fixed.h:190
friend bool operator<(const fixedf &a, const Sint64 b)
Definition fixed.h:45
friend bool operator<=(const fixedf &a, const fixedf &b)
Definition fixed.h:186
fixedf & operator*=(const fixedf &a)
Definition fixed.h:50
friend bool operator>(const fixedf &a, const fixedf &b)
Definition fixed.h:183
friend fixedf operator*(const fixedf &a, const Sint64 b)
Definition fixed.h:29
double ToDouble() const
Definition fixed.h:192
fixedf< 32 > fixed
Definition fixed.h:242