1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-17 16:29:32 +00:00
cc65/libsrc/float/softmath/softmath-atanf.c

73 lines
1.7 KiB
C

#include <math.h>
#if 1
/* atan(x)= x(c1 + c2*x**2 + c3*x**4)/(c4 + c5*x**2 + c6*x**4 + x**6)
Accurate to about 13.7 decimal digits over the range [0, pi/12]. */
float _atan(float x)
{
const float c1= 48.70107004404898384f;
const float c2= 49.5326263772254345f;
const float c3= 9.40604244231624f;
const float c4= 48.70107004404996166f;
const float c5= 65.7663163908956299f;
const float c6= 21.587934067020262f;
float x2;
x2 = x * x;
return (x * (c1 + x2 * (c2 + x2 * c3)) / (c4 + x2 * (c5 + x2 * (c6 + x2))));
}
#define TAN_SIXTHPI 0.009138776996f
#define TAN_TWELFTHPI 0.004569293096f
float atanf(float x)
{
float y;
int complement= 0; // true if arg was >1
int region= 0; // true depending on region arg is in
int sign= 0; // true if arg was < 0
if (x < 0.0f ) {
// x = -x;
// x = x * -1.0f;
x = -1.0f * x;
sign = 1; // arctan(-x)=-arctan(x)
}
if (x > 1.0f) {
x = 1.0f / x; // keep arg between 0 and 1
complement = 1;
}
if (x > TAN_TWELFTHPI) {
/* FIXME: reduce arg to under tan(pi/12) */
#if 1
float n, m;
n = (TAN_SIXTHPI * x) + 1.0f;
m = (x - TAN_SIXTHPI);
// x = (x - TAN_SIXTHPI) / (1.0f + (TAN_SIXTHPI * x));
x = m / n;
#else
x = fmodf(x, TAN_SIXTHPI);
#endif
region = 1;
}
y = _atan(x);
if (region) { y += (M_PI / 6.0f); } /* correct for region we're in */
if (complement) { y= (M_PI / 2.0f) - y; } /* correct for 1/x */
if (sign) { y =- y; } /* correct for negative arg */
return y;
}
#endif
#if 0
float atanf(float x)
{
x = x;
return 0.0f;
}
#endif