7 int fpclassify(float e)
17 bool isfinite(float e)
19 return !(isnan(e) || isinf(e));
23 return (e != 0) && (e + e == e);
27 // The sane way to detect NaN is this:
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.
34 // Negative NaN ("-nan") is much more common but plain "nan" can be created by negating *some* -nans so we need to check both.
35 // DP's QCVM and GMQCC's QCVM behave differently - one needs ftos(-(0.0 / 0.0)), the other ftos(-sqrt(-1)).
37 return s == "nan" || s == "-nan";
39 bool isnormal(float e)
50 return log(e + sqrt(e*e - 1));
54 return log(e + sqrt(e*e + 1));
58 return 0.5 * log((1+e) / (1-e));
62 return 0.5 * (exp(e) + exp(-e));
66 return 0.5 * (exp(e) - exp(-e));
70 return sinh(e) / cosh(e);
91 v.x = e / pow(2, v.y);
96 return floor(log2(fabs(e)));
98 float ldexp(float x, int e)
100 return x * pow(2, e);
102 float logn(float e, float base)
104 return log(e) / log(base);
108 return log(e) * M_LOG10E;
116 return log(e) * M_LOG2E;
120 return floor(log2(fabs(e)));
124 return '1 0 0' * (f - trunc(f)) + '0 1 0' * trunc(f);
127 float scalbn(float e, int n)
129 return e * pow(2, n);
134 return copysign(pow(fabs(e), (1.0/3.0)), e);
136 float hypot(float e, float f)
138 return sqrt(e*e + f*f);
143 // approximation taken from wikipedia
146 return copysign(sqrt(1 - exp(-f * (1.273239544735163 + 0.14001228868667 * f) / (1 + 0.14001228868667 * f))), e);
152 vector lgamma(float e)
154 // TODO improve accuracy
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';
163 // reflection formula:
164 // gamma(1-z) * gamma(z) = pi / sin(pi*z)
165 // lgamma(1-z) + lgamma(z) = log(pi) - log(sin(pi*z))
166 // sign of gamma(1-z) = sign of gamma(z) * sign of sin(pi*z)
168 v.x = log(M_PI) - log(fabs(v.z)) - v.x;
175 return lgamma(e + 1) - log(e) * '1 0 0';
177 return (0.5 * log(2 * M_PI * e) + e * (log(e) - 1)) * '1 0 0' + '0 1 0';
179 float tgamma(float e)
181 vector v = lgamma(e);
182 return exp(v.x) * v.y;
194 float pymod(float e, float f)
196 return e - f * floor(e / f);
199 float nearbyint(float e)
205 return (e>=0) ? floor(e) : ceil(e);
208 float fmod(float e, float f)
210 return e - f * trunc(e / f);
212 float remainder(float e, float f)
214 return e - f * rint(e / f);
216 vector remquo(float e, float f)
225 float copysign(float e, float f)
227 return fabs(e) * ((f>0) ? 1 : -1);
230 float nan(string tag)
234 float nextafter(float e, float f)
238 return nan("nextafter");
240 return -nextafter(-e, -f);
241 // now we know that e < f
242 // so we need the next number > e
244 d = max(fabs(e), 0.00000000000000000000001);
255 float nexttoward(float e, float f)
257 return nextafter(e, f);
260 float fdim(float e, float f)
264 float fmax(float e, float f)
268 float fmin(float e, float f)
272 float fma(float e, float f, float g)
277 int isgreater(float e, float f)
281 int isgreaterequal(float e, float f)
285 int isless(float e, float f)
289 int islessequal(float e, float f)
293 int islessgreater(float e, float f)
295 return e < f || e > f;
297 int isunordered(float e, float f)
299 return !(e < f || e == f || e > f);