Rename a few parameters and locals named x, y, z
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / warpzone / mathlib.qc
1 #include "mathlib.qh"
2 #if defined(CSQC)
3 #elif defined(MENUQC)
4 #elif defined(SVQC)
5 #endif
6
7 int 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 }
17 bool isfinite(float e)
18 {
19         return !(isnan(e) || isinf(e));
20 }
21 bool isinf(float e)
22 {
23         return (e != 0) && (e + e == e);
24 }
25 bool isnan(float e)
26 {
27         float f = e;
28         return (e != f);
29 }
30 bool isnormal(float e)
31 {
32         return isfinite(e);
33 }
34 bool signbit(float e)
35 {
36         return (e < 0);
37 }
38
39 float acosh(float e)
40 {
41         return log(e + sqrt(e*e - 1));
42 }
43 float asinh(float e)
44 {
45         return log(e + sqrt(e*e + 1));
46 }
47 float atanh(float e)
48 {
49         return 0.5 * log((1+e) / (1-e));
50 }
51 float cosh(float e)
52 {
53         return 0.5 * (exp(e) + exp(-e));
54 }
55 float sinh(float e)
56 {
57         return 0.5 * (exp(e) - exp(-e));
58 }
59 float tanh(float e)
60 {
61         return sinh(e) / cosh(e);
62 }
63
64 float exp(float e)
65 {
66         return pow(M_E, e);
67 }
68 float exp2(float e)
69 {
70         return pow(2, e);
71 }
72 float expm1(float e)
73 {
74         return exp(e) - 1;
75 }
76
77 vector frexp(float e)
78 {
79         vector v;
80         v.z = 0;
81         v.y = ilogb(e) + 1;
82         v.x = e / exp2(v.y);
83         return v;
84 }
85 int ilogb(float e)
86 {
87         return floor(log2(fabs(e)));
88 }
89 float ldexp(float e, int e)
90 {
91         return e * pow(2, e);
92 }
93 float logn(float e, float base)
94 {
95         return log(e) / log(base);
96 }
97 float log10(float e)
98 {
99         return log(e) * M_LOG10E;
100 }
101 float log1p(float e)
102 {
103         return log(e + 1);
104 }
105 float log2(float e)
106 {
107         return log(e) * M_LOG2E;
108 }
109 float logb(float e)
110 {
111         return floor(log2(fabs(e)));
112 }
113 vector modf(float f)
114 {
115         return '1 0 0' * (f - trunc(f)) + '0 1 0' * trunc(f);
116 }
117
118 float scalbn(float e, int n)
119 {
120         return e * pow(2, n);
121 }
122
123 float cbrt(float e)
124 {
125         return copysign(pow(fabs(e), 1.0/3.0), e);
126 }
127 float hypot(float e, float f)
128 {
129         return sqrt(e*e + f*f);
130 }
131
132 float erf(float e)
133 {
134         // approximation taken from wikipedia
135         float f;
136         f = e*e;
137         return copysign(sqrt(1 - exp(-f * (1.273239544735163 + 0.14001228868667 * f) / (1 + 0.14001228868667 * f))), e);
138 }
139 float erfc(float e)
140 {
141         return 1.0 - erf(e);
142 }
143 vector lgamma(float e)
144 {
145         // TODO improve accuracy
146         if(!isfinite(e))
147                 return fabs(e) * '1 0 0' + copysign(1, e) * '0 1 0';
148         if(e < 1 && e == floor(e))
149                 return nan("gamma") * '1 1 1';
150         if(e < 0.1)
151         {
152                 vector v;
153                 v = lgamma(1.0 - e);
154                 // reflection formula:
155                 // gamma(1-z) * gamma(z) = pi / sin(pi*z)
156                 // lgamma(1-z) + lgamma(z) = log(pi) - log(sin(pi*z))
157                 // sign of gamma(1-z) = sign of gamma(z) * sign of sin(pi*z)
158                 v.z = sin(M_PI * e);
159                 v.x = log(M_PI) - log(fabs(v.z)) - v.x;
160                 if(v.z < 0)
161                         v.y = -v.y;
162                 v.z = 0;
163                 return v;
164         }
165         if(e < 1.1)
166                 return lgamma(e + 1) - log(e) * '1 0 0';
167         e -= 1;
168         return (0.5 * log(2 * M_PI * e) + e * (log(e) - 1)) * '1 0 0' + '0 1 0';
169 }
170 float tgamma(float e)
171 {
172         vector v;
173         v = lgamma(e);
174         return exp(v.x) * v.y;
175 }
176
177 /**
178  * Pythonic mod:
179  * TODO: %% operator?
180  *
181  *  1 %  2 ==  1
182  * -1 %  2 ==  1
183  *  1 % -2 == -1
184  * -1 % -2 == -1
185  */
186 float pymod(float e, float f)
187 {
188         return e - f * floor(e / f);
189 }
190
191 float nearbyint(float e)
192 {
193         return rint(e);
194 }
195 float trunc(float e)
196 {
197         return (e>=0) ? floor(e) : ceil(e);
198 }
199
200 float fmod(float e, float f)
201 {
202         return e - f * trunc(e / f);
203 }
204 float remainder(float e, float f)
205 {
206         return e - f * rint(e / f);
207 }
208 vector remquo(float e, float f)
209 {
210         vector v;
211         v.z = 0;
212         v.y = rint(e / f);
213         v.x = e - f * v.y;
214         return v;
215 }
216
217 float copysign(float e, float f)
218 {
219         return fabs(e) * ((f>0) ? 1 : -1);
220 }
221 float nan(string tag)
222 {
223         return sqrt(-1);
224 }
225 float nextafter(float e, float f)
226 {
227         // TODO very crude
228         if(e == f)
229                 return nan("nextafter");
230         if(e > f)
231                 return -nextafter(-e, -f);
232         // now we know that e < f
233         // so we need the next number > e
234         float d, a, b;
235         d = max(fabs(e), 0.00000000000000000000001);
236         a = e + d;
237         do
238         {
239                 d *= 0.5;
240                 b = a;
241                 a = e + d;
242         }
243         while(a != e);
244         return b;
245 }
246 float nexttoward(float e, float f)
247 {
248         return nextafter(e, f);
249 }
250
251 float fdim(float e, float f)
252 {
253         return max(e-f, 0);
254 }
255 float fmax(float e, float f)
256 {
257         return max(e, f);
258 }
259 float fmin(float e, float f)
260 {
261         return min(e, f);
262 }
263 float fma(float e, float f, float g)
264 {
265         return e * f + g;
266 }
267
268 int isgreater(float e, float f)
269 {
270         return e > f;
271 }
272 int isgreaterequal(float e, float f)
273 {
274         return e >= f;
275 }
276 int isless(float e, float f)
277 {
278         return e < f;
279 }
280 int islessequal(float e, float f)
281 {
282         return e <= f;
283 }
284 int islessgreater(float e, float f)
285 {
286         return e < f || e > f;
287 }
288 int isunordered(float e, float f)
289 {
290         return !(e < f || e == f || e > f);
291 }