P8000/WEGA/contrib/lcc/lib/libm/hypot.c

49 lines
1.0 KiB
C

/* ~(#)hypot.c 2.1 */
/* ~(#)hypot.c 1.10 */
/*LINTLIBRARY*/
/*
* hypot(a, b) returns sqrt(a^2 + b^2), avoiding unnecessary overflows.
* Returns ERANGE error and value HUGE if the correct value would overflow.
*/
#include <math.h>
#include <values.h>
#include <errno.h>
#define ITERATIONS 4
double
hypot(a, b)
register double a, b;
{
register double t;
register int i = ITERATIONS;
struct exception exc;
if ((exc.arg1 = a) < 0)
a = -a;
if ((exc.arg2 = b) < 0)
b = -b;
if (a > b) { /* make sure |a| <= |b| */
t = a;
a = b;
b = t;
}
if ((t = a/b) < X_EPS) /* t <= 1 */
return (b); /* t << 1 */
a = 1 + t * t; /* a = 1 + (a/b)^2 */
t = 0.5 + 0.5 * a; /* first guess for sqrt */
do {
t = 0.5 * (t + a/t);
} while (--i > 0); /* t <= sqrt(2) */
if (b < MAXDOUBLE/M_SQRT2) /* result can't overflow */
return (t * b);
if ((t *= 0.5 * b) < MAXDOUBLE/2) /* result won't overflow */
return (t + t);
exc.type = OVERFLOW;
exc.name = "hypot";
exc.retval = HUGE;
if (!matherr(&exc))
errno = ERANGE;
return (exc.retval);
}