diff options
| author | Rodney W. Grimes <rgrimes@FreeBSD.org> | 1994-05-27 05:00:24 +0000 | 
|---|---|---|
| committer | Rodney W. Grimes <rgrimes@FreeBSD.org> | 1994-05-27 05:00:24 +0000 | 
| commit | 58f0484fa251c266ede97b591b499fe3dd4f578e (patch) | |
| tree | 41932a7161f4cd72005330a9c69747e7bab2ee5b /lib/libm/common_source | |
| parent | fb49e767ba942f74b1cee8814e085e5f2615ac53 (diff) | |
Notes
Diffstat (limited to 'lib/libm/common_source')
52 files changed, 8535 insertions, 0 deletions
| diff --git a/lib/libm/common_source/acos.3 b/lib/libm/common_source/acos.3 new file mode 100644 index 000000000000..6f1f3864f19b --- /dev/null +++ b/lib/libm/common_source/acos.3 @@ -0,0 +1,88 @@ +.\" Copyright (c) 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)acos.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt ACOS 3 +.Os +.Sh NAME +.Nm acos +.Nd arc cosine function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn acos "double x" +.Sh DESCRIPTION +The +.Fn acos +function computes the principal value of the arc cosine of +.Fa x . +A domain error occurs for arguments not in the range [-1, +1]. +For a discussion of error due to roundoff, see +.Xr math 3 . +.Sh RETURN VALUES +The  +.Fn acos +function returns the arc cosine in the range +.Bq 0 , \*(Pi +radians. +On the +.Tn VAX +and +.Tn Tahoe , +if: +.Bd -unfilled -offset indent +.Pf \&| Ns Ar x Ns \&| > 1 , +.Ed +.Pp +.Fn acos x +sets the global variable +.Va errno +to +.Dv EDOM +and a reserved operand fault is generated. +.Sh SEE ALSO +.Xr sin 3 , +.Xr cos 3 , +.Xr tan 3 , +.Xr asin 3 , +.Xr atan 3 , +.Xr atan2 3 , +.Xr sinh 3 , +.Xr cosh 3 , +.Xr tanh 3 , +.Xr math 3 , +.Sh STANDARDS +The +.Fn acos +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/acosh.3 b/lib/libm/common_source/acosh.3 new file mode 100644 index 000000000000..3023da506500 --- /dev/null +++ b/lib/libm/common_source/acosh.3 @@ -0,0 +1,81 @@ +.\" Copyright (c) 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)acosh.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt ACOSH 3 +.Os BSD 4.3 +.Sh NAME +.Nm acosh +.Nd inverse hyperbolic cosine function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn acosh "double x" +.Sh DESCRIPTION +The +.Fn acosh +function computes the inverse hyperbolic cosine +of the real +argument +.Ar x . +For a discussion of error due to roundoff, see +.Xr math 3 . +.Sh RETURN VALUES +The +.Fn acosh +function +returns the inverse hyperbolic cosine of +.Ar x . +On the +.Tn VAX +and +.Tn Tahoe , +if the argument is less than one +.Fn acosh +sets the global variable +.Va errno +to +.Er EDOM +and +causes a reserved operand fault. +.Sh SEE ALSO +.Xr asinh 3 , +.Xr atanh 3 , +.Xr exp 3 , +.Xr infnan 3 +.Xr math 3 , +.Sh HISTORY +The +.Fn acosh +function appeared in  +.Bx 4.3 . diff --git a/lib/libm/common_source/acosh.c b/lib/libm/common_source/acosh.c new file mode 100644 index 000000000000..bc16cc7b46a8 --- /dev/null +++ b/lib/libm/common_source/acosh.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)acosh.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* ACOSH(X) + * RETURN THE INVERSE HYPERBOLIC COSINE OF X + * DOUBLE PRECISION (VAX D FORMAT 56 BITS, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 2/16/85; + * REVISED BY K.C. NG on 3/6/85, 3/24/85, 4/16/85, 8/17/85. + * + * Required system supported functions : + *	sqrt(x) + * + * Required kernel function: + *	log1p(x) 		...return log(1+x) + * + * Method : + *	Based on  + *		acosh(x) = log [ x + sqrt(x*x-1) ] + *	we have + *		acosh(x) := log1p(x)+ln2,	if (x > 1.0E20); else		 + *		acosh(x) := log1p( sqrt(x-1) * (sqrt(x-1) + sqrt(x+1)) ) . + *	These formulae avoid the over/underflow complication. + * + * Special cases: + *	acosh(x) is NaN with signal if x<1. + *	acosh(NaN) is NaN without signal. + * + * Accuracy: + *	acosh(x) returns the exact inverse hyperbolic cosine of x nearly  + *	rounded. In a test run with 512,000 random arguments on a VAX, the + *	maximum observed error was 3.30 ulps (units of the last place) at + *	x=1.0070493753568216 . + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(ln2hi, 6.9314718055829871446E-1  ,7217,4031,0000,f7d0,   0, .B17217F7D00000) +vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC) + +ic(ln2hi, 6.9314718036912381649E-1,  -1, 1.62E42FEE00000) +ic(ln2lo, 1.9082149292705877000E-10,-33, 1.A39EF35793C76) + +#ifdef vccast +#define    ln2hi    vccast(ln2hi) +#define    ln2lo    vccast(ln2lo) +#endif + +double acosh(x) +double x; +{	 +	double t,big=1.E20; /* big+1==big */ + +#if !defined(vax)&&!defined(tahoe) +	if(x!=x) return(x);	/* x is NaN */ +#endif	/* !defined(vax)&&!defined(tahoe) */ + +    /* return log1p(x) + log(2) if x is large */ +	if(x>big) {t=log1p(x)+ln2lo; return(t+ln2hi);}  + +	t=sqrt(x-1.0); +	return(log1p(t*(t+sqrt(x+1.0)))); +} diff --git a/lib/libm/common_source/asin.3 b/lib/libm/common_source/asin.3 new file mode 100644 index 000000000000..9ca39caca63f --- /dev/null +++ b/lib/libm/common_source/asin.3 @@ -0,0 +1,90 @@ +.\" Copyright (c) 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)asin.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt ASIN 3 +.Os +.Sh NAME +.Nm asin +.Nd arc sine function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn asin "double  x" +.Sh DESCRIPTION +The +.Fn asin +function computes the principal value of the arc sine of +.Fa x . +A domain error occurs for arguments not in the range [-1, +1]. +For a discussion of error due to roundoff, see +.Xr math 3 . +.Sh RETURN VALUES +The +.Fn asin +function returns the arc sine in the range +.Bk -words +.Bq -\*(Pi/2, +\*(Pi/2 +.Ek +radians. +On the +.Tn VAX , +and Tahoe , +if: +.Bd -unfilled -offset indent +.Pf \&| Ns Ar x Ns \&| > 1 +.Ed +.Pp +the +global variable +.Va errno +is set to +.Er EDOM +and +a reserved operand fault generated. +.Sh SEE ALSO +.Xr acos 3 , +.Xr atan 3 , +.Xr atan2 3 , +.Xr cos 3 , +.Xr cosh 3 , +.Xr sin 3 , +.Xr sinh 3 , +.Xr tan 3 , +.Xr tanh 3 , +.Xr math 3 , +.Sh STANDARDS +The +.Fn asin +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/asincos.c b/lib/libm/common_source/asincos.c new file mode 100644 index 000000000000..c746b1652ac2 --- /dev/null +++ b/lib/libm/common_source/asincos.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)asincos.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* ASIN(X) + * RETURNS ARC SINE OF X + * DOUBLE PRECISION (IEEE DOUBLE 53 bits, VAX D FORMAT 56 bits) + * CODED IN C BY K.C. NG, 4/16/85, REVISED ON 6/10/85. + * + * Required system supported functions: + *	copysign(x,y) + *	sqrt(x) + * + * Required kernel function: + *	atan2(y,x)  + * + * Method :                   + *	asin(x) = atan2(x,sqrt(1-x*x)); for better accuracy, 1-x*x is  + *		  computed as follows + *			1-x*x                     if x <  0.5,  + *			2*(1-|x|)-(1-|x|)*(1-|x|) if x >= 0.5. + * + * Special cases: + *	if x is NaN, return x itself; + *	if |x|>1, return NaN. + * + * Accuracy: + * 1)  If atan2() uses machine PI, then + *  + *	asin(x) returns (PI/pi) * (the exact arc sine of x) nearly rounded; + *	and PI is the exact pi rounded to machine precision (see atan2 for + *      details): + * + *	in decimal: + *		pi = 3.141592653589793 23846264338327 .....  + *    53 bits   PI = 3.141592653589793 115997963 ..... , + *    56 bits   PI = 3.141592653589793 227020265 ..... ,   + * + *	in hexadecimal: + *		pi = 3.243F6A8885A308D313198A2E.... + *    53 bits   PI = 3.243F6A8885A30  =  2 * 1.921FB54442D18	error=.276ulps + *    56 bits   PI = 3.243F6A8885A308 =  4 * .C90FDAA22168C2    error=.206ulps + *	 + *	In a test run with more than 200,000 random arguments on a VAX, the  + *	maximum observed error in ulps (units in the last place) was + *	2.06 ulps.      (comparing against (PI/pi)*(exact asin(x))); + * + * 2)  If atan2() uses true pi, then + * + *	asin(x) returns the exact asin(x) with error below about 2 ulps. + * + *	In a test run with more than 1,024,000 random arguments on a VAX, the  + *	maximum observed error in ulps (units in the last place) was + *      1.99 ulps. + */ + +double asin(x) +double x; +{ +	double s,t,copysign(),atan2(),sqrt(),one=1.0; +#if !defined(vax)&&!defined(tahoe) +	if(x!=x) return(x);	/* x is NaN */ +#endif	/* !defined(vax)&&!defined(tahoe) */ +	s=copysign(x,one); +	if(s <= 0.5) +	    return(atan2(x,sqrt(one-x*x))); +	else  +	    { t=one-s; s=t+t; return(atan2(x,sqrt(s-t*t))); } + +} + +/* ACOS(X) + * RETURNS ARC COS OF X + * DOUBLE PRECISION (IEEE DOUBLE 53 bits, VAX D FORMAT 56 bits) + * CODED IN C BY K.C. NG, 4/16/85, REVISED ON 6/10/85. + * + * Required system supported functions: + *	copysign(x,y) + *	sqrt(x) + * + * Required kernel function: + *	atan2(y,x)  + * + * Method :                   + *			      ________ + *                           / 1 - x + *	acos(x) = 2*atan2(  / -------- , 1 ) . + *                        \/   1 + x + * + * Special cases: + *	if x is NaN, return x itself; + *	if |x|>1, return NaN. + * + * Accuracy: + * 1)  If atan2() uses machine PI, then + *  + *	acos(x) returns (PI/pi) * (the exact arc cosine of x) nearly rounded; + *	and PI is the exact pi rounded to machine precision (see atan2 for + *      details): + * + *	in decimal: + *		pi = 3.141592653589793 23846264338327 .....  + *    53 bits   PI = 3.141592653589793 115997963 ..... , + *    56 bits   PI = 3.141592653589793 227020265 ..... ,   + * + *	in hexadecimal: + *		pi = 3.243F6A8885A308D313198A2E.... + *    53 bits   PI = 3.243F6A8885A30  =  2 * 1.921FB54442D18	error=.276ulps + *    56 bits   PI = 3.243F6A8885A308 =  4 * .C90FDAA22168C2    error=.206ulps + *	 + *	In a test run with more than 200,000 random arguments on a VAX, the  + *	maximum observed error in ulps (units in the last place) was + *	2.07 ulps.      (comparing against (PI/pi)*(exact acos(x))); + * + * 2)  If atan2() uses true pi, then + * + *	acos(x) returns the exact acos(x) with error below about 2 ulps. + * + *	In a test run with more than 1,024,000 random arguments on a VAX, the  + *	maximum observed error in ulps (units in the last place) was + *	2.15 ulps. + */ + +double acos(x) +double x; +{ +	double t,copysign(),atan2(),sqrt(),one=1.0; +#if !defined(vax)&&!defined(tahoe) +	if(x!=x) return(x); +#endif	/* !defined(vax)&&!defined(tahoe) */ +	if( x != -1.0) +	    t=atan2(sqrt((one-x)/(one+x)),one); +	else +	    t=atan2(one,0.0);	/* t = PI/2 */ +	return(t+t); +} diff --git a/lib/libm/common_source/asinh.3 b/lib/libm/common_source/asinh.3 new file mode 100644 index 000000000000..3958960399a8 --- /dev/null +++ b/lib/libm/common_source/asinh.3 @@ -0,0 +1,69 @@ +.\" Copyright (c) 1985, 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)asinh.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt ASINH 3 +.Os BSD 4.3 +.Sh NAME +.Nm asinh +.Nd inverse hyperbolic sine function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn asinh "double x" +.Sh DESCRIPTION +The +.Fn asinh +function computes the inverse hyperbolic sine +of the real +argument +.Ar x . +For a discussion of error due to roundoff, see +.Xr math 3 . +.Sh RETURN VALUES +The +.Fn asinh +function +returns the inverse hyperbolic sine of +.Ar x . +.Sh SEE ALSO +.Xr acosh 3 , +.Xr atanh 3 , +.Xr exp 3 , +.Xr infnan 3 +.Xr math 3 , +.Sh HISTORY +The +.Fn asinh +function appeared in  +.Bx 4.3 . diff --git a/lib/libm/common_source/asinh.c b/lib/libm/common_source/asinh.c new file mode 100644 index 000000000000..5db8d2ddf7f8 --- /dev/null +++ b/lib/libm/common_source/asinh.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)asinh.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* ASINH(X) + * RETURN THE INVERSE HYPERBOLIC SINE OF X + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 2/16/85; + * REVISED BY K.C. NG on 3/7/85, 3/24/85, 4/16/85. + * + * Required system supported functions : + *	copysign(x,y) + *	sqrt(x) + * + * Required kernel function: + *	log1p(x) 		...return log(1+x) + * + * Method : + *	Based on  + *		asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] + *	we have + *	asinh(x) := x  if  1+x*x=1, + *		 := sign(x)*(log1p(x)+ln2))	 if sqrt(1+x*x)=x, else + *		 := sign(x)*log1p(|x| + |x|/(1/|x| + sqrt(1+(1/|x|)^2)) )   + * + * Accuracy: + *	asinh(x) returns the exact inverse hyperbolic sine of x nearly rounded. + *	In a test run with 52,000 random arguments on a VAX, the maximum  + *	observed error was 1.58 ulps (units in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ +#include "mathimpl.h" + +vc(ln2hi, 6.9314718055829871446E-1  ,7217,4031,0000,f7d0,   0, .B17217F7D00000) +vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC) + +ic(ln2hi, 6.9314718036912381649E-1,   -1, 1.62E42FEE00000) +ic(ln2lo, 1.9082149292705877000E-10, -33, 1.A39EF35793C76) + +#ifdef vccast +#define    ln2hi    vccast(ln2hi) +#define    ln2lo    vccast(ln2lo) +#endif + +double asinh(x) +double x; +{	 +	double t,s; +	const static double	small=1.0E-10,	/* fl(1+small*small) == 1 */ +				big  =1.0E20,	/* fl(1+big) == big */ +				one  =1.0   ;	 + +#if !defined(vax)&&!defined(tahoe) +	if(x!=x) return(x);	/* x is NaN */ +#endif	/* !defined(vax)&&!defined(tahoe) */ +	if((t=copysign(x,one))>small)  +	    if(t<big) { +	     	s=one/t; return(copysign(log1p(t+t/(s+sqrt(one+s*s))),x)); } +	    else	/* if |x| > big */ +		{s=log1p(t)+ln2lo; return(copysign(s+ln2hi,x));} +	else	/* if |x| < small */ +	    return(x); +} diff --git a/lib/libm/common_source/atan.3 b/lib/libm/common_source/atan.3 new file mode 100644 index 000000000000..776978e03bc4 --- /dev/null +++ b/lib/libm/common_source/atan.3 @@ -0,0 +1,74 @@ +.\" Copyright (c) 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)atan.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt ATAN 3 +.Os +.Sh NAME +.Nm atan +.Nd arc tangent function of one variable +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn atan "double x" +.Sh DESCRIPTION +The +.Fn atan +function computes the principal value of the arc tangent of +.Fa x . +For a discussion of error due to roundoff, see +.Xr math 3 . +.Sh RETURN VALUES +The +.Fn atan +function returns the arc tangent in the range +.Bk -words +.Bq -\*(Pi/2 , +\*(Pi/2 +.Ek +radians. +.Sh SEE ALSO +.Xr acos 3 , +.Xr asin 3 , +.Xr atan2 3 , +.Xr cos 3 , +.Xr cosh 3 , +.Xr sin 3 , +.Xr sinh 3 , +.Xr tan 3 , +.Xr tanh 3 , +.Xr math 3 , +.Sh STANDARDS +The +.Fn atan +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/atan.c b/lib/libm/common_source/atan.c new file mode 100644 index 000000000000..272c7f1cdc48 --- /dev/null +++ b/lib/libm/common_source/atan.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)atan.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* ATAN(X) + * RETURNS ARC TANGENT OF X + * DOUBLE PRECISION (IEEE DOUBLE 53 bits, VAX D FORMAT 56 bits) + * CODED IN C BY K.C. NG, 4/16/85, REVISED ON 6/10/85. + * + * Required kernel function: + *	atan2(y,x)  + * + * Method:                   + *	atan(x) = atan2(x,1.0).  + * + * Special case: + *	if x is NaN, return x itself. + * + * Accuracy: + * 1)  If atan2() uses machine PI, then + *  + *	atan(x) returns (PI/pi) * (the exact arc tangent of x) nearly rounded; + *	and PI is the exact pi rounded to machine precision (see atan2 for + *      details): + * + *	in decimal: + *		pi = 3.141592653589793 23846264338327 .....  + *    53 bits   PI = 3.141592653589793 115997963 ..... , + *    56 bits   PI = 3.141592653589793 227020265 ..... ,   + * + *	in hexadecimal: + *		pi = 3.243F6A8885A308D313198A2E.... + *    53 bits   PI = 3.243F6A8885A30  =  2 * 1.921FB54442D18	error=.276ulps + *    56 bits   PI = 3.243F6A8885A308 =  4 * .C90FDAA22168C2    error=.206ulps + *	 + *	In a test run with more than 200,000 random arguments on a VAX, the  + *	maximum observed error in ulps (units in the last place) was + *	0.86 ulps.      (comparing against (PI/pi)*(exact atan(x))). + * + * 2)  If atan2() uses true pi, then + * + *	atan(x) returns the exact atan(x) with error below about 2 ulps. + * + *	In a test run with more than 1,024,000 random arguments on a VAX, the  + *	maximum observed error in ulps (units in the last place) was + *	0.85 ulps. + */ + +double atan(x) +double x; +{ +	double atan2(),one=1.0; +	return(atan2(x,one)); +} diff --git a/lib/libm/common_source/atan2.3 b/lib/libm/common_source/atan2.3 new file mode 100644 index 000000000000..a5eb7ac0a709 --- /dev/null +++ b/lib/libm/common_source/atan2.3 @@ -0,0 +1,188 @@ +.\" Copyright (c) 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)atan2.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt ATAN2 3 +.Os +.Sh NAME +.Nm atan2 +.Nd arc tangent function of two variables +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn atan2 "double y" "double x" +.Sh DESCRIPTION +The +.Xr atan2 +function computes the principal value of the arc tangent of +.Ar y/ Ns Ar x , +using the signs of both arguments to determine the quadrant of +the return value. +.Sh RETURN VALUES +The +.Xr atan2 +function, if successful, +returns the arc tangent of  +.Ar y/ Ns Ar x +in the range +.Bk -words +.Bq \&- Ns \*(Pi , \&+ Ns \*(Pi +.Ek +radians. +If both +.Ar x +and +.Ar y +are zero, the global variable +.Va errno +is set to +.Er EDOM . +On the +.Tn VAX : +.Bl -column atan_(y,x)_:=____  sign(y)_(Pi_atan2(Xy_xX))___ +.It Fn atan2 y x No := Ta +.Fn atan y/x Ta +if +.Ar x +> 0, +.It Ta sign( Ns Ar y Ns )*(\*(Pi - +.Fn atan "\\*(Bay/x\\*(Ba" ) Ta +if +.Ar x +< 0, +.It Ta +.No 0 Ta +if x = y = 0, or +.It Ta +.Pf sign( Ar y Ns )*\\*(Pi/2 Ta +if +.Ar x += 0 \*(!= +.Ar y . +.El +.Sh NOTES +The function +.Fn atan2 +defines "if x > 0," +.Fn atan2 0 0 += 0 on a +.Tn VAX +despite that previously +.Fn atan2 0 0 +may have generated an error message. +The reasons for assigning a value to +.Fn atan2 0 0 +are these: +.Bl -enum -offset indent +.It +Programs that test arguments to avoid computing +.Fn atan2 0 0 +must be indifferent to its value. +Programs that require it to be invalid are vulnerable +to diverse reactions to that invalidity on diverse computer systems. +.It +The +.Fn atan2 +function is used mostly to convert from rectangular (x,y) +to polar +.if n\ +(r,theta) +.if t\ +(r,\(*h) +coordinates that must satisfy x = +.if n\ +r\(**cos theta +.if t\ +r\(**cos\(*h +and y = +.if n\ +r\(**sin theta. +.if t\ +r\(**sin\(*h. +These equations are satisfied when (x=0,y=0) +is mapped to +.if n \ +(r=0,theta=0) +.if t \ +(r=0,\(*h=0) +on a VAX.  In general, conversions to polar coordinates +should be computed thus: +.Bd -unfilled -offset indent +.if n \{\ +r	:= hypot(x,y);  ... := sqrt(x\(**x+y\(**y) +theta	:= atan2(y,x). +.\} +.if t \{\ +r	:= hypot(x,y);  ... := \(sr(x\u\s82\s10\d+y\u\s82\s10\d) +\(*h	:= atan2(y,x). +.\} +.Ed +.It +The foregoing formulas need not be altered to cope in a +reasonable way with signed zeros and infinities +on a machine that conforms to +.Tn IEEE 754 ; +the versions of +.Xr hypot 3 +and +.Fn atan2 +provided for +such a machine are designed to handle all cases. +That is why +.Fn atan2 \(+-0 \-0 += \(+-\*(Pi +for instance. +In general the formulas above are equivalent to these: +.Bd -unfilled -offset indent +.if n \ +r := sqrt(x\(**x+y\(**y); if r = 0 then x := copysign(1,x); +.if t \ +r := \(sr(x\(**x+y\(**y);\0\0if r = 0 then x := copysign(1,x); +.Ed +.El +.Sh SEE ALSO +.Xr acos 3 , +.Xr asin 3 , +.Xr atan 3 , +.Xr cos 3 , +.Xr cosh 3 , +.Xr sin 3 , +.Xr sinh 3 , +.Xr tan 3 , +.Xr tanh 3 , +.Xr math 3 , +.Sh STANDARDS +The +.Fn atan2 +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/atanh.3 b/lib/libm/common_source/atanh.3 new file mode 100644 index 000000000000..6f085362e283 --- /dev/null +++ b/lib/libm/common_source/atanh.3 @@ -0,0 +1,83 @@ +.\" Copyright (c) 1985, 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)atanh.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt ATANH 3 +.Os BSD 4.3 +.Sh NAME +.Nm atanh +.Nd inverse hyperbolic tangent function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn atanh "double x" +.Sh DESCRIPTION +The +.Fn  atanh +function computes the inverse hyperbolic tangent +of the real +argument +.Ar x . +For a discussion of error due to roundoff, see +.Xr math 3 . +.Sh RETURN VALUES +The +.Fn atanh +function +returns the inverse hyperbolic tangent of +.Ar x +if successful. +On the +.Tn VAX +and +.Tn Tahoe , +if the argument has absolute value +bigger than or equal to 1, +.Fn atanh +sets the global variable +.Va errno +to +.Er EDOM +and +a reserved operand fault is generated. +.Sh SEE ALSO +.Xr acosh 3 , +.Xr asinh 3 , +.Xr exp 3 , +.Xr infnan 3 +.Xr math 3 , +.Sh HISTORY +The +.Fn atanh +function appeared in +.Bx 4.3 . diff --git a/lib/libm/common_source/atanh.c b/lib/libm/common_source/atanh.c new file mode 100644 index 000000000000..89cb61cca25e --- /dev/null +++ b/lib/libm/common_source/atanh.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)atanh.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* ATANH(X) + * RETURN THE HYPERBOLIC ARC TANGENT OF X + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/8/85;  + * REVISED BY K.C. NG on 2/7/85, 3/7/85, 8/18/85. + * + * Required kernel function: + *	log1p(x) 	...return log(1+x) + * + * Method : + *	Return  + *                          1              2x                          x + *		atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) + *                          2             1 - x                      1 - x + * + * Special cases: + *	atanh(x) is NaN if |x| > 1 with signal; + *	atanh(NaN) is that NaN with no signal; + *	atanh(+-1) is +-INF with signal. + * + * Accuracy: + *	atanh(x) returns the exact hyperbolic arc tangent of x nearly rounded. + *	In a test run with 512,000 random arguments on a VAX, the maximum + *	observed error was 1.87 ulps (units in the last place) at + *	x= -3.8962076028810414000e-03. + */ +#include "mathimpl.h" + +#if defined(vax)||defined(tahoe) +#include <errno.h> +#endif	/* defined(vax)||defined(tahoe) */ + +double atanh(x) +double x; +{ +	double z; +	z = copysign(0.5,x); +	x = copysign(x,1.0); +#if defined(vax)||defined(tahoe) +	if (x == 1.0) { +	    return(copysign(1.0,z)*infnan(ERANGE));	/* sign(x)*INF */ +	} +#endif	/* defined(vax)||defined(tahoe) */ +	x = x/(1.0-x); +	return( z*log1p(x+x) ); +} diff --git a/lib/libm/common_source/ceil.3 b/lib/libm/common_source/ceil.3 new file mode 100644 index 000000000000..4bc02ba22cee --- /dev/null +++ b/lib/libm/common_source/ceil.3 @@ -0,0 +1,65 @@ +.\" Copyright (c) 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)ceil.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt CEIL 3 +.Os +.Sh NAME +.Nm ceil +.Nd smallest integral value not greater than x +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn ceil "double x" +.Sh DESCRIPTION +The +.Fn ceil +function computes the smallest integral value not less than +.Fa x . +.Sh RETURN VALUES +The +.Fn ceil +function returns the smallest integral value +expressed as a double. +.Sh SEE ALSO +.Xr abs 3 , +.Xr fabs 3 , +.Xr floor 3 , +.Xr rint 3 , +.Xr ieee 3 , +.Xr math.3 +.Sh STANDARDS +The +.Fn ceil +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/cos.3 b/lib/libm/common_source/cos.3 new file mode 100644 index 000000000000..d1051ed64e27 --- /dev/null +++ b/lib/libm/common_source/cos.3 @@ -0,0 +1,73 @@ +.\" Copyright (c) 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)cos.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt COS 3 +.Os +.Sh NAME +.Nm cos +.Nd cosine function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn cos "double x" +.Sh DESCRIPTION +The +.Fn cos +function computes the cosine of +.Fa x +(measured in radians). +A large magnitude argument may yield a result with little or no  +significance. +For a discussion of error due to roundoff, see +.Xr math 3 . +.Sh RETURN VALUES +The +.Fn cos +function returns the cosine value. +.Sh SEE ALSO +.Xr sin 3 , +.Xr tan 3 , +.Xr asin 3 , +.Xr acos 3 , +.Xr atan 3 , +.Xr atan2 3 , +.Xr sinh 3 , +.Xr cosh 3 , +.Xr tanh 3 , +.Xr math 3 , +.Sh STANDARDS +The +.Fn acos +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/cosh.3 b/lib/libm/common_source/cosh.3 new file mode 100644 index 000000000000..4eabf55de62c --- /dev/null +++ b/lib/libm/common_source/cosh.3 @@ -0,0 +1,74 @@ +.\" Copyright (c) 1989, 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)cosh.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt COSH 3 +.Os +.Sh NAME +.Nm cosh +.Nd hyperbolic cosine function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn cosh "double x" +.Sh DESCRIPTION +The +.Fn cosh +function computes the hyperbolic cosine of +.Fa x . +.Sh RETURN VALUES +The +.Fn cosh +function returns the hyperbolic cosine unless the magnitude +of +.Fa x +is too large; in this event, the global variable +.Va errno +is set to +.Er ERANGE .  +.Sh SEE ALSO +.Xr acos 3 , +.Xr asin 3 , +.Xr atan 3 , +.Xr atan2 3 , +.Xr cos 3 , +.Xr sin 3 , +.Xr sinh 3 , +.Xr tan 3 , +.Xr tanh 3 , +.Xr math 3 , +.Sh STANDARDS +The +.Fn cosh +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/cosh.c b/lib/libm/common_source/cosh.c new file mode 100644 index 000000000000..e2b30731b8c1 --- /dev/null +++ b/lib/libm/common_source/cosh.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)cosh.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* COSH(X) + * RETURN THE HYPERBOLIC COSINE OF X + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/8/85;  + * REVISED BY K.C. NG on 2/8/85, 2/23/85, 3/7/85, 3/29/85, 4/16/85. + * + * Required system supported functions : + *	copysign(x,y) + *	scalb(x,N) + * + * Required kernel function: + *	exp(x)  + *	exp__E(x,c)	...return exp(x+c)-1-x for |x|<0.3465 + * + * Method : + *	1. Replace x by |x|.  + *	2.  + *		                                        [ exp(x) - 1 ]^2  + *	    0        <= x <= 0.3465  :  cosh(x) := 1 + ------------------- + *			       			           2*exp(x) + * + *		                                   exp(x) +  1/exp(x) + *	    0.3465   <= x <= 22      :  cosh(x) := ------------------- + *			       			           2 + *	    22       <= x <= lnovfl  :  cosh(x) := exp(x)/2  + *	    lnovfl   <= x <= lnovfl+log(2) + *				     :  cosh(x) := exp(x)/2 (avoid overflow) + *	    log(2)+lnovfl <  x <  INF:  overflow to INF + * + *	Note: .3465 is a number near one half of ln2. + * + * Special cases: + *	cosh(x) is x if x is +INF, -INF, or NaN. + *	only cosh(0)=1 is exact for finite x. + * + * Accuracy: + *	cosh(x) returns the exact hyperbolic cosine of x nearly rounded. + *	In a test run with 768,000 random arguments on a VAX, the maximum + *	observed error was 1.23 ulps (units in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(mln2hi, 8.8029691931113054792E1   ,0f33,43b0,2bdb,c7e2,   7, .B00F33C7E22BDB) +vc(mln2lo,-4.9650192275318476525E-16 ,1b60,a70f,582a,279e, -50,-.8F1B60279E582A) +vc(lnovfl, 8.8029691931113053016E1   ,0f33,43b0,2bda,c7e2,   7, .B00F33C7E22BDA) + +ic(mln2hi, 7.0978271289338397310E2,    10, 1.62E42FEFA39EF) +ic(mln2lo, 2.3747039373786107478E-14, -45, 1.ABC9E3B39803F) +ic(lnovfl, 7.0978271289338397310E2,     9, 1.62E42FEFA39EF) + +#ifdef vccast +#define   mln2hi    vccast(mln2hi) +#define   mln2lo    vccast(mln2lo) +#define   lnovfl    vccast(lnovfl) +#endif + +#if defined(vax)||defined(tahoe) +static max = 126                      ; +#else	/* defined(vax)||defined(tahoe) */ +static max = 1023                     ; +#endif	/* defined(vax)||defined(tahoe) */ + +double cosh(x) +double x; +{	 +	static const double half=1.0/2.0, +		one=1.0, small=1.0E-18; /* fl(1+small)==1 */ +	double t; + +#if !defined(vax)&&!defined(tahoe) +	if(x!=x) return(x);	/* x is NaN */ +#endif	/* !defined(vax)&&!defined(tahoe) */ +	if((x=copysign(x,one)) <= 22) +	    if(x<0.3465)  +		if(x<small) return(one+x); +		else {t=x+__exp__E(x,0.0);x=t+t; return(one+t*t/(2.0+x)); } + +	    else /* for x lies in [0.3465,22] */ +	        { t=exp(x); return((t+one/t)*half); } + +	if( lnovfl <= x && x <= (lnovfl+0.7))  +        /* for x lies in [lnovfl, lnovfl+ln2], decrease x by ln(2^(max+1))  +         * and return 2^max*exp(x) to avoid unnecessary overflow  +         */ +	    return(scalb(exp((x-mln2hi)-mln2lo), max));  + +	else  +	    return(exp(x)*half);	/* for large x,  cosh(x)=exp(x)/2 */ +} diff --git a/lib/libm/common_source/erf.3 b/lib/libm/common_source/erf.3 new file mode 100644 index 000000000000..2c8f06565c3c --- /dev/null +++ b/lib/libm/common_source/erf.3 @@ -0,0 +1,82 @@ +.\" Copyright (c) 1985, 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)erf.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt ERF 3 +.Os BSD 4.3 +.Sh NAME +.Nm erf , +.Nm erfc +.Nd error function operators +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn erf "double x" +.Ft double +.Fn erfc "double x" +.Sh DESCRIPTION +These functions calculate the error function of +.Fa x . +.Pp +The +.Fn erf +calculates the error function of x; where +.Bd -filled -offset indent +.if n \{\ +erf(x) = 2/sqrt(pi)\(**\|integral from 0 to x of exp(\-t\(**t) dt. \} +.if t \{\ +erf\|(x) :=  +(2/\(sr\(*p)\|\(is\d\s8\z0\s10\u\u\s8x\s10\d\|exp(\-t\u\s82\s10\d)\|dt. \} +.Ed +.Pp +The +.Fn erfc +function calculates the complementary error function of +.Fa x ; +that is +.Fn erfc +subtracts the result of the error function +.Fn erf x +from 1.0. +This is useful, since for large +.Fa x +places disappear. +.Sh SEE ALSO +.Xr math 3 +.Sh HISTORY +The +.Fn erf +and +.Fn erfc +functions appeared in +.Bx 4.3 . diff --git a/lib/libm/common_source/erf.c b/lib/libm/common_source/erf.c new file mode 100644 index 000000000000..308f1a952d73 --- /dev/null +++ b/lib/libm/common_source/erf.c @@ -0,0 +1,396 @@ +/*- + * Copyright (c) 1992, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)erf.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* Modified Nov 30, 1992 P. McILROY: + *	Replaced expansions for x >= 1.25 (error 1.7ulp vs ~6ulp) + * Replaced even+odd with direct calculation for x < .84375, + * to avoid destructive cancellation. + * + * Performance of erfc(x): + * In 300000 trials in the range [.83, .84375] the + * maximum observed error was 3.6ulp. + * + * In [.84735,1.25] the maximum observed error was <2.5ulp in + * 100000 runs in the range [1.2, 1.25]. + * + * In [1.25,26] (Not including subnormal results) + * the error is < 1.7ulp. + */ + +/* double erf(double x) + * double erfc(double x) + *			     x + *		      2      |\ + *     erf(x)  =  ---------  | exp(-t*t)dt + *		   sqrt(pi) \| + *			     0 + * + *     erfc(x) =  1-erf(x) + * + * Method: + *      1. Reduce x to |x| by erf(-x) = -erf(x) + *	2. For x in [0, 0.84375] + *	    erf(x)  = x + x*P(x^2) + *          erfc(x) = 1 - erf(x)           if x<=0.25 + *                  = 0.5 + ((0.5-x)-x*P)  if x in [0.25,0.84375] + *	   where + *			2		 2	  4		  20   + *              P =  P(x ) = (p0 + p1 * x + p2 * x + ... + p10 * x  ) + * 	   is an approximation to (erf(x)-x)/x with precision + * + *						 -56.45 + *			| P - (erf(x)-x)/x | <= 2 + *	 + * + *	   Remark. The formula is derived by noting + *          erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) + *	   and that + *          2/sqrt(pi) = 1.128379167095512573896158903121545171688 + *	   is close to one. The interval is chosen because the fixed + *	   point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is + *	   near 0.6174), and by some experiment, 0.84375 is chosen to + * 	   guarantee the error is less than one ulp for erf. + * + *      3. For x in [0.84375,1.25], let s = x - 1, and + *         c = 0.84506291151 rounded to single (24 bits) + *         	erf(x)  = c  + P1(s)/Q1(s) + *         	erfc(x) = (1-c)  - P1(s)/Q1(s) + *         	|P1/Q1 - (erf(x)-c)| <= 2**-59.06 + *	   Remark: here we use the taylor series expansion at x=1. + *		erf(1+s) = erf(1) + s*Poly(s) + *			 = 0.845.. + P1(s)/Q1(s) + *	   That is, we use rational approximation to approximate + *			erf(1+s) - (c = (single)0.84506291151) + *	   Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] + *	   where  + *		P1(s) = degree 6 poly in s + *		Q1(s) = degree 6 poly in s + * + *	4. For x in [1.25, 2]; [2, 4] + *         	erf(x)  = 1.0 - tiny + *		erfc(x)	= (1/x)exp(-x*x-(.5*log(pi) -.5z + R(z)/S(z)) + * + *	Where z = 1/(x*x), R is degree 9, and S is degree 3; + *	 + *      5. For x in [4,28] + *         	erf(x)  = 1.0 - tiny + *		erfc(x)	= (1/x)exp(-x*x-(.5*log(pi)+eps + zP(z)) + * + *	Where P is degree 14 polynomial in 1/(x*x). + * + *      Notes: + *	   Here 4 and 5 make use of the asymptotic series + *			  exp(-x*x) + *		erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) ); + *			  x*sqrt(pi) + * + *		where for z = 1/(x*x) + *		P(z) ~ z/2*(-1 + z*3/2*(1 + z*5/2*(-1 + z*7/2*(1 +...)))) + * + *	   Thus we use rational approximation to approximate + *              erfc*x*exp(x*x) ~ 1/sqrt(pi); + * + *		The error bound for the target function, G(z) for + *		the interval + *		[4, 28]: + * 		|eps + 1/(z)P(z) - G(z)| < 2**(-56.61) + *		for [2, 4]: + *      	|R(z)/S(z) - G(z)|	 < 2**(-58.24) + *		for [1.25, 2]: + *		|R(z)/S(z) - G(z)|	 < 2**(-58.12) + * + *      6. For inf > x >= 28 + *         	erf(x)  = 1 - tiny  (raise inexact) + *         	erfc(x) = tiny*tiny (raise underflow) + * + *      7. Special cases: + *         	erf(0)  = 0, erf(inf)  = 1, erf(-inf) = -1, + *         	erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,  + *	   	erfc/erf(NaN) is NaN + */ + +#if defined(vax) || defined(tahoe) +#define _IEEE	0 +#define TRUNC(x) (double) (float) (x) +#else +#define _IEEE	1 +#define TRUNC(x) *(((int *) &x) + 1) &= 0xf8000000 +#define infnan(x) 0.0 +#endif + +#ifdef _IEEE_LIBM +/* + * redefining "___function" to "function" in _IEEE_LIBM mode + */ +#include "ieee_libm.h" +#endif + +static double +tiny	    = 1e-300, +half	    = 0.5, +one	    = 1.0, +two	    = 2.0, +c 	    = 8.45062911510467529297e-01, /* (float)0.84506291151 */ +/* + * Coefficients for approximation to erf in [0,0.84375] + */ +p0t8 = 1.02703333676410051049867154944018394163280, +p0 =   1.283791670955125638123339436800229927041e-0001, +p1 =  -3.761263890318340796574473028946097022260e-0001, +p2 =   1.128379167093567004871858633779992337238e-0001, +p3 =  -2.686617064084433642889526516177508374437e-0002, +p4 =   5.223977576966219409445780927846432273191e-0003, +p5 =  -8.548323822001639515038738961618255438422e-0004, +p6 =   1.205520092530505090384383082516403772317e-0004, +p7 =  -1.492214100762529635365672665955239554276e-0005, +p8 =   1.640186161764254363152286358441771740838e-0006, +p9 =  -1.571599331700515057841960987689515895479e-0007, +p10=   1.073087585213621540635426191486561494058e-0008; +/* + * Coefficients for approximation to erf in [0.84375,1.25]  + */ +static double +pa0 =  -2.362118560752659485957248365514511540287e-0003, +pa1 =   4.148561186837483359654781492060070469522e-0001, +pa2 =  -3.722078760357013107593507594535478633044e-0001, +pa3 =   3.183466199011617316853636418691420262160e-0001, +pa4 =  -1.108946942823966771253985510891237782544e-0001, +pa5 =   3.547830432561823343969797140537411825179e-0002, +pa6 =  -2.166375594868790886906539848893221184820e-0003, +qa1 =   1.064208804008442270765369280952419863524e-0001, +qa2 =   5.403979177021710663441167681878575087235e-0001, +qa3 =   7.182865441419627066207655332170665812023e-0002, +qa4 =   1.261712198087616469108438860983447773726e-0001, +qa5 =   1.363708391202905087876983523620537833157e-0002, +qa6 =   1.198449984679910764099772682882189711364e-0002; +/* + * log(sqrt(pi)) for large x expansions. + * The tail (lsqrtPI_lo) is included in the rational + * approximations. +*/ +static double +   lsqrtPI_hi = .5723649429247000819387380943226; +/* + * lsqrtPI_lo = .000000000000000005132975581353913; + * + * Coefficients for approximation to erfc in [2, 4] +*/ +static double +rb0  =	-1.5306508387410807582e-010,	/* includes lsqrtPI_lo */ +rb1  =	 2.15592846101742183841910806188e-008, +rb2  =	 6.24998557732436510470108714799e-001, +rb3  =	 8.24849222231141787631258921465e+000, +rb4  =	 2.63974967372233173534823436057e+001, +rb5  =	 9.86383092541570505318304640241e+000, +rb6  =	-7.28024154841991322228977878694e+000, +rb7  =	 5.96303287280680116566600190708e+000, +rb8  =	-4.40070358507372993983608466806e+000, +rb9  =	 2.39923700182518073731330332521e+000, +rb10 =	-6.89257464785841156285073338950e-001, +sb1  =	 1.56641558965626774835300238919e+001, +sb2  =	 7.20522741000949622502957936376e+001, +sb3  =	 9.60121069770492994166488642804e+001; +/* + * Coefficients for approximation to erfc in [1.25, 2] +*/ +static double +rc0  =	-2.47925334685189288817e-007,	/* includes lsqrtPI_lo */ +rc1  =	 1.28735722546372485255126993930e-005, +rc2  =	 6.24664954087883916855616917019e-001, +rc3  =	 4.69798884785807402408863708843e+000, +rc4  =	 7.61618295853929705430118701770e+000, +rc5  =	 9.15640208659364240872946538730e-001, +rc6  =	-3.59753040425048631334448145935e-001, +rc7  =	 1.42862267989304403403849619281e-001, +rc8  =	-4.74392758811439801958087514322e-002, +rc9  =	 1.09964787987580810135757047874e-002, +rc10 =	-1.28856240494889325194638463046e-003, +sc1  =	 9.97395106984001955652274773456e+000, +sc2  =	 2.80952153365721279953959310660e+001, +sc3  =	 2.19826478142545234106819407316e+001; +/* + * Coefficients for approximation to  erfc in [4,28] + */ +static double +rd0  =	-2.1491361969012978677e-016,	/* includes lsqrtPI_lo */ +rd1  =	-4.99999999999640086151350330820e-001, +rd2  =	 6.24999999772906433825880867516e-001, +rd3  =	-1.54166659428052432723177389562e+000, +rd4  =	 5.51561147405411844601985649206e+000, +rd5  =	-2.55046307982949826964613748714e+001, +rd6  =	 1.43631424382843846387913799845e+002, +rd7  =	-9.45789244999420134263345971704e+002, +rd8  =	 6.94834146607051206956384703517e+003, +rd9  =	-5.27176414235983393155038356781e+004, +rd10 =	 3.68530281128672766499221324921e+005, +rd11 =	-2.06466642800404317677021026611e+006, +rd12 =	 7.78293889471135381609201431274e+006, +rd13 =	-1.42821001129434127360582351685e+007; + +double erf(x) +	double x; +{ +	double R,S,P,Q,ax,s,y,z,r,fabs(),exp(); +	if(!finite(x)) {		/* erf(nan)=nan */ +	    if (isnan(x)) +		return(x); +	    return (x > 0 ? one : -one); /* erf(+/-inf)= +/-1 */ +	} +	if ((ax = x) < 0) +		ax = - ax; +	if (ax < .84375) { +	    if (ax < 3.7e-09) { +		if (ax < 1.0e-308) +		    return 0.125*(8.0*x+p0t8*x);  /*avoid underflow */ +		return x + p0*x; +	    } +	    y = x*x; +	    r = y*(p1+y*(p2+y*(p3+y*(p4+y*(p5+ +			y*(p6+y*(p7+y*(p8+y*(p9+y*p10))))))))); +	    return x + x*(p0+r); +	} +	if (ax < 1.25) {		/* 0.84375 <= |x| < 1.25 */ +	    s = fabs(x)-one; +	    P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); +	    Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); +	    if (x>=0) +		return (c + P/Q); +	    else +		return (-c - P/Q); +	} +	if (ax >= 6.0) {		/* inf>|x|>=6 */ +	    if (x >= 0.0) +		return (one-tiny); +	    else +		return (tiny-one); +	} +    /* 1.25 <= |x| < 6 */ +	z = -ax*ax; +	s = -one/z; +	if (ax < 2.0) { +		R = rc0+s*(rc1+s*(rc2+s*(rc3+s*(rc4+s*(rc5+ +			s*(rc6+s*(rc7+s*(rc8+s*(rc9+s*rc10))))))))); +		S = one+s*(sc1+s*(sc2+s*sc3)); +	} else { +		R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+ +			s*(rb6+s*(rb7+s*(rb8+s*(rb9+s*rb10))))))))); +		S = one+s*(sb1+s*(sb2+s*sb3)); +	} +	y = (R/S -.5*s) - lsqrtPI_hi; +	z += y; +	z = exp(z)/ax; +	if (x >= 0) +		return (one-z); +	else +		return (z-one); +} + +double erfc(x)  +	double x; +{ +	double R,S,P,Q,s,ax,y,z,r,fabs(),__exp__D(); +	if (!finite(x)) { +		if (isnan(x))		/* erfc(NaN) = NaN */ +			return(x); +		else if (x > 0)		/* erfc(+-inf)=0,2 */ +			return 0.0; +		else +			return 2.0; +	} +	if ((ax = x) < 0) +		ax = -ax; +	if (ax < .84375) {			/* |x|<0.84375 */ +	    if (ax < 1.38777878078144568e-17)  	/* |x|<2**-56 */ +		return one-x; +	    y = x*x; +	    r = y*(p1+y*(p2+y*(p3+y*(p4+y*(p5+ +			y*(p6+y*(p7+y*(p8+y*(p9+y*p10))))))))); +	    if (ax < .0625) {  	/* |x|<2**-4 */ +		return (one-(x+x*(p0+r))); +	    } else { +		r = x*(p0+r); +		r += (x-half); +	        return (half - r); +	    } +	} +	if (ax < 1.25) {		/* 0.84375 <= |x| < 1.25 */ +	    s = ax-one; +	    P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); +	    Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); +	    if (x>=0) { +	        z  = one-c; return z - P/Q;  +	    } else { +		z = c+P/Q; return one+z; +	    } +	} +	if (ax >= 28)	/* Out of range */ + 		if (x>0) +			return (tiny*tiny); +		else +			return (two-tiny); +	z = ax; +	TRUNC(z); +	y = z - ax; y *= (ax+z); +	z *= -z;			/* Here z + y = -x^2 */ +		s = one/(-z-y);		/* 1/(x*x) */ +	if (ax >= 4) {			/* 6 <= ax */ +		R = s*(rd1+s*(rd2+s*(rd3+s*(rd4+s*(rd5+ +			s*(rd6+s*(rd7+s*(rd8+s*(rd9+s*(rd10 +			+s*(rd11+s*(rd12+s*rd13)))))))))))); +		y += rd0; +	} else if (ax >= 2) { +		R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+ +			s*(rb6+s*(rb7+s*(rb8+s*(rb9+s*rb10))))))))); +		S = one+s*(sb1+s*(sb2+s*sb3)); +		y += R/S; +		R = -.5*s; +	} else { +		R = rc0+s*(rc1+s*(rc2+s*(rc3+s*(rc4+s*(rc5+ +			s*(rc6+s*(rc7+s*(rc8+s*(rc9+s*rc10))))))))); +		S = one+s*(sc1+s*(sc2+s*sc3)); +		y += R/S; +		R = -.5*s; +	} +	/* return exp(-x^2 - lsqrtPI_hi + R + y)/x;	*/ +	s = ((R + y) - lsqrtPI_hi) + z; +	y = (((z-s) - lsqrtPI_hi) + R) + y; +	r = __exp__D(s, y)/x; +	if (x>0) +		return r; +	else +		return two-r; +} diff --git a/lib/libm/common_source/exp.3 b/lib/libm/common_source/exp.3 new file mode 100644 index 000000000000..1bdf06088529 --- /dev/null +++ b/lib/libm/common_source/exp.3 @@ -0,0 +1,284 @@ +.\" Copyright (c) 1985, 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)exp.3	8.2 (Berkeley) 4/19/94 +.\" +.Dd April 19, 1994 +.Dt EXP 3 +.Os BSD 4 +.Sh NAME +.Nm exp , +.Nm expm1 , +.Nm log , +.Nm log10 , +.Nm log1p , +.Nm pow +.Nd exponential, logarithm, power functions +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn exp "double x" +.Ft double +.Fn expm1 "double x" +.Ft double +.Fn log "double x" +.Ft double +.Fn log10 "double x" +.Ft double +.Fn log1p "double x" +.Ft double +.Fn pow "double x" "double y" +.Sh DESCRIPTION +The +.Fn exp +function computes the exponential value of the given argument +.Fa x . +.Pp +The +.Fn expm1 +function computes the value exp(x)\-1 accurately even for tiny argument +.Fa x . +.Pp +The +.Fn log +function computes the value for the natural logarithm of +the argument x. +.Pp +The +.Fn log10 +function computes the value for the logarithm of +argument +.Fa x +to base 10. +.Pp +The +.Fn log1p +function computes +the value of log(1+x) accurately even for tiny argument +.Fa x . +.Pp +The +.Fn pow +computes the value +of +.Ar x +to the exponent +.Ar y . +.Sh ERROR (due to Roundoff etc.) +exp(x), log(x), expm1(x) and log1p(x) are accurate to within  +an +.Em up , +and log10(x) to within about 2 +.Em ups ; +an +.Em up +is one +.Em Unit +in the +.Em Last +.Em Place . +The error in +.Fn pow x y +is below about 2 +.Em ups +when its +magnitude is moderate, but increases as +.Fn pow x y +approaches +the over/underflow thresholds until almost as many bits could be +lost as are occupied by the floating\-point format's exponent +field; that is 8 bits for +.Tn "VAX D" +and 11 bits for IEEE 754 Double. +No such drastic loss has been exposed by testing; the worst +errors observed have been below 20 +.Em ups +for +.Tn "VAX D" , +300 +.Em ups +for +.Tn IEEE +754 Double. +Moderate values of +.Fn pow +are accurate enough that +.Fn pow integer integer +is exact until it is bigger than 2**56 on a +.Tn VAX , +2**53 for +.Tn IEEE +754. +.Sh RETURN VALUES +These functions will return the appropriate computation unless an error +occurs or an argument is out of range. +The functions +.Fn exp , +.Fn expm1 +and +.Fn pow +detect if the computed value will overflow, +set the global variable +.Va errno to +.Er RANGE +and cause a reserved operand fault on a +.Tn VAX +or +.Tn Tahoe . +The function +.Fn pow x y +checks to see if +.Fa x +< 0 and +.Fa y +is not an integer, in the event this is true, +the global variable +.Va errno +is set to +.Er EDOM +and on the +.Tn VAX +and +.Tn Tahoe +generate a reserved operand fault. +On a +.Tn VAX +and +.Tn Tahoe , +.Va errno +is set to +.Er EDOM +and the reserved operand is returned +by log unless +.Fa x +> 0, by +.Fn log1p +unless +.Fa x +> \-1. +.Sh NOTES +The functions exp(x)\-1 and log(1+x) are called +expm1 and logp1 in +.Tn BASIC +on the Hewlett\-Packard +.Tn HP Ns \-71B +and +.Tn APPLE +Macintosh, +.Tn EXP1 +and +.Tn LN1 +in Pascal, exp1 and log1 in C +on +.Tn APPLE +Macintoshes, where they have been provided to make +sure financial calculations of ((1+x)**n\-1)/x, namely +expm1(n\(**log1p(x))/x, will be accurate when x is tiny. +They also provide accurate inverse hyperbolic functions. +.Pp +The function +.Fn pow x 0 +returns x**0 = 1 for all x including x = 0, +.if n \ +Infinity +.if t \ +\(if +(not found on a +.Tn VAX ) , +and +.Em NaN +(the reserved +operand on a +.Tn VAX ) .  Previous implementations of pow may +have defined x**0 to be undefined in some or all of these +cases.  Here are reasons for returning x**0 = 1 always: +.Bl -enum -width indent +.It +Any program that already tests whether x is zero (or +infinite or \*(Na) before computing x**0 cannot care +whether 0**0 = 1 or not. Any program that depends +upon 0**0 to be invalid is dubious anyway since that +expression's meaning and, if invalid, its consequences  +vary from one computer system to another. +.It +Some Algebra texts (e.g. Sigler's) define x**0 = 1 for  +all x, including x = 0. +This is compatible with the convention that accepts a[0] +as the value of polynomial +.Bd -literal -offset indent +p(x) = a[0]\(**x**0 + a[1]\(**x**1 + a[2]\(**x**2 +...+ a[n]\(**x**n +.Ed +.Pp +at x = 0 rather than reject a[0]\(**0**0 as invalid. +.It +Analysts will accept 0**0 = 1 despite that x**y can +approach anything or nothing as x and y approach 0 +independently. +The reason for setting 0**0 = 1 anyway is this: +.Bd -filled -offset indent +If x(z) and y(z) are +.Em any +functions analytic (expandable +in power series) in z around z = 0, and if there  +x(0) = y(0) = 0, then x(z)**y(z) \(-> 1 as z \(-> 0. +.Ed +.It +If 0**0 = 1, then +.if n \ +infinity**0 = 1/0**0 = 1 too; and +.if t \ +\(if**0 = 1/0**0 = 1 too; and +then \*(Na**0 = 1 too because x**0 = 1 for all finite +and infinite x, i.e., independently of x. +.El +.Sh SEE ALSO +.Xr math 3 , +.Xr infnan 3 +.Sh HISTORY +A +.Fn exp , +.Fn log +and +.Fn pow +function +appeared in +.At v6 . +A +.Fn log10 +function +appeared in +.At v7 . +The +.Fn log1p +and +.Fn expm1 +functions appeared in +.Bx 4.3 . diff --git a/lib/libm/common_source/exp.c b/lib/libm/common_source/exp.c new file mode 100644 index 000000000000..9b4f045f82e4 --- /dev/null +++ b/lib/libm/common_source/exp.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)exp.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* EXP(X) + * RETURN THE EXPONENTIAL OF X + * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS) + * CODED IN C BY K.C. NG, 1/19/85;  + * REVISED BY K.C. NG on 2/6/85, 2/15/85, 3/7/85, 3/24/85, 4/16/85, 6/14/86. + * + * Required system supported functions: + *	scalb(x,n)	 + *	copysign(x,y)	 + *	finite(x) + * + * Method: + *	1. Argument Reduction: given the input x, find r and integer k such  + *	   that + *	                   x = k*ln2 + r,  |r| <= 0.5*ln2 .   + *	   r will be represented as r := z+c for better accuracy. + * + *	2. Compute exp(r) by  + * + *		exp(r) = 1 + r + r*R1/(2-R1), + *	   where + *		R1 = x - x^2*(p1+x^2*(p2+x^2*(p3+x^2*(p4+p5*x^2)))). + * + *	3. exp(x) = 2^k * exp(r) . + * + * Special cases: + *	exp(INF) is INF, exp(NaN) is NaN; + *	exp(-INF)=  0; + *	for finite argument, only exp(0)=1 is exact. + * + * Accuracy: + *	exp(x) returns the exponential of x nearly rounded. In a test run + *	with 1,156,000 random arguments on a VAX, the maximum observed + *	error was 0.869 ulps (units in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(ln2hi,  6.9314718055829871446E-1  ,7217,4031,0000,f7d0,   0, .B17217F7D00000) +vc(ln2lo,  1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC) +vc(lnhuge, 9.4961163736712506989E1   ,ec1d,43bd,9010,a73e,   7, .BDEC1DA73E9010) +vc(lntiny,-9.5654310917272452386E1   ,4f01,c3bf,33af,d72e,   7,-.BF4F01D72E33AF) +vc(invln2, 1.4426950408889634148E0   ,aa3b,40b8,17f1,295c,   1, .B8AA3B295C17F1) +vc(p1,     1.6666666666666602251E-1  ,aaaa,3f2a,a9f1,aaaa,  -2, .AAAAAAAAAAA9F1) +vc(p2,    -2.7777777777015591216E-3  ,0b60,bc36,ec94,b5f5,  -8,-.B60B60B5F5EC94) +vc(p3,     6.6137563214379341918E-5  ,b355,398a,f15f,792e, -13, .8AB355792EF15F) +vc(p4,    -1.6533902205465250480E-6  ,ea0e,b6dd,5f84,2e93, -19,-.DDEA0E2E935F84) +vc(p5,     4.1381367970572387085E-8  ,bb4b,3431,2683,95f5, -24, .B1BB4B95F52683) + +#ifdef vccast +#define    ln2hi    vccast(ln2hi) +#define    ln2lo    vccast(ln2lo) +#define   lnhuge    vccast(lnhuge) +#define   lntiny    vccast(lntiny) +#define   invln2    vccast(invln2) +#define       p1    vccast(p1) +#define       p2    vccast(p2) +#define       p3    vccast(p3) +#define       p4    vccast(p4) +#define       p5    vccast(p5) +#endif + +ic(p1,     1.6666666666666601904E-1,  -3,  1.555555555553E) +ic(p2,    -2.7777777777015593384E-3,  -9, -1.6C16C16BEBD93) +ic(p3,     6.6137563214379343612E-5, -14,  1.1566AAF25DE2C) +ic(p4,    -1.6533902205465251539E-6, -20, -1.BBD41C5D26BF1) +ic(p5,     4.1381367970572384604E-8, -25,  1.6376972BEA4D0) +ic(ln2hi,  6.9314718036912381649E-1,  -1,  1.62E42FEE00000) +ic(ln2lo,  1.9082149292705877000E-10,-33,  1.A39EF35793C76) +ic(lnhuge, 7.1602103751842355450E2,    9,  1.6602B15B7ECF2) +ic(lntiny,-7.5137154372698068983E2,    9, -1.77AF8EBEAE354) +ic(invln2, 1.4426950408889633870E0,    0,  1.71547652B82FE) + +double exp(x) +double x; +{ +	double  z,hi,lo,c; +	int k; + +#if !defined(vax)&&!defined(tahoe) +	if(x!=x) return(x);	/* x is NaN */ +#endif	/* !defined(vax)&&!defined(tahoe) */ +	if( x <= lnhuge ) { +		if( x >= lntiny ) { + +		    /* argument reduction : x --> x - k*ln2 */ + +			k=invln2*x+copysign(0.5,x);	/* k=NINT(x/ln2) */ + +		    /* express x-k*ln2 as hi-lo and let x=hi-lo rounded */ + +			hi=x-k*ln2hi; +			x=hi-(lo=k*ln2lo); + +		    /* return 2^k*[1+x+x*c/(2+c)]  */ +			z=x*x; +			c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5)))); +			return  scalb(1.0+(hi-(lo-(x*c)/(2.0-c))),k); + +		} +		/* end of x > lntiny */ + +		else  +		     /* exp(-big#) underflows to zero */ +		     if(finite(x))  return(scalb(1.0,-5000)); + +		     /* exp(-INF) is zero */ +		     else return(0.0); +	} +	/* end of x < lnhuge */ + +	else  +	/* exp(INF) is INF, exp(+big#) overflows to INF */ +	    return( finite(x) ?  scalb(1.0,5000)  : x); +} + +/* returns exp(r = x + c) for |c| < |x| with no overlap.  */ + +double __exp__D(x, c) +double x, c; +{ +	double  z,hi,lo, t; +	int k; + +#if !defined(vax)&&!defined(tahoe) +	if (x!=x) return(x);	/* x is NaN */ +#endif	/* !defined(vax)&&!defined(tahoe) */ +	if ( x <= lnhuge ) { +		if ( x >= lntiny ) { + +		    /* argument reduction : x --> x - k*ln2 */ +			z = invln2*x; +			k = z + copysign(.5, x); + +		    /* express (x+c)-k*ln2 as hi-lo and let x=hi-lo rounded */ + +			hi=(x-k*ln2hi);			/* Exact. */ +			x= hi - (lo = k*ln2lo-c); +		    /* return 2^k*[1+x+x*c/(2+c)]  */ +			z=x*x; +			c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5)))); +			c = (x*c)/(2.0-c); + +			return  scalb(1.+(hi-(lo - c)), k); +		} +		/* end of x > lntiny */ + +		else  +		     /* exp(-big#) underflows to zero */ +		     if(finite(x))  return(scalb(1.0,-5000)); + +		     /* exp(-INF) is zero */ +		     else return(0.0); +	} +	/* end of x < lnhuge */ + +	else  +	/* exp(INF) is INF, exp(+big#) overflows to INF */ +	    return( finite(x) ?  scalb(1.0,5000)  : x); +} diff --git a/lib/libm/common_source/exp__E.c b/lib/libm/common_source/exp__E.c new file mode 100644 index 000000000000..ab972477a04b --- /dev/null +++ b/lib/libm/common_source/exp__E.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)exp__E.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* exp__E(x,c) + * ASSUMPTION: c << x  SO THAT  fl(x+c)=x. + * (c is the correction term for x) + * exp__E RETURNS + * + *			 /  exp(x+c) - 1 - x ,  1E-19 < |x| < .3465736 + *       exp__E(x,c) = 	| 		      + *			 \  0 ,  |x| < 1E-19. + * + * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS) + * KERNEL FUNCTION OF EXP, EXPM1, POW FUNCTIONS + * CODED IN C BY K.C. NG, 1/31/85; + * REVISED BY K.C. NG on 3/16/85, 4/16/85. + * + * Required system supported function: + *	copysign(x,y)	 + * + * Method: + *	1. Rational approximation. Let r=x+c. + *	   Based on + *                                   2 * sinh(r/2)      + *                exp(r) - 1 =   ----------------------   , + *                               cosh(r/2) - sinh(r/2) + *	   exp__E(r) is computed using + *                   x*x            (x/2)*W - ( Q - ( 2*P  + x*P ) ) + *                   --- + (c + x*[---------------------------------- + c ]) + *                    2                          1 - W + * 	   where  P := p1*x^2 + p2*x^4, + *	          Q := q1*x^2 + q2*x^4 (for 56 bits precision, add q3*x^6) + *	          W := x/2-(Q-x*P), + * + *	   (See the listing below for the values of p1,p2,q1,q2,q3. The poly- + *	    nomials P and Q may be regarded as the approximations to sinh + *	    and cosh : + *		sinh(r/2) =  r/2 + r * P  ,  cosh(r/2) =  1 + Q . ) + * + *         The coefficients were obtained by a special Remez algorithm. + * + * Approximation error: + * + *   |	exp(x) - 1			   |        2**(-57),  (IEEE double) + *   | ------------  -  (exp__E(x,0)+x)/x  |  <=  + *   |	     x			           |	    2**(-69).  (VAX D) + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(p1, 1.5150724356786683059E-2 ,3abe,3d78,066a,67e1,  -6, .F83ABE67E1066A) +vc(p2, 6.3112487873718332688E-5 ,5b42,3984,0173,48cd, -13, .845B4248CD0173) +vc(q1, 1.1363478204690669916E-1 ,b95a,3ee8,ec45,44a2,  -3, .E8B95A44A2EC45) +vc(q2, 1.2624568129896839182E-3 ,7905,3ba5,f5e7,72e4,  -9, .A5790572E4F5E7) +vc(q3, 1.5021856115869022674E-6 ,9eb4,36c9,c395,604a, -19, .C99EB4604AC395) + +ic(p1, 1.3887401997267371720E-2,  -7, 1.C70FF8B3CC2CF) +ic(p2, 3.3044019718331897649E-5, -15, 1.15317DF4526C4) +ic(q1, 1.1110813732786649355E-1,  -4, 1.C719538248597) +ic(q2, 9.9176615021572857300E-4, -10, 1.03FC4CB8C98E8) + +#ifdef vccast +#define       p1    vccast(p1) +#define       p2    vccast(p2) +#define       q1    vccast(q1) +#define       q2    vccast(q2) +#define       q3    vccast(q3) +#endif + +double __exp__E(x,c) +double x,c; +{ +	const static double zero=0.0, one=1.0, half=1.0/2.0, small=1.0E-19; +	double z,p,q,xp,xh,w; +	if(copysign(x,one)>small) { +           z = x*x  ; +	   p = z*( p1 +z* p2 ); +#if defined(vax)||defined(tahoe) +           q = z*( q1 +z*( q2 +z* q3 )); +#else	/* defined(vax)||defined(tahoe) */ +           q = z*( q1 +z*  q2 ); +#endif	/* defined(vax)||defined(tahoe) */ +           xp= x*p     ;  +	   xh= x*half  ; +           w = xh-(q-xp)  ; +	   p = p+p; +	   c += x*((xh*w-(q-(p+xp)))/(one-w)+c); +	   return(z*half+c); +	} +	/* end of |x| > small */ + +	else { +	    if(x!=zero) one+small;	/* raise the inexact flag */ +	    return(copysign(zero,x)); +	} +} diff --git a/lib/libm/common_source/expm1.c b/lib/libm/common_source/expm1.c new file mode 100644 index 000000000000..760d2bed677d --- /dev/null +++ b/lib/libm/common_source/expm1.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)expm1.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* EXPM1(X) + * RETURN THE EXPONENTIAL OF X MINUS ONE + * DOUBLE PRECISION (IEEE 53 BITS, VAX D FORMAT 56 BITS) + * CODED IN C BY K.C. NG, 1/19/85;  + * REVISED BY K.C. NG on 2/6/85, 3/7/85, 3/21/85, 4/16/85. + * + * Required system supported functions: + *	scalb(x,n)	 + *	copysign(x,y)	 + *	finite(x) + * + * Kernel function: + *	exp__E(x,c) + * + * Method: + *	1. Argument Reduction: given the input x, find r and integer k such  + *	   that + *	                   x = k*ln2 + r,  |r| <= 0.5*ln2 .   + *	   r will be represented as r := z+c for better accuracy. + * + *	2. Compute EXPM1(r)=exp(r)-1 by  + * + *			EXPM1(r=z+c) := z + exp__E(z,c) + * + *	3. EXPM1(x) =  2^k * ( EXPM1(r) + 1-2^-k ). + * + * 	Remarks:  + *	   1. When k=1 and z < -0.25, we use the following formula for + *	      better accuracy: + *			EXPM1(x) = 2 * ( (z+0.5) + exp__E(z,c) ) + *	   2. To avoid rounding error in 1-2^-k where k is large, we use + *			EXPM1(x) = 2^k * { [z+(exp__E(z,c)-2^-k )] + 1 } + *	      when k>56.  + * + * Special cases: + *	EXPM1(INF) is INF, EXPM1(NaN) is NaN; + *	EXPM1(-INF)= -1; + *	for finite argument, only EXPM1(0)=0 is exact. + * + * Accuracy: + *	EXPM1(x) returns the exact (exp(x)-1) nearly rounded. In a test run with + *	1,166,000 random arguments on a VAX, the maximum observed error was + *	.872 ulps (units of the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(ln2hi,  6.9314718055829871446E-1  ,7217,4031,0000,f7d0,   0, .B17217F7D00000) +vc(ln2lo,  1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC) +vc(lnhuge, 9.4961163736712506989E1   ,ec1d,43bd,9010,a73e,   7, .BDEC1DA73E9010) +vc(invln2, 1.4426950408889634148E0   ,aa3b,40b8,17f1,295c,   1, .B8AA3B295C17F1) + +ic(ln2hi,  6.9314718036912381649E-1,   -1, 1.62E42FEE00000) +ic(ln2lo,  1.9082149292705877000E-10, -33, 1.A39EF35793C76) +ic(lnhuge, 7.1602103751842355450E2,     9, 1.6602B15B7ECF2) +ic(invln2, 1.4426950408889633870E0,     0, 1.71547652B82FE) + +#ifdef vccast +#define	ln2hi	vccast(ln2hi) +#define	ln2lo	vccast(ln2lo) +#define	lnhuge	vccast(lnhuge) +#define	invln2	vccast(invln2) +#endif + +double expm1(x) +double x; +{ +	const static double one=1.0, half=1.0/2.0;  +	double  z,hi,lo,c; +	int k; +#if defined(vax)||defined(tahoe) +	static prec=56; +#else	/* defined(vax)||defined(tahoe) */ +	static prec=53; +#endif	/* defined(vax)||defined(tahoe) */ + +#if !defined(vax)&&!defined(tahoe) +	if(x!=x) return(x);	/* x is NaN */ +#endif	/* !defined(vax)&&!defined(tahoe) */ + +	if( x <= lnhuge ) { +		if( x >= -40.0 ) { + +		    /* argument reduction : x - k*ln2 */ +			k= invln2 *x+copysign(0.5,x);	/* k=NINT(x/ln2) */ +			hi=x-k*ln2hi ;  +			z=hi-(lo=k*ln2lo); +			c=(hi-z)-lo; + +			if(k==0) return(z+__exp__E(z,c)); +			if(k==1) +			    if(z< -0.25)  +				{x=z+half;x +=__exp__E(z,c); return(x+x);} +			    else +				{z+=__exp__E(z,c); x=half+z; return(x+x);} +		    /* end of k=1 */ + +			else { +			    if(k<=prec) +			      { x=one-scalb(one,-k); z += __exp__E(z,c);} +			    else if(k<100) +			      { x = __exp__E(z,c)-scalb(one,-k); x+=z; z=one;} +			    else  +			      { x = __exp__E(z,c)+z; z=one;} + +			    return (scalb(x+z,k));   +			} +		} +		/* end of x > lnunfl */ + +		else  +		     /* expm1(-big#) rounded to -1 (inexact) */ +		     if(finite(x))   +			 { ln2hi+ln2lo; return(-one);} + +		     /* expm1(-INF) is -1 */ +		     else return(-one); +	} +	/* end of x < lnhuge */ + +	else  +	/*  expm1(INF) is INF, expm1(+big#) overflows to INF */ +	    return( finite(x) ?  scalb(one,5000) : x); +} diff --git a/lib/libm/common_source/fabs.3 b/lib/libm/common_source/fabs.3 new file mode 100644 index 000000000000..e4cf0f6e59fd --- /dev/null +++ b/lib/libm/common_source/fabs.3 @@ -0,0 +1,66 @@ +.\" Copyright (c) 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\"	@(#)fabs.3	8.1 (Berkeley) 6/4/93 +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)fabs.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt FABS 3 +.Os +.Sh NAME +.Nm fabs +.Nd floating-point absolute value function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn fabs "double x" +.Sh DESCRIPTION +The +.Fn fabs +function computes the absolute value of a floating-point number +.Fa x . +.Sh RETURN VALUES +The +.Fn fabs +function returns the absolute value of +.Fa x . +.Sh SEE ALSO +.Xr abs 3 , +.Xr ceil 3 , +.Xr floor 3 , +.Xr rint 3 , +.Xr ieee 3 , +.Xr math.3 +.Sh STANDARDS +The +.Fn fabs +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/floor.3 b/lib/libm/common_source/floor.3 new file mode 100644 index 000000000000..2df55f92b46c --- /dev/null +++ b/lib/libm/common_source/floor.3 @@ -0,0 +1,65 @@ +.\" Copyright (c) 1985, 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)floor.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt FLOOR 3 +.Os +.Sh NAME +.Nm floor +.Nd largest integral value not greater than x +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn floor "double x" +.Sh DESCRIPTION +The +.Fn floor +function computes the largest integral value not greater than +.Fa x . +.Sh RETURN VALUES +The +.Fn floor +function returns the largest integral value +expressed as a double. +.Sh SEE ALSO +.Xr abs 3 , +.Xr ieee 3 , +.Xr fabs 3 , +.Xr floor 3 , +.Xr rint 3 , +.Xr math 3 +.Sh STANDARDS +The +.Fn floor +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/floor.c b/lib/libm/common_source/floor.c new file mode 100644 index 000000000000..59900677ee5e --- /dev/null +++ b/lib/libm/common_source/floor.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)floor.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +#include "mathimpl.h" + +vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */ + +ic(L, 4503599627370496.0E0, 52, 1.0)			  /* 2**52 */ + +#ifdef vccast +#define	L	vccast(L) +#endif + +/* + * floor(x) := the largest integer no larger than x; + * ceil(x) := -floor(-x), for all real x. + * + * Note: Inexact will be signaled if x is not an integer, as is + *	customary for IEEE 754.  No other signal can be emitted. + */ +double +floor(x) +double x; +{ +	volatile double y; + +	if ( +#if !defined(vax)&&!defined(tahoe) +		x != x ||	/* NaN */ +#endif	/* !defined(vax)&&!defined(tahoe) */ +		x >= L)		/* already an even integer */ +		return x; +	else if (x < (double)0) +		return -ceil(-x); +	else {			/* now 0 <= x < L */ +		y = L+x;		/* destructive store must be forced */ +		y -= L;			/* an integer, and |x-y| < 1 */ +		return x < y ? y-(double)1 : y; +	} +} + +double +ceil(x) +double x; +{ +	volatile double y; + +	if ( +#if !defined(vax)&&!defined(tahoe) +		x != x ||	/* NaN */ +#endif	/* !defined(vax)&&!defined(tahoe) */ +		x >= L)		/* already an even integer */ +		return x; +	else if (x < (double)0) +		return -floor(-x); +	else {			/* now 0 <= x < L */ +		y = L+x;		/* destructive store must be forced */ +		y -= L;			/* an integer, and |x-y| < 1 */ +		return x > y ? y+(double)1 : y; +	} +} + +#ifndef ns32000			/* rint() is in ./NATIONAL/support.s */ +/* + * algorithm for rint(x) in pseudo-pascal form ... + * + * real rint(x): real x; + *	... delivers integer nearest x in direction of prevailing rounding + *	... mode + * const	L = (last consecutive integer)/2 + * 	  = 2**55; for VAX D + * 	  = 2**52; for IEEE 754 Double + * real	s,t; + * begin + * 	if x != x then return x;		... NaN + * 	if |x| >= L then return x;		... already an integer + * 	s := copysign(L,x); + * 	t := x + s;				... = (x+s) rounded to integer + * 	return t - s + * end; + * + * Note: Inexact will be signaled if x is not an integer, as is + *	customary for IEEE 754.  No other signal can be emitted. + */ +double +rint(x) +double x; +{ +	double s; +	volatile double t; +	const double one = 1.0; + +#if !defined(vax)&&!defined(tahoe) +	if (x != x)				/* NaN */ +		return (x); +#endif	/* !defined(vax)&&!defined(tahoe) */ +	if (copysign(x,one) >= L)		/* already an integer */ +	    return (x); +	s = copysign(L,x); +	t = x + s;				/* x+s rounded to integer */ +	return (t - s); +} +#endif	/* not national */ diff --git a/lib/libm/common_source/fmod.3 b/lib/libm/common_source/fmod.3 new file mode 100644 index 000000000000..d22420aebf9e --- /dev/null +++ b/lib/libm/common_source/fmod.3 @@ -0,0 +1,75 @@ +.\" Copyright (c) 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)fmod.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt FMOD 3 +.Os +.Sh NAME +.Nm fmod +.Nd floating-point remainder function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn fmod "double x" "double y" +.Sh DESCRIPTION +The +.Fn fmod +function computes the floating-point remainder of +.Fa x Ns / Fa y . +.Sh RETURN VALUES +The +.Fn fmod +function returns the value +.Sm off +.Fa x - Em i * Fa y , +.Sm on +for some integer +.Em i +such that, if +.Fa y +is non-zero, the result has the same sign as +.Fa x +and magnitude less than the magnitude of +.Fa y . +If +.Fa y +is zero, whether a domain error occurs or the +.Fn fmod +function returns zero is implementation-defined. +.Sh SEE ALSO +.Xr math 3 +.Sh STANDARDS +The +.Fn fmod +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/fmod.c b/lib/libm/common_source/fmod.c new file mode 100644 index 000000000000..09a31b29b39a --- /dev/null +++ b/lib/libm/common_source/fmod.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 1989, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)fmod.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* fmod.c + * + * SYNOPSIS + * + *    #include <math.h> + *    double fmod(double x, double y) + * + * DESCRIPTION + * + *    The fmod function computes the floating-point remainder of x/y. + * + * RETURNS + * + *    The fmod function returns the value x-i*y, for some integer i + * such that, if y is nonzero, the result has the same sign as x and + * magnitude less than the magnitude of y. + * + * On a VAX or CCI, + * + *    fmod(x,0) traps/faults on floating-point divided-by-zero. + * + * On IEEE-754 conforming machines with "isnan()" primitive, + * + *    fmod(x,0), fmod(INF,y) are invalid operations and NaN is returned. + * + */ +#if !defined(vax) && !defined(tahoe) +extern int isnan(),finite(); +#endif	/* !defined(vax) && !defined(tahoe) */ +extern double frexp(),ldexp(),fabs(); + +#ifdef TEST_FMOD +static double +_fmod(x,y) +#else	/* TEST_FMOD */ +double +fmod(x,y) +#endif	/* TEST_FMOD */ +double x,y; +{ +	int ir,iy; +	double r,w; + +	if (y == (double)0 +#if !defined(vax) && !defined(tahoe)	/* per "fmod" manual entry, SunOS 4.0 */ +		|| isnan(y) || !finite(x) +#endif	/* !defined(vax) && !defined(tahoe) */ +	    ) +	    return (x*y)/(x*y); + +	r = fabs(x); +	y = fabs(y); +	(void)frexp(y,&iy); +	while (r >= y) { +		(void)frexp(r,&ir); +		w = ldexp(y,ir-iy); +		r -= w <= r ? w : w*(double)0.5; +	} +	return x >= (double)0 ? r : -r; +} + +#ifdef TEST_FMOD +extern long random(); +extern double fmod(); + +#define	NTEST	10000 +#define	NCASES	3 + +static int nfail = 0; + +static void +doit(x,y) +double x,y; +{ +	double ro = fmod(x,y),rn = _fmod(x,y); +	if (ro != rn) { +		(void)printf(" x    = 0x%08.8x %08.8x (%24.16e)\n",x,x); +		(void)printf(" y    = 0x%08.8x %08.8x (%24.16e)\n",y,y); +		(void)printf(" fmod = 0x%08.8x %08.8x (%24.16e)\n",ro,ro); +		(void)printf("_fmod = 0x%08.8x %08.8x (%24.16e)\n",rn,rn); +		(void)printf("\n"); +	} +} + +main() +{ +	register int i,cases; +	double x,y; + +	srandom(12345); +	for (i = 0; i < NTEST; i++) { +		x = (double)random(); +		y = (double)random(); +		for (cases = 0; cases < NCASES; cases++) { +			switch (cases) { +			case 0: +				break; +			case 1: +				y = (double)1/y; break; +			case 2: +				x = (double)1/x; break; +			default: +				abort(); break; +			} +			doit(x,y); +			doit(x,-y); +			doit(-x,y); +			doit(-x,-y); +		} +	} +	if (nfail) +		(void)printf("Number of failures: %d (out of a total of %d)\n", +			nfail,NTEST*NCASES*4); +	else +		(void)printf("No discrepancies were found\n"); +	exit(0); +} +#endif	/* TEST_FMOD */ diff --git a/lib/libm/common_source/gamma.c b/lib/libm/common_source/gamma.c new file mode 100644 index 000000000000..5d270f05170e --- /dev/null +++ b/lib/libm/common_source/gamma.c @@ -0,0 +1,336 @@ +/*- + * Copyright (c) 1992, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)gamma.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* + * This code by P. McIlroy, Oct 1992; + * + * The financial support of UUNET Communications Services is greatfully + * acknowledged. + */ + +#include <math.h> +#include "mathimpl.h" +#include <errno.h> + +/* METHOD: + * x < 0: Use reflection formula, G(x) = pi/(sin(pi*x)*x*G(x)) + * 	At negative integers, return +Inf, and set errno. + * + * x < 6.5: + *	Use argument reduction G(x+1) = xG(x) to reach the + *	range [1.066124,2.066124].  Use a rational + *	approximation centered at the minimum (x0+1) to + *	ensure monotonicity. + * + * x >= 6.5: Use the asymptotic approximation (Stirling's formula) + *	adjusted for equal-ripples: + * + *	log(G(x)) ~= (x-.5)*(log(x)-1) + .5(log(2*pi)-1) + 1/x*P(1/(x*x)) + * + *	Keep extra precision in multiplying (x-.5)(log(x)-1), to + *	avoid premature round-off. + * + * Special values: + *	non-positive integer:	Set overflow trap; return +Inf; + *	x > 171.63:		Set overflow trap; return +Inf; + *	NaN: 			Set invalid trap;  return NaN + * + * Accuracy: Gamma(x) is accurate to within + *	x > 0:  error provably < 0.9ulp. + *	Maximum observed in 1,000,000 trials was .87ulp. + *	x < 0: + *	Maximum observed error < 4ulp in 1,000,000 trials. + */ + +static double neg_gam __P((double)); +static double small_gam __P((double)); +static double smaller_gam __P((double)); +static struct Double large_gam __P((double)); +static struct Double ratfun_gam __P((double, double)); + +/* + * Rational approximation, A0 + x*x*P(x)/Q(x), on the interval + * [1.066.., 2.066..] accurate to 4.25e-19. + */ +#define LEFT -.3955078125	/* left boundary for rat. approx */ +#define x0 .461632144968362356785	/* xmin - 1 */ + +#define a0_hi 0.88560319441088874992 +#define a0_lo -.00000000000000004996427036469019695 +#define P0	 6.21389571821820863029017800727e-01 +#define P1	 2.65757198651533466104979197553e-01 +#define P2	 5.53859446429917461063308081748e-03 +#define P3	 1.38456698304096573887145282811e-03 +#define P4	 2.40659950032711365819348969808e-03 +#define Q0	 1.45019531250000000000000000000e+00 +#define Q1	 1.06258521948016171343454061571e+00 +#define Q2	-2.07474561943859936441469926649e-01 +#define Q3	-1.46734131782005422506287573015e-01 +#define Q4	 3.07878176156175520361557573779e-02 +#define Q5	 5.12449347980666221336054633184e-03 +#define Q6	-1.76012741431666995019222898833e-03 +#define Q7	 9.35021023573788935372153030556e-05 +#define Q8	 6.13275507472443958924745652239e-06 +/* + * Constants for large x approximation (x in [6, Inf]) + * (Accurate to 2.8*10^-19 absolute) + */ +#define lns2pi_hi 0.418945312500000 +#define lns2pi_lo -.000006779295327258219670263595 +#define Pa0	 8.33333333333333148296162562474e-02 +#define Pa1	-2.77777777774548123579378966497e-03 +#define Pa2	 7.93650778754435631476282786423e-04 +#define Pa3	-5.95235082566672847950717262222e-04 +#define Pa4	 8.41428560346653702135821806252e-04 +#define Pa5	-1.89773526463879200348872089421e-03 +#define Pa6	 5.69394463439411649408050664078e-03 +#define Pa7	-1.44705562421428915453880392761e-02 + +static const double zero = 0., one = 1.0, tiny = 1e-300; +static int endian; +/* + * TRUNC sets trailing bits in a floating-point number to zero. + * is a temporary variable. + */ +#if defined(vax) || defined(tahoe) +#define _IEEE		0 +#define TRUNC(x)	x = (double) (float) (x) +#else +#define _IEEE		1 +#define TRUNC(x)	*(((int *) &x) + endian) &= 0xf8000000 +#define infnan(x)	0.0 +#endif + +double +gamma(x) +	double x; +{ +	struct Double u; +	endian = (*(int *) &one) ? 1 : 0; + +	if (x >= 6) { +		if(x > 171.63) +			return(one/zero); +		u = large_gam(x); +		return(__exp__D(u.a, u.b)); +	} else if (x >= 1.0 + LEFT + x0) +		return (small_gam(x)); +	else if (x > 1.e-17) +		return (smaller_gam(x)); +	else if (x > -1.e-17) { +		if (x == 0.0) +			if (!_IEEE) return (infnan(ERANGE)); +			else return (one/x); +		one+1e-20;		/* Raise inexact flag. */ +		return (one/x); +	} else if (!finite(x)) { +		if (_IEEE)		/* x = NaN, -Inf */ +			return (x*x); +		else +			return (infnan(EDOM)); +	 } else +		return (neg_gam(x)); +} +/* + * Accurate to max(ulp(1/128) absolute, 2^-66 relative) error. + */ +static struct Double +large_gam(x) +	double x; +{ +	double z, p; +	int i; +	struct Double t, u, v; + +	z = one/(x*x); +	p = Pa0+z*(Pa1+z*(Pa2+z*(Pa3+z*(Pa4+z*(Pa5+z*(Pa6+z*Pa7)))))); +	p = p/x; + +	u = __log__D(x); +	u.a -= one; +	v.a = (x -= .5); +	TRUNC(v.a); +	v.b = x - v.a; +	t.a = v.a*u.a;			/* t = (x-.5)*(log(x)-1) */ +	t.b = v.b*u.a + x*u.b; +	/* return t.a + t.b + lns2pi_hi + lns2pi_lo + p */ +	t.b += lns2pi_lo; t.b += p; +	u.a = lns2pi_hi + t.b; u.a += t.a; +	u.b = t.a - u.a; +	u.b += lns2pi_hi; u.b += t.b; +	return (u); +} +/* + * Good to < 1 ulp.  (provably .90 ulp; .87 ulp on 1,000,000 runs.) + * It also has correct monotonicity. + */ +static double +small_gam(x) +	double x; +{ +	double y, ym1, t, x1; +	struct Double yy, r; +	y = x - one; +	ym1 = y - one; +	if (y <= 1.0 + (LEFT + x0)) { +		yy = ratfun_gam(y - x0, 0); +		return (yy.a + yy.b); +	} +	r.a = y; +	TRUNC(r.a); +	yy.a = r.a - one; +	y = ym1; +	yy.b = r.b = y - yy.a; +	/* Argument reduction: G(x+1) = x*G(x) */ +	for (ym1 = y-one; ym1 > LEFT + x0; y = ym1--, yy.a--) { +		t = r.a*yy.a; +		r.b = r.a*yy.b + y*r.b; +		r.a = t; +		TRUNC(r.a); +		r.b += (t - r.a); +	} +	/* Return r*gamma(y). */ +	yy = ratfun_gam(y - x0, 0); +	y = r.b*(yy.a + yy.b) + r.a*yy.b; +	y += yy.a*r.a; +	return (y); +} +/* + * Good on (0, 1+x0+LEFT].  Accurate to 1ulp. + */ +static double +smaller_gam(x) +	double x; +{ +	double t, d; +	struct Double r, xx; +	if (x < x0 + LEFT) { +		t = x, TRUNC(t); +		d = (t+x)*(x-t); +		t *= t; +		xx.a = (t + x), TRUNC(xx.a); +		xx.b = x - xx.a; xx.b += t; xx.b += d; +		t = (one-x0); t += x; +		d = (one-x0); d -= t; d += x; +		x = xx.a + xx.b; +	} else { +		xx.a =  x, TRUNC(xx.a); +		xx.b = x - xx.a; +		t = x - x0; +		d = (-x0 -t); d += x; +	} +	r = ratfun_gam(t, d); +	d = r.a/x, TRUNC(d); +	r.a -= d*xx.a; r.a -= d*xx.b; r.a += r.b; +	return (d + r.a/x); +} +/* + * returns (z+c)^2 * P(z)/Q(z) + a0 + */ +static struct Double +ratfun_gam(z, c) +	double z, c; +{ +	int i; +	double p, q; +	struct Double r, t; + +	q = Q0 +z*(Q1+z*(Q2+z*(Q3+z*(Q4+z*(Q5+z*(Q6+z*(Q7+z*Q8))))))); +	p = P0 + z*(P1 + z*(P2 + z*(P3 + z*P4))); + +	/* return r.a + r.b = a0 + (z+c)^2*p/q, with r.a truncated to 26 bits. */ +	p = p/q; +	t.a = z, TRUNC(t.a);		/* t ~= z + c */ +	t.b = (z - t.a) + c; +	t.b *= (t.a + z); +	q = (t.a *= t.a);		/* t = (z+c)^2 */ +	TRUNC(t.a); +	t.b += (q - t.a); +	r.a = p, TRUNC(r.a);		/* r = P/Q */ +	r.b = p - r.a; +	t.b = t.b*p + t.a*r.b + a0_lo; +	t.a *= r.a;			/* t = (z+c)^2*(P/Q) */ +	r.a = t.a + a0_hi, TRUNC(r.a); +	r.b = ((a0_hi-r.a) + t.a) + t.b; +	return (r);			/* r = a0 + t */ +} + +static double +neg_gam(x) +	double x; +{ +	int sgn = 1; +	struct Double lg, lsine; +	double y, z; + +	y = floor(x + .5); +	if (y == x)		/* Negative integer. */ +		if(!_IEEE) +			return (infnan(ERANGE)); +		else +			return (one/zero); +	z = fabs(x - y); +	y = .5*ceil(x); +	if (y == ceil(y)) +		sgn = -1; +	if (z < .25) +		z = sin(M_PI*z); +	else +		z = cos(M_PI*(0.5-z)); +	/* Special case: G(1-x) = Inf; G(x) may be nonzero. */ +	if (x < -170) { +		if (x < -190) +			return ((double)sgn*tiny*tiny); +		y = one - x;		/* exact: 128 < |x| < 255 */ +		lg = large_gam(y); +		lsine = __log__D(M_PI/z);	/* = TRUNC(log(u)) + small */ +		lg.a -= lsine.a;		/* exact (opposite signs) */ +		lg.b -= lsine.b; +		y = -(lg.a + lg.b); +		z = (y + lg.a) + lg.b; +		y = __exp__D(y, z); +		if (sgn < 0) y = -y; +		return (y); +	} +	y = one-x; +	if (one-y == x) +		y = gamma(y); +	else		/* 1-x is inexact */ +		y = -x*gamma(-x); +	if (sgn < 0) y = -y; +	return (M_PI / (y*z)); +} diff --git a/lib/libm/common_source/hypot.3 b/lib/libm/common_source/hypot.3 new file mode 100644 index 000000000000..3a1de9a79bd5 --- /dev/null +++ b/lib/libm/common_source/hypot.3 @@ -0,0 +1,124 @@ +.\" Copyright (c) 1985, 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)hypot.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt HYPOT 3 +.Os BSD 4 +.Sh NAME +.Nm hypot , +.Nm cabs +.Nd euclidean distance and complex absolute value functions +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn hypot "double x" "double y" +.Fd struct {double x, y;} z; +.Ft double +.Fn cabs z +.Sh DESCRIPTION +The +.Fn hypot +and +.Fn cabs +functions +computes the +sqrt(x*x+y*y) +in such a way that underflow will not happen, and overflow +occurs only if the final result deserves it. +.Pp +.Fn hypot "\*(If" "v" += +.Fn hypot "v" "\*(If" += +\*(If for all +.Ar v , +including \*(Na. +.Sh ERROR (due to Roundoff, etc.) +Below 0.97 +.Em ulps . +Consequently +.Fn hypot "5.0" "12.0" += 13.0 +exactly; +in general, hypot and cabs return an integer whenever an +integer might be expected. +.Pp +The same cannot be said for the shorter and faster version of hypot +and cabs that is provided in the comments in cabs.c; its error can +exceed 1.2 +.Em ulps . +.Sh NOTES +As might be expected, +.Fn hypot "v" "\*(Na" +and +.Fn hypot "\*(Na" "v" +are \*(Na for all +.Em finite +.Ar v ; +with "reserved operand" in place of "\*(Na", the +same is true on a +.Tn VAX . +But programmers on machines other than a +.Tn VAX +(if has no \*(If) +might be surprised at first to discover that +.Fn hypot "\(+-\*(If" "\*(Na" += +\*(If. +This is intentional; it happens because +.Fn hypot "\*(If" "v" += +\*(If +for +.Em all +.Ar v , +finite or infinite. +Hence +.Fn hypot "\*(If" "v" +is independent of +.Ar v . +Unlike the reserved operand fault on a +.Tn VAX , +the +.Tn IEEE +\*(Na is designed to +disappear when it turns out to be irrelevant, as it does in +.Fn hypot "\*(If" "\*(Na" . +.Sh SEE ALSO +.Xr math 3 , +.Xr sqrt 3 +.Sh HISTORY +Both a +.Fn hypot +function and a +.Fn cabs +function +appeared in +.At v7 . diff --git a/lib/libm/common_source/ieee.3 b/lib/libm/common_source/ieee.3 new file mode 100644 index 000000000000..fd44617d82f8 --- /dev/null +++ b/lib/libm/common_source/ieee.3 @@ -0,0 +1,267 @@ +.\" Copyright (c) 1985, 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)ieee.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt IEEE 3 +.Os BSD 4.3 +.Sh NAME +.Nm copysign , +.Nm drem , +.Nm finite , +.Nm logb , +.Nm scalb +.Nd "IEEE 754 floating point support +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double  +.Fn copysign "double x" "double y" +.Ft double  +.Fn drem "double x" "double y" +.Ft int  +.Fn finite "double x" +.Ft double  +.Fn logb "double x" +.Ft double  +.Fn scalb "double x" "int n" +.Sh DESCRIPTION +These functions are required for, or recommended by the +.Tn IEEE +standard +754 for floating\-point arithmetic. +.Pp +The +.Fn copysign +function +returns +.Fa x +with its sign changed to +.Fa y Ns 's. +.Pp +The +.Fn drem +function +returns the remainder +.Fa r +:= +.Fa x +\- +.Fa n\(**y +where +.Fa n +is the integer nearest the exact value of +.Bk -words +.Fa x Ns / Ns Fa y ; +.Ek +moreover if +.Pf \\*(Ba Fa n +\- +.Sm off +.Fa x No / Fa y No \\*(Ba +.Sm on += +1/2 +then +.Fa n +is even.  Consequently +the remainder is computed exactly and +.Sm off +.Pf \\*(Ba Fa r No \\*(Ba +.Sm on +\*(Le +.Sm off +.Pf \\*(Ba Fa y No \\*(Ba/2. +.Sm on +But +.Fn drem x 0 +is exceptional. +(See below under +.Sx DIAGNOSTICS . ) +.Pp +The +.Fn finite +function returns the value 1 just when +\-\*(If \*(Lt +.Fa x +\*(Lt +\*(If; +otherwise a +zero is returned +(when +.Pf \\*(Ba Ns Fa x Ns \\*(Ba += \*(If or +.Fa x +is \*(Na or +is the +.Tn VAX Ns 's +reserved operand). +.Pp +The +.Fn logb +function returns +.Fa x Ns 's exponent +.Fa n , +a signed integer converted to double\-precision floating\-point and so +chosen that +1 (<= +.Pf \\*(Ba Ns Fa x Ns \\*(Ba2** Ns Fa n +< 2 +unless +.Fa x += 0 or +(only on machines that conform to +.Tn IEEE +754) +.Pf \\*(Ba Fa x Ns \\*(Ba += \*(If +or +.Fa x +lies between 0 and the Underflow Threshold. +(See below under +.Sx BUGS . ) +.Pp +The +.Fn scalb +function returns +.Fa x Ns \(**(2** Ns Fa n ) +computed, for integer n, without first computing +.Pf 2\(** Fa n . +.Sh RETURN VALUES +The +.Tn IEEE +standard +754 defines +.Fn drem x 0 +and +.Fn drem \\*(If y +to be invalid operations that produce a \*(Na. +On the +.Tn VAX ,  +.Fn drem x 0 +generates a reserved operand fault.  No \*(If +exists on a +.Tn VAX .  +.Pp +.Tn IEEE +754 defines +.if n \ +.Fn logb \(+-\\*(If += \*(If and +.Fn logb 0 += \-\*(If, and +requires the latter to signal Division\-by\-Zero. +But on a +.Tn VAX ,  +.Fn logb 0 += 1.0 \- 2.0**31 = \-2,147,483,647.0. +And if the correct value of +.Fn scalb +would overflow on a +.Tn VAX ,  +it generates a reserved operand fault and sets the global variable +.Va errno +to +.Dv ERANGE .  +.Sh SEE ALSO +.Xr floor 3 , +.Xr math 3 , +.Xr infnan 3 +.Sh HISTORY +The +.Nm ieee +functions appeared in  +.Bx 4.3 . +.Sh BUGS +Should +.Fn drem x 0 +and +.Fn logb 0 +on a +.Tn VAX +signal invalidity  +by setting +.Va errno No = Dv EDOM ? +Should +.Fn logb 0 +return  \-1.7e38? +.Pp +.Tn IEEE +754 currently specifies that +.Fn logb "denormalized no." += +.Fn logb "tiniest normalized no. > 0" +but the consensus has changed to the specification in the new  +proposed +.Tn IEEE +standard p854, namely that +.Fn logb x +satisfy  +.Bd -filled -offset indent +1 \(<= +.Fn scalb \\*(Bax\\*(Ba \-logb(x) +< +Radix\0 ... = 2 +for +.Tn IEEE +754 +.Ed +.Pp +for every x except 0,  +\*(If +and \*(Na. +Almost every program that assumes 754's specification will work +correctly if +.Fn logb +follows 854's specification instead. +.Pp +.Tn IEEE +754 requires +.Fn copysign x \\*(Na) += +.Pf \(+- Ns Fa x +but says nothing +else about the sign of a \*(Na.  A \*(Na +.Em (N Ns ot +.Em a +.Em N Ns umber ) +is +similar in spirit to the +.Tn VAX Ns 's +reserved operand, but very +different in important details.  Since the sign bit of a +reserved operand makes it look negative,   +.Bd -filled -offset indent +.Fn copysign x "reserved operand" += +.Pf \- Fa x ; +.Ed +.Pp +should this return the reserved operand instead? diff --git a/lib/libm/common_source/infnan.3 b/lib/libm/common_source/infnan.3 new file mode 100644 index 000000000000..6a94bf6b241b --- /dev/null +++ b/lib/libm/common_source/infnan.3 @@ -0,0 +1,180 @@ +.\" Copyright (c) 1985, 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)infnan.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt INFNAN 3 +.Os BSD 4.3 +.Sh NAME +.Nm infnan +.Nd signals invalid floating\-point operations on a +.Tn VAX +(temporary) +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double  +.Fn infnan "int iarg" +.Sh DESCRIPTION +At some time in the future, some of the useful properties of +the Infinities and \*(Nas in the +.Tn IEEE +standard 754 for Binary +Floating\-Point Arithmetic will be simulated in +.Tn UNIX +on the +.Tn DEC VAX +by using its Reserved Operands.  Meanwhile, the +Invalid, Overflow and Divide\-by\-Zero exceptions of the +.Tn IEEE +standard are being approximated on a +.Tn VAX +by calls to a +procedure +.Fn infnan +in appropriate places in +.Xr libm 3 . +When +better exception\-handling is implemented in +.Tn UNIX ,  +only +.Fn infnan +among the codes in +.Xr libm +will have to be changed. +And users of +.Xr libm +can design their own +.Fn infnan +now to +insulate themselves from future changes. +.Pp +Whenever an elementary function code in +.Xr libm +has to +simulate one of the aforementioned +.Tn IEEE +exceptions, it calls +.Fn infnan iarg +with an appropriate value of +.Fa iarg . +Then a +reserved operand fault stops computation.  But +.Fn infnan +could +be replaced by a function with the same name that returns +some plausible value, assigns an apt value to the global +variable +.Va errno , +and allows computation to resume. +Alternatively, the Reserved Operand Fault Handler could be +changed to respond by returning that plausible value, etc. +instead of aborting. +.Pp +In the table below, the first two columns show various +exceptions signaled by the +.Tn IEEE +standard, and the default +result it prescribes.  The third column shows what value is +given to +.Fa iarg +by functions in +.Xr libm +when they +invoke +.Fn infnan iarg +under analogous circumstances on a +.Tn VAX .  +Currently +.Fn infnan +stops computation under all those +circumstances.  The last two columns offer an alternative; +they suggest a setting for +.Va errno +and a value for a +revised +.Fn infnan +to return.  And a C program to +implement that suggestion follows.  +.sp 0.5 +.Bd -filled -offset indent +.Bl -column "IEEE Signal" "IEEE Default" XXERANGE ERANGEXXorXXEDOM +.It IEEE Signal	IEEE Default Ta +.Fa iarg Ta +.Va errno Ta +.Fn infnan +.It Invalid	\*(Na Ta +.Dv EDOM	EDOM	0 +.It Overflow	\(+-\*(If Ta +.Dv ERANGE	ERANGE	HUGE +.It Div\-by\-0	\(+-Infinity Ta +.Dv \(+-ERANGE	ERANGE or EDOM	\(+-HUGE +.It 	( Ns Dv HUGE No "= 1.7e38 ... nearly  2.0**127)" +.El +.Ed +.Pp +ALTERNATIVE +.Fn infnan : +.Bd -literal -offset indent +#include	<math.h> +#include	<errno.h> +extern int	errno ; +double	infnan(iarg) +int	iarg ; +{ +	switch(iarg) { +	case	\0ERANGE:	errno = ERANGE; return(HUGE); +	case	\-ERANGE:	errno = EDOM;	return(\-HUGE); +	default:		errno = EDOM;	return(0); +	} +} +.Ed +.Sh SEE ALSO +.Xr math 3 , +.Xr intro 2 , +.Xr signal 3 . +.Pp +.Dv ERANGE +and +.Dv EDOM +are defined in +.Aq Pa errno.h . +(See +.Xr intro 2 +for explanation of +.Dv EDOM +and +.Dv ERANGE . ) +.Sh HISTORY +The +.Fn infnan +function appeared in  +.Bx 4.3 . diff --git a/lib/libm/common_source/j0.3 b/lib/libm/common_source/j0.3 new file mode 100644 index 000000000000..cd4ac12905ce --- /dev/null +++ b/lib/libm/common_source/j0.3 @@ -0,0 +1,126 @@ +.\" Copyright (c) 1985, 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)j0.3	8.2 (Berkeley) 4/19/94 +.\" +.Dd April 19, 1994 +.Dt J0 3 +.Os BSD 4 +.Sh NAME +.Nm j0 , +.Nm j1 , +.Nm jn , +.Nm y0 , +.Nm y1 , +.Nm yn +.Nd bessel functions of first and second kind +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn j0 "double x" +.Ft double +.Fn j1 "double x" +.Ft double +.Fn jn "int n" "double x" +.Ft double +.Fn y0 "double x" +.Ft double +.Fn y1 "double x" +.Ft double +.Fn yn "int n" "double x" +.Sh DESCRIPTION +The functions +.Fn j0 +and +.Fn j1 +compute the +.Em Bessel function of the first kind of the order +0 and the +.Em order +1, respectively, +for the +real value +.Fa x ; +the function +.Fn jn +computes the +.Em Bessel function of the first kind of the integer order +.Fa n +for the real value +.Fa x . +.Pp +The functions +.Fn y0 +and +.Fn y1 +compute the linearly independent +.Em Bessel function of the second kind of the order +0 and the +.Em order +1, respectively, +for the positive +.Em integer +value +.Fa x +(expressed as a double); +the function +.Fn yn +computes the +.Em Bessel function of the second kind for the integer order +.Fa n +for the positive  +.Em integer +value +.Fa x +(expressed as a double). +.Sh RETURN VALUES +If these functions are successful, +the computed value is returned. On the +.Tn VAX +and +.Tn Tahoe +architectures, +a negative +.Fa x +value +results in an error; the global +variable +.Va errno +is set to +.Er EDOM +and a reserve operand fault is generated. +.Sh SEE ALSO +.Xr math 3 , +.Xr infnan 3 +.Sh HISTORY +A set of these functions +function appeared in +.At v7 . diff --git a/lib/libm/common_source/j0.c b/lib/libm/common_source/j0.c new file mode 100644 index 000000000000..a9b28b38caea --- /dev/null +++ b/lib/libm/common_source/j0.c @@ -0,0 +1,439 @@ +/*- + * Copyright (c) 1992, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)j0.c	8.2 (Berkeley) 11/30/93"; +#endif /* not lint */ + +/* + * 16 December 1992 + * Minor modifications by Peter McIlroy to adapt non-IEEE architecture. + */ + +/* + * ==================================================== + * Copyright (C) 1992 by Sun Microsystems, Inc. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice  + * is preserved. + * ==================================================== + * + * ******************* WARNING ******************** + * This is an alpha version of SunPro's FDLIBM (Freely + * Distributable Math Library) for IEEE double precision  + * arithmetic. FDLIBM is a basic math library written + * in C that runs on machines that conform to IEEE  + * Standard 754/854. This alpha version is distributed  + * for testing purpose. Those who use this software  + * should report any bugs to  + * + *		fdlibm-comments@sunpro.eng.sun.com + * + * -- K.C. Ng, Oct 12, 1992 + * ************************************************ + */ + +/* double j0(double x), y0(double x) + * Bessel function of the first and second kinds of order zero. + * Method -- j0(x): + *	1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ... + *	2. Reduce x to |x| since j0(x)=j0(-x),  and + *	   for x in (0,2) + *		j0(x) = 1-z/4+ z^2*R0/S0,  where z = x*x; + *	   (precision:  |j0-1+z/4-z^2R0/S0 |<2**-63.67 ) + *	   for x in (2,inf) + * 		j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0)) + * 	   where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) + *	   as follow: + *		cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + *			= 1/sqrt(2) * (cos(x) + sin(x)) + *		sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4) + *			= 1/sqrt(2) * (sin(x) - cos(x)) + * 	   (To avoid cancellation, use + *		sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * 	    to compute the worse one.) + *	    + *	3 Special cases + *		j0(nan)= nan + *		j0(0) = 1 + *		j0(inf) = 0 + *		 + * Method -- y0(x): + *	1. For x<2. + *	   Since  + *		y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...) + *	   therefore y0(x)-2/pi*j0(x)*ln(x) is an even function. + *	   We use the following function to approximate y0, + *		y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2 + *	   where  + *		U(z) = u0 + u1*z + ... + u6*z^6 + *		V(z) = 1  + v1*z + ... + v4*z^4 + *	   with absolute approximation error bounded by 2**-72. + *	   Note: For tiny x, U/V = u0 and j0(x)~1, hence + *		y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27) + *	2. For x>=2. + * 		y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0)) + * 	   where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) + *	   by the method mentioned above. + *	3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0. + */ + +#include <math.h> +#include <float.h> +#if defined(vax) || defined(tahoe) +#define _IEEE	0 +#else +#define _IEEE	1 +#define infnan(x) (0.0) +#endif + +static double pzero __P((double)), qzero __P((double)); + +static double  +huge 	= 1e300, +zero    = 0.0, +one	= 1.0, +invsqrtpi= 5.641895835477562869480794515607725858441e-0001, +tpi	= 0.636619772367581343075535053490057448, + 		/* R0/S0 on [0, 2.00] */ +r02 =   1.562499999999999408594634421055018003102e-0002, +r03 =  -1.899792942388547334476601771991800712355e-0004, +r04 =   1.829540495327006565964161150603950916854e-0006, +r05 =  -4.618326885321032060803075217804816988758e-0009, +s01 =   1.561910294648900170180789369288114642057e-0002, +s02 =   1.169267846633374484918570613449245536323e-0004, +s03 =   5.135465502073181376284426245689510134134e-0007, +s04 =   1.166140033337900097836930825478674320464e-0009; + +double +j0(x)  +	double x; +{ +	double z, s,c,ss,cc,r,u,v; + +	if (!finite(x)) +		if (_IEEE) return one/(x*x); +		else return (0); +	x = fabs(x); +	if (x >= 2.0) {	/* |x| >= 2.0 */ +		s = sin(x); +		c = cos(x); +		ss = s-c; +		cc = s+c; +		if (x < .5 * DBL_MAX) {  /* make sure x+x not overflow */ +		    z = -cos(x+x); +		    if ((s*c)<zero) cc = z/ss; +		    else 	    ss = z/cc; +		} +	/* +	 * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) +	 * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) +	 */ +		if (_IEEE && x> 6.80564733841876927e+38) /* 2^129 */ +			z = (invsqrtpi*cc)/sqrt(x); +		else { +		    u = pzero(x); v = qzero(x); +		    z = invsqrtpi*(u*cc-v*ss)/sqrt(x); +		} +		return z; +	} +	if (x < 1.220703125e-004) {		   /* |x| < 2**-13 */ +	    if (huge+x > one) {			   /* raise inexact if x != 0 */ +	        if (x < 7.450580596923828125e-009) /* |x|<2**-27 */ +			return one; +	        else return (one - 0.25*x*x); +	    } +	} +	z = x*x; +	r =  z*(r02+z*(r03+z*(r04+z*r05))); +	s =  one+z*(s01+z*(s02+z*(s03+z*s04))); +	if (x < one) {			/* |x| < 1.00 */ +	    return (one + z*(-0.25+(r/s))); +	} else { +	    u = 0.5*x; +	    return ((one+u)*(one-u)+z*(r/s)); +	} +} + +static double +u00 =  -7.380429510868722527422411862872999615628e-0002, +u01 =   1.766664525091811069896442906220827182707e-0001, +u02 =  -1.381856719455968955440002438182885835344e-0002, +u03 =   3.474534320936836562092566861515617053954e-0004, +u04 =  -3.814070537243641752631729276103284491172e-0006, +u05 =   1.955901370350229170025509706510038090009e-0008, +u06 =  -3.982051941321034108350630097330144576337e-0011, +v01 =   1.273048348341237002944554656529224780561e-0002, +v02 =   7.600686273503532807462101309675806839635e-0005, +v03 =   2.591508518404578033173189144579208685163e-0007, +v04 =   4.411103113326754838596529339004302243157e-0010; + +double +y0(x)  +	double x; +{ +	double z, s, c, ss, cc, u, v; +    /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0  */ +	if (!finite(x)) +		if (_IEEE) +			return (one/(x+x*x)); +		else +			return (0); +        if (x == 0) +		if (_IEEE)	return (-one/zero); +		else		return(infnan(-ERANGE)); +        if (x<0) +		if (_IEEE)	return (zero/zero); +		else		return (infnan(EDOM)); +        if (x >= 2.00) {	/* |x| >= 2.0 */ +        /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) +         * where x0 = x-pi/4 +         *      Better formula: +         *              cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) +         *                      =  1/sqrt(2) * (sin(x) + cos(x)) +         *              sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) +         *                      =  1/sqrt(2) * (sin(x) - cos(x)) +         * To avoid cancellation, use +         *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) +         * to compute the worse one. +         */ +                s = sin(x); +                c = cos(x); +                ss = s-c; +                cc = s+c; +	/* +	 * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) +	 * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) +	 */ +                if (x < .5 * DBL_MAX) {  /* make sure x+x not overflow */ +                    z = -cos(x+x); +                    if ((s*c)<zero) cc = z/ss; +                    else            ss = z/cc; +                } +                if (_IEEE && x > 6.80564733841876927e+38) /* > 2^129 */ +			z = (invsqrtpi*ss)/sqrt(x); +                else { +                    u = pzero(x); v = qzero(x); +                    z = invsqrtpi*(u*ss+v*cc)/sqrt(x); +                } +                return z; +	} +	if (x <= 7.450580596923828125e-009) {		/* x < 2**-27 */ +	    return (u00 + tpi*log(x)); +	} +	z = x*x; +	u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); +	v = one+z*(v01+z*(v02+z*(v03+z*v04))); +	return (u/v + tpi*(j0(x)*log(x))); +} + +/* The asymptotic expansions of pzero is + *	1 - 9/128 s^2 + 11025/98304 s^4 - ...,	where s = 1/x. + * For x >= 2, We approximate pzero by + * 	pzero(x) = 1 + (R/S) + * where  R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10 + * 	  S = 1 + ps0*s^2 + ... + ps4*s^10 + * and + *	| pzero(x)-1-R/S | <= 2  ** ( -60.26) + */ +static double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +   0.0, +  -7.031249999999003994151563066182798210142e-0002, +  -8.081670412753498508883963849859423939871e+0000, +  -2.570631056797048755890526455854482662510e+0002, +  -2.485216410094288379417154382189125598962e+0003, +  -5.253043804907295692946647153614119665649e+0003, +}; +static double ps8[5] = { +   1.165343646196681758075176077627332052048e+0002, +   3.833744753641218451213253490882686307027e+0003, +   4.059785726484725470626341023967186966531e+0004, +   1.167529725643759169416844015694440325519e+0005, +   4.762772841467309430100106254805711722972e+0004, +}; + +static double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +  -1.141254646918944974922813501362824060117e-0011, +  -7.031249408735992804117367183001996028304e-0002, +  -4.159610644705877925119684455252125760478e+0000, +  -6.767476522651671942610538094335912346253e+0001, +  -3.312312996491729755731871867397057689078e+0002, +  -3.464333883656048910814187305901796723256e+0002, +}; +static double ps5[5] = { +   6.075393826923003305967637195319271932944e+0001, +   1.051252305957045869801410979087427910437e+0003, +   5.978970943338558182743915287887408780344e+0003, +   9.625445143577745335793221135208591603029e+0003, +   2.406058159229391070820491174867406875471e+0003, +}; + +static double pr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +  -2.547046017719519317420607587742992297519e-0009, +  -7.031196163814817199050629727406231152464e-0002, +  -2.409032215495295917537157371488126555072e+0000, +  -2.196597747348830936268718293366935843223e+0001, +  -5.807917047017375458527187341817239891940e+0001, +  -3.144794705948885090518775074177485744176e+0001, +}; +static double ps3[5] = { +   3.585603380552097167919946472266854507059e+0001, +   3.615139830503038919981567245265266294189e+0002, +   1.193607837921115243628631691509851364715e+0003, +   1.127996798569074250675414186814529958010e+0003, +   1.735809308133357510239737333055228118910e+0002, +}; + +static double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +  -8.875343330325263874525704514800809730145e-0008, +  -7.030309954836247756556445443331044338352e-0002, +  -1.450738467809529910662233622603401167409e+0000, +  -7.635696138235277739186371273434739292491e+0000, +  -1.119316688603567398846655082201614524650e+0001, +  -3.233645793513353260006821113608134669030e+0000, +}; +static double ps2[5] = { +   2.222029975320888079364901247548798910952e+0001, +   1.362067942182152109590340823043813120940e+0002, +   2.704702786580835044524562897256790293238e+0002, +   1.538753942083203315263554770476850028583e+0002, +   1.465761769482561965099880599279699314477e+0001, +}; + +static double pzero(x) +	double x; +{ +	double *p,*q,z,r,s; +	if (x >= 8.00)			   {p = pr8; q= ps8;} +	else if (x >= 4.54545211791992188) {p = pr5; q= ps5;} +	else if (x >= 2.85714149475097656) {p = pr3; q= ps3;} +	else if (x >= 2.00)		   {p = pr2; q= ps2;} +	z = one/(x*x); +	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); +	s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); +	return one+ r/s; +} +		 + +/* For x >= 8, the asymptotic expansions of qzero is + *	-1/8 s + 75/1024 s^3 - ..., where s = 1/x. + * We approximate pzero by + * 	qzero(x) = s*(-1.25 + (R/S)) + * where  R = qr0 + qr1*s^2 + qr2*s^4 + ... + qr5*s^10 + * 	  S = 1 + qs0*s^2 + ... + qs5*s^12 + * and + *	| qzero(x)/s +1.25-R/S | <= 2  ** ( -61.22) + */ +static double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +   0.0, +   7.324218749999350414479738504551775297096e-0002, +   1.176820646822526933903301695932765232456e+0001, +   5.576733802564018422407734683549251364365e+0002, +   8.859197207564685717547076568608235802317e+0003, +   3.701462677768878501173055581933725704809e+0004, +}; +static double qs8[6] = { +   1.637760268956898345680262381842235272369e+0002, +   8.098344946564498460163123708054674227492e+0003, +   1.425382914191204905277585267143216379136e+0005, +   8.033092571195144136565231198526081387047e+0005, +   8.405015798190605130722042369969184811488e+0005, +  -3.438992935378666373204500729736454421006e+0005, +}; + +static double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +   1.840859635945155400568380711372759921179e-0011, +   7.324217666126847411304688081129741939255e-0002, +   5.835635089620569401157245917610984757296e+0000, +   1.351115772864498375785526599119895942361e+0002, +   1.027243765961641042977177679021711341529e+0003, +   1.989977858646053872589042328678602481924e+0003, +}; +static double qs5[6] = { +   8.277661022365377058749454444343415524509e+0001, +   2.077814164213929827140178285401017305309e+0003, +   1.884728877857180787101956800212453218179e+0004, +   5.675111228949473657576693406600265778689e+0004, +   3.597675384251145011342454247417399490174e+0004, +  -5.354342756019447546671440667961399442388e+0003, +}; + +static double qr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +   4.377410140897386263955149197672576223054e-0009, +   7.324111800429115152536250525131924283018e-0002, +   3.344231375161707158666412987337679317358e+0000, +   4.262184407454126175974453269277100206290e+0001, +   1.708080913405656078640701512007621675724e+0002, +   1.667339486966511691019925923456050558293e+0002, +}; +static double qs3[6] = { +   4.875887297245871932865584382810260676713e+0001, +   7.096892210566060535416958362640184894280e+0002, +   3.704148226201113687434290319905207398682e+0003, +   6.460425167525689088321109036469797462086e+0003, +   2.516333689203689683999196167394889715078e+0003, +  -1.492474518361563818275130131510339371048e+0002, +}; + +static double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +   1.504444448869832780257436041633206366087e-0007, +   7.322342659630792930894554535717104926902e-0002, +   1.998191740938159956838594407540292600331e+0000, +   1.449560293478857407645853071687125850962e+0001, +   3.166623175047815297062638132537957315395e+0001, +   1.625270757109292688799540258329430963726e+0001, +}; +static double qs2[6] = { +   3.036558483552191922522729838478169383969e+0001, +   2.693481186080498724211751445725708524507e+0002, +   8.447837575953201460013136756723746023736e+0002, +   8.829358451124885811233995083187666981299e+0002, +   2.126663885117988324180482985363624996652e+0002, +  -5.310954938826669402431816125780738924463e+0000, +}; + +static double qzero(x) +	double x; +{ +	double *p,*q, s,r,z; +	if (x >= 8.00)			   {p = qr8; q= qs8;} +	else if (x >= 4.54545211791992188) {p = qr5; q= qs5;} +	else if (x >= 2.85714149475097656) {p = qr3; q= qs3;} +	else if (x >= 2.00)		   {p = qr2; q= qs2;} +	z = one/(x*x); +	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); +	s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); +	return (-.125 + r/s)/x; +} diff --git a/lib/libm/common_source/j1.c b/lib/libm/common_source/j1.c new file mode 100644 index 000000000000..71602aac1381 --- /dev/null +++ b/lib/libm/common_source/j1.c @@ -0,0 +1,446 @@ +/*- + * Copyright (c) 1992, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)j1.c	8.2 (Berkeley) 11/30/93"; +#endif /* not lint */ + +/* + * 16 December 1992 + * Minor modifications by Peter McIlroy to adapt non-IEEE architecture. + */ + +/* + * ==================================================== + * Copyright (C) 1992 by Sun Microsystems, Inc. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice  + * is preserved. + * ==================================================== + * + * ******************* WARNING ******************** + * This is an alpha version of SunPro's FDLIBM (Freely + * Distributable Math Library) for IEEE double precision  + * arithmetic. FDLIBM is a basic math library written + * in C that runs on machines that conform to IEEE  + * Standard 754/854. This alpha version is distributed  + * for testing purpose. Those who use this software  + * should report any bugs to  + * + *		fdlibm-comments@sunpro.eng.sun.com + * + * -- K.C. Ng, Oct 12, 1992 + * ************************************************ + */ + +/* double j1(double x), y1(double x) + * Bessel function of the first and second kinds of order zero. + * Method -- j1(x): + *	1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ... + *	2. Reduce x to |x| since j1(x)=-j1(-x),  and + *	   for x in (0,2) + *		j1(x) = x/2 + x*z*R0/S0,  where z = x*x; + *	   (precision:  |j1/x - 1/2 - R0/S0 |<2**-61.51 ) + *	   for x in (2,inf) + * 		j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1)) + * 		y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) + * 	   where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) + *	   as follows: + *		cos(x1) =  cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + *			=  1/sqrt(2) * (sin(x) - cos(x)) + *		sin(x1) =  sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + *			= -1/sqrt(2) * (sin(x) + cos(x)) + * 	   (To avoid cancellation, use + *		sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * 	    to compute the worse one.) + *	    + *	3 Special cases + *		j1(nan)= nan + *		j1(0) = 0 + *		j1(inf) = 0 + *		 + * Method -- y1(x): + *	1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN  + *	2. For x<2. + *	   Since  + *		y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...) + *	   therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function. + *	   We use the following function to approximate y1, + *		y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2 + *	   where for x in [0,2] (abs err less than 2**-65.89) + *		U(z) = u0 + u1*z + ... + u4*z^4 + *		V(z) = 1  + v1*z + ... + v5*z^5 + *	   Note: For tiny x, 1/x dominate y1 and hence + *		y1(tiny) = -2/pi/tiny, (choose tiny<2**-54) + *	3. For x>=2. + * 		y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) + * 	   where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) + *	   by method mentioned above. + */ + +#include <math.h> +#include <float.h> + +#if defined(vax) || defined(tahoe) +#define _IEEE	0 +#else +#define _IEEE	1 +#define infnan(x) (0.0) +#endif + +static double pone(), qone(); + +static double  +huge    = 1e300, +zero    = 0.0, +one	= 1.0, +invsqrtpi= 5.641895835477562869480794515607725858441e-0001, +tpi	= 0.636619772367581343075535053490057448, + +	/* R0/S0 on [0,2] */ +r00 =  -6.250000000000000020842322918309200910191e-0002, +r01 =   1.407056669551897148204830386691427791200e-0003, +r02 =  -1.599556310840356073980727783817809847071e-0005, +r03 =   4.967279996095844750387702652791615403527e-0008, +s01 =   1.915375995383634614394860200531091839635e-0002, +s02 =   1.859467855886309024045655476348872850396e-0004, +s03 =   1.177184640426236767593432585906758230822e-0006, +s04 =   5.046362570762170559046714468225101016915e-0009, +s05 =   1.235422744261379203512624973117299248281e-0011; + +#define two_129	6.80564733841876926e+038	/* 2^129 */ +#define two_m54	5.55111512312578270e-017	/* 2^-54 */ +double j1(x)  +	double x; +{ +	double z, s,c,ss,cc,r,u,v,y; +	y = fabs(x); +	if (!finite(x))			/* Inf or NaN */ +		if (_IEEE && x != x) +			return(x); +		else +			return (copysign(x, zero)); +	y = fabs(x); +	if (y >= 2)			/* |x| >= 2.0 */ +	{ +		s = sin(y); +		c = cos(y); +		ss = -s-c; +		cc = s-c; +		if (y < .5*DBL_MAX) {  	/* make sure y+y not overflow */ +		    z = cos(y+y); +		    if ((s*c)<zero) cc = z/ss; +		    else 	    ss = z/cc; +		} +	/* +	 * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) +	 * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) +	 */ +#if !defined(vax) && !defined(tahoe) +		if (y > two_129)	 /* x > 2^129 */ +			z = (invsqrtpi*cc)/sqrt(y); +		else +#endif /* defined(vax) || defined(tahoe) */ +		{ +		    u = pone(y); v = qone(y); +		    z = invsqrtpi*(u*cc-v*ss)/sqrt(y); +		} +		if (x < 0) return -z; +		else  	 return  z; +	} +	if (y < 7.450580596923828125e-009) {	/* |x|<2**-27 */ +	    if(huge+x>one) return 0.5*x;/* inexact if x!=0 necessary */ +	} +	z = x*x; +	r =  z*(r00+z*(r01+z*(r02+z*r03))); +	s =  one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05)))); +	r *= x; +	return (x*0.5+r/s); +} + +static double u0[5] = { +  -1.960570906462389484206891092512047539632e-0001, +   5.044387166398112572026169863174882070274e-0002, +  -1.912568958757635383926261729464141209569e-0003, +   2.352526005616105109577368905595045204577e-0005, +   -9.190991580398788465315411784276789663849e-0008, +}; +static double v0[5] = { +   1.991673182366499064031901734535479833387e-0002, +   2.025525810251351806268483867032781294682e-0004, +   1.356088010975162198085369545564475416398e-0006, +   6.227414523646214811803898435084697863445e-0009, +   1.665592462079920695971450872592458916421e-0011, +}; + +double y1(x)  +	double x; +{ +	double z, s, c, ss, cc, u, v; +    /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ +	if (!finite(x)) +		if (!_IEEE) return (infnan(EDOM)); +		else if (x < 0) +			return(zero/zero); +		else if (x > 0) +			return (0); +		else +			return(x); +	if (x <= 0) { +		if (_IEEE && x == 0) return -one/zero; +		else if(x == 0) return(infnan(-ERANGE)); +		else if(_IEEE) return (zero/zero); +		else return(infnan(EDOM)); +	} +        if (x >= 2)			 /* |x| >= 2.0 */ +	{ +                s = sin(x); +                c = cos(x); +                ss = -s-c; +                cc = s-c; +		if (x < .5 * DBL_MAX)	/* make sure x+x not overflow */ +		{ +                    z = cos(x+x); +                    if ((s*c)>zero) cc = z/ss; +                    else            ss = z/cc; +                } +        /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) +         * where x0 = x-3pi/4 +         *      Better formula: +         *              cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) +         *                      =  1/sqrt(2) * (sin(x) - cos(x)) +         *              sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) +         *                      = -1/sqrt(2) * (cos(x) + sin(x)) +         * To avoid cancellation, use +         *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) +         * to compute the worse one. +         */ +                if (_IEEE && x>two_129) +			z = (invsqrtpi*ss)/sqrt(x); +                else { +                    u = pone(x); v = qone(x); +                    z = invsqrtpi*(u*ss+v*cc)/sqrt(x); +                } +                return z; +        }  +        if (x <= two_m54) {    /* x < 2**-54 */ +            return (-tpi/x); +        }  +        z = x*x; +        u = u0[0]+z*(u0[1]+z*(u0[2]+z*(u0[3]+z*u0[4]))); +        v = one+z*(v0[0]+z*(v0[1]+z*(v0[2]+z*(v0[3]+z*v0[4])))); +        return (x*(u/v) + tpi*(j1(x)*log(x)-one/x)); +} + +/* For x >= 8, the asymptotic expansions of pone is + *	1 + 15/128 s^2 - 4725/2^15 s^4 - ...,	where s = 1/x. + * We approximate pone by + * 	pone(x) = 1 + (R/S) + * where  R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10 + * 	  S = 1 + ps0*s^2 + ... + ps4*s^10 + * and + *	| pone(x)-1-R/S | <= 2  ** ( -60.06) + */ + +static double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +   0.0, +   1.171874999999886486643746274751925399540e-0001, +   1.323948065930735690925827997575471527252e+0001, +   4.120518543073785433325860184116512799375e+0002, +   3.874745389139605254931106878336700275601e+0003, +   7.914479540318917214253998253147871806507e+0003, +}; +static double ps8[5] = { +   1.142073703756784104235066368252692471887e+0002, +   3.650930834208534511135396060708677099382e+0003, +   3.695620602690334708579444954937638371808e+0004, +   9.760279359349508334916300080109196824151e+0004, +   3.080427206278887984185421142572315054499e+0004, +}; + +static double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +   1.319905195562435287967533851581013807103e-0011, +   1.171874931906140985709584817065144884218e-0001, +   6.802751278684328781830052995333841452280e+0000, +   1.083081829901891089952869437126160568246e+0002, +   5.176361395331997166796512844100442096318e+0002, +   5.287152013633375676874794230748055786553e+0002, +}; +static double ps5[5] = { +   5.928059872211313557747989128353699746120e+0001, +   9.914014187336144114070148769222018425781e+0002, +   5.353266952914879348427003712029704477451e+0003, +   7.844690317495512717451367787640014588422e+0003, +   1.504046888103610723953792002716816255382e+0003, +}; + +static double pr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +   3.025039161373736032825049903408701962756e-0009, +   1.171868655672535980750284752227495879921e-0001, +   3.932977500333156527232725812363183251138e+0000, +   3.511940355916369600741054592597098912682e+0001, +   9.105501107507812029367749771053045219094e+0001, +   4.855906851973649494139275085628195457113e+0001, +}; +static double ps3[5] = { +   3.479130950012515114598605916318694946754e+0001, +   3.367624587478257581844639171605788622549e+0002, +   1.046871399757751279180649307467612538415e+0003, +   8.908113463982564638443204408234739237639e+0002, +   1.037879324396392739952487012284401031859e+0002, +}; + +static double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +   1.077108301068737449490056513753865482831e-0007, +   1.171762194626833490512746348050035171545e-0001, +   2.368514966676087902251125130227221462134e+0000, +   1.224261091482612280835153832574115951447e+0001, +   1.769397112716877301904532320376586509782e+0001, +   5.073523125888185399030700509321145995160e+0000, +}; +static double ps2[5] = { +   2.143648593638214170243114358933327983793e+0001, +   1.252902271684027493309211410842525120355e+0002, +   2.322764690571628159027850677565128301361e+0002, +   1.176793732871470939654351793502076106651e+0002, +   8.364638933716182492500902115164881195742e+0000, +}; + +static double pone(x) +	double x; +{ +	double *p,*q,z,r,s; +	if (x >= 8.0) 			   {p = pr8; q= ps8;} +	else if (x >= 4.54545211791992188) {p = pr5; q= ps5;} +	else if (x >= 2.85714149475097656) {p = pr3; q= ps3;} +	else /* if (x >= 2.0) */	   {p = pr2; q= ps2;} +	z = one/(x*x); +	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); +	s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); +	return (one + r/s); +} +		 + +/* For x >= 8, the asymptotic expansions of qone is + *	3/8 s - 105/1024 s^3 - ..., where s = 1/x. + * We approximate pone by + * 	qone(x) = s*(0.375 + (R/S)) + * where  R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10 + * 	  S = 1 + qs1*s^2 + ... + qs6*s^12 + * and + *	| qone(x)/s -0.375-R/S | <= 2  ** ( -61.13) + */ + +static double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +   0.0, +  -1.025390624999927207385863635575804210817e-0001, +  -1.627175345445899724355852152103771510209e+0001, +  -7.596017225139501519843072766973047217159e+0002, +  -1.184980667024295901645301570813228628541e+0004, +  -4.843851242857503225866761992518949647041e+0004, +}; +static double qs8[6] = { +   1.613953697007229231029079421446916397904e+0002, +   7.825385999233484705298782500926834217525e+0003, +   1.338753362872495800748094112937868089032e+0005, +   7.196577236832409151461363171617204036929e+0005, +   6.666012326177764020898162762642290294625e+0005, +  -2.944902643038346618211973470809456636830e+0005, +}; + +static double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +  -2.089799311417640889742251585097264715678e-0011, +  -1.025390502413754195402736294609692303708e-0001, +  -8.056448281239359746193011295417408828404e+0000, +  -1.836696074748883785606784430098756513222e+0002, +  -1.373193760655081612991329358017247355921e+0003, +  -2.612444404532156676659706427295870995743e+0003, +}; +static double qs5[6] = { +   8.127655013843357670881559763225310973118e+0001, +   1.991798734604859732508048816860471197220e+0003, +   1.746848519249089131627491835267411777366e+0004, +   4.985142709103522808438758919150738000353e+0004, +   2.794807516389181249227113445299675335543e+0004, +  -4.719183547951285076111596613593553911065e+0003, +}; + +static double qr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +  -5.078312264617665927595954813341838734288e-0009, +  -1.025378298208370901410560259001035577681e-0001, +  -4.610115811394734131557983832055607679242e+0000, +  -5.784722165627836421815348508816936196402e+0001, +  -2.282445407376317023842545937526967035712e+0002, +  -2.192101284789093123936441805496580237676e+0002, +}; +static double qs3[6] = { +   4.766515503237295155392317984171640809318e+0001, +   6.738651126766996691330687210949984203167e+0002, +   3.380152866795263466426219644231687474174e+0003, +   5.547729097207227642358288160210745890345e+0003, +   1.903119193388108072238947732674639066045e+0003, +  -1.352011914443073322978097159157678748982e+0002, +}; + +static double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +  -1.783817275109588656126772316921194887979e-0007, +  -1.025170426079855506812435356168903694433e-0001, +  -2.752205682781874520495702498875020485552e+0000, +  -1.966361626437037351076756351268110418862e+0001, +  -4.232531333728305108194363846333841480336e+0001, +  -2.137192117037040574661406572497288723430e+0001, +}; +static double qs2[6] = { +   2.953336290605238495019307530224241335502e+0001, +   2.529815499821905343698811319455305266409e+0002, +   7.575028348686454070022561120722815892346e+0002, +   7.393932053204672479746835719678434981599e+0002, +   1.559490033366661142496448853793707126179e+0002, +  -4.959498988226281813825263003231704397158e+0000, +}; + +static double qone(x) +	double x; +{ +	double *p,*q, s,r,z; +	if (x >= 8.0)			   {p = qr8; q= qs8;} +	else if (x >= 4.54545211791992188) {p = qr5; q= qs5;} +	else if (x >= 2.85714149475097656) {p = qr3; q= qs3;} +	else /* if (x >= 2.0) */	   {p = qr2; q= qs2;} +	z = one/(x*x); +	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); +	s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); +	return (.375 + r/s)/x; +} diff --git a/lib/libm/common_source/jn.c b/lib/libm/common_source/jn.c new file mode 100644 index 000000000000..85a54012ecae --- /dev/null +++ b/lib/libm/common_source/jn.c @@ -0,0 +1,311 @@ +/*- + * Copyright (c) 1992, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)jn.c	8.2 (Berkeley) 11/30/93"; +#endif /* not lint */ + +/* + * 16 December 1992 + * Minor modifications by Peter McIlroy to adapt non-IEEE architecture. + */ + +/* + * ==================================================== + * Copyright (C) 1992 by Sun Microsystems, Inc. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice  + * is preserved. + * ==================================================== + * + * ******************* WARNING ******************** + * This is an alpha version of SunPro's FDLIBM (Freely + * Distributable Math Library) for IEEE double precision  + * arithmetic. FDLIBM is a basic math library written + * in C that runs on machines that conform to IEEE  + * Standard 754/854. This alpha version is distributed  + * for testing purpose. Those who use this software  + * should report any bugs to  + * + *		fdlibm-comments@sunpro.eng.sun.com + * + * -- K.C. Ng, Oct 12, 1992 + * ************************************************ + */ + +/* + * jn(int n, double x), yn(int n, double x) + * floating point Bessel's function of the 1st and 2nd kind + * of order n + *           + * Special cases: + *	y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal; + *	y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal. + * Note 2. About jn(n,x), yn(n,x) + *	For n=0, j0(x) is called, + *	for n=1, j1(x) is called, + *	for n<x, forward recursion us used starting + *	from values of j0(x) and j1(x). + *	for n>x, a continued fraction approximation to + *	j(n,x)/j(n-1,x) is evaluated and then backward + *	recursion is used starting from a supposed value + *	for j(n,x). The resulting value of j(0,x) is + *	compared with the actual value to correct the + *	supposed value of j(n,x). + * + *	yn(n,x) is similar in all respects, except + *	that forward recursion is used for all + *	values of n>1. + *	 + */ + +#include <math.h> +#include <float.h> +#include <errno.h> + +#if defined(vax) || defined(tahoe) +#define _IEEE	0 +#else +#define _IEEE	1 +#define infnan(x) (0.0) +#endif + +static double +invsqrtpi= 5.641895835477562869480794515607725858441e-0001, +two  = 2.0, +zero = 0.0, +one  = 1.0; + +double jn(n,x) +	int n; double x; +{ +	int i, sgn; +	double a, b, temp; +	double z, w; + +    /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) +     * Thus, J(-n,x) = J(n,-x) +     */ +    /* if J(n,NaN) is NaN */ +	if (_IEEE && isnan(x)) return x+x; +	if (n<0){		 +		n = -n; +		x = -x; +	} +	if (n==0) return(j0(x)); +	if (n==1) return(j1(x)); +	sgn = (n&1)&(x < zero);		/* even n -- 0, odd n -- sign(x) */ +	x = fabs(x); +	if (x == 0 || !finite (x)) 	/* if x is 0 or inf */ +	    b = zero; +	else if ((double) n <= x) { +			/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ +	    if (_IEEE && x >= 8.148143905337944345e+090) { +					/* x >= 2**302 */ +    /* (x >> n**2)  +     *	    Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) +     *	    Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) +     *	    Let s=sin(x), c=cos(x),  +     *		xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then +     * +     *		   n	sin(xn)*sqt2	cos(xn)*sqt2 +     *		---------------------------------- +     *		   0	 s-c		 c+s +     *		   1	-s-c 		-c+s +     *		   2	-s+c		-c-s +     *		   3	 s+c		 c-s +     */ +		switch(n&3) { +		    case 0: temp =  cos(x)+sin(x); break; +		    case 1: temp = -cos(x)+sin(x); break; +		    case 2: temp = -cos(x)-sin(x); break; +		    case 3: temp =  cos(x)-sin(x); break; +		} +		b = invsqrtpi*temp/sqrt(x); +	    } else {	 +	        a = j0(x); +	        b = j1(x); +	        for(i=1;i<n;i++){ +		    temp = b; +		    b = b*((double)(i+i)/x) - a; /* avoid underflow */ +		    a = temp; +	        } +	    } +	} else { +	    if (x < 1.86264514923095703125e-009) { /* x < 2**-29 */ +    /* x is tiny, return the first Taylor expansion of J(n,x)  +     * J(n,x) = 1/n!*(x/2)^n  - ... +     */ +		if (n > 33)	/* underflow */ +		    b = zero; +		else { +		    temp = x*0.5; b = temp; +		    for (a=one,i=2;i<=n;i++) { +			a *= (double)i;		/* a = n! */ +			b *= temp;		/* b = (x/2)^n */ +		    } +		    b = b/a; +		} +	    } else { +		/* use backward recurrence */ +		/* 			x      x^2      x^2        +		 *  J(n,x)/J(n-1,x) =  ----   ------   ------   ..... +		 *			2n  - 2(n+1) - 2(n+2) +		 * +		 * 			1      1        1        +		 *  (for large x)   =  ----  ------   ------   ..... +		 *			2n   2(n+1)   2(n+2) +		 *			-- - ------ - ------ -  +		 *			 x     x         x +		 * +		 * Let w = 2n/x and h=2/x, then the above quotient +		 * is equal to the continued fraction: +		 *		    1 +		 *	= ----------------------- +		 *		       1 +		 *	   w - ----------------- +		 *			  1 +		 * 	        w+h - --------- +		 *		       w+2h - ... +		 * +		 * To determine how many terms needed, let +		 * Q(0) = w, Q(1) = w(w+h) - 1, +		 * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), +		 * When Q(k) > 1e4	good for single  +		 * When Q(k) > 1e9	good for double  +		 * When Q(k) > 1e17	good for quadruple  +		 */ +	    /* determine k */ +		double t,v; +		double q0,q1,h,tmp; int k,m; +		w  = (n+n)/(double)x; h = 2.0/(double)x; +		q0 = w;  z = w+h; q1 = w*z - 1.0; k=1; +		while (q1<1.0e9) { +			k += 1; z += h; +			tmp = z*q1 - q0; +			q0 = q1; +			q1 = tmp; +		} +		m = n+n; +		for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t); +		a = t; +		b = one; +		/*  estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) +		 *  Hence, if n*(log(2n/x)) > ... +		 *  single 8.8722839355e+01 +		 *  double 7.09782712893383973096e+02 +		 *  long double 1.1356523406294143949491931077970765006170e+04 +		 *  then recurrent value may overflow and the result will +		 *  likely underflow to zero +		 */ +		tmp = n; +		v = two/x; +		tmp = tmp*log(fabs(v*tmp)); +	    	for (i=n-1;i>0;i--){ +		        temp = b; +		        b = ((i+i)/x)*b - a; +		        a = temp; +		    /* scale b to avoid spurious overflow */ +#			if defined(vax) || defined(tahoe) +#				define BMAX 1e13 +#			else +#				define BMAX 1e100 +#			endif /* defined(vax) || defined(tahoe) */ +			if (b > BMAX) { +				a /= b; +				t /= b; +				b = one; +			} +		} +	    	b = (t*j0(x)/b); +	    } +	} +	return ((sgn == 1) ? -b : b); +} +double yn(n,x)  +	int n; double x; +{ +	int i, sign; +	double a, b, temp; + +    /* Y(n,NaN), Y(n, x < 0) is NaN */ +	if (x <= 0 || (_IEEE && x != x)) +		if (_IEEE && x < 0) return zero/zero; +		else if (x < 0)     return (infnan(EDOM)); +		else if (_IEEE)     return -one/zero; +		else		    return(infnan(-ERANGE)); +	else if (!finite(x)) return(0); +	sign = 1; +	if (n<0){ +		n = -n; +		sign = 1 - ((n&1)<<2); +	} +	if (n == 0) return(y0(x)); +	if (n == 1) return(sign*y1(x)); +	if(_IEEE && x >= 8.148143905337944345e+090) { /* x > 2**302 */ +    /* (x >> n**2)  +     *	    Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) +     *	    Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) +     *	    Let s=sin(x), c=cos(x),  +     *		xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then +     * +     *		   n	sin(xn)*sqt2	cos(xn)*sqt2 +     *		---------------------------------- +     *		   0	 s-c		 c+s +     *		   1	-s-c 		-c+s +     *		   2	-s+c		-c-s +     *		   3	 s+c		 c-s +     */ +		switch (n&3) { +		    case 0: temp =  sin(x)-cos(x); break; +		    case 1: temp = -sin(x)-cos(x); break; +		    case 2: temp = -sin(x)+cos(x); break; +		    case 3: temp =  sin(x)+cos(x); break; +		} +		b = invsqrtpi*temp/sqrt(x); +	} else { +	    a = y0(x); +	    b = y1(x); +	/* quit if b is -inf */ +	    for (i = 1; i < n && !finite(b); i++){ +		temp = b; +		b = ((double)(i+i)/x)*b - a; +		a = temp; +	    } +	} +	if (!_IEEE && !finite(b)) +		return (infnan(-sign * ERANGE)); +	return ((sign > 0) ? b : -b); +} diff --git a/lib/libm/common_source/lgamma.3 b/lib/libm/common_source/lgamma.3 new file mode 100644 index 000000000000..92f68ab2a9eb --- /dev/null +++ b/lib/libm/common_source/lgamma.3 @@ -0,0 +1,123 @@ +.\" Copyright (c) 1985, 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)lgamma.3	8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt LGAMMA 3 +.Os BSD 4.3 +.Sh NAME +.Nm lgamma +.Nm gamma +.Nd log gamma function, gamma function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft extern int +.Fa signgam ; +.sp +.Ft double +.Fn lgamma "double x" +.Ft double +.Fn gamma "double x" +.Sh DESCRIPTION +.Fn Lgamma x +.if t \{\ +returns ln\||\(*G(x)| where +.Bd -unfilled -offset indent +\(*G(x) = \(is\d\s8\z0\s10\u\u\s8\(if\s10\d t\u\s8x\-1\s10\d e\u\s8\-t\s10\d dt	for x > 0 and +.br +\(*G(x) = \(*p/(\(*G(1\-x)\|sin(\(*px))	for x < 1. +.Ed +.\} +.if n \ +returns ln\||\(*G(x)|. +.Pp +The external integer +.Fa signgam +returns the sign of \(*G(x). +.Pp +.Fn Gamma x +returns \(*G(x), with no effect on +.Fa signgam . +.Sh IDIOSYNCRASIES +Do not use the expression +.Dq Li signgam\(**exp(lgamma(x)) +to compute g := \(*G(x). +Instead use a program like this (in C): +.Bd -literal -offset indent +lg = lgamma(x); g = signgam\(**exp(lg); +.Ed +.Pp +Only after +.Fn lgamma +has returned can signgam be correct. +.Pp +For arguments in its range, +.Fn gamma +is preferred, as for positive arguments +it is accurate to within one unit in the last place. +Exponentiation of +.Fn lgamma +will lose up to 10 significant bits. +.Sh RETURN VALUES +.Fn Gamma +and +.Fn lgamma +return appropriate values unless an argument is out of range. +Overflow will occur for sufficiently large positive values, and +non-positive integers. +On the +.Tn VAX, +the reserved operator is returned, +and +.Va errno +is set to +.Er ERANGE +For large non-integer negative values, +.Fn gamma +will underflow. +.Sh SEE ALSO +.Xr math 3 , +.Xr infnan 3 +.Sh HISTORY +The +.Nm lgamma +function appeared in  +.Bx 4.3 . +The +.Nm gamma +function appeared in +.Bx 4.4 . +The name +.Fn gamma +was originally dedicated to the +.Fn lgamma +function, so some old code may no longer be compatible. diff --git a/lib/libm/common_source/lgamma.c b/lib/libm/common_source/lgamma.c new file mode 100644 index 000000000000..b5cb49f07264 --- /dev/null +++ b/lib/libm/common_source/lgamma.c @@ -0,0 +1,307 @@ +/*- + * Copyright (c) 1992, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)lgamma.c	8.2 (Berkeley) 11/30/93"; +#endif /* not lint */ + +/* + * Coded by Peter McIlroy, Nov 1992; + * + * The financial support of UUNET Communications Services is greatfully + * acknowledged. + */ + +#include <math.h> +#include <errno.h> + +#include "mathimpl.h" + +/* Log gamma function. + * Error:  x > 0 error < 1.3ulp. + *	   x > 4, error < 1ulp. + *	   x > 9, error < .6ulp. + * 	   x < 0, all bets are off. (When G(x) ~ 1, log(G(x)) ~ 0) + * Method: + *	x > 6: + *		Use the asymptotic expansion (Stirling's Formula) + *	0 < x < 6: + *		Use gamma(x+1) = x*gamma(x) for argument reduction. + *		Use rational approximation in + *		the range 1.2, 2.5 + *		Two approximations are used, one centered at the + *		minimum to ensure monotonicity; one centered at 2 + *		to maintain small relative error. + *	x < 0: + *		Use the reflection formula, + *		G(1-x)G(x) = PI/sin(PI*x) + * Special values: + *	non-positive integer	returns +Inf. + *	NaN			returns NaN +*/ +static int endian; +#if defined(vax) || defined(tahoe) +#define _IEEE		0 +/* double and float have same size exponent field */ +#define TRUNC(x)	x = (double) (float) (x) +#else +#define _IEEE		1 +#define TRUNC(x)	*(((int *) &x) + endian) &= 0xf8000000 +#define infnan(x)	0.0 +#endif + +static double small_lgam(double); +static double large_lgam(double); +static double neg_lgam(double); +static double zero = 0.0, one = 1.0; +int signgam; + +#define UNDERFL (1e-1020 * 1e-1020) + +#define LEFT	(1.0 - (x0 + .25)) +#define RIGHT	(x0 - .218) +/* +/* Constants for approximation in [1.244,1.712] +*/ +#define x0	0.461632144968362356785 +#define x0_lo	-.000000000000000015522348162858676890521 +#define a0_hi	-0.12148629128932952880859 +#define a0_lo	.0000000007534799204229502 +#define r0	-2.771227512955130520e-002 +#define r1	-2.980729795228150847e-001 +#define r2	-3.257411333183093394e-001 +#define r3	-1.126814387531706041e-001 +#define r4	-1.129130057170225562e-002 +#define r5	-2.259650588213369095e-005 +#define s0	 1.714457160001714442e+000 +#define s1	 2.786469504618194648e+000 +#define s2	 1.564546365519179805e+000 +#define s3	 3.485846389981109850e-001 +#define s4	 2.467759345363656348e-002 +/* + * Constants for approximation in [1.71, 2.5] +*/ +#define a1_hi	4.227843350984671344505727574870e-01 +#define a1_lo	4.670126436531227189e-18 +#define p0	3.224670334241133695662995251041e-01 +#define p1	3.569659696950364669021382724168e-01 +#define p2	1.342918716072560025853732668111e-01 +#define p3	1.950702176409779831089963408886e-02 +#define p4	8.546740251667538090796227834289e-04 +#define q0	1.000000000000000444089209850062e+00 +#define q1	1.315850076960161985084596381057e+00 +#define q2	6.274644311862156431658377186977e-01 +#define q3	1.304706631926259297049597307705e-01 +#define q4	1.102815279606722369265536798366e-02 +#define q5	2.512690594856678929537585620579e-04 +#define q6	-1.003597548112371003358107325598e-06 +/* + * Stirling's Formula, adjusted for equal-ripple. x in [6,Inf]. +*/ +#define lns2pi	.418938533204672741780329736405 +#define pb0	 8.33333333333333148296162562474e-02 +#define pb1	-2.77777777774548123579378966497e-03 +#define pb2	 7.93650778754435631476282786423e-04 +#define pb3	-5.95235082566672847950717262222e-04 +#define pb4	 8.41428560346653702135821806252e-04 +#define pb5	-1.89773526463879200348872089421e-03 +#define pb6	 5.69394463439411649408050664078e-03 +#define pb7	-1.44705562421428915453880392761e-02 + +__pure double +lgamma(double x) +{ +	double r; + +	signgam = 1; +	endian = ((*(int *) &one)) ? 1 : 0; + +	if (!finite(x)) +		if (_IEEE) +			return (x+x); +		else return (infnan(EDOM)); + +	if (x > 6 + RIGHT) { +		r = large_lgam(x); +		return (r); +	} else if (x > 1e-16) +		return (small_lgam(x)); +	else if (x > -1e-16) { +		if (x < 0) +			signgam = -1, x = -x; +		return (-log(x)); +	} else +		return (neg_lgam(x)); +} + +static double +large_lgam(double x) +{ +	double z, p, x1; +	int i; +	struct Double t, u, v; +	u = __log__D(x); +	u.a -= 1.0; +	if (x > 1e15) { +		v.a = x - 0.5; +		TRUNC(v.a); +		v.b = (x - v.a) - 0.5; +		t.a = u.a*v.a; +		t.b = x*u.b + v.b*u.a; +		if (_IEEE == 0 && !finite(t.a)) +			return(infnan(ERANGE)); +		return(t.a + t.b); +	} +	x1 = 1./x; +	z = x1*x1; +	p = pb0+z*(pb1+z*(pb2+z*(pb3+z*(pb4+z*(pb5+z*(pb6+z*pb7)))))); +					/* error in approximation = 2.8e-19 */ + +	p = p*x1;			/* error < 2.3e-18 absolute */ +					/* 0 < p < 1/64 (at x = 5.5) */ +	v.a = x = x - 0.5; +	TRUNC(v.a);			/* truncate v.a to 26 bits. */ +	v.b = x - v.a; +	t.a = v.a*u.a;			/* t = (x-.5)*(log(x)-1) */ +	t.b = v.b*u.a + x*u.b; +	t.b += p; t.b += lns2pi;	/* return t + lns2pi + p */ +	return (t.a + t.b); +} + +static double +small_lgam(double x) +{ +	int x_int; +	double y, z, t, r = 0, p, q, hi, lo; +	struct Double rr; +	x_int = (x + .5); +	y = x - x_int; +	if (x_int <= 2 && y > RIGHT) { +		t = y - x0; +		y--; x_int++; +		goto CONTINUE; +	} else if (y < -LEFT) { +		t = y +(1.0-x0); +CONTINUE: +		z = t - x0_lo; +		p = r0+z*(r1+z*(r2+z*(r3+z*(r4+z*r5)))); +		q = s0+z*(s1+z*(s2+z*(s3+z*s4))); +		r = t*(z*(p/q) - x0_lo); +		t = .5*t*t; +		z = 1.0; +		switch (x_int) { +		case 6:	z  = (y + 5); +		case 5:	z *= (y + 4); +		case 4:	z *= (y + 3); +		case 3:	z *= (y + 2); +			rr = __log__D(z); +			rr.b += a0_lo; rr.a += a0_hi; +			return(((r+rr.b)+t+rr.a)); +		case 2: return(((r+a0_lo)+t)+a0_hi); +		case 0: r -= log1p(x); +		default: rr = __log__D(x); +			rr.a -= a0_hi; rr.b -= a0_lo; +			return(((r - rr.b) + t) - rr.a); +		} +	} else { +		p = p0+y*(p1+y*(p2+y*(p3+y*p4))); +		q = q0+y*(q1+y*(q2+y*(q3+y*(q4+y*(q5+y*q6))))); +		p = p*(y/q); +		t = (double)(float) y; +		z = y-t; +		hi = (double)(float) (p+a1_hi); +		lo = a1_hi - hi; lo += p; lo += a1_lo; +		r = lo*y + z*hi;	/* q + r = y*(a0+p/q) */ +		q = hi*t; +		z = 1.0; +		switch (x_int) { +		case 6:	z  = (y + 5); +		case 5:	z *= (y + 4); +		case 4:	z *= (y + 3); +		case 3:	z *= (y + 2); +			rr = __log__D(z); +			r += rr.b; r += q; +			return(rr.a + r); +		case 2:	return (q+ r); +		case 0: rr = __log__D(x); +			r -= rr.b; r -= log1p(x); +			r += q; r-= rr.a; +			return(r); +		default: rr = __log__D(x); +			r -= rr.b; +			q -= rr.a; +			return (r+q); +		} +	} +} + +static double +neg_lgam(double x) +{ +	int xi; +	double y, z, one = 1.0, zero = 0.0; +	extern double gamma(); + +	/* avoid destructive cancellation as much as possible */ +	if (x > -170) { +		xi = x; +		if (xi == x) +			if (_IEEE) +				return(one/zero); +			else +				return(infnan(ERANGE)); +		y = gamma(x); +		if (y < 0) +			y = -y, signgam = -1; +		return (log(y)); +	} +	z = floor(x + .5); +	if (z == x) {		/* convention: G(-(integer)) -> +Inf */ +		if (_IEEE) +			return (one/zero); +		else +			return (infnan(ERANGE)); +	} +	y = .5*ceil(x); +	if (y == ceil(y)) +		signgam = -1; +	x = -x; +	z = fabs(x + z);	/* 0 < z <= .5 */ +	if (z < .25) +		z = sin(M_PI*z); +	else +		z = cos(M_PI*(0.5-z)); +	z = log(M_PI/(z*x)); +	y = large_lgam(x); +	return (z - y); +} diff --git a/lib/libm/common_source/log.c b/lib/libm/common_source/log.c new file mode 100644 index 000000000000..ae186722f8df --- /dev/null +++ b/lib/libm/common_source/log.c @@ -0,0 +1,486 @@ +/* + * Copyright (c) 1992, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)log.c	8.2 (Berkeley) 11/30/93"; +#endif /* not lint */ + +#include <math.h> +#include <errno.h> + +#include "mathimpl.h" + +/* Table-driven natural logarithm. + * + * This code was derived, with minor modifications, from: + *	Peter Tang, "Table-Driven Implementation of the + *	Logarithm in IEEE Floating-Point arithmetic." ACM Trans. + *	Math Software, vol 16. no 4, pp 378-400, Dec 1990). + * + * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256, + * where F = j/128 for j an integer in [0, 128]. + * + * log(2^m) = log2_hi*m + log2_tail*m + * since m is an integer, the dominant term is exact. + * m has at most 10 digits (for subnormal numbers), + * and log2_hi has 11 trailing zero bits. + * + * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h + * logF_hi[] + 512 is exact. + * + * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ... + * the leading term is calculated to extra precision in two + * parts, the larger of which adds exactly to the dominant + * m and F terms. + * There are two cases: + *	1. when m, j are non-zero (m | j), use absolute + *	   precision for the leading term. + *	2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1). + *	   In this case, use a relative precision of 24 bits. + * (This is done differently in the original paper) + * + * Special cases: + *	0	return signalling -Inf + *	neg	return signalling NaN + *	+Inf	return +Inf +*/ + +#if defined(vax) || defined(tahoe) +#define _IEEE		0 +#define TRUNC(x)	x = (double) (float) (x) +#else +#define _IEEE		1 +#define endian		(((*(int *) &one)) ? 1 : 0) +#define TRUNC(x)	*(((int *) &x) + endian) &= 0xf8000000 +#define infnan(x)	0.0 +#endif + +#define N 128 + +/* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128. + * Used for generation of extend precision logarithms. + * The constant 35184372088832 is 2^45, so the divide is exact. + * It ensures correct reading of logF_head, even for inaccurate + * decimal-to-binary conversion routines.  (Everybody gets the + * right answer for integers less than 2^53.) + * Values for log(F) were generated using error < 10^-57 absolute + * with the bc -l package. +*/ +static double	A1 = 	  .08333333333333178827; +static double	A2 = 	  .01250000000377174923; +static double	A3 =	 .002232139987919447809; +static double	A4 =	.0004348877777076145742; + +static double logF_head[N+1] = { +	0., +	.007782140442060381246, +	.015504186535963526694, +	.023167059281547608406, +	.030771658666765233647, +	.038318864302141264488, +	.045809536031242714670, +	.053244514518837604555, +	.060624621816486978786, +	.067950661908525944454, +	.075223421237524235039, +	.082443669210988446138, +	.089612158689760690322, +	.096729626458454731618, +	.103796793681567578460, +	.110814366340264314203, +	.117783035656430001836, +	.124703478501032805070, +	.131576357788617315236, +	.138402322859292326029, +	.145182009844575077295, +	.151916042025732167530, +	.158605030176659056451, +	.165249572895390883786, +	.171850256926518341060, +	.178407657472689606947, +	.184922338493834104156, +	.191394852999565046047, +	.197825743329758552135, +	.204215541428766300668, +	.210564769107350002741, +	.216873938300523150246, +	.223143551314024080056, +	.229374101064877322642, +	.235566071312860003672, +	.241719936886966024758, +	.247836163904594286577, +	.253915209980732470285, +	.259957524436686071567, +	.265963548496984003577, +	.271933715484010463114, +	.277868451003087102435, +	.283768173130738432519, +	.289633292582948342896, +	.295464212893421063199, +	.301261330578199704177, +	.307025035294827830512, +	.312755710004239517729, +	.318453731118097493890, +	.324119468654316733591, +	.329753286372579168528, +	.335355541920762334484, +	.340926586970454081892, +	.346466767346100823488, +	.351976423156884266063, +	.357455888922231679316, +	.362905493689140712376, +	.368325561158599157352, +	.373716409793814818840, +	.379078352934811846353, +	.384411698910298582632, +	.389716751140440464951, +	.394993808240542421117, +	.400243164127459749579, +	.405465108107819105498, +	.410659924985338875558, +	.415827895143593195825, +	.420969294644237379543, +	.426084395310681429691, +	.431173464818130014464, +	.436236766774527495726, +	.441274560805140936281, +	.446287102628048160113, +	.451274644139630254358, +	.456237433481874177232, +	.461175715122408291790, +	.466089729924533457960, +	.470979715219073113985, +	.475845904869856894947, +	.480688529345570714212, +	.485507815781602403149, +	.490303988045525329653, +	.495077266798034543171, +	.499827869556611403822, +	.504556010751912253908, +	.509261901790523552335, +	.513945751101346104405, +	.518607764208354637958, +	.523248143765158602036, +	.527867089620485785417, +	.532464798869114019908, +	.537041465897345915436, +	.541597282432121573947, +	.546132437597407260909, +	.550647117952394182793, +	.555141507540611200965, +	.559615787935399566777, +	.564070138285387656651, +	.568504735352689749561, +	.572919753562018740922, +	.577315365035246941260, +	.581691739635061821900, +	.586049045003164792433, +	.590387446602107957005, +	.594707107746216934174, +	.599008189645246602594, +	.603290851438941899687, +	.607555250224322662688, +	.611801541106615331955, +	.616029877215623855590, +	.620240409751204424537, +	.624433288012369303032, +	.628608659422752680256, +	.632766669570628437213, +	.636907462236194987781, +	.641031179420679109171, +	.645137961373620782978, +	.649227946625615004450, +	.653301272011958644725, +	.657358072709030238911, +	.661398482245203922502, +	.665422632544505177065, +	.669430653942981734871, +	.673422675212350441142, +	.677398823590920073911, +	.681359224807238206267, +	.685304003098281100392, +	.689233281238557538017, +	.693147180560117703862 +}; + +static double logF_tail[N+1] = { +	0., +	-.00000000000000543229938420049, +	 .00000000000000172745674997061, +	-.00000000000001323017818229233, +	-.00000000000001154527628289872, +	-.00000000000000466529469958300, +	 .00000000000005148849572685810, +	-.00000000000002532168943117445, +	-.00000000000005213620639136504, +	-.00000000000001819506003016881, +	 .00000000000006329065958724544, +	 .00000000000008614512936087814, +	-.00000000000007355770219435028, +	 .00000000000009638067658552277, +	 .00000000000007598636597194141, +	 .00000000000002579999128306990, +	-.00000000000004654729747598444, +	-.00000000000007556920687451336, +	 .00000000000010195735223708472, +	-.00000000000017319034406422306, +	-.00000000000007718001336828098, +	 .00000000000010980754099855238, +	-.00000000000002047235780046195, +	-.00000000000008372091099235912, +	 .00000000000014088127937111135, +	 .00000000000012869017157588257, +	 .00000000000017788850778198106, +	 .00000000000006440856150696891, +	 .00000000000016132822667240822, +	-.00000000000007540916511956188, +	-.00000000000000036507188831790, +	 .00000000000009120937249914984, +	 .00000000000018567570959796010, +	-.00000000000003149265065191483, +	-.00000000000009309459495196889, +	 .00000000000017914338601329117, +	-.00000000000001302979717330866, +	 .00000000000023097385217586939, +	 .00000000000023999540484211737, +	 .00000000000015393776174455408, +	-.00000000000036870428315837678, +	 .00000000000036920375082080089, +	-.00000000000009383417223663699, +	 .00000000000009433398189512690, +	 .00000000000041481318704258568, +	-.00000000000003792316480209314, +	 .00000000000008403156304792424, +	-.00000000000034262934348285429, +	 .00000000000043712191957429145, +	-.00000000000010475750058776541, +	-.00000000000011118671389559323, +	 .00000000000037549577257259853, +	 .00000000000013912841212197565, +	 .00000000000010775743037572640, +	 .00000000000029391859187648000, +	-.00000000000042790509060060774, +	 .00000000000022774076114039555, +	 .00000000000010849569622967912, +	-.00000000000023073801945705758, +	 .00000000000015761203773969435, +	 .00000000000003345710269544082, +	-.00000000000041525158063436123, +	 .00000000000032655698896907146, +	-.00000000000044704265010452446, +	 .00000000000034527647952039772, +	-.00000000000007048962392109746, +	 .00000000000011776978751369214, +	-.00000000000010774341461609578, +	 .00000000000021863343293215910, +	 .00000000000024132639491333131, +	 .00000000000039057462209830700, +	-.00000000000026570679203560751, +	 .00000000000037135141919592021, +	-.00000000000017166921336082431, +	-.00000000000028658285157914353, +	-.00000000000023812542263446809, +	 .00000000000006576659768580062, +	-.00000000000028210143846181267, +	 .00000000000010701931762114254, +	 .00000000000018119346366441110, +	 .00000000000009840465278232627, +	-.00000000000033149150282752542, +	-.00000000000018302857356041668, +	-.00000000000016207400156744949, +	 .00000000000048303314949553201, +	-.00000000000071560553172382115, +	 .00000000000088821239518571855, +	-.00000000000030900580513238244, +	-.00000000000061076551972851496, +	 .00000000000035659969663347830, +	 .00000000000035782396591276383, +	-.00000000000046226087001544578, +	 .00000000000062279762917225156, +	 .00000000000072838947272065741, +	 .00000000000026809646615211673, +	-.00000000000010960825046059278, +	 .00000000000002311949383800537, +	-.00000000000058469058005299247, +	-.00000000000002103748251144494, +	-.00000000000023323182945587408, +	-.00000000000042333694288141916, +	-.00000000000043933937969737844, +	 .00000000000041341647073835565, +	 .00000000000006841763641591466, +	 .00000000000047585534004430641, +	 .00000000000083679678674757695, +	-.00000000000085763734646658640, +	 .00000000000021913281229340092, +	-.00000000000062242842536431148, +	-.00000000000010983594325438430, +	 .00000000000065310431377633651, +	-.00000000000047580199021710769, +	-.00000000000037854251265457040, +	 .00000000000040939233218678664, +	 .00000000000087424383914858291, +	 .00000000000025218188456842882, +	-.00000000000003608131360422557, +	-.00000000000050518555924280902, +	 .00000000000078699403323355317, +	-.00000000000067020876961949060, +	 .00000000000016108575753932458, +	 .00000000000058527188436251509, +	-.00000000000035246757297904791, +	-.00000000000018372084495629058, +	 .00000000000088606689813494916, +	 .00000000000066486268071468700, +	 .00000000000063831615170646519, +	 .00000000000025144230728376072, +	-.00000000000017239444525614834 +}; + +double +#ifdef _ANSI_SOURCE +log(double x) +#else +log(x) double x; +#endif +{ +	int m, j; +	double F, f, g, q, u, u2, v, zero = 0.0, one = 1.0; +	volatile double u1; + +	/* Catch special cases */ +	if (x <= 0) +		if (_IEEE && x == zero)	/* log(0) = -Inf */ +			return (-one/zero); +		else if (_IEEE)		/* log(neg) = NaN */ +			return (zero/zero); +		else if (x == zero)	/* NOT REACHED IF _IEEE */ +			return (infnan(-ERANGE)); +		else +			return (infnan(EDOM)); +	else if (!finite(x)) +		if (_IEEE)		/* x = NaN, Inf */ +			return (x+x); +		else +			return (infnan(ERANGE)); +	 +	/* Argument reduction: 1 <= g < 2; x/2^m = g;	*/ +	/* y = F*(1 + f/F) for |f| <= 2^-8		*/ + +	m = logb(x); +	g = ldexp(x, -m); +	if (_IEEE && m == -1022) { +		j = logb(g), m += j; +		g = ldexp(g, -j); +	} +	j = N*(g-1) + .5; +	F = (1.0/N) * j + 1;	/* F*128 is an integer in [128, 512] */ +	f = g - F; + +	/* Approximate expansion for log(1+f/F) ~= u + q */ +	g = 1/(2*F+f); +	u = 2*f*g; +	v = u*u; +	q = u*v*(A1 + v*(A2 + v*(A3 + v*A4))); + +    /* case 1: u1 = u rounded to 2^-43 absolute.  Since u < 2^-8, +     * 	       u1 has at most 35 bits, and F*u1 is exact, as F has < 8 bits. +     *         It also adds exactly to |m*log2_hi + log_F_head[j] | < 750 +    */ +	if (m | j) +		u1 = u + 513, u1 -= 513; + +    /* case 2:	|1-x| < 1/256. The m- and j- dependent terms are zero; +     * 		u1 = u to 24 bits. +    */ +	else +		u1 = u, TRUNC(u1); +	u2 = (2.0*(f - F*u1) - u1*f) * g; +			/* u1 + u2 = 2f/(2F+f) to extra precision.	*/ + +	/* log(x) = log(2^m*F*(1+f/F)) =				*/ +	/* (m*log2_hi+logF_head[j]+u1) + (m*log2_lo+logF_tail[j]+q);	*/ +	/* (exact) + (tiny)						*/ + +	u1 += m*logF_head[N] + logF_head[j];		/* exact */ +	u2 = (u2 + logF_tail[j]) + q;			/* tiny */ +	u2 += logF_tail[N]*m; +	return (u1 + u2); +} + +/* + * Extra precision variant, returning struct {double a, b;}; + * log(x) = a+b to 63 bits, with a is rounded to 26 bits. + */ +struct Double +#ifdef _ANSI_SOURCE +__log__D(double x) +#else +__log__D(x) double x; +#endif +{ +	int m, j; +	double F, f, g, q, u, v, u2, one = 1.0; +	volatile double u1; +	struct Double r; + +	/* Argument reduction: 1 <= g < 2; x/2^m = g;	*/ +	/* y = F*(1 + f/F) for |f| <= 2^-8		*/ + +	m = logb(x); +	g = ldexp(x, -m); +	if (_IEEE && m == -1022) { +		j = logb(g), m += j; +		g = ldexp(g, -j); +	} +	j = N*(g-1) + .5; +	F = (1.0/N) * j + 1; +	f = g - F; + +	g = 1/(2*F+f); +	u = 2*f*g; +	v = u*u; +	q = u*v*(A1 + v*(A2 + v*(A3 + v*A4))); +	if (m | j) +		u1 = u + 513, u1 -= 513; +	else +		u1 = u, TRUNC(u1); +	u2 = (2.0*(f - F*u1) - u1*f) * g; + +	u1 += m*logF_head[N] + logF_head[j]; + +	u2 +=  logF_tail[j]; u2 += q; +	u2 += logF_tail[N]*m; +	r.a = u1 + u2;			/* Only difference is here */ +	TRUNC(r.a); +	r.b = (u1 - r.a) + u2; +	return (r); +} diff --git a/lib/libm/common_source/log10.c b/lib/libm/common_source/log10.c new file mode 100644 index 000000000000..d2617ccebb9e --- /dev/null +++ b/lib/libm/common_source/log10.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)log10.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* LOG10(X) + * RETURN THE BASE 10 LOGARITHM OF x + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/20/85;  + * REVISED BY K.C. NG on 1/23/85, 3/7/85, 4/16/85. + *  + * Required kernel function: + *	log(x) + * + * Method : + *			     log(x) + *		log10(x) = ---------  or  [1/log(10)]*log(x) + *			    log(10) + * + *    Note: + *	  [log(10)]   rounded to 56 bits has error  .0895  ulps, + *	  [1/log(10)] rounded to 53 bits has error  .198   ulps; + *	  therefore, for better accuracy, in VAX D format, we divide  + *	  log(x) by log(10), but in IEEE Double format, we multiply  + *	  log(x) by [1/log(10)]. + * + * Special cases: + *	log10(x) is NaN with signal if x < 0;  + *	log10(+INF) is +INF with no signal; log10(0) is -INF with signal; + *	log10(NaN) is that NaN with no signal. + * + * Accuracy: + *	log10(X) returns the exact log10(x) nearly rounded. In a test run + *	with 1,536,000 random arguments on a VAX, the maximum observed + *	error was 1.74 ulps (units in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(ln10hi, 2.3025850929940456790E0 ,5d8d,4113,a8ac,ddaa, 2, .935D8DDDAAA8AC) + +ic(ivln10, 4.3429448190325181667E-1, -2, 1.BCB7B1526E50E) + +#ifdef vccast +#define	ln10hi	vccast(ln10hi) +#endif + + +double log10(x) +double x; +{ +#if defined(vax)||defined(tahoe) +	return(log(x)/ln10hi); +#else	/* defined(vax)||defined(tahoe) */ +	return(ivln10*log(x)); +#endif	/* defined(vax)||defined(tahoe) */ +} diff --git a/lib/libm/common_source/log1p.c b/lib/libm/common_source/log1p.c new file mode 100644 index 000000000000..cbf9fcd895e2 --- /dev/null +++ b/lib/libm/common_source/log1p.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)log1p.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* LOG1P(x)  + * RETURN THE LOGARITHM OF 1+x + * DOUBLE PRECISION (VAX D FORMAT 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/19/85;  + * REVISED BY K.C. NG on 2/6/85, 3/7/85, 3/24/85, 4/16/85. + *  + * Required system supported functions: + *	scalb(x,n)  + *	copysign(x,y) + *	logb(x)	 + *	finite(x) + * + * Required kernel function: + *	log__L(z) + * + * Method : + *	1. Argument Reduction: find k and f such that  + *			1+x  = 2^k * (1+f),  + *	   where  sqrt(2)/2 < 1+f < sqrt(2) . + * + *	2. Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) + *		 = 2s + 2/3 s**3 + 2/5 s**5 + ....., + *	   log(1+f) is computed by + * + *	     		log(1+f) = 2s + s*log__L(s*s) + *	   where + *		log__L(z) = z*(L1 + z*(L2 + z*(... (L6 + z*L7)...))) + * + *	   See log__L() for the values of the coefficients. + * + *	3. Finally,  log(1+x) = k*ln2 + log(1+f).   + * + *	Remarks 1. In step 3 n*ln2 will be stored in two floating point numbers + *		   n*ln2hi + n*ln2lo, where ln2hi is chosen such that the last  + *		   20 bits (for VAX D format), or the last 21 bits ( for IEEE  + *		   double) is 0. This ensures n*ln2hi is exactly representable. + *		2. In step 1, f may not be representable. A correction term c + *	 	   for f is computed. It follows that the correction term for + *		   f - t (the leading term of log(1+f) in step 2) is c-c*x. We + *		   add this correction term to n*ln2lo to attenuate the error. + * + * + * Special cases: + *	log1p(x) is NaN with signal if x < -1; log1p(NaN) is NaN with no signal; + *	log1p(INF) is +INF; log1p(-1) is -INF with signal; + *	only log1p(0)=0 is exact for finite argument. + * + * Accuracy: + *	log1p(x) returns the exact log(1+x) nearly rounded. In a test run  + *	with 1,536,000 random arguments on a VAX, the maximum observed + *	error was .846 ulps (units in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include <errno.h> +#include "mathimpl.h" + +vc(ln2hi, 6.9314718055829871446E-1  ,7217,4031,0000,f7d0,   0, .B17217F7D00000) +vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC) +vc(sqrt2, 1.4142135623730950622E0   ,04f3,40b5,de65,33f9,   1, .B504F333F9DE65) + +ic(ln2hi, 6.9314718036912381649E-1,   -1, 1.62E42FEE00000) +ic(ln2lo, 1.9082149292705877000E-10, -33, 1.A39EF35793C76) +ic(sqrt2, 1.4142135623730951455E0,     0, 1.6A09E667F3BCD) + +#ifdef vccast +#define	ln2hi	vccast(ln2hi) +#define	ln2lo	vccast(ln2lo) +#define	sqrt2	vccast(sqrt2) +#endif + +double log1p(x) +double x; +{ +	const static double zero=0.0, negone= -1.0, one=1.0,  +		      half=1.0/2.0, small=1.0E-20;   /* 1+small == 1 */ +	double z,s,t,c; +	int k; + +#if !defined(vax)&&!defined(tahoe) +	if(x!=x) return(x);	/* x is NaN */ +#endif	/* !defined(vax)&&!defined(tahoe) */ + +	if(finite(x)) { +	   if( x > negone ) { + +	   /* argument reduction */ +	      if(copysign(x,one)<small) return(x); +	      k=logb(one+x); z=scalb(x,-k); t=scalb(one,-k); +	      if(z+t >= sqrt2 )  +		  { k += 1 ; z *= half; t *= half; } +	      t += negone; x = z + t; +	      c = (t-x)+z ;		/* correction term for x */ + + 	   /* compute log(1+x)  */ +              s = x/(2+x); t = x*x*half; +	      c += (k*ln2lo-c*x); +	      z = c+s*(t+__log__L(s*s)); +	      x += (z - t) ; + +	      return(k*ln2hi+x); +	   } +	/* end of if (x > negone) */ + +	    else { +#if defined(vax)||defined(tahoe) +		if ( x == negone ) +		    return (infnan(-ERANGE));	/* -INF */ +		else +		    return (infnan(EDOM));	/* NaN */ +#else	/* defined(vax)||defined(tahoe) */ +		/* x = -1, return -INF with signal */ +		if ( x == negone ) return( negone/zero ); + +		/* negative argument for log, return NaN with signal */ +	        else return ( zero / zero ); +#endif	/* defined(vax)||defined(tahoe) */ +	    } +	} +    /* end of if (finite(x)) */ + +    /* log(-INF) is NaN */ +	else if(x<0)  +	     return(zero/zero); + +    /* log(+INF) is INF */ +	else return(x);       +} diff --git a/lib/libm/common_source/log__L.c b/lib/libm/common_source/log__L.c new file mode 100644 index 000000000000..c00158fa5172 --- /dev/null +++ b/lib/libm/common_source/log__L.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)log__L.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* log__L(Z) + *		LOG(1+X) - 2S			       X + * RETURN      ---------------  WHERE Z = S*S,  S = ------- , 0 <= Z <= .0294... + *		      S				     2 + X + *		      + * DOUBLE PRECISION (VAX D FORMAT 56 bits or IEEE DOUBLE 53 BITS) + * KERNEL FUNCTION FOR LOG; TO BE USED IN LOG1P, LOG, AND POW FUNCTIONS + * CODED IN C BY K.C. NG, 1/19/85;  + * REVISED BY K.C. Ng, 2/3/85, 4/16/85. + * + * Method : + *	1. Polynomial approximation: let s = x/(2+x).  + *	   Based on log(1+x) = log(1+s) - log(1-s) + *		 = 2s + 2/3 s**3 + 2/5 s**5 + ....., + * + *	   (log(1+x) - 2s)/s is computed by + * + *	       z*(L1 + z*(L2 + z*(... (L7 + z*L8)...))) + * + *	   where z=s*s. (See the listing below for Lk's values.) The  + *	   coefficients are obtained by a special Remez algorithm.  + * + * Accuracy: + *	Assuming no rounding error, the maximum magnitude of the approximation  + *	error (absolute) is 2**(-58.49) for IEEE double, and 2**(-63.63) + *	for VAX D format. + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(L1, 6.6666666666666703212E-1 ,aaaa,402a,aac5,aaaa,  0, .AAAAAAAAAAAAC5) +vc(L2, 3.9999999999970461961E-1 ,cccc,3fcc,2684,cccc, -1, .CCCCCCCCCC2684) +vc(L3, 2.8571428579395698188E-1 ,4924,3f92,5782,92f8, -1, .92492492F85782) +vc(L4, 2.2222221233634724402E-1 ,8e38,3f63,af2c,39b7, -2, .E38E3839B7AF2C) +vc(L5, 1.8181879517064680057E-1 ,2eb4,3f3a,655e,cc39, -2, .BA2EB4CC39655E) +vc(L6, 1.5382888777946145467E-1 ,8551,3f1d,781d,e8c5, -2, .9D8551E8C5781D) +vc(L7, 1.3338356561139403517E-1 ,95b3,3f08,cd92,907f, -2, .8895B3907FCD92) +vc(L8, 1.2500000000000000000E-1 ,0000,3f00,0000,0000, -2, .80000000000000) + +ic(L1, 6.6666666666667340202E-1, -1, 1.5555555555592) +ic(L2, 3.9999999999416702146E-1, -2, 1.999999997FF24) +ic(L3, 2.8571428742008753154E-1, -2, 1.24924941E07B4) +ic(L4, 2.2222198607186277597E-1, -3, 1.C71C52150BEA6) +ic(L5, 1.8183562745289935658E-1, -3, 1.74663CC94342F) +ic(L6, 1.5314087275331442206E-1, -3, 1.39A1EC014045B) +ic(L7, 1.4795612545334174692E-1, -3, 1.2F039F0085122) + +#ifdef vccast +#define	L1	vccast(L1) +#define	L2	vccast(L2) +#define	L3	vccast(L3) +#define	L4	vccast(L4) +#define	L5	vccast(L5) +#define	L6	vccast(L6) +#define	L7	vccast(L7) +#define	L8	vccast(L8) +#endif + +double __log__L(z) +double z; +{ +#if defined(vax)||defined(tahoe) +    return(z*(L1+z*(L2+z*(L3+z*(L4+z*(L5+z*(L6+z*(L7+z*L8)))))))); +#else	/* defined(vax)||defined(tahoe) */ +    return(z*(L1+z*(L2+z*(L3+z*(L4+z*(L5+z*(L6+z*L7))))))); +#endif	/* defined(vax)||defined(tahoe) */ +} diff --git a/lib/libm/common_source/math.3 b/lib/libm/common_source/math.3 new file mode 100644 index 000000000000..e44eab1f2a76 --- /dev/null +++ b/lib/libm/common_source/math.3 @@ -0,0 +1,632 @@ +.\" Copyright (c) 1985, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"	@(#)math.3	8.1 (Berkeley) 6/4/93 +.\" +.TH MATH 3 "June 4, 1993" +.UC 4 +.ds up \fIulp\fR +.ds nn \fINaN\fR +.de If +.if n \\ +\\$1Infinity\\$2 +.if t \\ +\\$1\\(if\\$2 +.. +.SH NAME +math \- introduction to mathematical library functions +.SH DESCRIPTION +These functions constitute the C math library, +.I libm. +The link editor searches this library under the \*(lq\-lm\*(rq option. +Declarations for these functions may be obtained from the include file +.RI < math.h >. +The Fortran math library is described in ``man 3f intro''. +.SH "LIST OF FUNCTIONS" +.sp 2 +.nf +.ta \w'copysign'u+2n +\w'infnan.3m'u+10n +\w'inverse trigonometric func'u +\fIName\fP	\fIAppears on Page\fP	\fIDescription\fP	\fIError Bound (ULPs)\fP +.ta \w'copysign'u+4n +\w'infnan.3m'u+4n +\w'inverse trigonometric function'u+6nC +.sp 5p +acos	sin.3m	inverse trigonometric function	3 +acosh	asinh.3m	inverse hyperbolic function	3 +asin	sin.3m	inverse trigonometric function	3 +asinh	asinh.3m	inverse hyperbolic function	3 +atan	sin.3m	inverse trigonometric function	1 +atanh	asinh.3m	inverse hyperbolic function	3 +atan2	sin.3m	inverse trigonometric function	2 +cabs	hypot.3m	complex absolute value	1 +cbrt	sqrt.3m	cube root	1 +ceil	floor.3m	integer no less than	0 +copysign	ieee.3m	copy sign bit	0 +cos	sin.3m	trigonometric function	1 +cosh	sinh.3m	hyperbolic function	3 +drem	ieee.3m	remainder	0 +erf	erf.3m	error function	??? +erfc	erf.3m	complementary error function	??? +exp	exp.3m	exponential	1 +expm1	exp.3m	exp(x)\-1	1 +fabs	floor.3m	absolute value	0 +floor	floor.3m	integer no greater than	0 +hypot	hypot.3m	Euclidean distance	1 +infnan	infnan.3m	signals exceptions +j0	j0.3m	bessel function	??? +j1	j0.3m	bessel function	??? +jn	j0.3m	bessel function	??? +lgamma	lgamma.3m	log gamma function; (formerly gamma.3m) +log	exp.3m	natural logarithm	1 +logb	ieee.3m	exponent extraction	0 +log10	exp.3m	logarithm to base 10	3 +log1p	exp.3m	log(1+x)	1 +pow	exp.3m	exponential x**y	60\-500 +rint	floor.3m	round to nearest integer	0 +scalb	ieee.3m	exponent adjustment	0 +sin	sin.3m	trigonometric function	1 +sinh	sinh.3m	hyperbolic function	3 +sqrt	sqrt.3m	square root	1 +tan	sin.3m	trigonometric function	3 +tanh	sinh.3m	hyperbolic function	3 +y0	j0.3m	bessel function	??? +y1	j0.3m	bessel function	??? +yn	j0.3m	bessel function	??? +.ta +.fi +.SH NOTES +In 4.3 BSD, distributed from the University of California +in late 1985, most of the foregoing functions come in two +versions, one for the double\-precision "D" format in the +DEC VAX\-11 family of computers, another for double\-precision +arithmetic conforming to the IEEE Standard 754 for Binary +Floating\-Point Arithmetic.  The two versions behave very +similarly, as should be expected from programs more accurate +and robust than was the norm when UNIX was born.  For +instance, the programs are accurate to within the numbers +of \*(ups tabulated above; an \*(up is one \fIU\fRnit in the \fIL\fRast +\fIP\fRlace.  And the programs have been cured of anomalies that +afflicted the older math library \fIlibm\fR in which incidents like +the following had been reported: +.RS +sqrt(\-1.0) = 0.0 and log(\-1.0) = \-1.7e38. +.br +cos(1.0e\-11) > cos(0.0) > 1.0. +.br +pow(x,1.0) +.if n \ +!= +.if t \ +\(!= +x when x = 2.0, 3.0, 4.0, ..., 9.0. +.br +pow(\-1.0,1.0e10) trapped on Integer Overflow. +.br +sqrt(1.0e30) and sqrt(1.0e\-30) were very slow. +.RE +However the two versions do differ in ways that have to be +explained, to which end the following notes are provided. +.PP +\fBDEC VAX\-11 D_floating\-point:\fR +.PP +This is the format for which the original math library \fIlibm\fR +was developed, and to which this manual is still principally +dedicated.  It is \fIthe\fR double\-precision format for the PDP\-11 +and the earlier VAX\-11 machines; VAX\-11s after 1983 were +provided with an optional "G" format closer to the IEEE +double\-precision format.  The earlier DEC MicroVAXs have no +D format, only G double\-precision. (Why?  Why not?) +.PP +Properties of D_floating\-point: +.RS +Wordsize: 64 bits, 8 bytes.  Radix: Binary. +.br +Precision: 56 +.if n \ +sig. +.if t \ +significant +bits, roughly like 17 +.if n \ +sig. +.if t \ +significant +decimals. +.RS +If x and x' are consecutive positive D_floating\-point +numbers (they differ by 1 \*(up), then +.br +1.3e\-17 < 0.5**56 < (x'\-x)/x \(<= 0.5**55 < 2.8e\-17. +.RE +.nf +.ta \w'Range:'u+1n +\w'Underflow threshold'u+1n +\w'= 2.0**127'u+1n +Range:	Overflow threshold	= 2.0**127	= 1.7e38. +	Underflow threshold	= 0.5**128	= 2.9e\-39. +	NOTE:  THIS RANGE IS COMPARATIVELY NARROW. +.ta +.fi +.RS +Overflow customarily stops computation. +.br +Underflow is customarily flushed quietly to zero. +.br +CAUTION: +.RS +It is possible to have x +.if n \ +!= +.if t \ +\(!= +y and yet +x\-y = 0 because of underflow.  Similarly +x > y > 0 cannot prevent either x\(**y = 0 +or  y/x = 0 from happening without warning. +.RE +.RE +Zero is represented ambiguously. +.RS +Although 2**55 different representations of zero are accepted by +the hardware, only the obvious representation is ever produced. +There is no \-0 on a VAX. +.RE +.If +is not part of the VAX architecture. +.br +Reserved operands: +.RS +of the 2**55 that the hardware +recognizes, only one of them is ever produced. +Any floating\-point operation upon a reserved +operand, even a MOVF or MOVD, customarily stops +computation, so they are not much used. +.RE +Exceptions: +.RS +Divisions by zero and operations that +overflow are invalid operations that customarily +stop computation or, in earlier machines, produce +reserved operands that will stop computation. +.RE +Rounding: +.RS +Every rational operation  (+, \-, \(**, /) on a +VAX (but not necessarily on a PDP\-11), if not an +over/underflow nor division by zero, is rounded to +within half an \*(up, and when the rounding error is +exactly half an \*(up then rounding is away from 0. +.RE +.RE +.PP +Except for its narrow range, D_floating\-point is one of the +better computer arithmetics designed in the 1960's. +Its properties are reflected fairly faithfully in the elementary +functions for a VAX distributed in 4.3 BSD. +They over/underflow only if their results have to lie out of range +or very nearly so, and then they behave much as any rational +arithmetic operation that over/underflowed would behave. +Similarly, expressions like log(0) and atanh(1) behave +like 1/0; and sqrt(\-3) and acos(3) behave like 0/0; +they all produce reserved operands and/or stop computation! +The situation is described in more detail in manual pages. +.RS +.ll -0.5i +\fIThis response seems excessively punitive, so it is destined +to be replaced at some time in the foreseeable future by a +more flexible but still uniform scheme being developed to +handle all floating\-point arithmetic exceptions neatly. +See infnan(3M) for the present state of affairs.\fR +.ll +0.5i +.RE +.PP +How do the functions in 4.3 BSD's new \fIlibm\fR for UNIX +compare with their counterparts in DEC's VAX/VMS library? +Some of the VMS functions are a little faster, some are +a little more accurate, some are more puritanical about +exceptions (like pow(0.0,0.0) and atan2(0.0,0.0)), +and most occupy much more memory than their counterparts in +\fIlibm\fR. +The VMS codes interpolate in large table to achieve +speed and accuracy; the \fIlibm\fR codes use tricky formulas +compact enough that all of them may some day fit into a ROM. +.PP +More important, DEC regards the VMS codes as proprietary +and guards them zealously against unauthorized use.  But the +\fIlibm\fR codes in 4.3 BSD are intended for the public domain; +they may be copied freely provided their provenance is always +acknowledged, and provided users assist the authors in their +researches by reporting experience with the codes. +Therefore no user of UNIX on a machine whose arithmetic resembles +VAX D_floating\-point need use anything worse than the new \fIlibm\fR. +.PP +\fBIEEE STANDARD 754 Floating\-Point Arithmetic:\fR +.PP +This standard is on its way to becoming more widely adopted +than any other design for computer arithmetic. +VLSI chips that conform to some version of that standard have been +produced by a host of manufacturers, among them ... +.nf +.ta 0.5i +\w'Intel i8070, i80287'u+6n +	Intel i8087, i80287	National Semiconductor  32081 +	Motorola 68881	Weitek WTL-1032, ... , -1165 +	Zilog Z8070	Western Electric (AT&T) WE32106. +.ta +.fi +Other implementations range from software, done thoroughly +in the Apple Macintosh, through VLSI in the Hewlett\-Packard +9000 series, to the ELXSI 6400 running ECL at 3 Megaflops. +Several other companies have adopted the formats +of IEEE 754 without, alas, adhering to the standard's way +of handling rounding and exceptions like over/underflow. +The DEC VAX G_floating\-point format is very similar to the IEEE +754 Double format, so similar that the C programs for the +IEEE versions of most of the elementary functions listed +above could easily be converted to run on a MicroVAX, though +nobody has volunteered to do that yet. +.PP +The codes in 4.3 BSD's \fIlibm\fR for machines that conform to +IEEE 754 are intended primarily for the National Semi. 32081 +and WTL 1164/65.  To use these codes with the Intel or Zilog +chips, or with the Apple Macintosh or ELXSI 6400, is to +forego the use of better codes provided (perhaps freely) by +those companies and designed by some of the authors of the +codes above. +Except for \fIatan\fR, \fIcabs\fR, \fIcbrt\fR, \fIerf\fR, +\fIerfc\fR, \fIhypot\fR, \fIj0\-jn\fR, \fIlgamma\fR, \fIpow\fR +and \fIy0\-yn\fR, +the Motorola 68881 has all the functions in \fIlibm\fR on chip, +and faster and more accurate; +it, Apple, the i8087, Z8070 and WE32106 all use 64 +.if n \ +sig. +.if t \ +significant +bits. +The main virtue of 4.3 BSD's +\fIlibm\fR codes is that they are intended for the public domain; +they may be copied freely provided their provenance is always +acknowledged, and provided users assist the authors in their +researches by reporting experience with the codes. +Therefore no user of UNIX on a machine that conforms to +IEEE 754 need use anything worse than the new \fIlibm\fR. +.PP +Properties of IEEE 754 Double\-Precision: +.RS +Wordsize: 64 bits, 8 bytes.  Radix: Binary. +.br +Precision: 53 +.if n \ +sig. +.if t \ +significant +bits, roughly like 16 +.if n \ +sig. +.if t \ +significant +decimals. +.RS +If x and x' are consecutive positive Double\-Precision +numbers (they differ by 1 \*(up), then +.br +1.1e\-16 < 0.5**53 < (x'\-x)/x \(<= 0.5**52 < 2.3e\-16. +.RE +.nf +.ta \w'Range:'u+1n +\w'Underflow threshold'u+1n +\w'= 2.0**1024'u+1n +Range:	Overflow threshold	= 2.0**1024	= 1.8e308 +	Underflow threshold	= 0.5**1022	= 2.2e\-308 +.ta +.fi +.RS +Overflow goes by default to a signed +.If "" . +.br +Underflow is \fIGradual,\fR rounding to the nearest +integer multiple of 0.5**1074 = 4.9e\-324. +.RE +Zero is represented ambiguously as +0 or \-0. +.RS +Its sign transforms correctly through multiplication or +division, and is preserved by addition of zeros +with like signs; but x\-x yields +0 for every +finite x.  The only operations that reveal zero's +sign are division by zero and copysign(x,\(+-0). +In particular, comparison (x > y, x \(>= y, etc.) +cannot be affected by the sign of zero; but if +finite x = y then +.If +\&= 1/(x\-y) +.if n \ +!= +.if t \ +\(!= +\-1/(y\-x) = +.If \- . +.RE +.If +is signed. +.RS +it persists when added to itself +or to any finite number.  Its sign transforms +correctly through multiplication and division, and +.If (finite)/\(+- \0=\0\(+-0 +(nonzero)/0 = +.If \(+- . +But  +.if n \ +Infinity\-Infinity, Infinity\(**0 and Infinity/Infinity +.if t \ +\(if\-\(if, \(if\(**0 and \(if/\(if +are, like 0/0 and sqrt(\-3), +invalid operations that produce \*(nn. ... +.RE +Reserved operands: +.RS +there are 2**53\-2 of them, all +called \*(nn (\fIN\fRot \fIa N\fRumber). +Some, called Signaling \*(nns, trap any floating\-point operation +performed upon them; they are used to mark missing +or uninitialized values, or nonexistent elements +of arrays.  The rest are Quiet \*(nns; they are +the default results of Invalid Operations, and +propagate through subsequent arithmetic operations. +If x +.if n \ +!= +.if t \ +\(!= +x then x is \*(nn; every other predicate +(x > y, x = y, x < y, ...) is FALSE if \*(nn is involved. +.br +NOTE: Trichotomy is violated by \*(nn. +.RS +Besides being FALSE, predicates that entail ordered +comparison, rather than mere (in)equality, +signal Invalid Operation when \*(nn is involved. +.RE +.RE +Rounding: +.RS +Every algebraic operation (+, \-, \(**, /, +.if n \ +sqrt) +.if t \ +\(sr) +is rounded by default to within half an \*(up, and +when the rounding error is exactly half an \*(up then +the rounded value's least significant bit is zero. +This kind of rounding is usually the best kind, +sometimes provably so; for instance, for every +x = 1.0, 2.0, 3.0, 4.0, ..., 2.0**52, we find +(x/3.0)\(**3.0 == x and (x/10.0)\(**10.0 == x and ... +despite that both the quotients and the products +have been rounded.  Only rounding like IEEE 754 +can do that.  But no single kind of rounding can be +proved best for every circumstance, so IEEE 754 +provides rounding towards zero or towards +.If + +or towards +.If \- +at the programmer's option.  And the +same kinds of rounding are specified for +Binary\-Decimal Conversions, at least for magnitudes +between roughly 1.0e\-10 and 1.0e37. +.RE +Exceptions: +.RS +IEEE 754 recognizes five kinds of floating\-point exceptions, +listed below in declining order of probable importance. +.RS +.nf +.ta \w'Invalid Operation'u+6n +\w'Gradual Underflow'u+2n +Exception	Default Result +.tc \(ru +		 +.tc +Invalid Operation	\*(nn, or FALSE +.if n \{\ +Overflow	\(+-Infinity +Divide by Zero	\(+-Infinity \} +.if t \{\ +Overflow	\(+-\(if +Divide by Zero	\(+-\(if \} +Underflow	Gradual Underflow +Inexact	Rounded value +.ta +.fi +.RE +NOTE:  An Exception is not an Error unless handled +badly.  What makes a class of exceptions exceptional +is that no single default response can be satisfactory +in every instance.  On the other hand, if a default +response will serve most instances satisfactorily, +the unsatisfactory instances cannot justify aborting +computation every time the exception occurs. +.RE +.PP +For each kind of floating\-point exception, IEEE 754 +provides a Flag that is raised each time its exception +is signaled, and stays raised until the program resets +it.  Programs may also test, save and restore a flag. +Thus, IEEE 754 provides three ways by which programs +may cope with exceptions for which the default result +might be unsatisfactory: +.IP 1) \w'\0\0\0\0'u +Test for a condition that might cause an exception +later, and branch to avoid the exception. +.IP 2) \w'\0\0\0\0'u +Test a flag to see whether an exception has occurred +since the program last reset its flag. +.IP 3) \w'\0\0\0\0'u +Test a result to see whether it is a value that only +an exception could have produced. +.RS +CAUTION: The only reliable ways to discover +whether Underflow has occurred are to test whether +products or quotients lie closer to zero than the +underflow threshold, or to test the Underflow +flag.  (Sums and differences cannot underflow in +IEEE 754; if x +.if n \ +!= +.if t \ +\(!= +y then x\-y is correct to +full precision and certainly nonzero regardless of +how tiny it may be.)  Products and quotients that +underflow gradually can lose accuracy gradually +without vanishing, so comparing them with zero +(as one might on a VAX) will not reveal the loss. +Fortunately, if a gradually underflowed value is +destined to be added to something bigger than the +underflow threshold, as is almost always the case, +digits lost to gradual underflow will not be missed +because they would have been rounded off anyway. +So gradual underflows are usually \fIprovably\fR ignorable. +The same cannot be said of underflows flushed to 0. +.RE +.PP +At the option of an implementor conforming to IEEE 754, +other ways to cope with exceptions may be provided: +.IP 4) \w'\0\0\0\0'u +ABORT.  This mechanism classifies an exception in +advance as an incident to be handled by means +traditionally associated with error\-handling +statements like "ON ERROR GO TO ...".  Different +languages offer different forms of this statement, +but most share the following characteristics: +.IP \(em \w'\0\0\0\0'u +No means is provided to substitute a value for +the offending operation's result and resume +computation from what may be the middle of an +expression.  An exceptional result is abandoned. +.IP \(em \w'\0\0\0\0'u +In a subprogram that lacks an error\-handling +statement, an exception causes the subprogram to +abort within whatever program called it, and so +on back up the chain of calling subprograms until +an error\-handling statement is encountered or the +whole task is aborted and memory is dumped. +.IP 5) \w'\0\0\0\0'u +STOP.  This mechanism, requiring an interactive +debugging environment, is more for the programmer +than the program.  It classifies an exception in +advance as a symptom of a programmer's error; the +exception suspends execution as near as it can to +the offending operation so that the programmer can +look around to see how it happened.  Quite often +the first several exceptions turn out to be quite +unexceptionable, so the programmer ought ideally +to be able to resume execution after each one as if +execution had not been stopped. +.IP 6) \w'\0\0\0\0'u +\&... Other ways lie beyond the scope of this document. +.RE +.PP +The crucial problem for exception handling is the problem of +Scope, and the problem's solution is understood, but not +enough manpower was available to implement it fully in time +to be distributed in 4.3 BSD's \fIlibm\fR.  Ideally, each +elementary function should act as if it were indivisible, or +atomic, in the sense that ... +.IP i) \w'iii)'u+2n +No exception should be signaled that is not deserved by +the data supplied to that function. +.IP ii) \w'iii)'u+2n +Any exception signaled should be identified with that +function rather than with one of its subroutines. +.IP iii) \w'iii)'u+2n +The internal behavior of an atomic function should not +be disrupted when a calling program changes from +one to another of the five or so ways of handling +exceptions listed above, although the definition +of the function may be correlated intentionally +with exception handling. +.PP +Ideally, every programmer should be able \fIconveniently\fR to +turn a debugged subprogram into one that appears atomic to +its users.  But simulating all three characteristics of an +atomic function is still a tedious affair, entailing hosts +of tests and saves\-restores; work is under way to ameliorate +the inconvenience. +.PP +Meanwhile, the functions in \fIlibm\fR are only approximately +atomic.  They signal no inappropriate exception except +possibly ... +.RS +Over/Underflow +.RS +when a result, if properly computed, might have lain barely within range, and +.RE +Inexact in \fIcabs\fR, \fIcbrt\fR, \fIhypot\fR, \fIlog10\fR and \fIpow\fR +.RS +when it happens to be exact, thanks to fortuitous cancellation of errors. +.RE +.RE +Otherwise, ... +.RS +Invalid Operation is signaled only when +.RS +any result but \*(nn would probably be misleading. +.RE +Overflow is signaled only when +.RS +the exact result would be finite but beyond the overflow threshold. +.RE +Divide\-by\-Zero is signaled only when +.RS +a function takes exactly infinite values at finite operands. +.RE +Underflow is signaled only when +.RS +the exact result would be nonzero but tinier than the underflow threshold. +.RE +Inexact is signaled only when +.RS +greater range or precision would be needed to represent the exact result. +.RE +.RE +.SH BUGS +When signals are appropriate, they are emitted by certain +operations within the codes, so a subroutine\-trace may be +needed to identify the function with its signal in case +method 5) above is in use.  And the codes all take the +IEEE 754 defaults for granted; this means that a decision to +trap all divisions by zero could disrupt a code that would +otherwise get correct results despite division by zero. +.SH SEE ALSO +An explanation of IEEE 754 and its proposed extension p854 +was published in the IEEE magazine MICRO in August 1984 under +the title "A Proposed Radix\- and Word\-length\-independent +Standard for Floating\-point Arithmetic" by W. J. Cody et al. +The manuals for Pascal, C and BASIC on the Apple Macintosh +document the features of IEEE 754 pretty well. +Articles in the IEEE magazine COMPUTER vol. 14 no. 3 (Mar. +1981), and in the ACM SIGNUM Newsletter Special Issue of +Oct. 1979, may be helpful although they pertain to +superseded drafts of the standard. diff --git a/lib/libm/common_source/mathimpl.h b/lib/libm/common_source/mathimpl.h new file mode 100644 index 000000000000..6a2a37d9f811 --- /dev/null +++ b/lib/libm/common_source/mathimpl.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 1988, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + *	@(#)mathimpl.h	8.1 (Berkeley) 6/4/93 + */ + +#include <sys/cdefs.h> +#include <math.h> + +#if defined(vax)||defined(tahoe) + +/* Deal with different ways to concatenate in cpp */ +#  ifdef __STDC__ +#    define	cat3(a,b,c) a ## b ## c +#  else +#    define	cat3(a,b,c) a/**/b/**/c +#  endif + +/* Deal with vax/tahoe byte order issues */ +#  ifdef vax +#    define	cat3t(a,b,c) cat3(a,b,c) +#  else +#    define	cat3t(a,b,c) cat3(a,c,b) +#  endif + +#  define vccast(name) (*(const double *)(cat3(name,,x))) + +   /* +    * Define a constant to high precision on a Vax or Tahoe. +    * +    * Args are the name to define, the decimal floating point value, +    * four 16-bit chunks of the float value in hex +    * (because the vax and tahoe differ in float format!), the power +    * of 2 of the hex-float exponent, and the hex-float mantissa. +    * Most of these arguments are not used at compile time; they are +    * used in a post-check to make sure the constants were compiled +    * correctly. +    * +    * People who want to use the constant will have to do their own +    *     #define foo vccast(foo) +    * since CPP cannot do this for them from inside another macro (sigh). +    * We define "vccast" if this needs doing. +    */ +#  define vc(name, value, x1,x2,x3,x4, bexp, xval) \ +	const static long cat3(name,,x)[] = {cat3t(0x,x1,x2), cat3t(0x,x3,x4)}; + +#  define ic(name, value, bexp, xval) ; + +#else	/* vax or tahoe */ + +   /* Hooray, we have an IEEE machine */ +#  undef vccast +#  define vc(name, value, x1,x2,x3,x4, bexp, xval) ; + +#  define ic(name, value, bexp, xval) \ +	const static double name = value; + +#endif	/* defined(vax)||defined(tahoe) */ + + +/* + * Functions internal to the math package, yet not static. + */ +extern double	__exp__E(); +extern double	__log__L(); + +struct Double {double a, b;}; +double __exp__D __P((double, double)); +struct Double __log__D __P((double)); diff --git a/lib/libm/common_source/pow.c b/lib/libm/common_source/pow.c new file mode 100644 index 000000000000..5121f3046421 --- /dev/null +++ b/lib/libm/common_source/pow.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)pow.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* POW(X,Y)   + * RETURN X**Y  + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/8/85;  + * REVISED BY K.C. NG on 7/10/85. + * KERNEL pow_P() REPLACED BY P. McILROY 7/22/92. + * Required system supported functions: + *      scalb(x,n)       + *      logb(x)          + *	copysign(x,y)	 + *	finite(x)	 + *	drem(x,y) + * + * Required kernel functions: + *	exp__D(a,c)			exp(a + c) for |a| << |c| + *	struct d_double dlog(x)		r.a + r.b, |r.b| < |r.a| + * + * Method + *	1. Compute and return log(x) in three pieces: + *		log(x) = n*ln2 + hi + lo, + *	   where n is an integer. + *	2. Perform y*log(x) by simulating muti-precision arithmetic and  + *	   return the answer in three pieces: + *		y*log(x) = m*ln2 + hi + lo, + *	   where m is an integer. + *	3. Return x**y = exp(y*log(x)) + *		= 2^m * ( exp(hi+lo) ). + * + * Special cases: + *	(anything) ** 0  is 1 ; + *	(anything) ** 1  is itself; + *	(anything) ** NaN is NaN; + *	NaN ** (anything except 0) is NaN; + *	+(anything > 1) ** +INF is +INF; + *	-(anything > 1) ** +INF is NaN; + *	+-(anything > 1) ** -INF is +0; + *	+-(anything < 1) ** +INF is +0; + *	+(anything < 1) ** -INF is +INF; + *	-(anything < 1) ** -INF is NaN; + *	+-1 ** +-INF is NaN and signal INVALID; + *	+0 ** +(anything except 0, NaN)  is +0; + *	-0 ** +(anything except 0, NaN, odd integer)  is +0; + *	+0 ** -(anything except 0, NaN)  is +INF and signal DIV-BY-ZERO; + *	-0 ** -(anything except 0, NaN, odd integer)  is +INF with signal; + *	-0 ** (odd integer) = -( +0 ** (odd integer) ); + *	+INF ** +(anything except 0,NaN) is +INF; + *	+INF ** -(anything except 0,NaN) is +0; + *	-INF ** (odd integer) = -( +INF ** (odd integer) ); + *	-INF ** (even integer) = ( +INF ** (even integer) ); + *	-INF ** -(anything except integer,NaN) is NaN with signal; + *	-(x=anything) ** (k=integer) is (-1)**k * (x ** k); + *	-(anything except 0) ** (non-integer) is NaN with signal; + * + * Accuracy: + *	pow(x,y) returns x**y nearly rounded. In particular, on a SUN, a VAX, + *	and a Zilog Z8000, + *			pow(integer,integer) + *	always returns the correct integer provided it is representable. + *	In a test run with 100,000 random arguments with 0 < x, y < 20.0 + *	on a VAX, the maximum observed error was 1.79 ulps (units in the  + *	last place). + * + * Constants : + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include <errno.h> +#include <math.h> + +#include "mathimpl.h" + +#if (defined(vax) || defined(tahoe)) +#define TRUNC(x)	x = (double) (float) x +#define _IEEE		0 +#else +#define _IEEE		1 +#define endian		(((*(int *) &one)) ? 1 : 0) +#define TRUNC(x) 	*(((int *) &x)+endian) &= 0xf8000000 +#define infnan(x)	0.0 +#endif		/* vax or tahoe */ + +const static double zero=0.0, one=1.0, two=2.0, negone= -1.0; + +static double pow_P __P((double, double)); + +double pow(x,y)  	 +double x,y; +{ +	double t; +	if (y==zero) +		return (one); +	else if (y==one || (_IEEE && x != x)) +		return (x);		/* if x is NaN or y=1 */ +	else if (_IEEE && y!=y)		/* if y is NaN */ +		return (y); +	else if (!finite(y))		/* if y is INF */ +		if ((t=fabs(x))==one)	/* +-1 ** +-INF is NaN */ +			return (y - y); +		else if (t>one) +			return ((y<0)? zero : ((x<zero)? y-y : y)); +		else +			return ((y>0)? zero : ((x<0)? y-y : -y)); +	else if (y==two) +		return (x*x); +	else if (y==negone) +		return (one/x); +    /* x > 0, x == +0 */ +	else if (copysign(one, x) == one) +		return (pow_P(x, y)); + +    /* sign(x)= -1 */ +	/* if y is an even integer */ +	else if ( (t=drem(y,two)) == zero) +		return (pow_P(-x, y)); + +	/* if y is an odd integer */ +	else if (copysign(t,one) == one) +		return (-pow_P(-x, y)); + +	/* Henceforth y is not an integer */ +	else if (x==zero)	/* x is -0 */ +		return ((y>zero)? -x : one/(-x)); +	else if (_IEEE) +		return (zero/zero); +	else +		return (infnan(EDOM)); +} +/* kernel function for x >= 0 */ +static double +#ifdef _ANSI_SOURCE +pow_P(double x, double y) +#else +pow_P(x, y) double x, y; +#endif +{ +	struct Double s, t, __log__D(); +	double  __exp__D(), huge = 1e300, tiny = 1e-300; + +	if (x == zero) +		if (y > zero) +			return (zero); +		else if (_IEEE) +			return (huge*huge); +		else +			return (infnan(ERANGE)); +	if (x == one) +		return (one); +	if (!finite(x)) +		if (y < zero) +			return (zero); +		else if (_IEEE) +			return (huge*huge); +		else +			return (infnan(ERANGE)); +	if (y >= 7e18)		/* infinity */ +		if (x < 1) +			return(tiny*tiny); +		else if (_IEEE) +			return (huge*huge); +		else +			return (infnan(ERANGE)); + +	/* Return exp(y*log(x)), using simulated extended */ +	/* precision for the log and the multiply.	  */ + +	s = __log__D(x); +	t.a = y; +	TRUNC(t.a); +	t.b = y - t.a; +	t.b = s.b*y + t.b*s.a; +	t.a *= s.a; +	s.a = t.a + t.b; +	s.b = (t.a - s.a) + t.b; +	return (__exp__D(s.a, s.b)); +} diff --git a/lib/libm/common_source/rint.3 b/lib/libm/common_source/rint.3 new file mode 100644 index 000000000000..00cbf1cdbf55 --- /dev/null +++ b/lib/libm/common_source/rint.3 @@ -0,0 +1,115 @@ +.\" Copyright (c) 1985, 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)rint.3	8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt RINT 3 +.Os +.Sh NAME +.Nm rint +.Nd round-to-closest integer functions +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn rint "double x" +.Sh DESCRIPTION +The +.Fn rint +function finds the integer (represented as a double precision number) +nearest to +.Fa x +in the direction of the prevailing rounding mode. +.Sh NOTES +On a +.Tn VAX , +.Fn rint x +is equivalent to adding half to the magnitude +and then rounding towards zero. +.Pp +In the default rounding mode, to nearest, +on a machine that conforms to +.Tn IEEE +754, +.Fn rint x +is the integer nearest +.Fa x +with the additional stipulation +that if +.Li |rint(x)\-x|=1/2 +then +.Fn rint x +is even. +Other rounding modes can make +.Fn rint +act like +.Fn floor , +or like +.Fn ceil , +or round towards zero. +.Pp +Another way to obtain an integer near +.Fa x +is to declare (in C) +.Bd -literal -offset indent +double x;\0\0\0\0 int k;\0\0\0\0k\0=\0x; +.Ed +.Pp +Most C compilers round +.Fa x +towards 0 to get the integer +.Fa k , +but +some do otherwise. +If in doubt, use +.Fn floor , +.Fn ceil , +or +.Fn rint +first, whichever you intend. +Also note that, if x is larger than +.Fa k +can accommodate, the value of +.Fa k +and the presence or absence of an integer overflow are hard to +predict. +.Sh SEE ALSO +.Xr abs 3 , +.Xr fabs 3 , +.Xr ceil 3 , +.Xr floor 3 , +.Xr ieee 3 , +.Xr math 3 +.Sh HISTORY +A +.Fn rint +function appeared in +.At v6 . diff --git a/lib/libm/common_source/sin.3 b/lib/libm/common_source/sin.3 new file mode 100644 index 000000000000..c9bddd920e78 --- /dev/null +++ b/lib/libm/common_source/sin.3 @@ -0,0 +1,72 @@ +.\" Copyright (c) 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\"	@(#)sin.3	8.1 (Berkeley) 6/4/93 +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)sin.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt SIN 3 +.Os +.Sh NAME +.Nm sin +.Nd sine function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn sin "double x" +.Sh DESCRIPTION +The +.Fn sin +function computes the sine of +.Fa x +(measured in radians). +A large magnitude argument may yield a result with little +or no significance. +.Sh RETURN VALUES +The +.Fn sin +function returns the sine value. +.Sh SEE ALSO +.Xr acos 3 , +.Xr asin 3 , +.Xr atan 3 , +.Xr atan2 3 , +.Xr cos 3 , +.Xr cosh 3 , +.Xr sinh 3 , +.Xr tan 3 , +.Xr tanh 3 , +.Xr math 3 , +.Sh STANDARDS +The +.Fn sin +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/sinh.3 b/lib/libm/common_source/sinh.3 new file mode 100644 index 000000000000..c8b1b7f53cc7 --- /dev/null +++ b/lib/libm/common_source/sinh.3 @@ -0,0 +1,74 @@ +.\" Copyright (c) 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"	@(#)sinh.3	8.1 (Berkeley) 6/4/93 +.Dd June 4, 1993 +.Dt SINH 3 +.Os +.Sh NAME +.Nm sinh +.Nd hyperbolic sine function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn sinh "double  x" +.Sh DESCRIPTION +The +.Fn sinh +function computes the hyperbolic sine of +.Fa x . +.Sh RETURN VALUES +The +.Fn sinh +function returns the hyperbolic sine value unless +the  magnitude  +of +.Fa x +is too large; in this event, the global variable +.Va errno +is set to +.Er ERANGE . +.Sh SEE ALSO +.Xr acos 3 , +.Xr asin 3 , +.Xr atan 3 , +.Xr atan2 3 , +.Xr cos 3 , +.Xr cosh 3 , +.Xr sin 3 , +.Xr tan 3 , +.Xr tanh 3 , +.Xr math 3 , +.Sh STANDARDS +The +.Fn sinh +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/sinh.c b/lib/libm/common_source/sinh.c new file mode 100644 index 000000000000..0516849cff13 --- /dev/null +++ b/lib/libm/common_source/sinh.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)sinh.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* SINH(X) + * RETURN THE HYPERBOLIC SINE OF X + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/8/85;  + * REVISED BY K.C. NG on 2/8/85, 3/7/85, 3/24/85, 4/16/85. + * + * Required system supported functions : + *	copysign(x,y) + *	scalb(x,N) + * + * Required kernel functions: + *	expm1(x)	...return exp(x)-1 + * + * Method : + *	1. reduce x to non-negative by sinh(-x) = - sinh(x). + *	2.  + * + *	                                      expm1(x) + expm1(x)/(expm1(x)+1) + *	    0 <= x <= lnovfl     : sinh(x) := -------------------------------- + *			       		                      2 + *     lnovfl <= x <= lnovfl+ln2 : sinh(x) := expm1(x)/2 (avoid overflow) + * lnovfl+ln2 <  x <  INF        :  overflow to INF + *	 + * + * Special cases: + *	sinh(x) is x if x is +INF, -INF, or NaN. + *	only sinh(0)=0 is exact for finite argument. + * + * Accuracy: + *	sinh(x) returns the exact hyperbolic sine of x nearly rounded. In + *	a test run with 1,024,000 random arguments on a VAX, the maximum + *	observed error was 1.93 ulps (units in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(mln2hi, 8.8029691931113054792E1   ,0f33,43b0,2bdb,c7e2,   7, .B00F33C7E22BDB) +vc(mln2lo,-4.9650192275318476525E-16 ,1b60,a70f,582a,279e, -50,-.8F1B60279E582A) +vc(lnovfl, 8.8029691931113053016E1   ,0f33,43b0,2bda,c7e2,   7, .B00F33C7E22BDA) + +ic(mln2hi, 7.0978271289338397310E2,    10, 1.62E42FEFA39EF) +ic(mln2lo, 2.3747039373786107478E-14, -45, 1.ABC9E3B39803F) +ic(lnovfl, 7.0978271289338397310E2,     9, 1.62E42FEFA39EF) + +#ifdef vccast +#define	mln2hi	vccast(mln2hi) +#define	mln2lo	vccast(mln2lo) +#define	lnovfl	vccast(lnovfl) +#endif + +#if defined(vax)||defined(tahoe) +static max = 126                      ; +#else	/* defined(vax)||defined(tahoe) */ +static max = 1023                     ; +#endif	/* defined(vax)||defined(tahoe) */ + + +double sinh(x) +double x; +{ +	static const double  one=1.0, half=1.0/2.0 ; +	double t, sign; +#if !defined(vax)&&!defined(tahoe) +	if(x!=x) return(x);	/* x is NaN */ +#endif	/* !defined(vax)&&!defined(tahoe) */ +	sign=copysign(one,x); +	x=copysign(x,one); +	if(x<lnovfl) +	    {t=expm1(x); return(copysign((t+t/(one+t))*half,sign));} + +	else if(x <= lnovfl+0.7) +		/* subtract x by ln(2^(max+1)) and return 2^max*exp(x)  +	    		to avoid unnecessary overflow */ +	    return(copysign(scalb(one+expm1((x-mln2hi)-mln2lo),max),sign)); + +	else  /* sinh(+-INF) = +-INF, sinh(+-big no.) overflow to +-INF */ +	    return( expm1(x)*sign ); +} diff --git a/lib/libm/common_source/sqrt.3 b/lib/libm/common_source/sqrt.3 new file mode 100644 index 000000000000..a6d47d911a7e --- /dev/null +++ b/lib/libm/common_source/sqrt.3 @@ -0,0 +1,120 @@ +.\" Copyright (c) 1985, 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)sqrt.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt SQRT 3 +.Os +.Sh NAME +.Nm cbrt , +.Nm sqrt +.Nd cube root and square root functions +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn cbrt "double x" +.Ft double +.Fn sqrt "double x" +.Sh DESCRIPTION +The +.Fn cbrt +function computes +the cube root of +.Ar x . +.Pp +The +.Fn sqrt +computes the +non-negative square root of x. +.Sh RETURN VALUES +The +.Fn cbrt +function returns the requested cube root. +The +.Fn sqrt +function returns the requested square root +unless an error occurs. +On the +.Tn VAX +or +.Tn Tahoe +processor an attempt to take the +.Fn sqrt +of negative +.Fa x +causes an error; in this event, +the global variable +.Va errno +is set to +.Dv EDOM +and a reserved operand fault is generated. +.Sh ERROR (due to Roundoff etc.) +The +.Fn cbrt +function +is accurate to within 0.7 +.Em ulps . +.Pp +The +.Fn sqrt +function on a +.Tn VAX +is accurate to within 0.501 +.Em ulps . +Sqrt on a machine that conforms to +.Tn IEEE +754 is correctly rounded +in accordance with the rounding mode in force; the error is less than +half an +.Em ulp +in the default mode (round\-to\-nearest). +An +.Em ulp +is one +.Em U Ns nit +in the +.Em L Ns ast +.Em P Ns lace +carried. +.Sh SEE ALSO +.Xr math 3 , +.Xr infnan 3 +.Sh STANDARDS +The +.Nm sqrt +function conforms to +.St -ansiC . +.Sh HISTORY +The +.Nm cbrt +function appeared in +.Bx 4.3 . diff --git a/lib/libm/common_source/tan.3 b/lib/libm/common_source/tan.3 new file mode 100644 index 000000000000..4e82ae32242a --- /dev/null +++ b/lib/libm/common_source/tan.3 @@ -0,0 +1,73 @@ +.\" Copyright (c) 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)tan.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt TAN 3 +.Os +.Sh NAME +.Nm tan +.Nd tangent function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn tan "double x" +.Sh DESCRIPTION +The +.Fn tan +function computes the tangent of +.Fa x +(measured in radians). +A large magnitude argument may yield a result +with little or no significance. +For a discussion of error due to roundoff, see +.Xr math 3 . +.Sh RETURN VALUES +The +.Fn tan +function returns the tangent value. +.Sh SEE ALSO +.Xr acos 3 , +.Xr asin 3 , +.Xr atan 3 , +.Xr atan2 3 , +.Xr cos 3 , +.Xr cosh 3 , +.Xr sin 3 , +.Xr sinh 3 , +.Xr tanh 3 , +.Xr math 3 , +.Sh STANDARDS +The +.Fn tan +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/tanh.3 b/lib/libm/common_source/tanh.3 new file mode 100644 index 000000000000..7531728c61ca --- /dev/null +++ b/lib/libm/common_source/tanh.3 @@ -0,0 +1,70 @@ +.\" Copyright (c) 1991, 1993 +.\"	The Regents of the University of California.  All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\"    must display the following acknowledgement: +.\"	This product includes software developed by the University of +.\"	California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\"    may be used to endorse or promote products derived from this software +.\"    without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\"     @(#)tanh.3	8.1 (Berkeley) 6/4/93 +.\" +.Dd June 4, 1993 +.Dt TANH 3 +.Os +.Sh NAME +.Nm tanh +.Nd hyperbolic tangent function +.Sh SYNOPSIS +.Fd #include <math.h> +.Ft double +.Fn tanh "double x" +.Sh DESCRIPTION +The +.Fn tanh +function computes the hyperbolic tangent of +.Fa x . +For a discussion of error due to roundoff, see +.Xr math 3 . +.Sh RETURN VALUES +The +.Fn tanh +function returns the hyperbolic tangent value. +.Sh SEE ALSO +.Xr acos 3 , +.Xr asin 3 , +.Xr atan 3 , +.Xr atan2 3 , +.Xr cos 3 , +.Xr cosh 3 , +.Xr sin 3 , +.Xr sinh 3 , +.Xr tan 3 , +.Xr math 3 , +.Sh STANDARDS +The +.Fn tanh +function conforms to +.St -ansiC . diff --git a/lib/libm/common_source/tanh.c b/lib/libm/common_source/tanh.c new file mode 100644 index 000000000000..d4923b3418bd --- /dev/null +++ b/lib/libm/common_source/tanh.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 1985, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the University of + *	California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)tanh.c	8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* TANH(X) + * RETURN THE HYPERBOLIC TANGENT OF X + * DOUBLE PRECISION (VAX D FORMAT 56 BITS, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/8/85;  + * REVISED BY K.C. NG on 2/8/85, 2/11/85, 3/7/85, 3/24/85. + * + * Required system supported functions : + *	copysign(x,y) + *	finite(x) + * + * Required kernel function: + *	expm1(x)	...exp(x)-1 + * + * Method : + *	1. reduce x to non-negative by tanh(-x) = - tanh(x). + *	2. + *	    0      <  x <=  1.e-10 :  tanh(x) := x + *					          -expm1(-2x) + *	    1.e-10 <  x <=  1      :  tanh(x) := -------------- + *					         expm1(-2x) + 2 + *							  2 + *	    1      <= x <=  22.0   :  tanh(x) := 1 -  --------------- + *						      expm1(2x) + 2 + *	    22.0   <  x <= INF     :  tanh(x) := 1. + * + *	Note: 22 was chosen so that fl(1.0+2/(expm1(2*22)+2)) == 1. + * + * Special cases: + *	tanh(NaN) is NaN; + *	only tanh(0)=0 is exact for finite argument. + * + * Accuracy: + *	tanh(x) returns the exact hyperbolic tangent of x nealy rounded. + *	In a test run with 1,024,000 random arguments on a VAX, the maximum + *	observed error was 2.22 ulps (units in the last place). + */ + +double tanh(x) +double x; +{ +	static double one=1.0, two=2.0, small = 1.0e-10, big = 1.0e10; +	double expm1(), t, copysign(), sign; +	int finite(); + +#if !defined(vax)&&!defined(tahoe) +	if(x!=x) return(x);	/* x is NaN */ +#endif	/* !defined(vax)&&!defined(tahoe) */ + +	sign=copysign(one,x); +	x=copysign(x,one); +	if(x < 22.0)  +	    if( x > one ) +		return(copysign(one-two/(expm1(x+x)+two),sign)); +	    else if ( x > small ) +		{t= -expm1(-(x+x)); return(copysign(t/(two-t),sign));} +	    else		/* raise the INEXACT flag for non-zero x */ +		{big+x; return(copysign(x,sign));} +	else if(finite(x)) +	    return (sign+1.0E-37); /* raise the INEXACT flag */ +	else +	    return(sign);	/* x is +- INF */ +} | 
