Print this page
11210 libm should be cstyle(1ONBLD) clean
*** 16,28 ****
--- 16,30 ----
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
+
/*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
+
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
*** 39,49 ****
#endif
#include <errno.h>
#undef fflush
#include <sys/isa_defs.h>
! /* INDENT OFF */
/*
* Report libm exception error according to System V Interface Definition
* (SVID).
* Error mapping:
* 1 -- acos(|x|>1)
--- 41,51 ----
#endif
#include <errno.h>
#undef fflush
#include <sys/isa_defs.h>
!
/*
* Report libm exception error according to System V Interface Definition
* (SVID).
* Error mapping:
* 1 -- acos(|x|>1)
*** 92,102 ****
* 44-- log1p(x<-1)
* 45-- logb(0)
* 46-- nextafter overflow
* 47-- scalb(x,inf)
*/
- /* INDENT ON */
static double setexception(int, double);
static const union {
unsigned x[2];
--- 94,103 ----
*** 118,956 ****
#define __LO(x) ((unsigned *)&x)[LOWORD]
#undef Inf
#define Inf HUGE_VAL
double
! _SVID_libm_err(double x, double y, int type) {
struct exception exc;
double t, w, ieee_retval = 0;
enum version lib_version = _lib_version;
int iy;
/* force libm_ieee behavior in SUSv3 mode */
if ((__xpg6 & _C99SUSv3_math_errexcept) != 0)
lib_version = libm_ieee;
! if (lib_version == c_issue_4) {
(void) fflush(stdout);
! }
exc.arg1 = x;
exc.arg2 = y;
switch (type) {
case 1:
/* acos(|x|>1) */
exc.type = DOMAIN;
exc.name = "acos";
ieee_retval = setexception(3, 1.0);
exc.retval = 0.0;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "acos: DOMAIN error\n", 19);
! }
errno = EDOM;
}
break;
case 2:
/* asin(|x|>1) */
exc.type = DOMAIN;
exc.name = "asin";
exc.retval = 0.0;
ieee_retval = setexception(3, 1.0);
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "asin: DOMAIN error\n", 19);
! }
errno = EDOM;
}
break;
case 3:
/* atan2(+-0,+-0) */
exc.arg1 = y;
exc.arg2 = x;
exc.type = DOMAIN;
exc.name = "atan2";
! ieee_retval = copysign(1.0, x) == 1.0 ? y :
! copysign(PI_RZ + DBL_MIN, y);
exc.retval = 0.0;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "atan2: DOMAIN error\n", 20);
! }
errno = EDOM;
}
break;
case 4:
/* hypot(finite,finite) overflow */
exc.type = OVERFLOW;
exc.name = "hypot";
ieee_retval = Inf;
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
break;
case 5:
/* cosh(finite) overflow */
exc.type = OVERFLOW;
exc.name = "cosh";
ieee_retval = setexception(2, 1.0);
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
break;
case 6:
/* exp(finite) overflow */
exc.type = OVERFLOW;
exc.name = "exp";
ieee_retval = setexception(2, 1.0);
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
break;
case 7:
/* exp(finite) underflow */
exc.type = UNDERFLOW;
exc.name = "exp";
ieee_retval = setexception(1, 1.0);
exc.retval = 0.0;
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
break;
case 8:
/* y0(0) = -inf */
exc.type = DOMAIN; /* should be SING for IEEE */
exc.name = "y0";
ieee_retval = setexception(0, -1.0);
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "y0: DOMAIN error\n", 17);
! }
errno = EDOM;
}
break;
case 9:
/* y0(x<0) = NaN */
exc.type = DOMAIN;
exc.name = "y0";
ieee_retval = setexception(3, 1.0);
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "y0: DOMAIN error\n", 17);
! }
errno = EDOM;
}
break;
case 10:
/* y1(0) = -inf */
exc.type = DOMAIN; /* should be SING for IEEE */
exc.name = "y1";
ieee_retval = setexception(0, -1.0);
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "y1: DOMAIN error\n", 17);
! }
errno = EDOM;
}
break;
case 11:
/* y1(x<0) = NaN */
exc.type = DOMAIN;
exc.name = "y1";
ieee_retval = setexception(3, 1.0);
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "y1: DOMAIN error\n", 17);
! }
errno = EDOM;
}
break;
case 12:
/* yn(n,0) = -inf */
exc.type = DOMAIN; /* should be SING for IEEE */
exc.name = "yn";
ieee_retval = setexception(0, -1.0);
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "yn: DOMAIN error\n", 17);
! }
errno = EDOM;
}
break;
case 13:
/* yn(x<0) = NaN */
exc.type = DOMAIN;
exc.name = "yn";
ieee_retval = setexception(3, 1.0);
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "yn: DOMAIN error\n", 17);
! }
errno = EDOM;
}
break;
case 14:
/* lgamma(finite) overflow */
exc.type = OVERFLOW;
exc.name = "lgamma";
ieee_retval = setexception(2, 1.0);
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
break;
case 15:
/* lgamma(-integer) or lgamma(0) */
exc.type = SING;
exc.name = "lgamma";
ieee_retval = setexception(0, 1.0);
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "lgamma: SING error\n", 19);
! }
errno = EDOM;
}
break;
case 16:
/* log(0) */
exc.type = SING;
exc.name = "log";
ieee_retval = setexception(0, -1.0);
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, "log: SING error\n", 16);
errno = EDOM;
} else {
errno = ERANGE;
}
}
break;
case 17:
/* log(x<0) */
exc.type = DOMAIN;
exc.name = "log";
ieee_retval = setexception(3, 1.0);
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "log: DOMAIN error\n", 18);
! }
errno = EDOM;
}
break;
case 18:
/* log10(0) */
exc.type = SING;
exc.name = "log10";
ieee_retval = setexception(0, -1.0);
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, "log10: SING error\n", 18);
errno = EDOM;
} else {
errno = ERANGE;
}
}
break;
case 19:
/* log10(x<0) */
exc.type = DOMAIN;
exc.name = "log10";
ieee_retval = setexception(3, 1.0);
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "log10: DOMAIN error\n", 20);
! }
errno = EDOM;
}
break;
case 20:
! /* pow(0.0,0.0) */
! /* error only if lib_version == c_issue_4 */
exc.type = DOMAIN;
exc.name = "pow";
exc.retval = 0.0;
ieee_retval = 1.0;
if (lib_version != c_issue_4) {
exc.retval = 1.0;
} else if (!matherr(&exc)) {
(void) write(2, "pow(0,0): DOMAIN error\n", 23);
errno = EDOM;
}
break;
case 21:
/* pow(x,y) overflow */
exc.type = OVERFLOW;
exc.name = "pow";
! exc.retval = (lib_version == c_issue_4)? HUGE : HUGE_VAL;
if (signbit(x)) {
t = rint(y);
if (t == y) {
w = rint(0.5 * y);
! if (t != w + w) { /* y is odd */
exc.retval = -exc.retval;
}
}
! }
ieee_retval = setexception(2, exc.retval);
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
break;
case 22:
/* pow(x,y) underflow */
exc.type = UNDERFLOW;
exc.name = "pow";
exc.retval = 0.0;
if (signbit(x)) {
t = rint(y);
if (t == y) {
w = rint(0.5 * y);
if (t != w + w) /* y is odd */
exc.retval = -exc.retval;
}
}
ieee_retval = setexception(1, exc.retval);
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
break;
case 23:
/* (+-0)**neg */
exc.type = DOMAIN;
exc.name = "pow";
ieee_retval = setexception(0, 1.0);
{
int ahy, k, j, yisint, ly, hx;
! /* INDENT OFF */
/*
* determine if y is an odd int when x = -0
* yisint = 0 ... y is not an integer
* yisint = 1 ... y is an odd int
* yisint = 2 ... y is an even int
*/
! /* INDENT ON */
hx = __HI(x);
! ahy = __HI(y)&0x7fffffff;
ly = __LO(y);
yisint = 0;
if (ahy >= 0x43400000) {
yisint = 2; /* even integer y */
} else if (ahy >= 0x3ff00000) {
k = (ahy >> 20) - 0x3ff; /* exponent */
if (k > 20) {
j = ly >> (52 - k);
if ((j << (52 - k)) == ly)
yisint = 2 - (j & 1);
} else if (ly == 0) {
j = ahy >> (20 - k);
if ((j << (20 - k)) == ahy)
yisint = 2 - (j & 1);
}
}
if (hx < 0 && yisint == 1)
ieee_retval = -ieee_retval;
}
if (lib_version == c_issue_4)
exc.retval = 0.0;
else
exc.retval = -HUGE_VAL;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, "pow(0,neg): DOMAIN error\n",
25);
}
errno = EDOM;
}
break;
case 24:
/* neg**non-integral */
exc.type = DOMAIN;
exc.name = "pow";
ieee_retval = setexception(3, 1.0);
if (lib_version == c_issue_4)
exc.retval = 0.0;
else
exc.retval = ieee_retval; /* X/Open allow NaN */
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2,
"neg**non-integral: DOMAIN error\n", 32);
}
errno = EDOM;
}
break;
case 25:
/* sinh(finite) overflow */
exc.type = OVERFLOW;
exc.name = "sinh";
ieee_retval = copysign(Inf, x);
if (lib_version == c_issue_4)
exc.retval = x > 0.0 ? HUGE : -HUGE;
else
exc.retval = x > 0.0 ? HUGE_VAL : -HUGE_VAL;
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
break;
case 26:
/* sqrt(x<0) */
exc.type = DOMAIN;
exc.name = "sqrt";
ieee_retval = setexception(3, 1.0);
if (lib_version == c_issue_4)
exc.retval = 0.0;
else
exc.retval = ieee_retval; /* quiet NaN */
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "sqrt: DOMAIN error\n", 19);
! }
errno = EDOM;
}
break;
case 27:
/* fmod(x,0) */
exc.type = DOMAIN;
exc.name = "fmod";
if (fp_class(x) == fp_quiet)
ieee_retval = NaN;
else
ieee_retval = setexception(3, 1.0);
if (lib_version == c_issue_4)
exc.retval = x;
else
exc.retval = ieee_retval;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "fmod: DOMAIN error\n", 20);
! }
errno = EDOM;
}
break;
case 28:
/* remainder(x,0) */
exc.type = DOMAIN;
exc.name = "remainder";
if (fp_class(x) == fp_quiet)
ieee_retval = NaN;
else
ieee_retval = setexception(3, 1.0);
exc.retval = NaN;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "remainder: DOMAIN error\n",
24);
! }
errno = EDOM;
}
break;
case 29:
/* acosh(x<1) */
exc.type = DOMAIN;
exc.name = "acosh";
ieee_retval = setexception(3, 1.0);
exc.retval = NaN;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "acosh: DOMAIN error\n", 20);
! }
errno = EDOM;
}
break;
case 30:
/* atanh(|x|>1) */
exc.type = DOMAIN;
exc.name = "atanh";
ieee_retval = setexception(3, 1.0);
exc.retval = NaN;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "atanh: DOMAIN error\n", 20);
! }
errno = EDOM;
}
break;
case 31:
/* atanh(|x|=1) */
exc.type = SING;
exc.name = "atanh";
ieee_retval = setexception(0, x);
exc.retval = ieee_retval;
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, "atanh: SING error\n", 18);
errno = EDOM;
} else {
errno = ERANGE;
}
}
break;
case 32:
/* scalb overflow; SVID also returns +-HUGE_VAL */
exc.type = OVERFLOW;
exc.name = "scalb";
ieee_retval = setexception(2, x);
exc.retval = x > 0.0 ? HUGE_VAL : -HUGE_VAL;
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
break;
case 33:
/* scalb underflow */
exc.type = UNDERFLOW;
exc.name = "scalb";
ieee_retval = setexception(1, x);
exc.retval = ieee_retval; /* +-0.0 */
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
break;
case 34:
/* j0(|x|>X_TLOSS) */
exc.type = TLOSS;
exc.name = "j0";
exc.retval = 0.0;
ieee_retval = y;
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, exc.name, 2);
(void) write(2, ": TLOSS error\n", 14);
}
errno = ERANGE;
}
break;
case 35:
/* y0(x>X_TLOSS) */
exc.type = TLOSS;
exc.name = "y0";
exc.retval = 0.0;
ieee_retval = y;
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, exc.name, 2);
(void) write(2, ": TLOSS error\n", 14);
}
errno = ERANGE;
}
break;
case 36:
/* j1(|x|>X_TLOSS) */
exc.type = TLOSS;
exc.name = "j1";
exc.retval = 0.0;
ieee_retval = y;
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, exc.name, 2);
(void) write(2, ": TLOSS error\n", 14);
}
errno = ERANGE;
}
break;
case 37:
/* y1(x>X_TLOSS) */
exc.type = TLOSS;
exc.name = "y1";
exc.retval = 0.0;
ieee_retval = y;
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, exc.name, 2);
(void) write(2, ": TLOSS error\n", 14);
}
errno = ERANGE;
}
break;
case 38:
! /* jn(|x|>X_TLOSS) */
! /* incorrect ieee value: ieee should never be here */
exc.type = TLOSS;
exc.name = "jn";
exc.retval = 0.0;
ieee_retval = 0.0; /* shall not be used */
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, exc.name, 2);
(void) write(2, ": TLOSS error\n", 14);
}
errno = ERANGE;
}
break;
case 39:
! /* yn(x>X_TLOSS) */
! /* incorrect ieee value: ieee should never be here */
exc.type = TLOSS;
exc.name = "yn";
exc.retval = 0.0;
ieee_retval = 0.0; /* shall not be used */
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, exc.name, 2);
(void) write(2, ": TLOSS error\n", 14);
}
errno = ERANGE;
}
break;
case 40:
/* gamma(finite) overflow */
exc.type = OVERFLOW;
exc.name = "gamma";
ieee_retval = setexception(2, 1.0);
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
break;
case 41:
/* gamma(-integer) or gamma(0) */
exc.type = SING;
exc.name = "gamma";
ieee_retval = setexception(0, 1.0);
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "gamma: SING error\n", 18);
! }
errno = EDOM;
}
break;
case 42:
! /* pow(NaN,0.0) */
! /* error if lib_version == c_issue_4 or ansi_1 */
exc.type = DOMAIN;
exc.name = "pow";
exc.retval = x;
ieee_retval = 1.0;
if (lib_version == strict_ansi) {
exc.retval = 1.0;
} else if (!matherr(&exc)) {
! if ((lib_version == c_issue_4) || (lib_version == ansi_1))
errno = EDOM;
}
break;
case 43:
/* log1p(-1) */
exc.type = SING;
exc.name = "log1p";
ieee_retval = setexception(0, -1.0);
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, "log1p: SING error\n", 18);
errno = EDOM;
} else {
errno = ERANGE;
}
}
break;
case 44:
/* log1p(x<-1) */
exc.type = DOMAIN;
exc.name = "log1p";
ieee_retval = setexception(3, 1.0);
exc.retval = ieee_retval;
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4) {
(void) write(2, "log1p: DOMAIN error\n", 20);
! }
errno = EDOM;
}
break;
case 45:
/* logb(0) */
exc.type = DOMAIN;
exc.name = "logb";
ieee_retval = setexception(0, -1.0);
exc.retval = -HUGE_VAL;
if (lib_version == strict_ansi)
errno = EDOM;
else if (!matherr(&exc))
errno = EDOM;
break;
case 46:
/* nextafter overflow */
exc.type = OVERFLOW;
exc.name = "nextafter";
/*
* The value as returned by setexception is +/-DBL_MAX in
* round-to-{zero,-/+Inf} mode respectively, which is not
* usable.
*/
(void) setexception(2, x);
ieee_retval = x > 0 ? Inf : -Inf;
exc.retval = x > 0 ? HUGE_VAL : -HUGE_VAL;
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
break;
case 47:
/* scalb(x,inf) */
iy = ((int *)&y)[HIWORD];
if (lib_version == c_issue_4)
/* SVID3: ERANGE in all cases */
errno = ERANGE;
else if ((x == 0.0 && iy > 0) || (!finite(x) && iy < 0))
/* EDOM for scalb(0,+inf) or scalb(inf,-inf) */
errno = EDOM;
! exc.retval = ieee_retval = ((iy < 0)? x / -y : x * y);
break;
}
switch (lib_version) {
case c_issue_4:
case ansi_1:
case strict_ansi:
return (exc.retval);
/* NOTREACHED */
default:
return (ieee_retval);
}
/* NOTREACHED */
}
static double
! setexception(int n, double x) {
/*
* n =
* 0 division by zero
* 1 underflow
* 2 overflow
--- 119,1118 ----
#define __LO(x) ((unsigned *)&x)[LOWORD]
#undef Inf
#define Inf HUGE_VAL
double
! _SVID_libm_err(double x, double y, int type)
! {
struct exception exc;
double t, w, ieee_retval = 0;
enum version lib_version = _lib_version;
int iy;
/* force libm_ieee behavior in SUSv3 mode */
if ((__xpg6 & _C99SUSv3_math_errexcept) != 0)
lib_version = libm_ieee;
!
! if (lib_version == c_issue_4)
(void) fflush(stdout);
!
exc.arg1 = x;
exc.arg2 = y;
+
switch (type) {
case 1:
/* acos(|x|>1) */
exc.type = DOMAIN;
exc.name = "acos";
ieee_retval = setexception(3, 1.0);
exc.retval = 0.0;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "acos: DOMAIN error\n", 19);
!
errno = EDOM;
}
+
break;
case 2:
/* asin(|x|>1) */
exc.type = DOMAIN;
exc.name = "asin";
exc.retval = 0.0;
ieee_retval = setexception(3, 1.0);
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "asin: DOMAIN error\n", 19);
!
errno = EDOM;
}
+
break;
case 3:
/* atan2(+-0,+-0) */
exc.arg1 = y;
exc.arg2 = x;
exc.type = DOMAIN;
exc.name = "atan2";
! ieee_retval = copysign(1.0, x) == 1.0 ? y : copysign(PI_RZ +
! DBL_MIN, y);
exc.retval = 0.0;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "atan2: DOMAIN error\n", 20);
!
errno = EDOM;
}
+
break;
case 4:
/* hypot(finite,finite) overflow */
exc.type = OVERFLOW;
exc.name = "hypot";
ieee_retval = Inf;
+
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
+
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
+
break;
case 5:
/* cosh(finite) overflow */
exc.type = OVERFLOW;
exc.name = "cosh";
ieee_retval = setexception(2, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
+
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
+
break;
case 6:
/* exp(finite) overflow */
exc.type = OVERFLOW;
exc.name = "exp";
ieee_retval = setexception(2, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
+
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
+
break;
case 7:
/* exp(finite) underflow */
exc.type = UNDERFLOW;
exc.name = "exp";
ieee_retval = setexception(1, 1.0);
exc.retval = 0.0;
+
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
+
break;
case 8:
/* y0(0) = -inf */
exc.type = DOMAIN; /* should be SING for IEEE */
exc.name = "y0";
ieee_retval = setexception(0, -1.0);
+
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "y0: DOMAIN error\n", 17);
!
errno = EDOM;
}
+
break;
case 9:
/* y0(x<0) = NaN */
exc.type = DOMAIN;
exc.name = "y0";
ieee_retval = setexception(3, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "y0: DOMAIN error\n", 17);
!
errno = EDOM;
}
+
break;
case 10:
/* y1(0) = -inf */
exc.type = DOMAIN; /* should be SING for IEEE */
exc.name = "y1";
ieee_retval = setexception(0, -1.0);
+
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "y1: DOMAIN error\n", 17);
!
errno = EDOM;
}
+
break;
case 11:
/* y1(x<0) = NaN */
exc.type = DOMAIN;
exc.name = "y1";
ieee_retval = setexception(3, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "y1: DOMAIN error\n", 17);
!
errno = EDOM;
}
+
break;
case 12:
/* yn(n,0) = -inf */
exc.type = DOMAIN; /* should be SING for IEEE */
exc.name = "yn";
ieee_retval = setexception(0, -1.0);
+
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "yn: DOMAIN error\n", 17);
!
errno = EDOM;
}
+
break;
case 13:
/* yn(x<0) = NaN */
exc.type = DOMAIN;
exc.name = "yn";
ieee_retval = setexception(3, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "yn: DOMAIN error\n", 17);
!
errno = EDOM;
}
+
break;
case 14:
/* lgamma(finite) overflow */
exc.type = OVERFLOW;
exc.name = "lgamma";
ieee_retval = setexception(2, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
+
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
+
break;
case 15:
/* lgamma(-integer) or lgamma(0) */
exc.type = SING;
exc.name = "lgamma";
ieee_retval = setexception(0, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "lgamma: SING error\n", 19);
!
errno = EDOM;
}
+
break;
case 16:
/* log(0) */
exc.type = SING;
exc.name = "log";
ieee_retval = setexception(0, -1.0);
+
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, "log: SING error\n", 16);
errno = EDOM;
} else {
errno = ERANGE;
}
}
+
break;
case 17:
/* log(x<0) */
exc.type = DOMAIN;
exc.name = "log";
ieee_retval = setexception(3, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "log: DOMAIN error\n", 18);
!
errno = EDOM;
}
+
break;
case 18:
/* log10(0) */
exc.type = SING;
exc.name = "log10";
ieee_retval = setexception(0, -1.0);
+
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, "log10: SING error\n", 18);
errno = EDOM;
} else {
errno = ERANGE;
}
}
+
break;
case 19:
/* log10(x<0) */
exc.type = DOMAIN;
exc.name = "log10";
ieee_retval = setexception(3, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "log10: DOMAIN error\n", 20);
!
errno = EDOM;
}
+
break;
case 20:
!
! /*
! * pow(0.0,0.0)
! * error only if lib_version == c_issue_4
! */
exc.type = DOMAIN;
exc.name = "pow";
exc.retval = 0.0;
ieee_retval = 1.0;
+
if (lib_version != c_issue_4) {
exc.retval = 1.0;
} else if (!matherr(&exc)) {
(void) write(2, "pow(0,0): DOMAIN error\n", 23);
errno = EDOM;
}
+
break;
case 21:
/* pow(x,y) overflow */
exc.type = OVERFLOW;
exc.name = "pow";
! exc.retval = (lib_version == c_issue_4) ? HUGE : HUGE_VAL;
!
if (signbit(x)) {
t = rint(y);
+
if (t == y) {
w = rint(0.5 * y);
!
! if (t != w + w) /* y is odd */
exc.retval = -exc.retval;
}
}
!
ieee_retval = setexception(2, exc.retval);
+
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
+
break;
case 22:
/* pow(x,y) underflow */
exc.type = UNDERFLOW;
exc.name = "pow";
exc.retval = 0.0;
+
if (signbit(x)) {
t = rint(y);
+
if (t == y) {
w = rint(0.5 * y);
+
if (t != w + w) /* y is odd */
exc.retval = -exc.retval;
}
}
+
ieee_retval = setexception(1, exc.retval);
+
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
+
break;
case 23:
/* (+-0)**neg */
exc.type = DOMAIN;
exc.name = "pow";
ieee_retval = setexception(0, 1.0);
{
int ahy, k, j, yisint, ly, hx;
!
! /* BEGIN CSTYLED */
/*
* determine if y is an odd int when x = -0
* yisint = 0 ... y is not an integer
* yisint = 1 ... y is an odd int
* yisint = 2 ... y is an even int
*/
! /* END CSTYLED */
hx = __HI(x);
! ahy = __HI(y) & 0x7fffffff;
ly = __LO(y);
yisint = 0;
+
if (ahy >= 0x43400000) {
yisint = 2; /* even integer y */
} else if (ahy >= 0x3ff00000) {
k = (ahy >> 20) - 0x3ff; /* exponent */
+
if (k > 20) {
j = ly >> (52 - k);
+
if ((j << (52 - k)) == ly)
yisint = 2 - (j & 1);
} else if (ly == 0) {
j = ahy >> (20 - k);
+
if ((j << (20 - k)) == ahy)
yisint = 2 - (j & 1);
}
}
+
if (hx < 0 && yisint == 1)
ieee_retval = -ieee_retval;
}
+
if (lib_version == c_issue_4)
exc.retval = 0.0;
else
exc.retval = -HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, "pow(0,neg): DOMAIN error\n",
25);
}
+
errno = EDOM;
}
+
break;
case 24:
/* neg**non-integral */
exc.type = DOMAIN;
exc.name = "pow";
ieee_retval = setexception(3, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = 0.0;
else
exc.retval = ieee_retval; /* X/Open allow NaN */
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2,
"neg**non-integral: DOMAIN error\n", 32);
}
+
errno = EDOM;
}
+
break;
case 25:
/* sinh(finite) overflow */
exc.type = OVERFLOW;
exc.name = "sinh";
ieee_retval = copysign(Inf, x);
+
if (lib_version == c_issue_4)
exc.retval = x > 0.0 ? HUGE : -HUGE;
else
exc.retval = x > 0.0 ? HUGE_VAL : -HUGE_VAL;
+
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
+
break;
case 26:
/* sqrt(x<0) */
exc.type = DOMAIN;
exc.name = "sqrt";
ieee_retval = setexception(3, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = 0.0;
else
exc.retval = ieee_retval; /* quiet NaN */
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "sqrt: DOMAIN error\n", 19);
!
errno = EDOM;
}
+
break;
case 27:
/* fmod(x,0) */
exc.type = DOMAIN;
exc.name = "fmod";
+
if (fp_class(x) == fp_quiet)
ieee_retval = NaN;
else
ieee_retval = setexception(3, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = x;
else
exc.retval = ieee_retval;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "fmod: DOMAIN error\n", 20);
!
errno = EDOM;
}
+
break;
case 28:
/* remainder(x,0) */
exc.type = DOMAIN;
exc.name = "remainder";
+
if (fp_class(x) == fp_quiet)
ieee_retval = NaN;
else
ieee_retval = setexception(3, 1.0);
+
exc.retval = NaN;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "remainder: DOMAIN error\n",
24);
!
errno = EDOM;
}
+
break;
case 29:
/* acosh(x<1) */
exc.type = DOMAIN;
exc.name = "acosh";
ieee_retval = setexception(3, 1.0);
exc.retval = NaN;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "acosh: DOMAIN error\n", 20);
!
errno = EDOM;
}
+
break;
case 30:
/* atanh(|x|>1) */
exc.type = DOMAIN;
exc.name = "atanh";
ieee_retval = setexception(3, 1.0);
exc.retval = NaN;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "atanh: DOMAIN error\n", 20);
!
errno = EDOM;
}
+
break;
case 31:
/* atanh(|x|=1) */
exc.type = SING;
exc.name = "atanh";
ieee_retval = setexception(0, x);
exc.retval = ieee_retval;
+
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, "atanh: SING error\n", 18);
errno = EDOM;
} else {
errno = ERANGE;
}
}
+
break;
case 32:
/* scalb overflow; SVID also returns +-HUGE_VAL */
exc.type = OVERFLOW;
exc.name = "scalb";
ieee_retval = setexception(2, x);
exc.retval = x > 0.0 ? HUGE_VAL : -HUGE_VAL;
+
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
+
break;
case 33:
/* scalb underflow */
exc.type = UNDERFLOW;
exc.name = "scalb";
ieee_retval = setexception(1, x);
exc.retval = ieee_retval; /* +-0.0 */
+
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
+
break;
case 34:
/* j0(|x|>X_TLOSS) */
exc.type = TLOSS;
exc.name = "j0";
exc.retval = 0.0;
ieee_retval = y;
+
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, exc.name, 2);
(void) write(2, ": TLOSS error\n", 14);
}
+
errno = ERANGE;
}
+
break;
case 35:
/* y0(x>X_TLOSS) */
exc.type = TLOSS;
exc.name = "y0";
exc.retval = 0.0;
ieee_retval = y;
+
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, exc.name, 2);
(void) write(2, ": TLOSS error\n", 14);
}
+
errno = ERANGE;
}
+
break;
case 36:
/* j1(|x|>X_TLOSS) */
exc.type = TLOSS;
exc.name = "j1";
exc.retval = 0.0;
ieee_retval = y;
+
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, exc.name, 2);
(void) write(2, ": TLOSS error\n", 14);
}
+
errno = ERANGE;
}
+
break;
case 37:
/* y1(x>X_TLOSS) */
exc.type = TLOSS;
exc.name = "y1";
exc.retval = 0.0;
ieee_retval = y;
+
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, exc.name, 2);
(void) write(2, ": TLOSS error\n", 14);
}
+
errno = ERANGE;
}
+
break;
case 38:
!
! /*
! * jn(|x|>X_TLOSS)
! * incorrect ieee value: ieee should never be here
! */
exc.type = TLOSS;
exc.name = "jn";
exc.retval = 0.0;
ieee_retval = 0.0; /* shall not be used */
+
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, exc.name, 2);
(void) write(2, ": TLOSS error\n", 14);
}
+
errno = ERANGE;
}
+
break;
case 39:
!
! /*
! * yn(x>X_TLOSS)
! * incorrect ieee value: ieee should never be here
! */
exc.type = TLOSS;
exc.name = "yn";
exc.retval = 0.0;
ieee_retval = 0.0; /* shall not be used */
+
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, exc.name, 2);
(void) write(2, ": TLOSS error\n", 14);
}
+
errno = ERANGE;
}
+
break;
case 40:
/* gamma(finite) overflow */
exc.type = OVERFLOW;
exc.name = "gamma";
ieee_retval = setexception(2, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
+
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
+
break;
case 41:
/* gamma(-integer) or gamma(0) */
exc.type = SING;
exc.name = "gamma";
ieee_retval = setexception(0, 1.0);
+
if (lib_version == c_issue_4)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "gamma: SING error\n", 18);
!
errno = EDOM;
}
+
break;
case 42:
!
! /*
! * pow(NaN,0.0)
! * error if lib_version == c_issue_4 or ansi_1
! */
exc.type = DOMAIN;
exc.name = "pow";
exc.retval = x;
ieee_retval = 1.0;
+
if (lib_version == strict_ansi) {
exc.retval = 1.0;
} else if (!matherr(&exc)) {
! if ((lib_version == c_issue_4) || (lib_version ==
! ansi_1))
errno = EDOM;
}
+
break;
case 43:
/* log1p(-1) */
exc.type = SING;
exc.name = "log1p";
ieee_retval = setexception(0, -1.0);
+
if (lib_version == c_issue_4)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
+
if (lib_version == strict_ansi) {
errno = ERANGE;
} else if (!matherr(&exc)) {
if (lib_version == c_issue_4) {
(void) write(2, "log1p: SING error\n", 18);
errno = EDOM;
} else {
errno = ERANGE;
}
}
+
break;
case 44:
/* log1p(x<-1) */
exc.type = DOMAIN;
exc.name = "log1p";
ieee_retval = setexception(3, 1.0);
exc.retval = ieee_retval;
+
if (lib_version == strict_ansi) {
errno = EDOM;
} else if (!matherr(&exc)) {
! if (lib_version == c_issue_4)
(void) write(2, "log1p: DOMAIN error\n", 20);
!
errno = EDOM;
}
+
break;
case 45:
/* logb(0) */
exc.type = DOMAIN;
exc.name = "logb";
ieee_retval = setexception(0, -1.0);
exc.retval = -HUGE_VAL;
+
if (lib_version == strict_ansi)
errno = EDOM;
else if (!matherr(&exc))
errno = EDOM;
+
break;
case 46:
/* nextafter overflow */
exc.type = OVERFLOW;
exc.name = "nextafter";
+
/*
* The value as returned by setexception is +/-DBL_MAX in
* round-to-{zero,-/+Inf} mode respectively, which is not
* usable.
*/
(void) setexception(2, x);
ieee_retval = x > 0 ? Inf : -Inf;
exc.retval = x > 0 ? HUGE_VAL : -HUGE_VAL;
+
if (lib_version == strict_ansi)
errno = ERANGE;
else if (!matherr(&exc))
errno = ERANGE;
+
break;
case 47:
/* scalb(x,inf) */
iy = ((int *)&y)[HIWORD];
+
if (lib_version == c_issue_4)
/* SVID3: ERANGE in all cases */
errno = ERANGE;
else if ((x == 0.0 && iy > 0) || (!finite(x) && iy < 0))
/* EDOM for scalb(0,+inf) or scalb(inf,-inf) */
errno = EDOM;
!
! exc.retval = ieee_retval = ((iy < 0) ? x / -y : x * y);
break;
}
+
switch (lib_version) {
case c_issue_4:
case ansi_1:
case strict_ansi:
return (exc.retval);
/* NOTREACHED */
default:
return (ieee_retval);
}
+
/* NOTREACHED */
}
static double
! setexception(int n, double x)
! {
/*
* n =
* 0 division by zero
* 1 underflow
* 2 overflow
*** 970,976 ****
--- 1132,1139 ----
break;
case 3: /* invalid */
retv = zero * Inf; /* for Cheetah */
break;
}
+
return (retv);
}