📄 atan.c
字号:
/* @(#)atan.c 1.11 *//*LINTLIBRARY*//* * atan returns the arctangent of its double-precision argument, * in the range [-pi/2, pi/2]. * There are no error returns. * * atan2(y, x) returns the arctangent of y/x, * in the range [-pi, pi]. * atan2 discovers what quadrant the angle is in and calls atan. * atan2 returns EDOM error and value 0 if both arguments are zero. * * Coefficients are #5077 from Hart & Cheney (19.56D). */#include <math.h>#include <values.h>#include <errno.h>#define SQ2_M_1 0.41421356237309504880#define SQ2_P_1 2.41421356237309504880#define NEG 1#define INV 2#define MID 4doubleatan(x)register double x;{ register int type = 0; if (x < 0) { x = -x; type = NEG; } if (x > SQ2_P_1) { x = 1/x; type |= INV; } else if (x > SQ2_M_1) { x = (x - 1)/(x + 1); type |= MID; } if (x < -X_EPS || x > X_EPS) { /* skip for efficiency and to prevent underflow */ static double p[] = { 0.161536412982230228262e2, 0.26842548195503973794141e3, 0.11530293515404850115428136e4, 0.178040631643319697105464587e4, 0.89678597403663861959987488e3, }, q[] = { 1.0, 0.5895697050844462222791e2, 0.536265374031215315104235e3, 0.16667838148816337184521798e4, 0.207933497444540981287275926e4, 0.89678597403663861962481162e3, }; register double xsq = x * x; x *= _POLY4(xsq, p)/_POLY5(xsq, q); } if (type & INV) x = M_PI_2 - x; else if (type & MID) x += M_PI_4; return (type & NEG ? -x : x);}doubleatan2(y, x)register double y, x;{ register int neg_y = 0; struct exception exc; double at; exc.arg1 = y; if (!x && !y) { exc.type = DOMAIN; exc.name = "atan2"; exc.arg2 = x; exc.retval = 0.0; if (!matherr(&exc)) { (void) write(2, "atan2: DOMAIN error\n", 20); errno = EDOM; } return (exc.retval); } /* * The next lines determine if |x| is negligible compared to |y|, * without dividing, and without adding values of the same sign. */ if (exc.arg1 < 0) { exc.arg1 = -exc.arg1; neg_y++; } if (exc.arg1 - _ABS(x) == exc.arg1) return (neg_y ? -M_PI_2 : M_PI_2); /* * The next line assumes that if y/x underflows the result * is zero with no error indication, so it's safe to divide. */ at = atan(y/x); if (x > 0) /* return arctangent directly */ return (at); if (neg_y) /* x < 0, adjust arctangent for */ return (at - M_PI); /* correct quadrant */ else return (at + M_PI);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -