Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
mathlib.qc
Go to the documentation of this file.
1#include "mathlib.qh"
2#if defined(CSQC)
3#elif defined(MENUQC)
4#elif defined(SVQC)
5#endif
6
7int fpclassify(float e)
8{
9 if(isnan(e))
10 return FP_NAN;
11 if(isinf(e))
12 return FP_INFINITE;
13 if(e == 0)
14 return FP_ZERO;
15 return FP_NORMAL;
16}
17bool isfinite(float e)
18{
19 return !(isnan(e) || isinf(e));
20}
21bool isinf(float e)
22{
23 return (e != 0) && (e + e == e);
24}
25bool isnan(float e)
26{
27 // The sane way to detect NaN is this:
28 float f = e;
29 return (e != f);
30 // but darkplaces used to be compiled with -ffinite-math-only which broke it.
31 // DP is fixed now but until all clients update (so after 0.8.3) we have to use the following workaround
32 // or they'd have issues when connecting to newer servers.
33 // bones_was_here: fixed in 0.8.5 and later.
34
35 // Negative NaN ("-nan") is much more common but plain "nan" can be created by negating *some* -nans so we need to check both.
36 // DP's QCVM and GMQCC's QCVM behave differently - one needs ftos(-(0.0 / 0.0)), the other ftos(-sqrt(-1)).
37// string s = ftos(e);
38// return s == "nan" || s == "-nan";
39}
40bool isnormal(float e)
41{
42 return isfinite(e);
43}
44bool signbit(float e)
45{
46 return (e < 0);
47}
48
49float acosh(float e)
50{
51 return log(e + sqrt(e*e - 1));
52}
53float asinh(float e)
54{
55 return log(e + sqrt(e*e + 1));
56}
57float atanh(float e)
58{
59 return 0.5 * log((1+e) / (1-e));
60}
61float cosh(float e)
62{
63 return 0.5 * (exp(e) + exp(-e));
64}
65float sinh(float e)
66{
67 return 0.5 * (exp(e) - exp(-e));
68}
69float tanh(float e)
70{
71 return sinh(e) / cosh(e);
72}
73
74float exp(float e)
75{
76 return pow(M_E, e);
77}
78float exp2(float e)
79{
80 return pow(2, e);
81}
82float expm1(float e)
83{
84 return exp(e) - 1;
85}
86
87vector frexp(float e)
88{
89 vector v;
90 v.z = 0;
91 v.y = ilogb(e) + 1;
92 v.x = e / pow(2, v.y);
93 return v;
94}
95int ilogb(float e)
96{
97 return floor(log2(fabs(e)));
98}
99float ldexp(float x, int e)
100{
101 return x * pow(2, e);
102}
103float logn(float e, float base)
104{
105 return log(e) / log(base);
106}
107float log10(float e)
108{
109 return log(e) * M_LOG10E;
110}
111float log1p(float e)
112{
113 return log(e + 1);
114}
115float log2(float e)
116{
117 return log(e) * M_LOG2E;
118}
119float logb(float e)
120{
121 return floor(log2(fabs(e)));
122}
123vector modf(float f)
124{
125 return '1 0 0' * (f - trunc(f)) + '0 1 0' * trunc(f);
126}
127
128float scalbn(float e, int n)
129{
130 return e * pow(2, n);
131}
132
133float cbrt(float e)
134{
135 return copysign(pow(fabs(e), (1.0/3.0)), e);
136}
137float hypot(float e, float f)
138{
139 return sqrt(e*e + f*f);
140}
141
142float erf(float e)
143{
144 // approximation taken from wikipedia
145 float f;
146 f = e*e;
147 return copysign(sqrt(1 - exp(-f * (1.273239544735163 + 0.14001228868667 * f) / (1 + 0.14001228868667 * f))), e);
148}
149float erfc(float e)
150{
151 return 1.0 - erf(e);
152}
154{
155 // TODO improve accuracy
156 if(!isfinite(e))
157 return fabs(e) * '1 0 0' + copysign(1, e) * '0 1 0';
158 if(e < 1 && e == floor(e))
159 return nan("gamma") * '1 1 1';
160 if(e < 0.1)
161 {
162 vector v;
163 v = lgamma(1.0 - e);
164 // reflection formula:
165 // gamma(1-z) * gamma(z) = pi / sin(pi*z)
166 // lgamma(1-z) + lgamma(z) = log(pi) - log(sin(pi*z))
167 // sign of gamma(1-z) = sign of gamma(z) * sign of sin(pi*z)
168 v.z = sin(M_PI * e);
169 v.x = log(M_PI) - log(fabs(v.z)) - v.x;
170 if(v.z < 0)
171 v.y = -v.y;
172 v.z = 0;
173 return v;
174 }
175 if(e < 1.1)
176 return lgamma(e + 1) - log(e) * '1 0 0';
177 e -= 1;
178 return (0.5 * log(2 * M_PI * e) + e * (log(e) - 1)) * '1 0 0' + '0 1 0';
179}
180float tgamma(float e)
181{
182 vector v = lgamma(e);
183 return exp(v.x) * v.y;
184}
185
195float pymod(float e, float f)
196{
197 return e - f * floor(e / f);
198}
199
200float nearbyint(float e)
201{
202 return rint(e);
203}
204float trunc(float e)
205{
206 return (e>=0) ? floor(e) : ceil(e);
207}
208
209float fmod(float e, float f)
210{
211 return e - f * trunc(e / f);
212}
213float remainder(float e, float f)
214{
215 return e - f * rint(e / f);
216}
217vector remquo(float e, float f)
218{
219 vector v;
220 v.z = 0;
221 v.y = rint(e / f);
222 v.x = e - f * v.y;
223 return v;
224}
225
226float copysign(float e, float f)
227{
228 return fabs(e) * ((f>0) ? 1 : -1);
229}
230
231float nan(string tag)
232{
233 return sqrt(-1);
234}
235float nextafter(float e, float f)
236{
237 // TODO very crude
238 if(e == f)
239 return nan("nextafter");
240 if(e > f)
241 return -nextafter(-e, -f);
242 // now we know that e < f
243 // so we need the next number > e
244 float d, a, b;
245 d = max(fabs(e), 0.00000000000000000000001);
246 a = e + d;
247 do
248 {
249 d *= 0.5;
250 b = a;
251 a = e + d;
252 }
253 while(a != e);
254 return b;
255}
256float nexttoward(float e, float f)
257{
258 return nextafter(e, f);
259}
260
261float fdim(float e, float f)
262{
263 return max(e-f, 0);
264}
265float fmax(float e, float f)
266{
267 return max(e, f);
268}
269float fmin(float e, float f)
270{
271 return min(e, f);
272}
273float fma(float e, float f, float g)
274{
275 return e * f + g;
276}
277
278int isgreater(float e, float f)
279{
280 return e > f;
281}
282int isgreaterequal(float e, float f)
283{
284 return e >= f;
285}
286int isless(float e, float f)
287{
288 return e < f;
289}
290int islessequal(float e, float f)
291{
292 return e <= f;
293}
294int islessgreater(float e, float f)
295{
296 return e < f || e > f;
297}
298int isunordered(float e, float f)
299{
300 return !(e < f || e == f || e > f);
301}
float log(float f)
#define pow(a, b)
Definition _all.inc:67
float trunc(float e)
Definition mathlib.qc:204
float erf(float e)
Definition mathlib.qc:142
float fdim(float e, float f)
Definition mathlib.qc:261
bool signbit(float e)
Definition mathlib.qc:44
int ilogb(float e)
Definition mathlib.qc:95
bool isinf(float e)
Definition mathlib.qc:21
float erfc(float e)
Definition mathlib.qc:149
int isgreater(float e, float f)
Definition mathlib.qc:278
float log2(float e)
Definition mathlib.qc:115
vector remquo(float e, float f)
Definition mathlib.qc:217
float nan(string tag)
Definition mathlib.qc:231
float fmin(float e, float f)
Definition mathlib.qc:269
float fmax(float e, float f)
Definition mathlib.qc:265
float exp2(float e)
Definition mathlib.qc:78
float expm1(float e)
Definition mathlib.qc:82
float cbrt(float e)
Definition mathlib.qc:133
float log1p(float e)
Definition mathlib.qc:111
float sinh(float e)
Definition mathlib.qc:65
float remainder(float e, float f)
Definition mathlib.qc:213
vector lgamma(float e)
Definition mathlib.qc:153
float exp(float e)
Definition mathlib.qc:74
bool isnormal(float e)
Definition mathlib.qc:40
float hypot(float e, float f)
Definition mathlib.qc:137
float nextafter(float e, float f)
Definition mathlib.qc:235
float cosh(float e)
Definition mathlib.qc:61
float log10(float e)
Definition mathlib.qc:107
float copysign(float e, float f)
Definition mathlib.qc:226
float tanh(float e)
Definition mathlib.qc:69
int islessequal(float e, float f)
Definition mathlib.qc:290
int isunordered(float e, float f)
Definition mathlib.qc:298
float logn(float e, float base)
Definition mathlib.qc:103
float ldexp(float x, int e)
Definition mathlib.qc:99
float logb(float e)
Definition mathlib.qc:119
float atanh(float e)
Definition mathlib.qc:57
vector frexp(float e)
Definition mathlib.qc:87
float tgamma(float e)
Definition mathlib.qc:180
float nearbyint(float e)
Definition mathlib.qc:200
bool isfinite(float e)
Definition mathlib.qc:17
int isgreaterequal(float e, float f)
Definition mathlib.qc:282
float scalbn(float e, int n)
Definition mathlib.qc:128
vector modf(float f)
Definition mathlib.qc:123
float fmod(float e, float f)
Definition mathlib.qc:209
int fpclassify(float e)
Definition mathlib.qc:7
float asinh(float e)
Definition mathlib.qc:53
float acosh(float e)
Definition mathlib.qc:49
int islessgreater(float e, float f)
Definition mathlib.qc:294
int isless(float e, float f)
Definition mathlib.qc:286
float pymod(float e, float f)
Pythonic mod: TODO: %% operator?
Definition mathlib.qc:195
bool isnan(float e)
Definition mathlib.qc:25
float fma(float e, float f, float g)
Definition mathlib.qc:273
float nexttoward(float e, float f)
Definition mathlib.qc:256
const float M_E
Definition mathlib.qh:102
const float M_LOG10E
Definition mathlib.qh:104
const int FP_NAN
Definition mathlib.qh:8
const int FP_NORMAL
Definition mathlib.qh:12
const int FP_INFINITE
Definition mathlib.qh:9
const float M_LOG2E
Definition mathlib.qh:103
#define M_PI
Definition mathlib.qh:108
const int FP_ZERO
Definition mathlib.qh:10
float ceil(float f)
float sqrt(float f)
float sin(float f)
float min(float f,...)
float rint(float f)
float fabs(float f)
float floor(float f)
float max(float f,...)
vector
Definition self.qh:92