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 broken because of a compiler bug
28 // (works with constants but breaks when assigned to variables)
29 // use conversion to string instead
33 // Negative NaN ("-nan") is much more common but plain "nan" can be created by negating *some* -nans so we need to check both.
34 // DP's QCVM and GMQCC's QCVM behave differently - one needs ftos(-(0.0 / 0.0)), the other ftos(-sqrt(-1)).
36 return s == "nan" || s == "-nan";
38 bool isnormal(float e)
49 return log(e + sqrt(e*e - 1));
53 return log(e + sqrt(e*e + 1));
57 return 0.5 * log((1+e) / (1-e));
61 return 0.5 * (exp(e) + exp(-e));
65 return 0.5 * (exp(e) - exp(-e));
69 return sinh(e) / cosh(e);
90 v.x = e / pow(2, v.y);
95 return floor(log2(fabs(e)));
97 float ldexp(float x, int e)
101 float logn(float e, float base)
103 return log(e) / log(base);
107 return log(e) * M_LOG10E;
115 return log(e) * M_LOG2E;
119 return floor(log2(fabs(e)));
123 return '1 0 0' * (f - trunc(f)) + '0 1 0' * trunc(f);
126 float scalbn(float e, int n)
128 return e * pow(2, n);
133 return copysign(pow(fabs(e), (1.0/3.0)), e);
135 float hypot(float e, float f)
137 return sqrt(e*e + f*f);
142 // approximation taken from wikipedia
145 return copysign(sqrt(1 - exp(-f * (1.273239544735163 + 0.14001228868667 * f) / (1 + 0.14001228868667 * f))), e);
151 vector lgamma(float e)
153 // TODO improve accuracy
155 return fabs(e) * '1 0 0' + copysign(1, e) * '0 1 0';
156 if(e < 1 && e == floor(e))
157 return nan("gamma") * '1 1 1';
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)
167 v.x = log(M_PI) - log(fabs(v.z)) - v.x;
174 return lgamma(e + 1) - log(e) * '1 0 0';
176 return (0.5 * log(2 * M_PI * e) + e * (log(e) - 1)) * '1 0 0' + '0 1 0';
178 float tgamma(float e)
180 vector v = lgamma(e);
181 return exp(v.x) * v.y;
193 float pymod(float e, float f)
195 return e - f * floor(e / f);
198 float nearbyint(float e)
204 return (e>=0) ? floor(e) : ceil(e);
207 float fmod(float e, float f)
209 return e - f * trunc(e / f);
211 float remainder(float e, float f)
213 return e - f * rint(e / f);
215 vector remquo(float e, float f)
224 float copysign(float e, float f)
226 return fabs(e) * ((f>0) ? 1 : -1);
228 /// Always use `isnan` function to compare because `float x = nan(); x == x;` gives true
229 float nan(string tag)
233 float nextafter(float e, float f)
237 return nan("nextafter");
239 return -nextafter(-e, -f);
240 // now we know that e < f
241 // so we need the next number > e
243 d = max(fabs(e), 0.00000000000000000000001);
254 float nexttoward(float e, float f)
256 return nextafter(e, f);
259 float fdim(float e, float f)
263 float fmax(float e, float f)
267 float fmin(float e, float f)
271 float fma(float e, float f, float g)
276 int isgreater(float e, float f)
280 int isgreaterequal(float e, float f)
284 int isless(float e, float f)
288 int islessequal(float e, float f)
292 int islessgreater(float e, float f)
294 return e < f || e > f;
296 int isunordered(float e, float f)
298 return !(e < f || e == f || e > f);