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 = e*e;
146 return copysign(sqrt(1 - exp(-f * (1.273239544735163 + 0.14001228868667 * f) / (1 + 0.14001228868667 * f))), e);
147}
148float erfc(float e)
149{
150 return 1.0 - erf(e);
151}
153{
154 // TODO improve accuracy
155 if(!isfinite(e))
156 return fabs(e) * '1 0 0' + copysign(1, e) * '0 1 0';
157 if(e < 1 && e == floor(e))
158 return nan("gamma") * '1 1 1';
159 if(e < 0.1)
160 {
161 vector v = lgamma(1.0 - e);
162 // reflection formula:
163 // gamma(1-z) * gamma(z) = pi / sin(pi*z)
164 // lgamma(1-z) + lgamma(z) = log(pi) - log(sin(pi*z))
165 // sign of gamma(1-z) = sign of gamma(z) * sign of sin(pi*z)
166 v.z = sin(M_PI * e);
167 v.x = log(M_PI) - log(fabs(v.z)) - v.x;
168 if(v.z < 0)
169 v.y = -v.y;
170 v.z = 0;
171 return v;
172 }
173 if(e < 1.1)
174 return lgamma(e + 1) - log(e) * '1 0 0';
175 --e;
176 return (0.5 * log(2 * M_PI * e) + e * (log(e) - 1)) * '1 0 0' + '0 1 0';
177}
178float tgamma(float e)
179{
180 vector v = lgamma(e);
181 return exp(v.x) * v.y;
182}
183
193float pymod(float e, float f)
194{
195 return e - f * floor(e / f);
196}
197
198float nearbyint(float e)
199{
200 return rint(e);
201}
202float trunc(float e)
203{
204 return (e>=0) ? floor(e) : ceil(e);
205}
206
207float fmod(float e, float f)
208{
209 return e - f * trunc(e / f);
210}
211float remainder(float e, float f)
212{
213 return e - f * rint(e / f);
214}
215vector remquo(float e, float f)
216{
217 vector v;
218 v.z = 0;
219 v.y = rint(e / f);
220 v.x = e - f * v.y;
221 return v;
222}
223
224float copysign(float e, float f)
225{
226 return fabs(e) * ((f>0) ? 1 : -1);
227}
228
229float nan(string tag)
230{
231 return sqrt(-1);
232}
233float nextafter(float e, float f)
234{
235 // TODO very crude
236 if(e == f)
237 return nan("nextafter");
238 if(e > f)
239 return -nextafter(-e, -f);
240 // now we know that e < f
241 // so we need the next number > e
242 float d, a, b;
243 d = max(fabs(e), 0.00000000000000000000001);
244 a = e + d;
245 do
246 {
247 d *= 0.5;
248 b = a;
249 a = e + d;
250 }
251 while(a != e);
252 return b;
253}
254float nexttoward(float e, float f)
255{
256 return nextafter(e, f);
257}
258
259float fdim(float e, float f)
260{
261 return max(e-f, 0);
262}
263float fmax(float e, float f)
264{
265 return max(e, f);
266}
267float fmin(float e, float f)
268{
269 return min(e, f);
270}
271float fma(float e, float f, float g)
272{
273 return e * f + g;
274}
275
276int isgreater(float e, float f)
277{
278 return e > f;
279}
280int isgreaterequal(float e, float f)
281{
282 return e >= f;
283}
284int isless(float e, float f)
285{
286 return e < f;
287}
288int islessequal(float e, float f)
289{
290 return e <= f;
291}
292int islessgreater(float e, float f)
293{
294 return e < f || e > f;
295}
296int isunordered(float e, float f)
297{
298 return !(e < f || e == f || e > f);
299}
float log(float f)
#define pow(a, b)
Definition _all.inc:67
float trunc(float e)
Definition mathlib.qc:202
float erf(float e)
Definition mathlib.qc:142
float fdim(float e, float f)
Definition mathlib.qc:259
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:148
int isgreater(float e, float f)
Definition mathlib.qc:276
float log2(float e)
Definition mathlib.qc:115
vector remquo(float e, float f)
Definition mathlib.qc:215
float nan(string tag)
Definition mathlib.qc:229
float fmin(float e, float f)
Definition mathlib.qc:267
float fmax(float e, float f)
Definition mathlib.qc:263
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:211
vector lgamma(float e)
Definition mathlib.qc:152
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:233
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:224
float tanh(float e)
Definition mathlib.qc:69
int islessequal(float e, float f)
Definition mathlib.qc:288
int isunordered(float e, float f)
Definition mathlib.qc:296
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:178
float nearbyint(float e)
Definition mathlib.qc:198
bool isfinite(float e)
Definition mathlib.qc:17
int isgreaterequal(float e, float f)
Definition mathlib.qc:280
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:207
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:292
int isless(float e, float f)
Definition mathlib.qc:284
float pymod(float e, float f)
Pythonic mod: TODO: %% operator?
Definition mathlib.qc:193
bool isnan(float e)
Definition mathlib.qc:25
float fma(float e, float f, float g)
Definition mathlib.qc:271
float nexttoward(float e, float f)
Definition mathlib.qc:254
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