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 return ftos(e) == "-nan";
35 bool isnormal(float e)
46 return log(e + sqrt(e*e - 1));
50 return log(e + sqrt(e*e + 1));
54 return 0.5 * log((1+e) / (1-e));
58 return 0.5 * (exp(e) + exp(-e));
62 return 0.5 * (exp(e) - exp(-e));
66 return sinh(e) / cosh(e);
87 v.x = e / pow(2, v.y);
92 return floor(log2(fabs(e)));
94 float ldexp(float x, int e)
98 float logn(float e, float base)
100 return log(e) / log(base);
104 return log(e) * M_LOG10E;
112 return log(e) * M_LOG2E;
116 return floor(log2(fabs(e)));
120 return '1 0 0' * (f - trunc(f)) + '0 1 0' * trunc(f);
123 float scalbn(float e, int n)
125 return e * pow(2, n);
130 return copysign(pow(fabs(e), (1.0/3.0)), e);
132 float hypot(float e, float f)
134 return sqrt(e*e + f*f);
139 // approximation taken from wikipedia
142 return copysign(sqrt(1 - exp(-f * (1.273239544735163 + 0.14001228868667 * f) / (1 + 0.14001228868667 * f))), e);
148 vector lgamma(float e)
150 // TODO improve accuracy
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';
159 // reflection formula:
160 // gamma(1-z) * gamma(z) = pi / sin(pi*z)
161 // lgamma(1-z) + lgamma(z) = log(pi) - log(sin(pi*z))
162 // sign of gamma(1-z) = sign of gamma(z) * sign of sin(pi*z)
164 v.x = log(M_PI) - log(fabs(v.z)) - v.x;
171 return lgamma(e + 1) - log(e) * '1 0 0';
173 return (0.5 * log(2 * M_PI * e) + e * (log(e) - 1)) * '1 0 0' + '0 1 0';
175 float tgamma(float e)
177 vector v = lgamma(e);
178 return exp(v.x) * v.y;
190 float pymod(float e, float f)
192 return e - f * floor(e / f);
195 float nearbyint(float e)
201 return (e>=0) ? floor(e) : ceil(e);
204 float fmod(float e, float f)
206 return e - f * trunc(e / f);
208 float remainder(float e, float f)
210 return e - f * rint(e / f);
212 vector remquo(float e, float f)
221 float copysign(float e, float f)
223 return fabs(e) * ((f>0) ? 1 : -1);
225 /// Always use `isnan` function to compare because `float x = nan(); x == x;` gives true
226 float nan(string tag)
230 float nextafter(float e, float f)
234 return nan("nextafter");
236 return -nextafter(-e, -f);
237 // now we know that e < f
238 // so we need the next number > e
240 d = max(fabs(e), 0.00000000000000000000001);
251 float nexttoward(float e, float f)
253 return nextafter(e, f);
256 float fdim(float e, float f)
260 float fmax(float e, float f)
264 float fmin(float e, float f)
268 float fma(float e, float f, float g)
273 int isgreater(float e, float f)
277 int isgreaterequal(float e, float f)
281 int isless(float e, float f)
285 int islessequal(float e, float f)
289 int islessgreater(float e, float f)
291 return e < f || e > f;
293 int isunordered(float e, float f)
295 return !(e < f || e == f || e > f);