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