2001-03-11  Ulrich Drepper  <drepper@redhat.com>

	Last-bit accurate math library implementation by IBM Haifa.
	Contributed by Abraham Ziv <ziv@il.ibm.com>, Moshe Olshansky
	<olshansk@il.ibm.com>, Ealan Henis <ealan@il.ibm.com>, and
	Anna Reitman <reitman@il.ibm.com>.
	* math/Makefile (dbl-only-routines): New variable.
	(libm-routines): Add $(dbl-only-routines).
	* sysdeps/ieee754/dbl-64/e_acos.c: Empty, definition is in e_asin.c.
	* sysdeps/ieee754/dbl-64/e_asin.c: Replaced with accurate asin
	implementation.
	* sysdeps/ieee754/dbl-64/e_atan2.c: Replaced with accurate atan2
	implementation.
	* sysdeps/ieee754/dbl-64/e_exp.c: Replaced with accurate exp
	implementation.
	* sysdeps/ieee754/dbl-64/e_lgamma_r.c: Don't use __kernel_sin and
	__kernel_cos.
	* sysdeps/ieee754/dbl-64/e_log.c: Replaced with accurate log
	implementation.
	* sysdeps/ieee754/dbl-64/e_remainder.c: Replaced with accurate
	remainder implementation.
	* sysdeps/ieee754/dbl-64/e_pow.c: Replaced with accurate pow
	implementation.
	* sysdeps/ieee754/dbl-64/e_sqrt.c: Replaced with accurate sqrt
	implementation.
	* sysdeps/ieee754/dbl-64/k_cos.c: Empty, definition is in s_sin.c.
	* sysdeps/ieee754/dbl-64/k_sin.c: Empty, definition is in s_sin.c.
	* sysdeps/ieee754/dbl-64/s_atan.c: Replaced with accurate atan
	implementation.
	* sysdeps/ieee754/dbl-64/s_cos.c: Empty, definition is in s_sin.c.
	* sysdeps/ieee754/dbl-64/s_sin.c: Replaced with accurate sin/cos
	implementation.
	* sysdeps/ieee754/dbl-64/s_sincos.c: Rewritten to not use __kernel_sin
	and __kernel_cos.
	* sysdeps/ieee754/dbl-64/s_tan.c: Replaced with accurate tan
	implementation.
	* sysdeps/ieee754/dbl-64/Dist: Add new non-code files.
	* sysdeps/ieee754/dbl-64/MathLib.h: New file.
	* sysdeps/ieee754/dbl-64/asincos.tbl: New file.
	* sysdeps/ieee754/dbl-64/atnat.h: New file.
	* sysdeps/ieee754/dbl-64/atnat2.h: New file.
	* sysdeps/ieee754/dbl-64/branred.c: New file.
	* sysdeps/ieee754/dbl-64/branred.h: New file.
	* sysdeps/ieee754/dbl-64/dla.h: New file.
	* sysdeps/ieee754/dbl-64/doasin.c: New file.
	* sysdeps/ieee754/dbl-64/doasin.h: New file.
	* sysdeps/ieee754/dbl-64/dosincos.c: New file.
	* sysdeps/ieee754/dbl-64/dosincos.h: New file.
	* sysdeps/ieee754/dbl-64/endian.h: New file.
	* sysdeps/ieee754/dbl-64/halfulp.c: New file.
	* sysdeps/ieee754/dbl-64/mpa.c: New file.
	* sysdeps/ieee754/dbl-64/mpa.h: New file.
	* sysdeps/ieee754/dbl-64/mpa2.h: New file.
	* sysdeps/ieee754/dbl-64/mpatan.c: New file.
	* sysdeps/ieee754/dbl-64/mpatan.h: New file.
	* sysdeps/ieee754/dbl-64/mpatan2.c: New file.
	* sysdeps/ieee754/dbl-64/mpexp.c: New file.
	* sysdeps/ieee754/dbl-64/mpexp.h: New file.
	* sysdeps/ieee754/dbl-64/mplog.c: New file.
	* sysdeps/ieee754/dbl-64/mplog.h: New file.
	* sysdeps/ieee754/dbl-64/mpsqrt.c: New file.
	* sysdeps/ieee754/dbl-64/mpsqrt.h: New file.
	* sysdeps/ieee754/dbl-64/mptan.c: New file.
	* sysdeps/ieee754/dbl-64/mydefs.h: New file.
	* sysdeps/ieee754/dbl-64/powtwo.tbl: New file.
	* sysdeps/ieee754/dbl-64/root.tbl: New file.
	* sysdeps/ieee754/dbl-64/sincos.tbl: New file.
	* sysdeps/ieee754/dbl-64/sincos32.c: New file.
	* sysdeps/ieee754/dbl-64/sincos32.h: New file.
	* sysdeps/ieee754/dbl-64/slowexp.c: New file.
	* sysdeps/ieee754/dbl-64/slowpow.c: New file.
	* sysdeps/ieee754/dbl-64/uasncs.h: New file.
	* sysdeps/ieee754/dbl-64/uatan.tbl: New file.
	* sysdeps/ieee754/dbl-64/uexp.h: New file.
	* sysdeps/ieee754/dbl-64/uexp.tbl: New file.
	* sysdeps/ieee754/dbl-64/ulog.h: New file.
	* sysdeps/ieee754/dbl-64/ulog.tbl: New file.
	* sysdeps/ieee754/dbl-64/upow.h: New file.
	* sysdeps/ieee754/dbl-64/upow.tbl: New file.
	* sysdeps/ieee754/dbl-64/urem.h: New file.
	* sysdeps/ieee754/dbl-64/uroot.h: New file.
	* sysdeps/ieee754/dbl-64/usncs.h: New file.
	* sysdeps/ieee754/dbl-64/utan.h: New file.
	* sysdeps/ieee754/dbl-64/utan.tbl: New file.
	* sysdeps/i386/fpu/branred.c: New file.
	* sysdeps/i386/fpu/doasin.c: New file.
	* sysdeps/i386/fpu/dosincos.c: New file.
	* sysdeps/i386/fpu/halfulp.c: New file.
	* sysdeps/i386/fpu/mpa.c: New file.
	* sysdeps/i386/fpu/mpatan.c: New file.
	* sysdeps/i386/fpu/mpatan2.c: New file.
	* sysdeps/i386/fpu/mpexp.c: New file.
	* sysdeps/i386/fpu/mplog.c: New file.
	* sysdeps/i386/fpu/mpsqrt.c: New file.
	* sysdeps/i386/fpu/mptan.c: New file.
	* sysdeps/i386/fpu/sincos32.c: New file.
	* sysdeps/i386/fpu/slowexp.c: New file.
	* sysdeps/i386/fpu/slowpow.c: New file.
	* sysdeps/ia64/fpu/branred.c: New file.
	* sysdeps/ia64/fpu/doasin.c: New file.
	* sysdeps/ia64/fpu/dosincos.c: New file.
	* sysdeps/ia64/fpu/halfulp.c: New file.
	* sysdeps/ia64/fpu/mpa.c: New file.
	* sysdeps/ia64/fpu/mpatan.c: New file.
	* sysdeps/ia64/fpu/mpatan2.c: New file.
	* sysdeps/ia64/fpu/mpexp.c: New file.
	* sysdeps/ia64/fpu/mplog.c: New file.
	* sysdeps/ia64/fpu/mpsqrt.c: New file.
	* sysdeps/ia64/fpu/mptan.c: New file.
	* sysdeps/ia64/fpu/sincos32.c: New file.
	* sysdeps/ia64/fpu/slowexp.c: New file.
	* sysdeps/ia64/fpu/slowpow.c: New file.
	* sysdeps/m68k/fpu/branred.c: New file.
	* sysdeps/m68k/fpu/doasin.c: New file.
	* sysdeps/m68k/fpu/dosincos.c: New file.
	* sysdeps/m68k/fpu/halfulp.c: New file.
	* sysdeps/m68k/fpu/mpa.c: New file.
	* sysdeps/m68k/fpu/mpatan.c: New file.
	* sysdeps/m68k/fpu/mpatan2.c: New file.
	* sysdeps/m68k/fpu/mpexp.c: New file.
	* sysdeps/m68k/fpu/mplog.c: New file.
	* sysdeps/m68k/fpu/mpsqrt.c: New file.
	* sysdeps/m68k/fpu/mptan.c: New file.
	* sysdeps/m68k/fpu/sincos32.c: New file.
	* sysdeps/m68k/fpu/slowexp.c: New file.
	* sysdeps/m68k/fpu/slowpow.c: New file.

	* iconvdata/gconv-modules: Add a number of alias, mostly for IBM
	codepages.
This commit is contained in:
Ulrich Drepper 2001-03-12 00:04:52 +00:00
parent d3c8723f64
commit e4d8276142
109 changed files with 42270 additions and 2166 deletions

130
ChangeLog
View File

@ -1,3 +1,133 @@
2001-03-11 Ulrich Drepper <drepper@redhat.com>
Last-bit accurate math library implementation by IBM Haifa.
Contributed by Abraham Ziv <ziv@il.ibm.com>, Moshe Olshansky
<olshansk@il.ibm.com>, Ealan Henis <ealan@il.ibm.com>, and
Anna Reitman <reitman@il.ibm.com>.
* math/Makefile (dbl-only-routines): New variable.
(libm-routines): Add $(dbl-only-routines).
* sysdeps/ieee754/dbl-64/e_acos.c: Empty, definition is in e_asin.c.
* sysdeps/ieee754/dbl-64/e_asin.c: Replaced with accurate asin
implementation.
* sysdeps/ieee754/dbl-64/e_atan2.c: Replaced with accurate atan2
implementation.
* sysdeps/ieee754/dbl-64/e_exp.c: Replaced with accurate exp
implementation.
* sysdeps/ieee754/dbl-64/e_lgamma_r.c: Don't use __kernel_sin and
__kernel_cos.
* sysdeps/ieee754/dbl-64/e_log.c: Replaced with accurate log
implementation.
* sysdeps/ieee754/dbl-64/e_remainder.c: Replaced with accurate
remainder implementation.
* sysdeps/ieee754/dbl-64/e_pow.c: Replaced with accurate pow
implementation.
* sysdeps/ieee754/dbl-64/e_sqrt.c: Replaced with accurate sqrt
implementation.
* sysdeps/ieee754/dbl-64/k_cos.c: Empty, definition is in s_sin.c.
* sysdeps/ieee754/dbl-64/k_sin.c: Empty, definition is in s_sin.c.
* sysdeps/ieee754/dbl-64/s_atan.c: Replaced with accurate atan
implementation.
* sysdeps/ieee754/dbl-64/s_cos.c: Empty, definition is in s_sin.c.
* sysdeps/ieee754/dbl-64/s_sin.c: Replaced with accurate sin/cos
implementation.
* sysdeps/ieee754/dbl-64/s_sincos.c: Rewritten to not use __kernel_sin
and __kernel_cos.
* sysdeps/ieee754/dbl-64/s_tan.c: Replaced with accurate tan
implementation.
* sysdeps/ieee754/dbl-64/Dist: Add new non-code files.
* sysdeps/ieee754/dbl-64/MathLib.h: New file.
* sysdeps/ieee754/dbl-64/asincos.tbl: New file.
* sysdeps/ieee754/dbl-64/atnat.h: New file.
* sysdeps/ieee754/dbl-64/atnat2.h: New file.
* sysdeps/ieee754/dbl-64/branred.c: New file.
* sysdeps/ieee754/dbl-64/branred.h: New file.
* sysdeps/ieee754/dbl-64/dla.h: New file.
* sysdeps/ieee754/dbl-64/doasin.c: New file.
* sysdeps/ieee754/dbl-64/doasin.h: New file.
* sysdeps/ieee754/dbl-64/dosincos.c: New file.
* sysdeps/ieee754/dbl-64/dosincos.h: New file.
* sysdeps/ieee754/dbl-64/endian.h: New file.
* sysdeps/ieee754/dbl-64/halfulp.c: New file.
* sysdeps/ieee754/dbl-64/mpa.c: New file.
* sysdeps/ieee754/dbl-64/mpa.h: New file.
* sysdeps/ieee754/dbl-64/mpa2.h: New file.
* sysdeps/ieee754/dbl-64/mpatan.c: New file.
* sysdeps/ieee754/dbl-64/mpatan.h: New file.
* sysdeps/ieee754/dbl-64/mpatan2.c: New file.
* sysdeps/ieee754/dbl-64/mpexp.c: New file.
* sysdeps/ieee754/dbl-64/mpexp.h: New file.
* sysdeps/ieee754/dbl-64/mplog.c: New file.
* sysdeps/ieee754/dbl-64/mplog.h: New file.
* sysdeps/ieee754/dbl-64/mpsqrt.c: New file.
* sysdeps/ieee754/dbl-64/mpsqrt.h: New file.
* sysdeps/ieee754/dbl-64/mptan.c: New file.
* sysdeps/ieee754/dbl-64/mydefs.h: New file.
* sysdeps/ieee754/dbl-64/powtwo.tbl: New file.
* sysdeps/ieee754/dbl-64/root.tbl: New file.
* sysdeps/ieee754/dbl-64/sincos.tbl: New file.
* sysdeps/ieee754/dbl-64/sincos32.c: New file.
* sysdeps/ieee754/dbl-64/sincos32.h: New file.
* sysdeps/ieee754/dbl-64/slowexp.c: New file.
* sysdeps/ieee754/dbl-64/slowpow.c: New file.
* sysdeps/ieee754/dbl-64/uasncs.h: New file.
* sysdeps/ieee754/dbl-64/uatan.tbl: New file.
* sysdeps/ieee754/dbl-64/uexp.h: New file.
* sysdeps/ieee754/dbl-64/uexp.tbl: New file.
* sysdeps/ieee754/dbl-64/ulog.h: New file.
* sysdeps/ieee754/dbl-64/ulog.tbl: New file.
* sysdeps/ieee754/dbl-64/upow.h: New file.
* sysdeps/ieee754/dbl-64/upow.tbl: New file.
* sysdeps/ieee754/dbl-64/urem.h: New file.
* sysdeps/ieee754/dbl-64/uroot.h: New file.
* sysdeps/ieee754/dbl-64/usncs.h: New file.
* sysdeps/ieee754/dbl-64/utan.h: New file.
* sysdeps/ieee754/dbl-64/utan.tbl: New file.
* sysdeps/i386/fpu/branred.c: New file.
* sysdeps/i386/fpu/doasin.c: New file.
* sysdeps/i386/fpu/dosincos.c: New file.
* sysdeps/i386/fpu/halfulp.c: New file.
* sysdeps/i386/fpu/mpa.c: New file.
* sysdeps/i386/fpu/mpatan.c: New file.
* sysdeps/i386/fpu/mpatan2.c: New file.
* sysdeps/i386/fpu/mpexp.c: New file.
* sysdeps/i386/fpu/mplog.c: New file.
* sysdeps/i386/fpu/mpsqrt.c: New file.
* sysdeps/i386/fpu/mptan.c: New file.
* sysdeps/i386/fpu/sincos32.c: New file.
* sysdeps/i386/fpu/slowexp.c: New file.
* sysdeps/i386/fpu/slowpow.c: New file.
* sysdeps/ia64/fpu/branred.c: New file.
* sysdeps/ia64/fpu/doasin.c: New file.
* sysdeps/ia64/fpu/dosincos.c: New file.
* sysdeps/ia64/fpu/halfulp.c: New file.
* sysdeps/ia64/fpu/mpa.c: New file.
* sysdeps/ia64/fpu/mpatan.c: New file.
* sysdeps/ia64/fpu/mpatan2.c: New file.
* sysdeps/ia64/fpu/mpexp.c: New file.
* sysdeps/ia64/fpu/mplog.c: New file.
* sysdeps/ia64/fpu/mpsqrt.c: New file.
* sysdeps/ia64/fpu/mptan.c: New file.
* sysdeps/ia64/fpu/sincos32.c: New file.
* sysdeps/ia64/fpu/slowexp.c: New file.
* sysdeps/ia64/fpu/slowpow.c: New file.
* sysdeps/m68k/fpu/branred.c: New file.
* sysdeps/m68k/fpu/doasin.c: New file.
* sysdeps/m68k/fpu/dosincos.c: New file.
* sysdeps/m68k/fpu/halfulp.c: New file.
* sysdeps/m68k/fpu/mpa.c: New file.
* sysdeps/m68k/fpu/mpatan.c: New file.
* sysdeps/m68k/fpu/mpatan2.c: New file.
* sysdeps/m68k/fpu/mpexp.c: New file.
* sysdeps/m68k/fpu/mplog.c: New file.
* sysdeps/m68k/fpu/mpsqrt.c: New file.
* sysdeps/m68k/fpu/mptan.c: New file.
* sysdeps/m68k/fpu/sincos32.c: New file.
* sysdeps/m68k/fpu/slowexp.c: New file.
* sysdeps/m68k/fpu/slowpow.c: New file.
* iconvdata/gconv-modules: Add a number of alias, mostly for IBM
codepages.
2001-03-11 Andreas Jaeger <aj@suse.de>
* elf/elf.h (EM_*): Synch with official list.

7
NEWS
View File

@ -1,4 +1,4 @@
GNU C Library NEWS -- history of user-visible changes. 2001-3-4
GNU C Library NEWS -- history of user-visible changes. 2001-3-11
Copyright (C) 1992-1999, 2000, 2001 Free Software Foundation, Inc.
See the end for copying conditions.
@ -16,6 +16,11 @@ Version 2.2.3
* Stephen Moshier implemented j0, j1, jn, y0, y1, yn, and lgamma for the
96-bit long double format.
* The beginning of a last-bit accurate math library by IBM Haifa were added.
The basic double functions exist today. Contributed by Abraham Ziv
<ziv@il.ibm.com>, Moshe Olshansky <olshansk@il.ibm.com>, Ealan Henis
<ealan@il.ibm.com>, and Anna Reitman <reitman@il.ibm.com>.
* An asynchronous name lookup library was added. The interface is designed
after POSIX AIO. The proposal was circulated beforehand to get comments.
No negative ones came in. Implemented by Ulrich Drepper.

View File

@ -58,9 +58,13 @@ libm-calls = e_acos e_acosh e_asin e_atan2 e_atanh e_cosh e_exp e_fmod \
s_catan s_casin s_ccos s_csin s_ctan s_ctanh s_cacos \
s_casinh s_cacosh s_catanh s_csqrt s_cpow s_cproj s_clog10 \
s_fma s_lrint s_llrint s_lround s_llround e_exp10
dbl-only-routines := branred doasin dosincos halfulp mpa mpatan2 \
mpatan mpexp mplog mpsqrt mptan sincos32 slowexp \
slowpow
libm-routines = $(strip $(libm-support) $(libm-calls) \
$(patsubst %_rf,%f_r,$(libm-calls:=f)) \
$(long-m-$(long-double-fcts)))
$(long-m-$(long-double-fcts))) \
$(dbl-only-routines)
long-m-routines = $(patsubst %_rl,%l_r,$(libm-calls:=l))
long-m-support = t_sincosl k_sincosl
long-m-yes = $(long-m-routines) $(long-m-support)

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

1
sysdeps/i386/fpu/mpa.c Normal file
View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

1
sysdeps/i386/fpu/mpexp.c Normal file
View File

@ -0,0 +1 @@
/* Not needed. */

1
sysdeps/i386/fpu/mplog.c Normal file
View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

1
sysdeps/i386/fpu/mptan.c Normal file
View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

1
sysdeps/ia64/fpu/mpa.c Normal file
View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

1
sysdeps/ia64/fpu/mpexp.c Normal file
View File

@ -0,0 +1 @@
/* Not needed. */

1
sysdeps/ia64/fpu/mplog.c Normal file
View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

1
sysdeps/ia64/fpu/mptan.c Normal file
View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -1 +1,34 @@
asincos.tbl
atnat.h
atnat2.h
branred.h
dla.h
doasin.h
dosincos.h
endian.h
MathLib.h
mpa.h
mpa2.h
mpatan.h
mpexp.h
mplog.h
mpsqrt.h
mydefs.h
powtwo.tbl
root.tbl
sincos.tbl
sincos32.h
t_exp2.h
uasncs.h
uatan.tbl
uexp.h
uexp.tbl
ulog.h
ulog.tbl
upow.h
upow.tbl
urem.h
uroot.h
usncs.h
utan.h
utan.tbl

View File

@ -0,0 +1,102 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/********************************************************************/
/* Ultimate math functions. Each function computes the exact */
/* theoretical value of its argument rounded to nearest or even. */
/* */
/* Assumption: Machine arithmetic operations are performed in */
/* round nearest mode of IEEE 754 standard. */
/********************************************************************/
#ifndef UMATH_LIB
#define UMATH_LIB
/********************************************************************/
/* Function changes the precision mode to IEEE 754 double precision */
/* and the rounding mode to nearest or even. */
/* It returns the original status of these modes. */
/* See further explanations of usage in DPChange.h */
/********************************************************************/
unsigned short Init_Lib();
/********************************************************************/
/* Function that changes the precision and rounding modes to the */
/* specified by the argument received. See further explanations in */
/* DPChange.h */
/********************************************************************/
void Exit_Lib(unsigned short);
/* The asin() function calculates the arc sine of its argument. */
/* The function returns the arc sine in radians */
/* (between -PI/2 and PI/2). */
/* If the argument is greater than 1 or less than -1 it returns */
/* a NaN. */
double uasin(double );
/* The acos() function calculates the arc cosine of its argument. */
/* The function returns the arc cosine in radians */
/* (between -PI/2 and PI/2). */
/* If the argument is greater than 1 or less than -1 it returns */
/* a NaN. */
double uacos(double );
/* The atan() function calculates the arctanget of its argument. */
/* The function returns the arc tangent in radians */
/* (between -PI/2 and PI/2). */
double uatan(double );
/* The uatan2() function calculates the arc tangent of the two arguments x */
/* and y (x is the right argument and y is the left one).The signs of both */
/* arguments are used to determine the quadrant of the result. */
/* The function returns the result in radians, which is between -PI and PI */
double uatan2(double ,double );
/* Compute log(x). The base of log is e (natural logarithm) */
double ulog(double );
/* Compute e raised to the power of argument x. */
double uexp(double );
/* Compute sin(x). The argument x is assumed to be given in radians.*/
double usin(double );
/* Compute cos(x). The argument x is assumed to be given in radians.*/
double ucos(double );
/* Compute tan(x). The argument x is assumed to be given in radians.*/
double utan(double );
/* Compute the square root of non-negative argument x. */
/* If x is negative the returned value is NaN. */
double usqrt(double );
/* Compute x raised to the power of y, where x is the left argument */
/* and y is the right argument. The function returns a NaN if x<0. */
/* If x equals zero it returns -inf */
double upow(double , double );
/* Computing x mod y, where x is the left argument and y is the */
/* right one. */
double uremainder(double , double );
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,166 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/************************************************************************/
/* MODULE_NAME: atnat.h */
/* */
/* */
/* common data and variables definition for BIG or LITTLE ENDIAN */
/************************************************************************/
#ifndef ATNAT_H
#define ATNAT_H
#define M 4
#ifdef BIG_ENDI
static const number
/* polynomial I */
/**/ d3 = {0xbfd55555, 0x55555555, }, /* -0.333... */
/**/ d5 = {0x3fc99999, 0x999997fd, }, /* 0.199... */
/**/ d7 = {0xbfc24924, 0x923f7603, }, /* -0.142... */
/**/ d9 = {0x3fbc71c6, 0xe5129a3b, }, /* 0.111... */
/**/ d11 = {0xbfb74580, 0x22b13c25, }, /* -0.090... */
/**/ d13 = {0x3fb375f0, 0x8b31cbce, }, /* 0.076... */
/* polynomial II */
/**/ f3 = {0xbfd55555, 0x55555555, }, /* -1/3 */
/**/ ff3 = {0xbc755555, 0x55555555, }, /* -1/3-f3 */
/**/ f5 = {0x3fc99999, 0x9999999a, }, /* 1/5 */
/**/ ff5 = {0xbc699999, 0x9999999a, }, /* 1/5-f5 */
/**/ f7 = {0xbfc24924, 0x92492492, }, /* -1/7 */
/**/ ff7 = {0xbc624924, 0x92492492, }, /* -1/7-f7 */
/**/ f9 = {0x3fbc71c7, 0x1c71c71c, }, /* 1/9 */
/**/ ff9 = {0x3c5c71c7, 0x1c71c71c, }, /* 1/9-f9 */
/**/ f11 = {0xbfb745d1, 0x745d1746, }, /* -1/11 */
/**/ f13 = {0x3fb3b13b, 0x13b13b14, }, /* 1/13 */
/**/ f15 = {0xbfb11111, 0x11111111, }, /* -1/15 */
/**/ f17 = {0x3fae1e1e, 0x1e1e1e1e, }, /* 1/17 */
/**/ f19 = {0xbfaaf286, 0xbca1af28, }, /* -1/19 */
/* constants */
/**/ zero = {0x00000000, 0x00000000, }, /* 0 */
/**/ one = {0x3ff00000, 0x00000000, }, /* 1 */
/**/ a = {0x3e4bb67a, 0x00000000, }, /* 1.290e-8 */
/**/ b = {0x3fb00000, 0x00000000, }, /* 1/16 */
/**/ c = {0x3ff00000, 0x00000000, }, /* 1 */
/**/ d = {0x40300000, 0x00000000, }, /* 16 */
/**/ e = {0x43349ff2, 0x00000000, }, /* 5.805e15 */
/**/ hpi = {0x3ff921fb, 0x54442d18, }, /* pi/2 */
/**/ mhpi = {0xbff921fb, 0x54442d18, }, /* -pi/2 */
/**/ hpi1 = {0x3c91a626, 0x33145c07, }, /* pi/2-hpi */
/**/ u1 = {0x3c2d3382, 0x00000000, }, /* 7.915e-19 */
/**/ u21 = {0x3c6dffc0, 0x00000000, }, /* 1.301e-17 */
/**/ u22 = {0x3c527bd0, 0x00000000, }, /* 4.008e-18 */
/**/ u23 = {0x3c3cd057, 0x00000000, }, /* 1.562e-18 */
/**/ u24 = {0x3c329cdf, 0x00000000, }, /* 1.009e-18 */
/**/ u31 = {0x3c3a1edf, 0x00000000, }, /* 1.416e-18 */
/**/ u32 = {0x3c33f0e1, 0x00000000, }, /* 1.081e-18 */
/**/ u4 = {0x3bf955e4, 0x00000000, }, /* 8.584e-20 */
/**/ u5 = {0x3aaef2d1, 0x00000000, }, /* 5e-26 */
/**/ u6 = {0x3a98c56d, 0x00000000, }, /* 2.001e-26 */
/**/ u7 = {0x3a9375de, 0x00000000, }, /* 1.572e-26 */
/**/ u8 = {0x3a6eeb36, 0x00000000, }, /* 3.122e-27 */
/**/ u9[M] ={{0x38c1aa5b, 0x00000000, }, /* 2.658e-35 */
/**/ {0x35c1aa4d, 0x00000000, }, /* 9.443e-50 */
/**/ {0x32c1aa88, 0x00000000, }, /* 3.355e-64 */
/**/ {0x11c1aa56, 0x00000000, }},/* 3.818e-223 */
/**/ two8 = {0x40700000, 0x00000000, }, /* 2**8=256 */
/**/ two52 = {0x43300000, 0x00000000, }; /* 2**52 */
#else
#ifdef LITTLE_ENDI
static const number
/* polynomial I */
/**/ d3 = {0x55555555, 0xbfd55555, }, /* -0.333... */
/**/ d5 = {0x999997fd, 0x3fc99999, }, /* 0.199... */
/**/ d7 = {0x923f7603, 0xbfc24924, }, /* -0.142... */
/**/ d9 = {0xe5129a3b, 0x3fbc71c6, }, /* 0.111... */
/**/ d11 = {0x22b13c25, 0xbfb74580, }, /* -0.090... */
/**/ d13 = {0x8b31cbce, 0x3fb375f0, }, /* 0.076... */
/* polynomial II */
/**/ f3 = {0x55555555, 0xbfd55555, }, /* -1/3 */
/**/ ff3 = {0x55555555, 0xbc755555, }, /* -1/3-f3 */
/**/ f5 = {0x9999999a, 0x3fc99999, }, /* 1/5 */
/**/ ff5 = {0x9999999a, 0xbc699999, }, /* 1/5-f5 */
/**/ f7 = {0x92492492, 0xbfc24924, }, /* -1/7 */
/**/ ff7 = {0x92492492, 0xbc624924, }, /* -1/7-f7 */
/**/ f9 = {0x1c71c71c, 0x3fbc71c7, }, /* 1/9 */
/**/ ff9 = {0x1c71c71c, 0x3c5c71c7, }, /* 1/9-f9 */
/**/ f11 = {0x745d1746, 0xbfb745d1, }, /* -1/11 */
/**/ f13 = {0x13b13b14, 0x3fb3b13b, }, /* 1/13 */
/**/ f15 = {0x11111111, 0xbfb11111, }, /* -1/15 */
/**/ f17 = {0x1e1e1e1e, 0x3fae1e1e, }, /* 1/17 */
/**/ f19 = {0xbca1af28, 0xbfaaf286, }, /* -1/19 */
/* constants */
/**/ zero = {0x00000000, 0x00000000, }, /* 0 */
/**/ one = {0x00000000, 0x3ff00000, }, /* 1 */
/**/ a = {0x00000000, 0x3e4bb67a, }, /* 1.290e-8 */
/**/ b = {0x00000000, 0x3fb00000, }, /* 1/16 */
/**/ c = {0x00000000, 0x3ff00000, }, /* 1 */
/**/ d = {0x00000000, 0x40300000, }, /* 16 */
/**/ e = {0x00000000, 0x43349ff2, }, /* 5.805e15 */
/**/ hpi = {0x54442d18, 0x3ff921fb, }, /* pi/2 */
/**/ mhpi = {0x54442d18, 0xbff921fb, }, /* -pi/2 */
/**/ hpi1 = {0x33145c07, 0x3c91a626, }, /* pi/2-hpi */
/**/ u1 = {0x00000000, 0x3c2d3382, }, /* 7.915e-19 */
/**/ u21 = {0x00000000, 0x3c6dffc0, }, /* 1.301e-17 */
/**/ u22 = {0x00000000, 0x3c527bd0, }, /* 4.008e-18 */
/**/ u23 = {0x00000000, 0x3c3cd057, }, /* 1.562e-18 */
/**/ u24 = {0x00000000, 0x3c329cdf, }, /* 1.009e-18 */
/**/ u31 = {0x00000000, 0x3c3a1edf, }, /* 1.416e-18 */
/**/ u32 = {0x00000000, 0x3c33f0e1, }, /* 1.081e-18 */
/**/ u4 = {0x00000000, 0x3bf955e4, }, /* 8.584e-20 */
/**/ u5 = {0x00000000, 0x3aaef2d1, }, /* 5e-26 */
/**/ u6 = {0x00000000, 0x3a98c56d, }, /* 2.001e-26 */
/**/ u7 = {0x00000000, 0x3a9375de, }, /* 1.572e-26 */
/**/ u8 = {0x00000000, 0x3a6eeb36, }, /* 3.122e-27 */
/**/ u9[M] ={{0x00000000, 0x38c1aa5b, }, /* 2.658e-35 */
/**/ {0x00000000, 0x35c1aa4d, }, /* 9.443e-50 */
/**/ {0x00000000, 0x32c1aa88, }, /* 3.355e-64 */
/**/ {0x00000000, 0x11c1aa56, }},/* 3.818e-223 */
/**/ two8 = {0x00000000, 0x40700000, }, /* 2**8=256 */
/**/ two52 = {0x00000000, 0x43300000, }; /* 2**52 */
#endif
#endif
#define ZERO zero.d
#define ONE one.d
#define A a.d
#define B b.d
#define C c.d
#define D d.d
#define E e.d
#define HPI hpi.d
#define MHPI mhpi.d
#define HPI1 hpi1.d
#define U1 u1.d
#define U21 u21.d
#define U22 u22.d
#define U23 u23.d
#define U24 u24.d
#define U31 u31.d
#define U32 u32.d
#define U4 u4.d
#define U5 u5.d
#define U6 u6.d
#define U7 u7.d
#define U8 u8.d
#define TWO8 two8.d
#define TWO52 two52.d
#endif

View File

@ -0,0 +1,183 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/************************************************************************/
/* MODULE_NAME: atnat2.h */
/* */
/* */
/* common data and variables definition for BIG or LITTLE ENDIAN */
/************************************************************************/
#ifndef ATNAT2_H
#define ATNAT2_H
#define MM 5
#ifdef BIG_ENDI
static const number
/* polynomial I */
/**/ d3 = {0xbfd55555, 0x55555555, }, /* -0.333... */
/**/ d5 = {0x3fc99999, 0x999997fd, }, /* 0.199... */
/**/ d7 = {0xbfc24924, 0x923f7603, }, /* -0.142... */
/**/ d9 = {0x3fbc71c6, 0xe5129a3b, }, /* 0.111... */
/**/ d11 = {0xbfb74580, 0x22b13c25, }, /* -0.090... */
/**/ d13 = {0x3fb375f0, 0x8b31cbce, }, /* 0.076... */
/* polynomial II */
/**/ f3 = {0xbfd55555, 0x55555555, }, /* -1/3 */
/**/ ff3 = {0xbc755555, 0x55555555, }, /* -1/3-f3 */
/**/ f5 = {0x3fc99999, 0x9999999a, }, /* 1/5 */
/**/ ff5 = {0xbc699999, 0x9999999a, }, /* 1/5-f5 */
/**/ f7 = {0xbfc24924, 0x92492492, }, /* -1/7 */
/**/ ff7 = {0xbc624924, 0x92492492, }, /* -1/7-f7 */
/**/ f9 = {0x3fbc71c7, 0x1c71c71c, }, /* 1/9 */
/**/ ff9 = {0x3c5c71c7, 0x1c71c71c, }, /* 1/9-f9 */
/**/ f11 = {0xbfb745d1, 0x745d1746, }, /* -1/11 */
/**/ f13 = {0x3fb3b13b, 0x13b13b14, }, /* 1/13 */
/**/ f15 = {0xbfb11111, 0x11111111, }, /* -1/15 */
/**/ f17 = {0x3fae1e1e, 0x1e1e1e1e, }, /* 1/17 */
/**/ f19 = {0xbfaaf286, 0xbca1af28, }, /* -1/19 */
/* constants */
/**/ zero = {0x00000000, 0x00000000, }, /* 0 */
/**/ mzero = {0x80000000, 0x00000000, }, /* -0 */
/**/ one = {0x3ff00000, 0x00000000, }, /* 1 */
/**/ inv16 = {0x3fb00000, 0x00000000, }, /* 1/16 */
/**/ opi = {0x400921fb, 0x54442d18, }, /* pi */
/**/ opi1 = {0x3ca1a626, 0x33145c07, }, /* pi-opi */
/**/ mopi = {0xc00921fb, 0x54442d18, }, /* -pi */
/**/ hpi = {0x3ff921fb, 0x54442d18, }, /* pi/2 */
/**/ hpi1 = {0x3c91a626, 0x33145c07, }, /* pi/2-hpi */
/**/ mhpi = {0xbff921fb, 0x54442d18, }, /* -pi/2 */
/**/ qpi = {0x3fe921fb, 0x54442d18, }, /* pi/4 */
/**/ qpi1 = {0x3c81a626, 0x33145c07, }, /* pi/4-qpi */
/**/ mqpi = {0xbfe921fb, 0x54442d18, }, /* -pi/4 */
/**/ tqpi = {0x4002d97c, 0x7f3321d2, }, /* 3pi/4 */
/**/ tqpi1 = {0x3c9a7939, 0x4c9e8a0a, }, /* 3pi/4-tqpi */
/**/ mtqpi = {0xc002d97c, 0x7f3321d2, }, /* -3pi/4 */
/**/ u1 = {0x3c314c2a, 0x00000000, }, /* 9.377e-19 */
/**/ u2 = {0x3bf955e4, 0x00000000, }, /* 8.584e-20 */
/**/ u3 = {0x3bf955e4, 0x00000000, }, /* 8.584e-20 */
/**/ u4 = {0x3bf955e4, 0x00000000, }, /* 8.584e-20 */
/**/ u5 = {0x3aaef2d1, 0x00000000, }, /* 5e-26 */
/**/ u6 = {0x3a6eeb36, 0x00000000, }, /* 3.122e-27 */
/**/ u7 = {0x3a6eeb36, 0x00000000, }, /* 3.122e-27 */
/**/ u8 = {0x3a6eeb36, 0x00000000, }, /* 3.122e-27 */
/**/ u91 = {0x3c6dffc0, 0x00000000, }, /* 1.301e-17 */
/**/ u92 = {0x3c527bd0, 0x00000000, }, /* 4.008e-18 */
/**/ u93 = {0x3c3cd057, 0x00000000, }, /* 1.562e-18 */
/**/ u94 = {0x3c329cdf, 0x00000000, }, /* 1.009e-18 */
/**/ ua1 = {0x3c3a1edf, 0x00000000, }, /* 1.416e-18 */
/**/ ua2 = {0x3c33f0e1, 0x00000000, }, /* 1.081e-18 */
/**/ ub = {0x3a98c56d, 0x00000000, }, /* 2.001e-26 */
/**/ uc = {0x3a9375de, 0x00000000, }, /* 1.572e-26 */
/**/ ud[MM] ={{0x38c6eddf, 0x00000000, }, /* 3.450e-35 */
/**/ {0x35c6ef60, 0x00000000, }, /* 1.226e-49 */
/**/ {0x32c6ed2f, 0x00000000, }, /* 4.354e-64 */
/**/ {0x23c6eee8, 0x00000000, }, /* 2.465e-136 */
/**/ {0x11c6ed16, 0x00000000, }},/* 4.955e-223 */
/**/ ue = {0x38900e9d, 0x00000000, }, /* 3.02e-36 */
/**/ two8 = {0x40700000, 0x00000000, }, /* 2**8=256 */
/**/ two52 = {0x43300000, 0x00000000, }, /* 2**52 */
/**/ two500 = {0x5f300000, 0x00000000, }, /* 2**500 */
/**/ twom500 = {0x20b00000, 0x00000000, }, /* 2**(-500) */
/**/ twom1022 = {0x00100000, 0x00000000, }; /* 2**(-1022) */
#else
#ifdef LITTLE_ENDI
static const number
/* polynomial I */
/**/ d3 = {0x55555555, 0xbfd55555, }, /* -0.333... */
/**/ d5 = {0x999997fd, 0x3fc99999, }, /* 0.199... */
/**/ d7 = {0x923f7603, 0xbfc24924, }, /* -0.142... */
/**/ d9 = {0xe5129a3b, 0x3fbc71c6, }, /* 0.111... */
/**/ d11 = {0x22b13c25, 0xbfb74580, }, /* -0.090... */
/**/ d13 = {0x8b31cbce, 0x3fb375f0, }, /* 0.076... */
/* polynomial II */
/**/ f3 = {0x55555555, 0xbfd55555, }, /* -1/3 */
/**/ ff3 = {0x55555555, 0xbc755555, }, /* -1/3-f3 */
/**/ f5 = {0x9999999a, 0x3fc99999, }, /* 1/5 */
/**/ ff5 = {0x9999999a, 0xbc699999, }, /* 1/5-f5 */
/**/ f7 = {0x92492492, 0xbfc24924, }, /* -1/7 */
/**/ ff7 = {0x92492492, 0xbc624924, }, /* -1/7-f7 */
/**/ f9 = {0x1c71c71c, 0x3fbc71c7, }, /* 1/9 */
/**/ ff9 = {0x1c71c71c, 0x3c5c71c7, }, /* 1/9-f9 */
/**/ f11 = {0x745d1746, 0xbfb745d1, }, /* -1/11 */
/**/ f13 = {0x13b13b14, 0x3fb3b13b, }, /* 1/13 */
/**/ f15 = {0x11111111, 0xbfb11111, }, /* -1/15 */
/**/ f17 = {0x1e1e1e1e, 0x3fae1e1e, }, /* 1/17 */
/**/ f19 = {0xbca1af28, 0xbfaaf286, }, /* -1/19 */
/* constants */
/**/ zero = {0x00000000, 0x00000000, }, /* 0 */
/**/ mzero = {0x00000000, 0x80000000, }, /* -0 */
/**/ one = {0x00000000, 0x3ff00000, }, /* 1 */
/**/ inv16 = {0x00000000, 0x3fb00000, }, /* 1/16 */
/**/ opi = {0x54442d18, 0x400921fb, }, /* pi */
/**/ opi1 = {0x33145c07, 0x3ca1a626, }, /* pi-opi */
/**/ mopi = {0x54442d18, 0xc00921fb, }, /* -pi */
/**/ hpi = {0x54442d18, 0x3ff921fb, }, /* pi/2 */
/**/ hpi1 = {0x33145c07, 0x3c91a626, }, /* pi/2-hpi */
/**/ mhpi = {0x54442d18, 0xbff921fb, }, /* -pi/2 */
/**/ qpi = {0x54442d18, 0x3fe921fb, }, /* pi/4 */
/**/ qpi1 = {0x33145c07, 0x3c81a626, }, /* pi/4-qpi */
/**/ mqpi = {0x54442d18, 0xbfe921fb, }, /* -pi/4 */
/**/ tqpi = {0x7f3321d2, 0x4002d97c, }, /* 3pi/4 */
/**/ tqpi1 = {0x4c9e8a0a, 0x3c9a7939, }, /* 3pi/4-tqpi */
/**/ mtqpi = {0x7f3321d2, 0xc002d97c, }, /* -3pi/4 */
/**/ u1 = {0x00000000, 0x3c314c2a, }, /* 9.377e-19 */
/**/ u2 = {0x00000000, 0x3bf955e4, }, /* 8.584e-20 */
/**/ u3 = {0x00000000, 0x3bf955e4, }, /* 8.584e-20 */
/**/ u4 = {0x00000000, 0x3bf955e4, }, /* 8.584e-20 */
/**/ u5 = {0x00000000, 0x3aaef2d1, }, /* 5e-26 */
/**/ u6 = {0x00000000, 0x3a6eeb36, }, /* 3.122e-27 */
/**/ u7 = {0x00000000, 0x3a6eeb36, }, /* 3.122e-27 */
/**/ u8 = {0x00000000, 0x3a6eeb36, }, /* 3.122e-27 */
/**/ u91 = {0x00000000, 0x3c6dffc0, }, /* 1.301e-17 */
/**/ u92 = {0x00000000, 0x3c527bd0, }, /* 4.008e-18 */
/**/ u93 = {0x00000000, 0x3c3cd057, }, /* 1.562e-18 */
/**/ u94 = {0x00000000, 0x3c329cdf, }, /* 1.009e-18 */
/**/ ua1 = {0x00000000, 0x3c3a1edf, }, /* 1.416e-18 */
/**/ ua2 = {0x00000000, 0x3c33f0e1, }, /* 1.081e-18 */
/**/ ub = {0x00000000, 0x3a98c56d, }, /* 2.001e-26 */
/**/ uc = {0x00000000, 0x3a9375de, }, /* 1.572e-26 */
/**/ ud[MM] ={{0x00000000, 0x38c6eddf, }, /* 3.450e-35 */
/**/ {0x00000000, 0x35c6ef60, }, /* 1.226e-49 */
/**/ {0x00000000, 0x32c6ed2f, }, /* 4.354e-64 */
/**/ {0x00000000, 0x23c6eee8, }, /* 2.465e-136 */
/**/ {0x00000000, 0x11c6ed16, }},/* 4.955e-223 */
/**/ ue = {0x00000000, 0x38900e9d, }, /* 3.02e-36 */
/**/ two8 = {0x00000000, 0x40700000, }, /* 2**8=256 */
/**/ two52 = {0x00000000, 0x43300000, }, /* 2**52 */
/**/ two500 = {0x00000000, 0x5f300000, }, /* 2**500 */
/**/ twom500 = {0x00000000, 0x20b00000, }, /* 2**(-500) */
/**/ twom1022 = {0x00000000, 0x00100000, }; /* 2**(-1022) */
#endif
#endif
#define ZERO zero.d
#define MZERO mzero.d
#define ONE one.d
#define TWO8 two8.d
#define TWO52 two52.d
#define TWOM1022 twom1022.d
#endif

View File

@ -0,0 +1,139 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*******************************************************************/
/* */
/* MODULE_NAME: branred.c */
/* */
/* FUNCTIONS: branred */
/* */
/* FILES NEEDED: branred.h mydefs.h endian.h mpa.h */
/* mha.c */
/* */
/* Routine branred() performs range reduction of a double number */
/* x into Double length number a+aa,such that */
/* x=n*pi/2+(a+aa), abs(a+aa)<pi/4, n=0,+-1,+-2,.... */
/* Routine returns the integer (n mod 4) of the above description */
/* of x. */
/*******************************************************************/
#include "endian.h"
#include "mydefs.h"
#include "branred.h"
/*******************************************************************/
/* Routine branred() performs range reduction of a double number */
/* x into Double length number a+aa,such that */
/* x=n*pi/2+(a+aa), abs(a+aa)<pi/4, n=0,+-1,+-2,.... */
/* Routine return integer (n mod 4) */
/*******************************************************************/
int branred(double x, double *a, double *aa)
{
int i,k,n;
mynumber u,v,gor;
double r[6],s,t,sum,b,bb,sum1,sum2,b1,bb1,b2,bb2,x1,x2,t1,t2;
x*=tm600.x;
t=x*split; /* split x to two numbers */
x1=t-(t-x);
x2=x-x1;
sum=0;
u.x = x1;
k = (u.i[HIGH_HALF]>>20)&2047;
k = (k-450)/24;
if (k<0)
k=0;
gor.x = t576.x;
gor.i[HIGH_HALF] -= ((k*24)<<20);
for (i=0;i<6;i++)
{ r[i] = x1*toverp[k+i]*gor.x; gor.x *= tm24.x; }
for (i=0;i<3;i++) {
s=(r[i]+big.x)-big.x;
sum+=s;
r[i]-=s;
}
t=0;
for (i=0;i<6;i++)
t+=r[5-i];
bb=(((((r[0]-t)+r[1])+r[2])+r[3])+r[4])+r[5];
s=(t+big.x)-big.x;
sum+=s;
t-=s;
b=t+bb;
bb=(t-b)+bb;
s=(sum+big1.x)-big1.x;
sum-=s;
b1=b;
bb1=bb;
sum1=sum;
sum=0;
u.x = x2;
k = (u.i[HIGH_HALF]>>20)&2047;
k = (k-450)/24;
if (k<0)
k=0;
gor.x = t576.x;
gor.i[HIGH_HALF] -= ((k*24)<<20);
for (i=0;i<6;i++)
{ r[i] = x2*toverp[k+i]*gor.x; gor.x *= tm24.x; }
for (i=0;i<3;i++) {
s=(r[i]+big.x)-big.x;
sum+=s;
r[i]-=s;
}
t=0;
for (i=0;i<6;i++)
t+=r[5-i];
bb=(((((r[0]-t)+r[1])+r[2])+r[3])+r[4])+r[5];
s=(t+big.x)-big.x;
sum+=s;
t-=s;
b=t+bb;
bb=(t-b)+bb;
s=(sum+big1.x)-big1.x;
sum-=s;
b2=b;
bb2=bb;
sum2=sum;
sum=sum1+sum2;
b=b1+b2;
bb = (ABS(b1)>ABS(b2))? (b1-b)+b2 : (b2-b)+b1;
if (b > 0.5)
{b-=1.0; sum+=1.0;}
else if (b < -0.5)
{b+=1.0; sum-=1.0;}
s=b+(bb+bb1+bb2);
t=((b-s)+bb)+(bb1+bb2);
b=s*split;
t1=b-(b-s);
t2=s-t1;
b=s*hp0.x;
bb=(((t1*mp1.x-b)+t1*mp2.x)+t2*mp1.x)+(t2*mp2.x+s*hp1.x+t*hp0.x);
s=b+bb;
t=(b-s)+bb;
*a=s;
*aa=t;
return ((int) sum)&3; /* return quater of unit circle */
}

View File

@ -0,0 +1,80 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/************************************************************************/
/* MODULE_NAME: branred.h */
/* */
/* */
/* common data and variables definition for BIG or LITTLE ENDIAN */
/************************************************************************/
#ifndef BRANRED_H
#define BRANRED_H
#ifdef BIG_ENDI
static const mynumber
/**/ t576 = {0x63f00000, 0x00000000 }, /* 2 ^ 576 */
/**/ tm600 = {0x1a700000, 0x00000000 }, /* 2 ^- 600 */
/**/ tm24 = {0x3e700000, 0x00000000 }, /* 2 ^- 24 */
/**/ big = {0x43380000, 0x00000000 }, /* 6755399441055744 */
/**/ big1 = {0x43580000, 0x00000000 }, /* 27021597764222976 */
/**/ hp0 = {0x3FF921FB, 0x54442D18 } ,/* 1.5707963267948966 */
/**/ hp1 = {0x3C91A626, 0x33145C07 } ,/* 6.123233995736766e-17 */
/**/ mp1 = {0x3FF921FB, 0x58000000 }, /* 1.5707963407039642 */
/**/ mp2 = {0xBE4DDE97, 0x40000000 }; /*-1.3909067675399456e-08 */
#else
#ifdef LITTLE_ENDI
static const mynumber
/**/ t576 = {0x00000000, 0x63f00000 }, /* 2 ^ 576 */
/**/ tm600 = {0x00000000, 0x1a700000 }, /* 2 ^- 600 */
/**/ tm24 = {0x00000000, 0x3e700000 }, /* 2 ^- 24 */
/**/ big = {0x00000000, 0x43380000 }, /* 6755399441055744 */
/**/ big1 = {0x00000000, 0x43580000 }, /* 27021597764222976 */
/**/ hp0 = {0x54442D18, 0x3FF921FB }, /* 1.5707963267948966 */
/**/ hp1 = {0x33145C07, 0x3C91A626 }, /* 6.123233995736766e-17 */
/**/ mp1 = {0x58000000, 0x3FF921FB }, /* 1.5707963407039642 */
/**/ mp2 = {0x40000000, 0xBE4DDE97 }; /*-1.3909067675399456e-08 */
#endif
#endif
static const double toverp[75] = { /* 2/ PI base 24*/
10680707.0, 7228996.0, 1387004.0, 2578385.0, 16069853.0,
12639074.0, 9804092.0, 4427841.0, 16666979.0, 11263675.0,
12935607.0, 2387514.0, 4345298.0, 14681673.0, 3074569.0,
13734428.0, 16653803.0, 1880361.0, 10960616.0, 8533493.0,
3062596.0, 8710556.0, 7349940.0, 6258241.0, 3772886.0,
3769171.0, 3798172.0, 8675211.0, 12450088.0, 3874808.0,
9961438.0, 366607.0, 15675153.0, 9132554.0, 7151469.0,
3571407.0, 2607881.0, 12013382.0, 4155038.0, 6285869.0,
7677882.0, 13102053.0, 15825725.0, 473591.0, 9065106.0,
15363067.0, 6271263.0, 9264392.0, 5636912.0, 4652155.0,
7056368.0, 13614112.0, 10155062.0, 1944035.0, 9527646.0,
15080200.0, 6658437.0, 6231200.0, 6832269.0, 16767104.0,
5075751.0, 3212806.0, 1398474.0, 7579849.0, 6349435.0,
12618859.0, 4703257.0, 12806093.0, 14477321.0, 2786137.0,
12875403.0, 9837734.0, 14528324.0, 13719321.0, 343717.0 };
static const double split = 134217729.0;
#endif

View File

@ -0,0 +1,173 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/***********************************************************************/
/*MODULE_NAME: dla.h */
/* */
/* This file holds C language macros for 'Double Length Floating Point */
/* Arithmetic'. The macros are based on the paper: */
/* T.J.Dekker, "A floating-point Technique for extending the */
/* Available Precision", Number. Math. 18, 224-242 (1971). */
/* A Double-Length number is defined by a pair (r,s), of IEEE double */
/* precision floating point numbers that satisfy, */
/* */
/* abs(s) <= abs(r+s)*2**(-53)/(1+2**(-53)). */
/* */
/* The computer arithmetic assumed is IEEE double precision in */
/* round to nearest mode. All variables in the macros must be of type */
/* IEEE double. */
/***********************************************************************/
/* CN = 1+2**27 = '41a0000002000000' IEEE double format */
#define CN 134217729.0
/* Exact addition of two single-length floating point numbers, Dekker. */
/* The macro produces a double-length number (z,zz) that satisfies */
/* z+zz = x+y exactly. */
#define EADD(x,y,z,zz) \
z=(x)+(y); zz=(ABS(x)>ABS(y)) ? (((x)-(z))+(y)) : (((y)-(z))+(x));
/* Exact subtraction of two single-length floating point numbers, Dekker. */
/* The macro produces a double-length number (z,zz) that satisfies */
/* z+zz = x-y exactly. */
#define ESUB(x,y,z,zz) \
z=(x)-(y); zz=(ABS(x)>ABS(y)) ? (((x)-(z))-(y)) : ((x)-((y)+(z)));
/* Exact multiplication of two single-length floating point numbers, */
/* Veltkamp. The macro produces a double-length number (z,zz) that */
/* satisfies z+zz = x*y exactly. p,hx,tx,hy,ty are temporary */
/* storage variables of type double. */
#define EMULV(x,y,z,zz,p,hx,tx,hy,ty) \
p=CN*(x); hx=((x)-p)+p; tx=(x)-hx; \
p=CN*(y); hy=((y)-p)+p; ty=(y)-hy; \
z=(x)*(y); zz=(((hx*hy-z)+hx*ty)+tx*hy)+tx*ty;
/* Exact multiplication of two single-length floating point numbers, Dekker. */
/* The macro produces a nearly double-length number (z,zz) (see Dekker) */
/* that satisfies z+zz = x*y exactly. p,hx,tx,hy,ty,q are temporary */
/* storage variables of type double. */
#define MUL12(x,y,z,zz,p,hx,tx,hy,ty,q) \
p=CN*(x); hx=((x)-p)+p; tx=(x)-hx; \
p=CN*(y); hy=((y)-p)+p; ty=(y)-hy; \
p=hx*hy; q=hx*ty+tx*hy; z=p+q; zz=((p-z)+q)+tx*ty;
/* Double-length addition, Dekker. The macro produces a double-length */
/* number (z,zz) which satisfies approximately z+zz = x+xx + y+yy. */
/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy) */
/* are assumed to be double-length numbers. r,s are temporary */
/* storage variables of type double. */
#define ADD2(x,xx,y,yy,z,zz,r,s) \
r=(x)+(y); s=(ABS(x)>ABS(y)) ? \
(((((x)-r)+(y))+(yy))+(xx)) : \
(((((y)-r)+(x))+(xx))+(yy)); \
z=r+s; zz=(r-z)+s;
/* Double-length subtraction, Dekker. The macro produces a double-length */
/* number (z,zz) which satisfies approximately z+zz = x+xx - (y+yy). */
/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy) */
/* are assumed to be double-length numbers. r,s are temporary */
/* storage variables of type double. */
#define SUB2(x,xx,y,yy,z,zz,r,s) \
r=(x)-(y); s=(ABS(x)>ABS(y)) ? \
(((((x)-r)-(y))-(yy))+(xx)) : \
((((x)-((y)+r))+(xx))-(yy)); \
z=r+s; zz=(r-z)+s;
/* Double-length multiplication, Dekker. The macro produces a double-length */
/* number (z,zz) which satisfies approximately z+zz = (x+xx)*(y+yy). */
/* An error bound: abs((x+xx)*(y+yy))*1.24e-31. (x,xx), (y,yy) */
/* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc are */
/* temporary storage variables of type double. */
#define MUL2(x,xx,y,yy,z,zz,p,hx,tx,hy,ty,q,c,cc) \
MUL12(x,y,c,cc,p,hx,tx,hy,ty,q) \
cc=((x)*(yy)+(xx)*(y))+cc; z=c+cc; zz=(c-z)+cc;
/* Double-length division, Dekker. The macro produces a double-length */
/* number (z,zz) which satisfies approximately z+zz = (x+xx)/(y+yy). */
/* An error bound: abs((x+xx)/(y+yy))*1.50e-31. (x,xx), (y,yy) */
/* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc,u,uu */
/* are temporary storage variables of type double. */
#define DIV2(x,xx,y,yy,z,zz,p,hx,tx,hy,ty,q,c,cc,u,uu) \
c=(x)/(y); MUL12(c,y,u,uu,p,hx,tx,hy,ty,q) \
cc=(((((x)-u)-uu)+(xx))-c*(yy))/(y); z=c+cc; zz=(c-z)+cc;
/* Double-length addition, slower but more accurate than ADD2. */
/* The macro produces a double-length */
/* number (z,zz) which satisfies approximately z+zz = (x+xx)+(y+yy). */
/* An error bound: abs(x+xx + y+yy)*1.50e-31. (x,xx), (y,yy) */
/* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */
/* are temporary storage variables of type double. */
#define ADD2A(x,xx,y,yy,z,zz,r,rr,s,ss,u,uu,w) \
r=(x)+(y); \
if (ABS(x)>ABS(y)) { rr=((x)-r)+(y); s=(rr+(yy))+(xx); } \
else { rr=((y)-r)+(x); s=(rr+(xx))+(yy); } \
if (rr!=0.0) { \
z=r+s; zz=(r-z)+s; } \
else { \
ss=(ABS(xx)>ABS(yy)) ? (((xx)-s)+(yy)) : (((yy)-s)+(xx)); \
u=r+s; \
uu=(ABS(r)>ABS(s)) ? ((r-u)+s) : ((s-u)+r) ; \
w=uu+ss; z=u+w; \
zz=(ABS(u)>ABS(w)) ? ((u-z)+w) : ((w-z)+u) ; }
/* Double-length subtraction, slower but more accurate than SUB2. */
/* The macro produces a double-length */
/* number (z,zz) which satisfies approximately z+zz = (x+xx)-(y+yy). */
/* An error bound: abs(x+xx - (y+yy))*1.50e-31. (x,xx), (y,yy) */
/* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */
/* are temporary storage variables of type double. */
#define SUB2A(x,xx,y,yy,z,zz,r,rr,s,ss,u,uu,w) \
r=(x)-(y); \
if (ABS(x)>ABS(y)) { rr=((x)-r)-(y); s=(rr-(yy))+(xx); } \
else { rr=(x)-((y)+r); s=(rr+(xx))-(yy); } \
if (rr!=0.0) { \
z=r+s; zz=(r-z)+s; } \
else { \
ss=(ABS(xx)>ABS(yy)) ? (((xx)-s)-(yy)) : ((xx)-((yy)+s)); \
u=r+s; \
uu=(ABS(r)>ABS(s)) ? ((r-u)+s) : ((s-u)+r) ; \
w=uu+ss; z=u+w; \
zz=(ABS(u)>ABS(w)) ? ((u-z)+w) : ((w-z)+u) ; }

View File

@ -0,0 +1,81 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/**********************************************************************/
/* MODULE_NAME: doasin.c */
/* */
/* FUNCTION: doasin */
/* */
/* FILES NEEDED:endian.h mydefs.h dla.h doasin.h */
/* mpa.c */
/* */
/* Compute arcsin(x,dx,v) of double-length number (x+dx) the result */
/* stored in v where v= v[0]+v[1] =arcsin(x+dx) */
/**********************************************************************/
#include "endian.h"
#include "mydefs.h"
#include "dla.h"
/********************************************************************/
/* Compute arcsin(x,dx,v) of double-length number (x+dx) the result */
/* stored in v where v= v[0]+v[1] =arcsin(x+dx) */
/********************************************************************/
void doasin(double x, double dx, double v[]) {
#include "doasin.h"
static const double
d5 = 0.22372159090911789889975459505194491E-01,
d6 = 0.17352764422456822913014975683014622E-01,
d7 = 0.13964843843786693521653681033981614E-01,
d8 = 0.11551791438485242609036067259086589E-01,
d9 = 0.97622386568166960207425666787248914E-02,
d10 = 0.83638737193775788576092749009744976E-02,
d11 = 0.79470250400727425881446981833568758E-02;
double xx,p,pp,u,uu,r,s;
double hx,tx,hy,ty,tp,tq,tc,tcc;
/* Taylor series for arcsin for Double-Length numbers */
xx = x*x+2.0*x*dx;
p = ((((((d11*xx+d10)*xx+d9)*xx+d8)*xx+d7)*xx+d6)*xx+d5)*xx;
pp = 0;
MUL2(x,dx,x,dx,u,uu,tp,hx,tx,hy,ty,tq,tc,tcc);
ADD2(p,pp,c4.x,cc4.x,p,pp,r,s);
MUL2(p,pp,u,uu,p,pp,tp,hx,tx,hy,ty,tq,tc,tcc);
ADD2(p,pp,c3.x,cc3.x,p,pp,r,s);
MUL2(p,pp,u,uu,p,pp,tp,hx,tx,hy,ty,tq,tc,tcc);
ADD2(p,pp,c2.x,cc2.x,p,pp,r,s);
MUL2(p,pp,u,uu,p,pp,tp,hx,tx,hy,ty,tq,tc,tcc);
ADD2(p,pp,c1.x,cc1.x,p,pp,r,s);
MUL2(p,pp,u,uu,p,pp,tp,hx,tx,hy,ty,tq,tc,tcc);
MUL2(p,pp,x,dx,p,pp,tp,hx,tx,hy,ty,tq,tc,tcc);
ADD2(p,pp,x,dx,p,pp,r,s);
v[0]=p;
v[1]=pp; /* arcsin(x+dx)=v[0]+v[1] */
}

View File

@ -0,0 +1,62 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/************************************************************************/
/* MODULE_NAME: doasin.h */
/* */
/* */
/* common data and variables definition for BIG or LITTLE ENDIAN */
/************************************************************************/
#ifndef DOASIN_H
#define DOASIN_H
#ifdef BIG_ENDI
static const mynumber
/**/ c1 = {0x3FC55555, 0x55555555}, /* 0.16666666666666666 */
/**/ cc1 = {0x3C655555, 0x55775389}, /* 9.2518585419753846e-18 */
/**/ c2 = {0x3FB33333, 0x33333333}, /* 0.074999999999999997 */
/**/ cc2 = {0x3C499993, 0x63F1A115}, /* 2.7755472886508899e-18 */
/**/ c3 = {0x3FA6DB6D, 0xB6DB6DB7}, /* 0.044642857142857144 */
/**/ cc3 = {0xBC320FC0, 0x3D5CF0C5}, /* -9.7911734574147224e-19 */
/**/ c4 = {0x3F9F1C71, 0xC71C71C5}, /* 0.030381944444444437 */
/**/ cc4 = {0xBC02B240, 0xFF23ED1E}; /* -1.2669108566898312e-19 */
#else
#ifdef LITTLE_ENDI
static const mynumber
/**/ c1 = {0x55555555, 0x3FC55555}, /* 0.16666666666666666 */
/**/ cc1 = {0x55775389, 0x3C655555}, /* 9.2518585419753846e-18 */
/**/ c2 = {0x33333333, 0x3FB33333}, /* 0.074999999999999997 */
/**/ cc2 = {0x63F1A115, 0x3C499993}, /* 2.7755472886508899e-18 */
/**/ c3 = {0xB6DB6DB7, 0x3FA6DB6D}, /* 0.044642857142857144 */
/**/ cc3 = {0x3D5CF0C5, 0xBC320FC0}, /* -9.7911734574147224e-19 */
/**/ c4 = {0xC71C71C5, 0x3F9F1C71}, /* 0.030381944444444437 */
/**/ cc4 = {0xFF23ED1E, 0xBC02B240}; /* -1.2669108566898312e-19 */
#endif
#endif
#endif

View File

@ -0,0 +1,181 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/********************************************************************/
/* */
/* MODULE_NAME: dosincos.c */
/* */
/* */
/* FUNCTIONS: dubsin */
/* dubcos */
/* docos */
/* FILES NEEDED: endian.h mydefs.h dla.h dosincos.h */
/* sincos.tbl */
/* */
/* Routines compute sin() and cos() as Double-Length numbers */
/********************************************************************/
#include "endian.h"
#include "mydefs.h"
#include "sincos.tbl"
#include "dla.h"
#include "dosincos.h"
/***********************************************************************/
/* Routine receive Double-Length number (x+dx) and computing sin(x+dx) */
/* as Double-Length number and store it at array v .It computes it by */
/* arithmetic action on Double-Length numbers */
/*(x+dx) between 0 and PI/4 */
/***********************************************************************/
void dubsin(double x, double dx, double v[]) {
double xx,y,yy,z,zz,r,s,p,hx,tx,hy,ty,q,c,cc,d,dd,d2,dd2,e,ee,
sn,ssn,cs,ccs,ds,dss,dc,dcc;
mynumber u;
int4 k;
u.x=x+big.x;
k = u.i[LOW_HALF]<<2;
x=x-(u.x-big.x);
d=x+dx;
dd=(x-d)+dx;
/* sin(x+dx)=sin(Xi+t)=sin(Xi)*cos(t) + cos(Xi)sin(t) where t ->0 */
MUL2(d,dd,d,dd,d2,dd2,p,hx,tx,hy,ty,q,c,cc);
sn=sincos.x[k]; /* */
ssn=sincos.x[k+1]; /* sin(Xi) and cos(Xi) */
cs=sincos.x[k+2]; /* */
ccs=sincos.x[k+3]; /* */
MUL2(d2,dd2,s7.x,ss7.x,ds,dss,p,hx,tx,hy,ty,q,c,cc); /* Taylor */
ADD2(ds,dss,s5.x,ss5.x,ds,dss,r,s);
MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc); /* series */
ADD2(ds,dss,s3.x,ss3.x,ds,dss,r,s);
MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc); /* for sin */
MUL2(d,dd,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
ADD2(ds,dss,d,dd,ds,dss,r,s); /* ds=sin(t) */
MUL2(d2,dd2,c8.x,cc8.x,dc,dcc,p,hx,tx,hy,ty,q,c,cc); ;/* Taylor */
ADD2(dc,dcc,c6.x,cc6.x,dc,dcc,r,s);
MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); /* series */
ADD2(dc,dcc,c4.x,cc4.x,dc,dcc,r,s);
MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); /* for cos */
ADD2(dc,dcc,c2.x,cc2.x,dc,dcc,r,s);
MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); /* dc=cos(t) */
MUL2(cs,ccs,ds,dss,e,ee,p,hx,tx,hy,ty,q,c,cc);
MUL2(dc,dcc,sn,ssn,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
SUB2(e,ee,dc,dcc,e,ee,r,s);
ADD2(e,ee,sn,ssn,e,ee,r,s); /* e+ee=sin(x+dx) */
v[0]=e;
v[1]=ee;
}
/**********************************************************************/
/* Routine receive Double-Length number (x+dx) and computes cos(x+dx) */
/* as Double-Length number and store it in array v .It computes it by */
/* arithmetic action on Double-Length numbers */
/*(x+dx) between 0 and PI/4 */
/**********************************************************************/
void dubcos(double x, double dx, double v[]) {
double xx,y,yy,z,zz,r,s,p,hx,tx,hy,ty,q,c,cc,d,dd,d2,dd2,e,ee,
sn,ssn,cs,ccs,ds,dss,dc,dcc;
mynumber u;
int4 k;
u.x=x+big.x;
k = u.i[LOW_HALF]<<2;
x=x-(u.x-big.x);
d=x+dx;
dd=(x-d)+dx; /* cos(x+dx)=cos(Xi+t)=cos(Xi)cos(t) - sin(Xi)sin(t) */
MUL2(d,dd,d,dd,d2,dd2,p,hx,tx,hy,ty,q,c,cc);
sn=sincos.x[k]; /* */
ssn=sincos.x[k+1]; /* sin(Xi) and cos(Xi) */
cs=sincos.x[k+2]; /* */
ccs=sincos.x[k+3]; /* */
MUL2(d2,dd2,s7.x,ss7.x,ds,dss,p,hx,tx,hy,ty,q,c,cc);
ADD2(ds,dss,s5.x,ss5.x,ds,dss,r,s);
MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
ADD2(ds,dss,s3.x,ss3.x,ds,dss,r,s);
MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
MUL2(d,dd,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
ADD2(ds,dss,d,dd,ds,dss,r,s);
MUL2(d2,dd2,c8.x,cc8.x,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
ADD2(dc,dcc,c6.x,cc6.x,dc,dcc,r,s);
MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
ADD2(dc,dcc,c4.x,cc4.x,dc,dcc,r,s);
MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
ADD2(dc,dcc,c2.x,cc2.x,dc,dcc,r,s);
MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
MUL2(cs,ccs,ds,dss,e,ee,p,hx,tx,hy,ty,q,c,cc);
MUL2(dc,dcc,sn,ssn,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
MUL2(d2,dd2,s7.x,ss7.x,ds,dss,p,hx,tx,hy,ty,q,c,cc);
ADD2(ds,dss,s5.x,ss5.x,ds,dss,r,s);
MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
ADD2(ds,dss,s3.x,ss3.x,ds,dss,r,s);
MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
MUL2(d,dd,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
ADD2(ds,dss,d,dd,ds,dss,r,s);
MUL2(d2,dd2,c8.x,cc8.x,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
ADD2(dc,dcc,c6.x,cc6.x,dc,dcc,r,s);
MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
ADD2(dc,dcc,c4.x,cc4.x,dc,dcc,r,s);
MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
ADD2(dc,dcc,c2.x,cc2.x,dc,dcc,r,s);
MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
MUL2(sn,ssn,ds,dss,e,ee,p,hx,tx,hy,ty,q,c,cc);
MUL2(dc,dcc,cs,ccs,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
ADD2(e,ee,dc,dcc,e,ee,r,s);
SUB2(cs,ccs,e,ee,e,ee,r,s);
v[0]=e;
v[1]=ee;
}
/**********************************************************************/
/* Routine receive Double-Length number (x+dx) and computes cos(x+dx) */
/* as Double-Length number and store it in array v */
/**********************************************************************/
void docos(double x, double dx, double v[]) {
double y,yy,p,w[2];
if (x>0) {y=x; yy=dx;}
else {y=-x; yy=-dx;}
if (y<0.5*hp0.x) /* y< PI/4 */
{dubcos(y,yy,w); v[0]=w[0]; v[1]=w[1];}
else if (y<1.5*hp0.x) { /* y< 3/4 * PI */
p=hp0.x-y; /* p = PI/2 - y */
yy=hp1.x-yy;
y=p+yy;
yy=(p-y)+yy;
if (y>0) {dubsin(y,yy,w); v[0]=w[0]; v[1]=w[1];}
/* cos(x) = sin ( 90 - x ) */
else {dubsin(-y,-yy,w); v[0]=-w[0]; v[1]=-w[1];
}
}
else { /* y>= 3/4 * PI */
p=2.0*hp0.x-y; /* p = PI- y */
yy=2.0*hp1.x-yy;
y=p+yy;
yy=(p-y)+yy;
dubcos(y,yy,w);
v[0]=-w[0];
v[1]=-w[1];
}
}

View File

@ -0,0 +1,79 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/************************************************************************/
/* MODULE_NAME: dosincos.h */
/* */
/* */
/* common data and variables definition for BIG or LITTLE ENDIAN */
/************************************************************************/
#ifndef DOSINCOS_H
#define DOSINCOS_H
#ifdef BIG_ENDI
static const mynumber
/**/ s3 = {0xBFC55555, 0x55555555}, /* -0.16666666666666666 */
/**/ ss3 = {0xBC6553AA, 0xE77EE482}, /* -9.2490366677784492e-18 */
/**/ s5 = {0x3F811111, 0x11110F15}, /* 0.008333333333332452 */
/**/ ss5 = {0xBC21AC06, 0xDA488820}, /* -4.7899996586987931e-19 */
/**/ s7 = {0xBF2A019F, 0x5816C78D}, /* -0.00019841261022928957 */
/**/ ss7 = {0x3BCDCEC9, 0x6A18BF2A}, /* 1.2624077757871259e-20 */
/**/ c2 = {0x3FE00000, 0x00000000}, /* 0.5 */
/**/ cc2 = {0xBA282FD8, 0x00000000}, /* -1.5264073330037701e-28 */
/**/ c4 = {0xBFA55555, 0x55555555}, /* -0.041666666666666664 */
/**/ cc4 = {0xBC4554BC, 0x2FFF257E}, /* -2.312711276085743e-18 */
/**/ c6 = {0x3F56C16C, 0x16C16A96}, /* 0.0013888888888888055 */
/**/ cc6 = {0xBBD2E846, 0xE6346F14}, /* -1.6015133010194884e-20 */
/**/ c8 = {0xBEFA019F, 0x821D5987}, /* -2.480157866754367e-05 */
/**/ cc8 = {0x3B7AB71E, 0x72FFE5CC}, /* 3.5357416224857556e-22 */
/**/ big = {0x42c80000, 0x00000000}, /* 52776558133248 */
/**/ hp0 = {0x3FF921FB, 0x54442D18 }, /* PI / 2 */
/**/ hp1 = {0x3C91A626, 0x33145C07 }; /* 6.123233995736766e-17 */
#else
#ifdef LITTLE_ENDI
static const mynumber
/**/ s3 = {0x55555555, 0xBFC55555}, /* -0.16666666666666666 */
/**/ ss3 = {0xE77EE482, 0xBC6553AA}, /* -9.2490366677784492e-18 */
/**/ s5 = {0x11110F15, 0x3F811111}, /* 0.008333333333332452 */
/**/ ss5 = {0xDA488820, 0xBC21AC06}, /* -4.7899996586987931e-19 */
/**/ s7 = {0x5816C78D, 0xBF2A019F}, /* -0.00019841261022928957 */
/**/ ss7 = {0x6A18BF2A, 0x3BCDCEC9}, /* 1.2624077757871259e-20 */
/**/ c2 = {0x00000000, 0x3FE00000}, /* 0.5 */
/**/ cc2 = {0x00000000, 0xBA282FD8}, /* -1.5264073330037701e-28 */
/**/ c4 = {0x55555555, 0xBFA55555}, /* -0.041666666666666664 */
/**/ cc4 = {0x2FFF257E, 0xBC4554BC}, /* -2.312711276085743e-18 */
/**/ c6 = {0x16C16A96, 0x3F56C16C}, /* 0.0013888888888888055 */
/**/ cc6 = {0xE6346F14, 0xBBD2E846}, /* -1.6015133010194884e-20 */
/**/ c8 = {0x821D5987, 0xBEFA019F}, /* -2.480157866754367e-05 */
/**/ cc8 = {0x72FFE5CC, 0x3B7AB71E}, /* 3.5357416224857556e-22 */
/**/ big = {0x00000000, 0x42c80000}, /* 52776558133248 */
/**/ hp0 = {0x54442D18, 0x3FF921FB }, /* PI / 2 */
/**/ hp1 = {0x33145C07, 0x3C91A626 }; /* 6.123233995736766e-17 */
#endif
#endif
#endif

View File

@ -1,144 +1 @@
/* @(#)e_acos.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* 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.
* ====================================================
*/
/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25,
for performance improvement on pipelined processors.
*/
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: e_acos.c,v 1.9 1995/05/12 04:57:13 jtc Exp $";
#endif
/* __ieee754_acos(x)
* Method :
* acos(x) = pi/2 - asin(x)
* acos(-x) = pi/2 + asin(x)
* For |x|<=0.5
* acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c)
* For x>0.5
* acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
* = 2asin(sqrt((1-x)/2))
* = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z)
* = 2f + (2c + 2s*z*R(z))
* where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
* for f so that f+c ~ sqrt(z).
* For x<-0.5
* acos(x) = pi - 2asin(sqrt((1-|x|)/2))
* = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
*
* Special cases:
* if x is NaN, return x itself;
* if |x|>1, return NaN with invalid signal.
*
* Function needed: __ieee754_sqrt
*/
#include "math.h"
#include "math_private.h"
#define one qS[0]
#ifdef __STDC__
static const double
#else
static double
#endif
pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
pS[] = {1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
-3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
-4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
3.47933107596021167570e-05}, /* 0x3F023DE1, 0x0DFDF709 */
qS[] ={1.0, -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
-6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
7.70381505559019352791e-02}; /* 0x3FB3B8C5, 0xB12E9282 */
#ifdef __STDC__
double __ieee754_acos(double x)
#else
double __ieee754_acos(x)
double x;
#endif
{
double z,p,q,r,w,s,c,df,p1,p2,p3,q1,q2,z2,z4,z6;
int32_t hx,ix;
GET_HIGH_WORD(hx,x);
ix = hx&0x7fffffff;
if(ix>=0x3ff00000) { /* |x| >= 1 */
u_int32_t lx;
GET_LOW_WORD(lx,x);
if(((ix-0x3ff00000)|lx)==0) { /* |x|==1 */
if(hx>0) return 0.0; /* acos(1) = 0 */
else return pi+2.0*pio2_lo; /* acos(-1)= pi */
}
return (x-x)/(x-x); /* acos(|x|>1) is NaN */
}
if(ix<0x3fe00000) { /* |x| < 0.5 */
if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
z = x*x;
#ifdef DO_NOT_USE_THIS
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
#else
p1 = z*pS[0]; z2=z*z;
p2 = pS[1]+z*pS[2]; z4=z2*z2;
p3 = pS[3]+z*pS[4]; z6=z4*z2;
q1 = one+z*qS[1];
q2 = qS[2]+z*qS[3];
p = p1 + z2*p2 + z4*p3 + z6*pS[5];
q = q1 + z2*q2 + z4*qS[4];
#endif
r = p/q;
return pio2_hi - (x - (pio2_lo-x*r));
} else if (hx<0) { /* x < -0.5 */
z = (one+x)*0.5;
#ifdef DO_NOT_USE_THIS
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
#else
p1 = z*pS[0]; z2=z*z;
p2 = pS[1]+z*pS[2]; z4=z2*z2;
p3 = pS[3]+z*pS[4]; z6=z4*z2;
q1 = one+z*qS[1];
q2 = qS[2]+z*qS[3];
p = p1 + z2*p2 + z4*p3 + z6*pS[5];
q = q1 + z2*q2 + z4*qS[4];
#endif
s = __ieee754_sqrt(z);
r = p/q;
w = r*s-pio2_lo;
return pi - 2.0*(s+w);
} else { /* x > 0.5 */
z = (one-x)*0.5;
s = __ieee754_sqrt(z);
df = s;
SET_LOW_WORD(df,0);
c = (z-df*df)/(s+df);
#ifdef DO_NOT_USE_THIS
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
#else
p1 = z*pS[0]; z2=z*z;
p2 = pS[1]+z*pS[2]; z4=z2*z2;
p3 = pS[3]+z*pS[4]; z6=z4*z2;
q1 = one+z*qS[1];
q2 = qS[2]+z*qS[3];
p = p1 + z2*p2 + z4*p3 + z6*pS[5];
q = q1 + z2*q2 + z4*qS[4];
#endif
r = p/q;
w = r*s+c;
return 2.0*(df+w);
}
}
/* In e_asin.c */

View File

@ -1,143 +1,623 @@
/* @(#)e_asin.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* 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.
* ====================================================
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25,
for performance improvement on pipelined processors.
*/
/******************************************************************/
/* MODULE_NAME:uasncs.c */
/* */
/* FUNCTIONS: uasin */
/* uacos */
/* FILES NEEDED: dla.h endian.h mpa.h mydefs.h usncs.h */
/* doasin.c sincos32.c dosincos.c mpa.c */
/* sincos.tbl asincos.tbl powtwo.tbl root.tbl */
/* */
/* Ultimate asin/acos routines. Given an IEEE double machine */
/* number x, compute the correctly rounded value of */
/* arcsin(x)or arccos(x) according to the function called. */
/* Assumption: Machine arithmetic operations are performed in */
/* round to nearest mode of IEEE 754 standard. */
/* */
/******************************************************************/
#include "endian.h"
#include "mydefs.h"
#include "asincos.tbl"
#include "root.tbl"
#include "powtwo.tbl"
#include "MathLib.h"
#include "uasncs.h"
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: e_asin.c,v 1.9 1995/05/12 04:57:22 jtc Exp $";
#endif
void __doasin(double x, double dx, double w[]);
void __dubsin(double x, double dx, double v[]);
void __dubcos(double x, double dx, double v[]);
void __docos(double x, double dx, double v[]);
double __sin32(double x, double res, double res1);
double __cos32(double x, double res, double res1);
/* __ieee754_asin(x)
* Method :
* Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
* we approximate asin(x) on [0,0.5] by
* asin(x) = x + x*x^2*R(x^2)
* where
* R(x^2) is a rational approximation of (asin(x)-x)/x^3
* and its remez error is bounded by
* |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
*
* For x in [0.5,1]
* asin(x) = pi/2-2*asin(sqrt((1-x)/2))
* Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
* then for x>0.98
* asin(x) = pi/2 - 2*(s+s*z*R(z))
* = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
* For x<=0.98, let pio4_hi = pio2_hi/2, then
* f = hi part of s;
* c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
* and
* asin(x) = pi/2 - 2*(s+s*z*R(z))
* = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
* = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
*
* Special cases:
* if x is NaN, return x itself;
* if |x|>1, return NaN with invalid signal.
*
*/
/***************************************************************************/
/* An ultimate asin routine. Given an IEEE double machine number x */
/* it computes the correctly rounded (to nearest) value of arcsin(x) */
/***************************************************************************/
double __ieee754_asin(double x){
double x1,x2,xx,s1,s2,res1,p,t,res,r,cor,cc,y,c,z,w[2];
mynumber u,v;
int4 k,m,n,nn;
u.x = x;
m = u.i[HIGH_HALF];
k = 0x7fffffff&m; /* no sign */
#include "math.h"
#include "math_private.h"
#define one qS[0]
#ifdef __STDC__
static const double
#else
static double
#endif
huge = 1.000e+300,
pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
/* coefficient for R(x^2) */
pS[] = {1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
-3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
-4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
3.47933107596021167570e-05}, /* 0x3F023DE1, 0x0DFDF709 */
qS[] = {1.0, -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
-6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
7.70381505559019352791e-02}; /* 0x3FB3B8C5, 0xB12E9282 */
#ifdef __STDC__
double __ieee754_asin(double x)
#else
double __ieee754_asin(x)
double x;
#endif
{
double t,w,p,q,c,r,s,p1,p2,p3,q1,q2,z2,z4,z6;
int32_t hx,ix;
GET_HIGH_WORD(hx,x);
ix = hx&0x7fffffff;
if(ix>= 0x3ff00000) { /* |x|>= 1 */
u_int32_t lx;
GET_LOW_WORD(lx,x);
if(((ix-0x3ff00000)|lx)==0)
/* asin(1)=+-pi/2 with inexact */
return x*pio2_hi+x*pio2_lo;
return (x-x)/(x-x); /* asin(|x|>1) is NaN */
} else if (ix<0x3fe00000) { /* |x|<0.5 */
if(ix<0x3e400000) { /* if |x| < 2**-27 */
if(huge+x>one) return x;/* return x with inexact if x!=0*/
} else {
t = x*x;
#ifdef DO_NOT_USE_THIS
p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
#else
p1 = t*pS[0]; z2=t*t;
p2 = pS[1]+t*pS[2]; z4=z2*z2;
p3 = pS[3]+t*pS[4]; z6=z4*z2;
q1 = one+t*qS[1];
q2 = qS[2]+t*qS[3];
p = p1 + z2*p2 + z4*p3 + z6*pS[5];
q = q1 + z2*q2 + z4*qS[4];
#endif
w = p/q;
return x+x*w;
}
if (k < 0x3e500000) return x; /* for x->0 => sin(x)=x */
/*----------------------2^-26 <= |x| < 2^ -3 -----------------*/
else
if (k < 0x3fc00000) {
x2 = x*x;
t = (((((f6*x2 + f5)*x2 + f4)*x2 + f3)*x2 + f2)*x2 + f1)*(x2*x);
res = x+t; /* res=arcsin(x) according to Taylor series */
cor = (x-res)+t;
if (res == res+1.025*cor) return res;
else {
x1 = x+big;
xx = x*x;
x1 -= big;
x2 = x - x1;
p = x1*x1*x1;
s1 = a1.x*p;
s2 = ((((((c7*xx + c6)*xx + c5)*xx + c4)*xx + c3)*xx + c2)*xx*xx*x +
((a1.x+a2.x)*x2*x2+ 0.5*x1*x)*x2) + a2.x*p;
res1 = x+s1;
s2 = ((x-res1)+s1)+s2;
res = res1+s2;
cor = (res1-res)+s2;
if (res == res+1.00014*cor) return res;
else {
__doasin(x,0,w);
if (w[0]==(w[0]+1.00000001*w[1])) return w[0];
else {
y=ABS(x);
res=ABS(w[0]);
res1=ABS(w[0]+1.1*w[1]);
return (m>0)?sin32(y,res,res1):-sin32(y,res,res1);
}
/* 1> |x|>= 0.5 */
w = one-fabs(x);
t = w*0.5;
#ifdef DO_NOT_USE_THIS
p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
#else
p1 = t*pS[0]; z2=t*t;
p2 = pS[1]+t*pS[2]; z4=z2*z2;
p3 = pS[3]+t*pS[4]; z6=z4*z2;
q1 = one+t*qS[1];
q2 = qS[2]+t*qS[3];
p = p1 + z2*p2 + z4*p3 + z6*pS[5];
q = q1 + z2*q2 + z4*qS[4];
#endif
s = __ieee754_sqrt(t);
if(ix>=0x3FEF3333) { /* if |x| > 0.975 */
w = p/q;
t = pio2_hi-(2.0*(s+s*w)-pio2_lo);
} else {
w = s;
SET_LOW_WORD(w,0);
c = (t-w*w)/(s+w);
r = p/q;
p = 2.0*s*r-(pio2_lo-2.0*c);
q = pio4_hi-2.0*w;
t = pio4_hi-(p-q);
}
}
}
/*---------------------0.125 <= |x| < 0.5 -----------------------------*/
else if (k < 0x3fe00000) {
if (k<0x3fd00000) n = 11*((k&0x000fffff)>>15);
else n = 11*((k&0x000fffff)>>14)+352;
if (m>0) xx = x - asncs.x[n];
else xx = -x - asncs.x[n];
t = asncs.x[n+1]*xx;
p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
+xx*asncs.x[n+6]))))+asncs.x[n+7];
t+=p;
res =asncs.x[n+8] +t;
cor = (asncs.x[n+8]-res)+t;
if (res == res+1.05*cor) return (m>0)?res:-res;
else {
r=asncs.x[n+8]+xx*asncs.x[n+9];
t=((asncs.x[n+8]-r)+xx*asncs.x[n+9])+(p+xx*asncs.x[n+10]);
res = r+t;
cor = (r-res)+t;
if (res == res+1.0005*cor) return (m>0)?res:-res;
else {
res1=res+1.1*cor;
z=0.5*(res1-res);
__dubsin(res,z,w);
z=(w[0]-ABS(x))+w[1];
if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
else {
y=ABS(x);
return (m>0)?sin32(y,res,res1):-sin32(y,res,res1);
}
if(hx>0) return t; else return -t;
}
}
} /* else if (k < 0x3fe00000) */
/*-------------------- 0.5 <= |x| < 0.75 -----------------------------*/
else
if (k < 0x3fe80000) {
n = 1056+((k&0x000fe000)>>11)*3;
if (m>0) xx = x - asncs.x[n];
else xx = -x - asncs.x[n];
t = asncs.x[n+1]*xx;
p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
+xx*(asncs.x[n+6]+xx*asncs.x[n+7])))))+asncs.x[n+8];
t+=p;
res =asncs.x[n+9] +t;
cor = (asncs.x[n+9]-res)+t;
if (res == res+1.01*cor) return (m>0)?res:-res;
else {
r=asncs.x[n+9]+xx*asncs.x[n+10];
t=((asncs.x[n+9]-r)+xx*asncs.x[n+10])+(p+xx*asncs.x[n+11]);
res = r+t;
cor = (r-res)+t;
if (res == res+1.0005*cor) return (m>0)?res:-res;
else {
res1=res+1.1*cor;
z=0.5*(res1-res);
__dubsin(res,z,w);
z=(w[0]-ABS(x))+w[1];
if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
else {
y=ABS(x);
return (m>0)?sin32(y,res,res1):-sin32(y,res,res1);
}
}
}
} /* else if (k < 0x3fe80000) */
/*--------------------- 0.75 <= |x|< 0.921875 ----------------------*/
else
if (k < 0x3fed8000) {
n = 992+((k&0x000fe000)>>13)*13;
if (m>0) xx = x - asncs.x[n];
else xx = -x - asncs.x[n];
t = asncs.x[n+1]*xx;
p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
+xx*(asncs.x[n+6]+xx*(asncs.x[n+7]+xx*asncs.x[n+8]))))))+asncs.x[n+9];
t+=p;
res =asncs.x[n+10] +t;
cor = (asncs.x[n+10]-res)+t;
if (res == res+1.01*cor) return (m>0)?res:-res;
else {
r=asncs.x[n+10]+xx*asncs.x[n+11];
t=((asncs.x[n+10]-r)+xx*asncs.x[n+11])+(p+xx*asncs.x[n+12]);
res = r+t;
cor = (r-res)+t;
if (res == res+1.0008*cor) return (m>0)?res:-res;
else {
res1=res+1.1*cor;
z=0.5*(res1-res);
y=hp0.x-res;
z=((hp0.x-y)-res)+(hp1.x-z);
__dubcos(y,z,w);
z=(w[0]-ABS(x))+w[1];
if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
else {
y=ABS(x);
return (m>0)?sin32(y,res,res1):-sin32(y,res,res1);
}
}
}
} /* else if (k < 0x3fed8000) */
/*-------------------0.921875 <= |x| < 0.953125 ------------------------*/
else
if (k < 0x3fee8000) {
n = 884+((k&0x000fe000)>>13)*14;
if (m>0) xx = x - asncs.x[n];
else xx = -x - asncs.x[n];
t = asncs.x[n+1]*xx;
p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
+xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
xx*asncs.x[n+9])))))))+asncs.x[n+10];
t+=p;
res =asncs.x[n+11] +t;
cor = (asncs.x[n+11]-res)+t;
if (res == res+1.01*cor) return (m>0)?res:-res;
else {
r=asncs.x[n+11]+xx*asncs.x[n+12];
t=((asncs.x[n+11]-r)+xx*asncs.x[n+12])+(p+xx*asncs.x[n+13]);
res = r+t;
cor = (r-res)+t;
if (res == res+1.0007*cor) return (m>0)?res:-res;
else {
res1=res+1.1*cor;
z=0.5*(res1-res);
y=(hp0.x-res)-z;
z=y+hp1.x;
y=(y-z)+hp1.x;
__dubcos(z,y,w);
z=(w[0]-ABS(x))+w[1];
if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
else {
y=ABS(x);
return (m>0)?sin32(y,res,res1):-sin32(y,res,res1);
}
}
}
} /* else if (k < 0x3fee8000) */
/*--------------------0.953125 <= |x| < 0.96875 ------------------------*/
else
if (k < 0x3fef0000) {
n = 768+((k&0x000fe000)>>13)*15;
if (m>0) xx = x - asncs.x[n];
else xx = -x - asncs.x[n];
t = asncs.x[n+1]*xx;
p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
+xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
xx*(asncs.x[n+9]+xx*asncs.x[n+10]))))))))+asncs.x[n+11];
t+=p;
res =asncs.x[n+12] +t;
cor = (asncs.x[n+12]-res)+t;
if (res == res+1.01*cor) return (m>0)?res:-res;
else {
r=asncs.x[n+12]+xx*asncs.x[n+13];
t=((asncs.x[n+12]-r)+xx*asncs.x[n+13])+(p+xx*asncs.x[n+14]);
res = r+t;
cor = (r-res)+t;
if (res == res+1.0007*cor) return (m>0)?res:-res;
else {
res1=res+1.1*cor;
z=0.5*(res1-res);
y=(hp0.x-res)-z;
z=y+hp1.x;
y=(y-z)+hp1.x;
__dubcos(z,y,w);
z=(w[0]-ABS(x))+w[1];
if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
else {
y=ABS(x);
return (m>0)?sin32(y,res,res1):-sin32(y,res,res1);
}
}
}
} /* else if (k < 0x3fef0000) */
/*--------------------0.96875 <= |x| < 1 --------------------------------*/
else
if (k<0x3ff00000) {
z = 0.5*((m>0)?(1.0-x):(1.0+x));
v.x=z;
k=v.i[HIGH_HALF];
t=inroot[(k&0x001fffff)>>14]*powtwo[511-(k>>21)];
r=1.0-t*t*z;
t = t*(rt0+r*(rt1+r*(rt2+r*rt3)));
c=t*z;
t=c*(1.5-0.5*t*c);
y=(c+t24)-t24;
cc = (z-y*y)/(t+y);
p=(((((f6*z+f5)*z+f4)*z+f3)*z+f2)*z+f1)*z;
cor = (hp1.x - 2.0*cc)-2.0*(y+cc)*p;
res1 = hp0.x - 2.0*y;
res =res1 + cor;
if (res == res+1.003*((res1-res)+cor)) return (m>0)?res:-res;
else {
c=y+cc;
cc=(y-c)+cc;
__doasin(c,cc,w);
res1=hp0.x-2.0*w[0];
cor=((hp0.x-res1)-2.0*w[0])+(hp1.x-2.0*w[1]);
res = res1+cor;
cor = (res1-res)+cor;
if (res==(res+1.0000001*cor)) return (m>0)?res:-res;
else {
y=ABS(x);
res1=res+1.1*cor;
return (m>0)?sin32(y,res,res1):-sin32(y,res,res1);
}
}
} /* else if (k < 0x3ff00000) */
/*---------------------------- |x|>=1 -------------------------------*/
else if (k==0x3ff00000 && u.i[LOW_HALF]==0) return (m>0)?hp0.x:-hp0.x;
else {
u.i[HIGH_HALF]=0x7ff00000;
v.i[HIGH_HALF]=0x7ff00000;
u.i[LOW_HALF]=0;
v.i[LOW_HALF]=0;
return u.x/v.x; /* NaN */
}
}
/*******************************************************************/
/* */
/* End of arcsine, below is arccosine */
/* */
/*******************************************************************/
double __ieee754_acos(double x)
{
double x1,x2,xx,s1,s2,res1,p,t,res,r,cor,cc,y,c,z,w[2],eps;
double fc;
mynumber u,v;
int4 k,m,n,nn;
u.x = x;
m = u.i[HIGH_HALF];
k = 0x7fffffff&m;
/*------------------- |x|<2.77556*10^-17 ----------------------*/
if (k < 0x3c880000) return hp0.x;
/*----------------- 2.77556*10^-17 <= |x| < 2^-3 --------------*/
else
if (k < 0x3fc00000) {
x2 = x*x;
t = (((((f6*x2 + f5)*x2 + f4)*x2 + f3)*x2 + f2)*x2 + f1)*(x2*x);
r=hp0.x-x;
cor=(((hp0.x-r)-x)+hp1.x)-t;
res = r+cor;
cor = (r-res)+cor;
if (res == res+1.004*cor) return res;
else {
x1 = x+big;
xx = x*x;
x1 -= big;
x2 = x - x1;
p = x1*x1*x1;
s1 = a1.x*p;
s2 = ((((((c7*xx + c6)*xx + c5)*xx + c4)*xx + c3)*xx + c2)*xx*xx*x +
((a1.x+a2.x)*x2*x2+ 0.5*x1*x)*x2) + a2.x*p;
res1 = x+s1;
s2 = ((x-res1)+s1)+s2;
r=hp0.x-res1;
cor=(((hp0.x-r)-res1)+hp1.x)-s2;
res = r+cor;
cor = (r-res)+cor;
if (res == res+1.00004*cor) return res;
else {
__doasin(x,0,w);
r=hp0.x-w[0];
cor=((hp0.x-r)-w[0])+(hp1.x-w[1]);
res=r+cor;
cor=(r-res)+cor;
if (res ==(res +1.00000001*cor)) return res;
else {
res1=res+1.1*cor;
return cos32(x,res,res1);
}
}
}
} /* else if (k < 0x3fc00000) */
/*---------------------- 0.125 <= |x| < 0.5 --------------------*/
else
if (k < 0x3fe00000) {
if (k<0x3fd00000) n = 11*((k&0x000fffff)>>15);
else n = 11*((k&0x000fffff)>>14)+352;
if (m>0) xx = x - asncs.x[n];
else xx = -x - asncs.x[n];
t = asncs.x[n+1]*xx;
p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
xx*(asncs.x[n+5]+xx*asncs.x[n+6]))))+asncs.x[n+7];
t+=p;
y = (m>0)?(hp0.x-asncs.x[n+8]):(hp0.x+asncs.x[n+8]);
t = (m>0)?(hp1.x-t):(hp1.x+t);
res = y+t;
if (res == res+1.02*((y-res)+t)) return res;
else {
r=asncs.x[n+8]+xx*asncs.x[n+9];
t=((asncs.x[n+8]-r)+xx*asncs.x[n+9])+(p+xx*asncs.x[n+10]);
if (m>0)
{p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; }
else
{p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); }
res = p+t;
cor = (p-res)+t;
if (res == (res+1.0002*cor)) return res;
else {
res1=res+1.1*cor;
z=0.5*(res1-res);
__docos(res,z,w);
z=(w[0]-x)+w[1];
if (z>1.0e-27) return max(res,res1);
else if (z<-1.0e-27) return min(res,res1);
else return cos32(x,res,res1);
}
}
} /* else if (k < 0x3fe00000) */
/*--------------------------- 0.5 <= |x| < 0.75 ---------------------*/
else
if (k < 0x3fe80000) {
n = 1056+((k&0x000fe000)>>11)*3;
if (m>0) {xx = x - asncs.x[n]; eps=1.04; }
else {xx = -x - asncs.x[n]; eps=1.02; }
t = asncs.x[n+1]*xx;
p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
xx*(asncs.x[n+5]+xx*(asncs.x[n+6]+
xx*asncs.x[n+7])))))+asncs.x[n+8];
t+=p;
y = (m>0)?(hp0.x-asncs.x[n+9]):(hp0.x+asncs.x[n+9]);
t = (m>0)?(hp1.x-t):(hp1.x+t);
res = y+t;
if (res == res+eps*((y-res)+t)) return res;
else {
r=asncs.x[n+9]+xx*asncs.x[n+10];
t=((asncs.x[n+9]-r)+xx*asncs.x[n+10])+(p+xx*asncs.x[n+11]);
if (m>0) {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; eps=1.0004; }
else {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); eps=1.0002; }
res = p+t;
cor = (p-res)+t;
if (res == (res+eps*cor)) return res;
else {
res1=res+1.1*cor;
z=0.5*(res1-res);
__docos(res,z,w);
z=(w[0]-x)+w[1];
if (z>1.0e-27) return max(res,res1);
else if (z<-1.0e-27) return min(res,res1);
else return cos32(x,res,res1);
}
}
} /* else if (k < 0x3fe80000) */
/*------------------------- 0.75 <= |x| < 0.921875 -------------*/
else
if (k < 0x3fed8000) {
n = 992+((k&0x000fe000)>>13)*13;
if (m>0) {xx = x - asncs.x[n]; eps = 1.04; }
else {xx = -x - asncs.x[n]; eps = 1.01; }
t = asncs.x[n+1]*xx;
p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
xx*(asncs.x[n+5]+xx*(asncs.x[n+6]+xx*(asncs.x[n+7]+
xx*asncs.x[n+8]))))))+asncs.x[n+9];
t+=p;
y = (m>0)?(hp0.x-asncs.x[n+10]):(hp0.x+asncs.x[n+10]);
t = (m>0)?(hp1.x-t):(hp1.x+t);
res = y+t;
if (res == res+eps*((y-res)+t)) return res;
else {
r=asncs.x[n+10]+xx*asncs.x[n+11];
t=((asncs.x[n+10]-r)+xx*asncs.x[n+11])+(p+xx*asncs.x[n+12]);
if (m>0) {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; eps=1.0032; }
else {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); eps=1.0008; }
res = p+t;
cor = (p-res)+t;
if (res == (res+eps*cor)) return res;
else {
res1=res+1.1*cor;
z=0.5*(res1-res);
__docos(res,z,w);
z=(w[0]-x)+w[1];
if (z>1.0e-27) return max(res,res1);
else if (z<-1.0e-27) return min(res,res1);
else return cos32(x,res,res1);
}
}
} /* else if (k < 0x3fed8000) */
/*-------------------0.921875 <= |x| < 0.953125 ------------------*/
else
if (k < 0x3fee8000) {
n = 884+((k&0x000fe000)>>13)*14;
if (m>0) {xx = x - asncs.x[n]; eps=1.04; }
else {xx = -x - asncs.x[n]; eps =1.005; }
t = asncs.x[n+1]*xx;
p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
+xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
xx*asncs.x[n+9])))))))+asncs.x[n+10];
t+=p;
y = (m>0)?(hp0.x-asncs.x[n+11]):(hp0.x+asncs.x[n+11]);
t = (m>0)?(hp1.x-t):(hp1.x+t);
res = y+t;
if (res == res+eps*((y-res)+t)) return res;
else {
r=asncs.x[n+11]+xx*asncs.x[n+12];
t=((asncs.x[n+11]-r)+xx*asncs.x[n+12])+(p+xx*asncs.x[n+13]);
if (m>0) {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; eps=1.0030; }
else {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); eps=1.0005; }
res = p+t;
cor = (p-res)+t;
if (res == (res+eps*cor)) return res;
else {
res1=res+1.1*cor;
z=0.5*(res1-res);
__docos(res,z,w);
z=(w[0]-x)+w[1];
if (z>1.0e-27) return max(res,res1);
else if (z<-1.0e-27) return min(res,res1);
else return cos32(x,res,res1);
}
}
} /* else if (k < 0x3fee8000) */
/*--------------------0.953125 <= |x| < 0.96875 ----------------*/
else
if (k < 0x3fef0000) {
n = 768+((k&0x000fe000)>>13)*15;
if (m>0) {xx = x - asncs.x[n]; eps=1.04; }
else {xx = -x - asncs.x[n]; eps=1.005;}
t = asncs.x[n+1]*xx;
p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
+xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+xx*(asncs.x[n+9]+
xx*asncs.x[n+10]))))))))+asncs.x[n+11];
t+=p;
y = (m>0)?(hp0.x-asncs.x[n+12]):(hp0.x+asncs.x[n+12]);
t = (m>0)?(hp1.x-t):(hp1.x+t);
res = y+t;
if (res == res+eps*((y-res)+t)) return res;
else {
r=asncs.x[n+12]+xx*asncs.x[n+13];
t=((asncs.x[n+12]-r)+xx*asncs.x[n+13])+(p+xx*asncs.x[n+14]);
if (m>0) {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; eps=1.0030; }
else {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); eps=1.0005; }
res = p+t;
cor = (p-res)+t;
if (res == (res+eps*cor)) return res;
else {
res1=res+1.1*cor;
z=0.5*(res1-res);
__docos(res,z,w);
z=(w[0]-x)+w[1];
if (z>1.0e-27) return max(res,res1);
else if (z<-1.0e-27) return min(res,res1);
else return cos32(x,res,res1);
}
}
} /* else if (k < 0x3fef0000) */
/*-----------------0.96875 <= |x| < 1 ---------------------------*/
else
if (k<0x3ff00000) {
z = 0.5*((m>0)?(1.0-x):(1.0+x));
v.x=z;
k=v.i[HIGH_HALF];
t=inroot[(k&0x001fffff)>>14]*powtwo[511-(k>>21)];
r=1.0-t*t*z;
t = t*(rt0+r*(rt1+r*(rt2+r*rt3)));
c=t*z;
t=c*(1.5-0.5*t*c);
y = (t27*c+c)-t27*c;
cc = (z-y*y)/(t+y);
p=(((((f6*z+f5)*z+f4)*z+f3)*z+f2)*z+f1)*z;
if (m<0) {
cor = (hp1.x - cc)-(y+cc)*p;
res1 = hp0.x - y;
res =res1 + cor;
if (res == res+1.002*((res1-res)+cor)) return (res+res);
else {
c=y+cc;
cc=(y-c)+cc;
__doasin(c,cc,w);
res1=hp0.x-w[0];
cor=((hp0.x-res1)-w[0])+(hp1.x-w[1]);
res = res1+cor;
cor = (res1-res)+cor;
if (res==(res+1.000001*cor)) return (res+res);
else {
res=res+res;
res1=res+1.2*cor;
return cos32(x,res,res1);
}
}
}
else {
cor = cc+p*(y+cc);
res = y + cor;
if (res == res+1.03*((y-res)+cor)) return (res+res);
else {
c=y+cc;
cc=(y-c)+cc;
__doasin(c,cc,w);
res = w[0];
cor=w[1];
if (res==(res+1.000001*cor)) return (res+res);
else {
res=res+res;
res1=res+1.2*cor;
return cos32(x,res,res1);
}
}
}
} /* else if (k < 0x3ff00000) */
/*---------------------------- |x|>=1 -----------------------*/
else
if (k==0x3ff00000 && u.i[LOW_HALF]==0) return (m>0)?0:2.0*hp0.x;
else {
u.i[HIGH_HALF]=0x7ff00000;
v.i[HIGH_HALF]=0x7ff00000;
u.i[LOW_HALF]=0;
v.i[LOW_HALF]=0;
return u.x/v.x;
}
}

View File

@ -1,130 +1,395 @@
/* @(#)e_atan2.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* 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.
* ====================================================
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/************************************************************************/
/* MODULE_NAME: atnat2.c */
/* */
/* FUNCTIONS: uatan2 */
/* atan2Mp */
/* signArctan2 */
/* normalized */
/* */
/* FILES NEEDED: dla.h endian.h mpa.h mydefs.h atnat2.h */
/* mpatan.c mpatan2.c mpsqrt.c */
/* uatan.tbl */
/* */
/* An ultimate atan2() routine. Given two IEEE double machine numbers y,*/
/* x it computes the correctly rounded (to nearest) value of atan2(y,x).*/
/* */
/* Assumption: Machine arithmetic operations are performed in */
/* round to nearest mode of IEEE 754 standard. */
/* */
/************************************************************************/
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: e_atan2.c,v 1.8 1995/05/10 20:44:51 jtc Exp $";
#endif
#include "dla.h"
#include "mpa.h"
#include "MathLib.h"
#include "uatan.tbl"
#include "atnat2.h"
/************************************************************************/
/* An ultimate atan2 routine. Given two IEEE double machine numbers y,x */
/* it computes the correctly rounded (to nearest) value of atan2(y,x). */
/* Assumption: Machine arithmetic operations are performed in */
/* round to nearest mode of IEEE 754 standard. */
/************************************************************************/
static double atan2Mp(double ,double ,const int[]);
static double signArctan2(double ,double);
static double normalized(double ,double,double ,double);
void __mpatan2(mp_no *,mp_no *,mp_no *,int);
/* __ieee754_atan2(y,x)
* Method :
* 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
* 2. Reduce x to positive by (if x and y are unexceptional):
* ARG (x+iy) = arctan(y/x) ... if x > 0,
* ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
*
* Special cases:
*
* ATAN2((anything), NaN ) is NaN;
* ATAN2(NAN , (anything) ) is NaN;
* ATAN2(+-0, +(anything but NaN)) is +-0 ;
* ATAN2(+-0, -(anything but NaN)) is +-pi ;
* ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
* ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
* ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
* ATAN2(+-INF,+INF ) is +-pi/4 ;
* ATAN2(+-INF,-INF ) is +-3pi/4;
* ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
*
* 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.
*/
double __ieee754_atan2(double y,double x) {
#include "math.h"
#include "math_private.h"
int i,de,ux,dx,uy,dy,p;
static const int pr[MM]={6,8,10,20,32};
double ax,ay,u,du,u9,ua,v,vv,dv,t1,t2,t3,t4,t5,t6,t7,t8,
z,zz,z1,z2,cor,s1,ss1,s2,ss2;
number num;
mp_no mperr,mpt1,mpx,mpy,mpz,mpz1,mpz2;
#ifdef __STDC__
static const double
#else
static double
#endif
tiny = 1.0e-300,
zero = 0.0,
pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */
pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */
pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
static const int ep= 59768832, /* 57*16**5 */
em=-59768832; /* -57*16**5 */
#ifdef __STDC__
double __ieee754_atan2(double y, double x)
#else
double __ieee754_atan2(y,x)
double y,x;
#endif
{
double z;
int32_t k,m,hx,hy,ix,iy;
u_int32_t lx,ly;
/* x=NaN or y=NaN */
num.d = x; ux = num.i[HIGH_HALF]; dx = num.i[LOW_HALF];
if ((ux&0x7ff00000) ==0x7ff00000) {
if (((ux&0x000fffff)|dx)!=0x00000000) return x+x; }
num.d = y; uy = num.i[HIGH_HALF]; dy = num.i[LOW_HALF];
if ((uy&0x7ff00000) ==0x7ff00000) {
if (((uy&0x000fffff)|dy)!=0x00000000) return y+y; }
EXTRACT_WORDS(hx,lx,x);
ix = hx&0x7fffffff;
EXTRACT_WORDS(hy,ly,y);
iy = hy&0x7fffffff;
if(((ix|((lx|-lx)>>31))>0x7ff00000)||
((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */
return x+y;
if(((hx-0x3ff00000)|lx)==0) return __atan(y); /* x=1.0 */
m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */
/* y=+-0 */
if (uy==0x00000000) {
if (dy==0x00000000) {
if ((ux&0x80000000)==0x00000000) return ZERO;
else return opi.d; } }
else if (uy==0x80000000) {
if (dy==0x00000000) {
if ((ux&0x80000000)==0x00000000) return MZERO;
else return mopi.d;} }
/* when y = 0 */
if((iy|ly)==0) {
switch(m) {
case 0:
case 1: return y; /* atan(+-0,+anything)=+-0 */
case 2: return pi+tiny;/* atan(+0,-anything) = pi */
case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
}
}
/* when x = 0 */
if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
/* when x is INF */
if(ix==0x7ff00000) {
if(iy==0x7ff00000) {
switch(m) {
case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
}
} else {
switch(m) {
case 0: return zero ; /* atan(+...,+INF) */
case 1: return -zero ; /* atan(-...,+INF) */
case 2: return pi+tiny ; /* atan(+...,-INF) */
case 3: return -pi-tiny ; /* atan(-...,-INF) */
}
}
}
/* when y is INF */
if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
/* x=+-0 */
if (x==ZERO) {
if ((uy&0x80000000)==0x00000000) return hpi.d;
else return mhpi.d; }
/* compute y/x */
k = (iy-ix)>>20;
if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */
else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */
else z=__atan(fabs(y/x)); /* safe to do y/x */
switch (m) {
case 0: return z ; /* atan(+,+) */
case 1: {
u_int32_t zh;
GET_HIGH_WORD(zh,z);
SET_HIGH_WORD(z,zh ^ 0x80000000);
}
return z ; /* atan(-,+) */
case 2: return pi-(z-pi_lo);/* atan(+,-) */
default: /* case 3 */
return (z-pi_lo)-pi;/* atan(-,-) */
}
/* x=+-INF */
if (ux==0x7ff00000) {
if (dx==0x00000000) {
if (uy==0x7ff00000) {
if (dy==0x00000000) return qpi.d; }
else if (uy==0xfff00000) {
if (dy==0x00000000) return mqpi.d; }
else {
if ((uy&0x80000000)==0x00000000) return ZERO;
else return MZERO; }
}
}
else if (ux==0xfff00000) {
if (dx==0x00000000) {
if (uy==0x7ff00000) {
if (dy==0x00000000) return tqpi.d; }
else if (uy==0xfff00000) {
if (dy==0x00000000) return mtqpi.d; }
else {
if ((uy&0x80000000)==0x00000000) return opi.d;
else return mopi.d; }
}
}
/* y=+-INF */
if (uy==0x7ff00000) {
if (dy==0x00000000) return hpi.d; }
else if (uy==0xfff00000) {
if (dy==0x00000000) return mhpi.d; }
/* either x/y or y/x is very close to zero */
ax = (x<ZERO) ? -x : x; ay = (y<ZERO) ? -y : y;
de = (uy & 0x7ff00000) - (ux & 0x7ff00000);
if (de>=ep) { return ((y>ZERO) ? hpi.d : mhpi.d); }
else if (de<=em) {
if (x>ZERO) {
if ((z=ay/ax)<TWOM1022) return normalized(ax,ay,y,z);
else return signArctan2(y,z); }
else { return ((y>ZERO) ? opi.d : mopi.d); } }
/* if either x or y is extremely close to zero, scale abs(x), abs(y). */
if (ax<twom500.d || ay<twom500.d) { ax*=two500.d; ay*=two500.d; }
/* x,y which are neither special nor extreme */
if (ay<ax) {
u=ay/ax;
EMULV(ax,u,v,vv,t1,t2,t3,t4,t5)
du=((ay-v)-vv)/ax; }
else {
u=ax/ay;
EMULV(ay,u,v,vv,t1,t2,t3,t4,t5)
du=((ax-v)-vv)/ay; }
if (x>ZERO) {
/* (i) x>0, abs(y)< abs(x): atan(ay/ax) */
if (ay<ax) {
if (u<inv16.d) {
v=u*u; zz=du+u*v*(d3.d+v*(d5.d+v*(d7.d+v*(d9.d+v*(d11.d+v*d13.d)))));
if ((z=u+(zz-u1.d*u)) == u+(zz+u1.d*u)) return signArctan2(y,z);
MUL2(u,du,u,du,v,vv,t1,t2,t3,t4,t5,t6,t7,t8)
s1=v*(f11.d+v*(f13.d+v*(f15.d+v*(f17.d+v*f19.d))));
ADD2(f9.d,ff9.d,s1,ZERO,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f7.d,ff7.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f5.d,ff5.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f3.d,ff3.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(u,du,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(u,du,s2,ss2,s1,ss1,t1,t2)
if ((z=s1+(ss1-u5.d*s1)) == s1+(ss1+u5.d*s1)) return signArctan2(y,z);
return atan2Mp(x,y,pr);
}
else {
i=(TWO52+TWO8*u)-TWO52; i-=16;
t3=u-cij[i][0].d;
EADD(t3,du,v,dv)
t1=cij[i][1].d; t2=cij[i][2].d;
zz=v*t2+(dv*t2+v*v*(cij[i][3].d+v*(cij[i][4].d+
v*(cij[i][5].d+v* cij[i][6].d))));
if (i<112) {
if (i<48) u9=u91.d; /* u < 1/4 */
else u9=u92.d; } /* 1/4 <= u < 1/2 */
else {
if (i<176) u9=u93.d; /* 1/2 <= u < 3/4 */
else u9=u94.d; } /* 3/4 <= u <= 1 */
if ((z=t1+(zz-u9*t1)) == t1+(zz+u9*t1)) return signArctan2(y,z);
t1=u-hij[i][0].d;
EADD(t1,du,v,vv)
s1=v*(hij[i][11].d+v*(hij[i][12].d+v*(hij[i][13].d+
v*(hij[i][14].d+v* hij[i][15].d))));
ADD2(hij[i][9].d,hij[i][10].d,s1,ZERO,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][7].d,hij[i][8].d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][5].d,hij[i][6].d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][3].d,hij[i][4].d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][1].d,hij[i][2].d,s1,ss1,s2,ss2,t1,t2)
if ((z=s2+(ss2-ub.d*s2)) == s2+(ss2+ub.d*s2)) return signArctan2(y,z);
return atan2Mp(x,y,pr);
}
}
/* (ii) x>0, abs(x)<=abs(y): pi/2-atan(ax/ay) */
else {
if (u<inv16.d) {
v=u*u;
zz=u*v*(d3.d+v*(d5.d+v*(d7.d+v*(d9.d+v*(d11.d+v*d13.d)))));
ESUB(hpi.d,u,t2,cor)
t3=((hpi1.d+cor)-du)-zz;
if ((z=t2+(t3-u2.d)) == t2+(t3+u2.d)) return signArctan2(y,z);
MUL2(u,du,u,du,v,vv,t1,t2,t3,t4,t5,t6,t7,t8)
s1=v*(f11.d+v*(f13.d+v*(f15.d+v*(f17.d+v*f19.d))));
ADD2(f9.d,ff9.d,s1,ZERO,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f7.d,ff7.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f5.d,ff5.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f3.d,ff3.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(u,du,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(u,du,s2,ss2,s1,ss1,t1,t2)
SUB2(hpi.d,hpi1.d,s1,ss1,s2,ss2,t1,t2)
if ((z=s2+(ss2-u6.d)) == s2+(ss2+u6.d)) return signArctan2(y,z);
return atan2Mp(x,y,pr);
}
else {
i=(TWO52+TWO8*u)-TWO52; i-=16;
v=(u-cij[i][0].d)+du;
zz=hpi1.d-v*(cij[i][2].d+v*(cij[i][3].d+v*(cij[i][4].d+
v*(cij[i][5].d+v* cij[i][6].d))));
t1=hpi.d-cij[i][1].d;
if (i<112) ua=ua1.d; /* w < 1/2 */
else ua=ua2.d; /* w >= 1/2 */
if ((z=t1+(zz-ua)) == t1+(zz+ua)) return signArctan2(y,z);
t1=u-hij[i][0].d;
EADD(t1,du,v,vv)
s1=v*(hij[i][11].d+v*(hij[i][12].d+v*(hij[i][13].d+
v*(hij[i][14].d+v* hij[i][15].d))));
ADD2(hij[i][9].d,hij[i][10].d,s1,ZERO,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][7].d,hij[i][8].d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][5].d,hij[i][6].d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][3].d,hij[i][4].d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][1].d,hij[i][2].d,s1,ss1,s2,ss2,t1,t2)
SUB2(hpi.d,hpi1.d,s2,ss2,s1,ss1,t1,t2)
if ((z=s1+(ss1-uc.d)) == s1+(ss1+uc.d)) return signArctan2(y,z);
return atan2Mp(x,y,pr);
}
}
}
else {
/* (iii) x<0, abs(x)< abs(y): pi/2+atan(ax/ay) */
if (ax<ay) {
if (u<inv16.d) {
v=u*u;
zz=u*v*(d3.d+v*(d5.d+v*(d7.d+v*(d9.d+v*(d11.d+v*d13.d)))));
EADD(hpi.d,u,t2,cor)
t3=((hpi1.d+cor)+du)+zz;
if ((z=t2+(t3-u3.d)) == t2+(t3+u3.d)) return signArctan2(y,z);
MUL2(u,du,u,du,v,vv,t1,t2,t3,t4,t5,t6,t7,t8)
s1=v*(f11.d+v*(f13.d+v*(f15.d+v*(f17.d+v*f19.d))));
ADD2(f9.d,ff9.d,s1,ZERO,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f7.d,ff7.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f5.d,ff5.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f3.d,ff3.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(u,du,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(u,du,s2,ss2,s1,ss1,t1,t2)
ADD2(hpi.d,hpi1.d,s1,ss1,s2,ss2,t1,t2)
if ((z=s2+(ss2-u7.d)) == s2+(ss2+u7.d)) return signArctan2(y,z);
return atan2Mp(x,y,pr);
}
else {
i=(TWO52+TWO8*u)-TWO52; i-=16;
v=(u-cij[i][0].d)+du;
zz=hpi1.d+v*(cij[i][2].d+v*(cij[i][3].d+v*(cij[i][4].d+
v*(cij[i][5].d+v* cij[i][6].d))));
t1=hpi.d+cij[i][1].d;
if (i<112) ua=ua1.d; /* w < 1/2 */
else ua=ua2.d; /* w >= 1/2 */
if ((z=t1+(zz-ua)) == t1+(zz+ua)) return signArctan2(y,z);
t1=u-hij[i][0].d;
EADD(t1,du,v,vv)
s1=v*(hij[i][11].d+v*(hij[i][12].d+v*(hij[i][13].d+
v*(hij[i][14].d+v* hij[i][15].d))));
ADD2(hij[i][9].d,hij[i][10].d,s1,ZERO,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][7].d,hij[i][8].d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][5].d,hij[i][6].d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][3].d,hij[i][4].d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][1].d,hij[i][2].d,s1,ss1,s2,ss2,t1,t2)
ADD2(hpi.d,hpi1.d,s2,ss2,s1,ss1,t1,t2)
if ((z=s1+(ss1-uc.d)) == s1+(ss1+uc.d)) return signArctan2(y,z);
return atan2Mp(x,y,pr);
}
}
/* (iv) x<0, abs(y)<=abs(x): pi-atan(ax/ay) */
else {
if (u<inv16.d) {
v=u*u;
zz=u*v*(d3.d+v*(d5.d+v*(d7.d+v*(d9.d+v*(d11.d+v*d13.d)))));
ESUB(opi.d,u,t2,cor)
t3=((opi1.d+cor)-du)-zz;
if ((z=t2+(t3-u4.d)) == t2+(t3+u4.d)) return signArctan2(y,z);
MUL2(u,du,u,du,v,vv,t1,t2,t3,t4,t5,t6,t7,t8)
s1=v*(f11.d+v*(f13.d+v*(f15.d+v*(f17.d+v*f19.d))));
ADD2(f9.d,ff9.d,s1,ZERO,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f7.d,ff7.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f5.d,ff5.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f3.d,ff3.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(u,du,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(u,du,s2,ss2,s1,ss1,t1,t2)
SUB2(opi.d,opi1.d,s1,ss1,s2,ss2,t1,t2)
if ((z=s2+(ss2-u8.d)) == s2+(ss2+u8.d)) return signArctan2(y,z);
return atan2Mp(x,y,pr);
}
else {
i=(TWO52+TWO8*u)-TWO52; i-=16;
v=(u-cij[i][0].d)+du;
zz=opi1.d-v*(cij[i][2].d+v*(cij[i][3].d+v*(cij[i][4].d+
v*(cij[i][5].d+v* cij[i][6].d))));
t1=opi.d-cij[i][1].d;
if (i<112) ua=ua1.d; /* w < 1/2 */
else ua=ua2.d; /* w >= 1/2 */
if ((z=t1+(zz-ua)) == t1+(zz+ua)) return signArctan2(y,z);
t1=u-hij[i][0].d;
EADD(t1,du,v,vv)
s1=v*(hij[i][11].d+v*(hij[i][12].d+v*(hij[i][13].d+
v*(hij[i][14].d+v* hij[i][15].d))));
ADD2(hij[i][9].d,hij[i][10].d,s1,ZERO,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][7].d,hij[i][8].d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][5].d,hij[i][6].d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][3].d,hij[i][4].d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][1].d,hij[i][2].d,s1,ss1,s2,ss2,t1,t2)
SUB2(opi.d,opi1.d,s2,ss2,s1,ss1,t1,t2)
if ((z=s1+(ss1-uc.d)) == s1+(ss1+uc.d)) return signArctan2(y,z);
return atan2Mp(x,y,pr);
}
}
}
}
/* Treat the Denormalized case */
static double normalized(double ax,double ay,double y, double z)
{ int p;
mp_no mpx,mpy,mpz,mperr,mpz2,mpt1;
p=6;
dbl_mp(ax,&mpx,p); dbl_mp(ay,&mpy,p); dvd(&mpy,&mpx,&mpz,p);
dbl_mp(ue.d,&mpt1,p); mul(&mpz,&mpt1,&mperr,p);
sub(&mpz,&mperr,&mpz2,p); mp_dbl(&mpz2,&z,p);
return signArctan2(y,z);
}
/* Fix the sign and return after stage 1 or stage 2 */
static double signArctan2(double y,double z)
{
return ((y<ZERO) ? -z : z);
}
/* Stage 3: Perform a multi-Precision computation */
static double atan2Mp(double x,double y,const int pr[])
{
double z1,z2;
int i,p;
mp_no mpx,mpy,mpz,mpz1,mpz2,mperr,mpt1;
for (i=0; i<MM; i++) {
p = pr[i];
dbl_mp(x,&mpx,p); dbl_mp(y,&mpy,p);
__mpatan2(&mpy,&mpx,&mpz,p);
dbl_mp(ud[i].d,&mpt1,p); mul(&mpz,&mpt1,&mperr,p);
add(&mpz,&mperr,&mpz1,p); sub(&mpz,&mperr,&mpz2,p);
mp_dbl(&mpz1,&z1,p); mp_dbl(&mpz2,&z2,p);
if (z1==z2) return z1;
}
return z1; /*if unpossible to do exact computing */
}

View File

@ -1,163 +1,243 @@
/* Double-precision floating point e^x.
Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Geoffrey Keating <geoffk@ozemail.com.au>
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/***************************************************************************/
/* MODULE_NAME:uexp.c */
/* */
/* FUNCTION:uexp */
/* exp1 */
/* */
/* FILES NEEDED:dla.h endian.h mpa.h mydefs.h uexp.h */
/* mpa.c mpexp.x slowexp.c */
/* */
/* An ultimate exp routine. Given an IEEE double machine number x */
/* it computes the correctly rounded (to nearest) value of e^x */
/* Assumption: Machine arithmetic operations are performed in */
/* round to nearest mode of IEEE 754 standard. */
/* */
/***************************************************************************/
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
#include "endian.h"
#include "uexp.h"
#include "mydefs.h"
#include "MathLib.h"
#include "uexp.tbl"
double __slowexp(double);
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
/***************************************************************************/
/* An ultimate exp routine. Given an IEEE double machine number x */
/* it computes the correctly rounded (to nearest) value of e^x */
/***************************************************************************/
double __ieee754_exp(double x) {
double bexp, t, eps, del, base, y, al, bet, res, rem, cor;
mynumber junk1, junk2, binexp = {0,0};
int4 k,i,j,m,n,ex;
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
junk1.x = x;
m = junk1.i[HIGH_HALF];
n = m&hugeint;
/* How this works:
The basic design here is from
Shmuel Gal and Boris Bachelis, "An Accurate Elementary Mathematical
Library for the IEEE Floating Point Standard", ACM Trans. Math. Soft.,
17 (1), March 1991, pp. 26-45.
if (n > smallint && n < bigint) {
The input value, x, is written as
y = x*log2e.x + three51.x;
bexp = y - three51.x; /* multiply the result by 2**bexp */
x = n * ln(2)_0 + t/512 + delta[t] + x + n * ln(2)_1
junk1.x = y;
where:
- n is an integer, 1024 >= n >= -1075;
- ln(2)_0 is the first 43 bits of ln(2), and ln(2)_1 is the remainder, so
that |ln(2)_1| < 2^-32;
- t is an integer, 177 >= t >= -177
- delta is based on a table entry, delta[t] < 2^-28
- x is whatever is left, |x| < 2^-10
eps = bexp*ln_two2.x; /* x = bexp*ln(2) + t - eps */
t = x - bexp*ln_two1.x;
Then e^x is approximated as
y = t + three33.x;
base = y - three33.x; /* t rounded to a multiple of 2**-18 */
junk2.x = y;
del = (t - base) - eps; /* x = bexp*ln(2) + base + del */
eps = del + del*del*(p3.x*del + p2.x);
e^x = 2^n_1 ( 2^n_0 e^(t/512 + delta[t])
+ ( 2^n_0 e^(t/512 + delta[t])
* ( p(x + n * ln(2)_1)
- n*ln(2)_1
- n*ln(2)_1 * p(x + n * ln(2)_1) ) ) )
binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+1023)<<20;
where
- p(x) is a polynomial approximating e(x)-1;
- e^(t/512 + delta[t]) is obtained from a table;
- n_1 + n_0 = n, so that |n_0| < DBL_MIN_EXP-1.
i = ((junk2.i[LOW_HALF]>>8)&0xfffffffe)+356;
j = (junk2.i[LOW_HALF]&511)<<1;
If it happens that n_1 == 0 (this is the usual case), that multiplication
is omitted.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdlib.h>
#include <float.h>
#include <ieee754.h>
#include <math.h>
#include <fenv.h>
#include <inttypes.h>
#include <math_private.h>
al = coar.x[i]*fine.x[j];
bet =(coar.x[i]*fine.x[j+1] + coar.x[i+1]*fine.x[j]) + coar.x[i+1]*fine.x[j+1];
extern const float __exp_deltatable[178];
extern const double __exp_atable[355] /* __attribute__((mode(DF))) */;
rem=(bet + bet*eps)+al*eps;
res = al + rem;
cor = (al - res) + rem;
if (res == (res+cor*err_0)) return res*binexp.x;
else return __slowexp(x); /*if error is over bound */
}
static const volatile double TWO1023 = 8.988465674311579539e+307;
static const volatile double TWOM1000 = 9.3326361850321887899e-302;
if (n <= smallint) return 1.0;
double
__ieee754_exp (double x)
{
static const double himark = 709.7827128933840868;
static const double lomark = -745.1332191019412221;
/* Check for usual case. */
if (isless (x, himark) && isgreater (x, lomark))
{
static const double THREEp42 = 13194139533312.0;
static const double THREEp51 = 6755399441055744.0;
/* 1/ln(2). */
static const double M_1_LN2 = 1.442695040888963387;
/* ln(2), part 1 */
static const double M_LN2_0 = .6931471805598903302;
/* ln(2), part 2 */
static const double M_LN2_1 = 5.497923018708371155e-14;
if (n >= badint) {
if (n > infint) return(zero/zero); /* x is NaN, return invalid */
if (n < infint) return ( (x>0) ? (hhuge*hhuge) : (tiny*tiny) );
/* x is finite, cause either overflow or underflow */
if (junk1.i[LOW_HALF] != 0) return (zero/zero); /* x is NaN */
return ((x>0)?inf.x:zero ); /* |x| = inf; return either inf or 0 */
}
int tval, unsafe, n_i;
double x22, n, t, dely, result;
union ieee754_double ex2_u, scale_u;
fenv_t oldenv;
feholdexcept (&oldenv);
#ifdef FE_TONEAREST
fesetround (FE_TONEAREST);
#endif
/* Calculate n. */
n = x * M_1_LN2 + THREEp51;
n -= THREEp51;
x = x - n*M_LN2_0;
/* Calculate t/512. */
t = x + THREEp42;
t -= THREEp42;
x -= t;
/* Compute tval = t. */
tval = (int) (t * 512.0);
if (t >= 0)
x -= __exp_deltatable[tval];
else
x += __exp_deltatable[-tval];
/* Now, the variable x contains x + n*ln(2)_1. */
dely = n*M_LN2_1;
/* Compute ex2 = 2^n_0 e^(t/512+delta[t]). */
ex2_u.d = __exp_atable[tval+177];
n_i = (int)n;
/* 'unsafe' is 1 iff n_1 != 0. */
unsafe = abs(n_i) >= -DBL_MIN_EXP - 1;
ex2_u.ieee.exponent += n_i >> unsafe;
/* Compute scale = 2^n_1. */
scale_u.d = 1.0;
scale_u.ieee.exponent += n_i - (n_i >> unsafe);
/* Approximate e^x2 - 1, using a fourth-degree polynomial,
with maximum error in [-2^-10-2^-28,2^-10+2^-28]
less than 4.9e-19. */
x22 = (((0.04166666898464281565
* x + 0.1666666766008501610)
* x + 0.499999999999990008)
* x + 0.9999999999999976685) * x;
/* Allow for impact of dely. */
x22 -= dely + dely*x22;
/* Return result. */
fesetenv (&oldenv);
result = x22 * ex2_u.d + ex2_u.d;
if (!unsafe)
return result;
else
return result * scale_u.d;
y = x*log2e.x + three51.x;
bexp = y - three51.x;
junk1.x = y;
eps = bexp*ln_two2.x;
t = x - bexp*ln_two1.x;
y = t + three33.x;
base = y - three33.x;
junk2.x = y;
del = (t - base) - eps;
eps = del + del*del*(p3.x*del + p2.x);
i = ((junk2.i[LOW_HALF]>>8)&0xfffffffe)+356;
j = (junk2.i[LOW_HALF]&511)<<1;
al = coar.x[i]*fine.x[j];
bet =(coar.x[i]*fine.x[j+1] + coar.x[i+1]*fine.x[j]) + coar.x[i+1]*fine.x[j+1];
rem=(bet + bet*eps)+al*eps;
res = al + rem;
cor = (al - res) + rem;
if (m>>31) {
ex=junk1.i[LOW_HALF];
if (res < 1.0) {res+=res; cor+=cor; ex-=1;}
if (ex >=-1022) {
binexp.i[HIGH_HALF] = (1023+ex)<<20;
if (res == (res+cor*err_0)) return res*binexp.x;
else return __slowexp(x); /*if error is over bound */
}
/* Exceptional cases: */
else if (isless (x, himark))
{
if (__isinf (x))
/* e^-inf == 0, with no error. */
return 0;
else
/* Underflow */
return TWOM1000 * TWOM1000;
ex = -(1022+ex);
binexp.i[HIGH_HALF] = (1023-ex)<<20;
res*=binexp.x;
cor*=binexp.x;
eps=1.0000000001+err_0*binexp.x;
t=1.0+res;
y = ((1.0-t)+res)+cor;
res=t+y;
cor = (t-res)+y;
if (res == (res + eps*cor))
{ binexp.i[HIGH_HALF] = 0x00100000;
return (res-1.0)*binexp.x;
}
else
/* Return x, if x is a NaN or Inf; or overflow, otherwise. */
return TWO1023*x;
else return __slowexp(x); /* if error is over bound */
}
else {
binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+767)<<20;
if (res == (res+cor*err_0)) return res*binexp.x*t256.x;
else return __slowexp(x);
}
}
/************************************************************************/
/* Compute e^(x+xx)(Double-Length number) .The routine also receive */
/* bound of error of previous calculation .If after computing exp */
/* error bigger than allows routine return non positive number */
/*else return e^(x + xx) (always positive ) */
/************************************************************************/
double __exp1(double x, double xx, double error) {
double bexp, t, eps, del, base, y, al, bet, res, rem, cor;
mynumber junk1, junk2, binexp = {0,0};
int4 k,i,j,m,n,ex;
junk1.x = x;
m = junk1.i[HIGH_HALF];
n = m&hugeint; /* no sign */
if (n > smallint && n < bigint) {
y = x*log2e.x + three51.x;
bexp = y - three51.x; /* multiply the result by 2**bexp */
junk1.x = y;
eps = bexp*ln_two2.x; /* x = bexp*ln(2) + t - eps */
t = x - bexp*ln_two1.x;
y = t + three33.x;
base = y - three33.x; /* t rounded to a multiple of 2**-18 */
junk2.x = y;
del = (t - base) + (xx-eps); /* x = bexp*ln(2) + base + del */
eps = del + del*del*(p3.x*del + p2.x);
binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+1023)<<20;
i = ((junk2.i[LOW_HALF]>>8)&0xfffffffe)+356;
j = (junk2.i[LOW_HALF]&511)<<1;
al = coar.x[i]*fine.x[j];
bet =(coar.x[i]*fine.x[j+1] + coar.x[i+1]*fine.x[j]) + coar.x[i+1]*fine.x[j+1];
rem=(bet + bet*eps)+al*eps;
res = al + rem;
cor = (al - res) + rem;
if (res == (res+cor*(1.0+error+err_1))) return res*binexp.x;
else return -10.0;
}
if (n <= smallint) return 1.0; /* if x->0 e^x=1 */
if (n >= badint) {
if (n > infint) return(zero/zero); /* x is NaN, return invalid */
if (n < infint) return ( (x>0) ? (hhuge*hhuge) : (tiny*tiny) );
/* x is finite, cause either overflow or underflow */
if (junk1.i[LOW_HALF] != 0) return (zero/zero); /* x is NaN */
return ((x>0)?inf.x:zero ); /* |x| = inf; return either inf or 0 */
}
y = x*log2e.x + three51.x;
bexp = y - three51.x;
junk1.x = y;
eps = bexp*ln_two2.x;
t = x - bexp*ln_two1.x;
y = t + three33.x;
base = y - three33.x;
junk2.x = y;
del = (t - base) + (xx-eps);
eps = del + del*del*(p3.x*del + p2.x);
i = ((junk2.i[LOW_HALF]>>8)&0xfffffffe)+356;
j = (junk2.i[LOW_HALF]&511)<<1;
al = coar.x[i]*fine.x[j];
bet =(coar.x[i]*fine.x[j+1] + coar.x[i+1]*fine.x[j]) + coar.x[i+1]*fine.x[j+1];
rem=(bet + bet*eps)+al*eps;
res = al + rem;
cor = (al - res) + rem;
if (m>>31) {
ex=junk1.i[LOW_HALF];
if (res < 1.0) {res+=res; cor+=cor; ex-=1;}
if (ex >=-1022) {
binexp.i[HIGH_HALF] = (1023+ex)<<20;
if (res == (res+cor*(1.0+error+err_1))) return res*binexp.x;
else return -10.0;
}
ex = -(1022+ex);
binexp.i[HIGH_HALF] = (1023-ex)<<20;
res*=binexp.x;
cor*=binexp.x;
eps=1.00000000001+(error+err_1)*binexp.x;
t=1.0+res;
y = ((1.0-t)+res)+cor;
res=t+y;
cor = (t-res)+y;
if (res == (res + eps*cor))
{binexp.i[HIGH_HALF] = 0x00100000; return (res-1.0)*binexp.x;}
else return -10.0;
}
else {
binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+767)<<20;
if (res == (res+cor*(1.0+error+err_1)))
return res*binexp.x*t256.x;
else return -10.0;
}
}

View File

@ -199,14 +199,14 @@ static double zero= 0.00000000000000000000e+00;
}
}
switch (n) {
case 0: y = __kernel_sin(pi*y,zero,0); break;
case 0: y = sin(pi*y); break;
case 1:
case 2: y = __kernel_cos(pi*(0.5-y),zero); break;
case 2: y = cos(pi*(0.5-y)); break;
case 3:
case 4: y = __kernel_sin(pi*(one-y),zero,0); break;
case 4: y = sin(pi*(one-y)); break;
case 5:
case 6: y = -__kernel_cos(pi*(y-1.5),zero); break;
default: y = __kernel_sin(pi*(y-2.0),zero,0); break;
case 6: y = -cos(pi*(y-1.5)); break;
default: y = sin(pi*(y-2.0)); break;
}
return -y;
}

View File

@ -1,165 +1,197 @@
/* @(#)e_log.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* 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.
* ====================================================
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25,
for performance improvement on pipelined processors.
*/
/*********************************************************************/
/* */
/* MODULE_NAME:ulog.h */
/* */
/* FUNCTION:ulog */
/* */
/* FILES NEEDED: dla.h endian.h mpa.h mydefs.h ulog.h */
/* mpexp.c mplog.c mpa.c */
/* ulog.tbl */
/* */
/* An ultimate log routine. Given an IEEE double machine number x */
/* it computes the correctly rounded (to nearest) value of log(x). */
/* Assumption: Machine arithmetic operations are performed in */
/* round to nearest mode of IEEE 754 standard. */
/* */
/*********************************************************************/
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: e_log.c,v 1.8 1995/05/10 20:45:49 jtc Exp $";
#endif
/* __ieee754_log(x)
* Return the logarithm of x
*
* Method :
* 1. Argument Reduction: find k and f such that
* x = 2^k * (1+f),
* where sqrt(2)/2 < 1+f < sqrt(2) .
*
* 2. Approximation of log(1+f).
* 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 + .....,
* = 2s + s*R
* We use a special Reme algorithm on [0,0.1716] to generate
* a polynomial of degree 14 to approximate R The maximum error
* of this polynomial approximation is bounded by 2**-58.45. In
* other words,
* 2 4 6 8 10 12 14
* R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s
* (the values of Lg1 to Lg7 are listed in the program)
* and
* | 2 14 | -58.45
* | Lg1*s +...+Lg7*s - R(z) | <= 2
* | |
* Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
* In order to guarantee error in log below 1ulp, we compute log
* by
* log(1+f) = f - s*(f - R) (if f is not too large)
* log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)
*
* 3. Finally, log(x) = k*ln2 + log(1+f).
* = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
* Here ln2 is split into two floating point number:
* ln2_hi + ln2_lo,
* where n*ln2_hi is always exact for |n| < 2000.
*
* Special cases:
* log(x) is NaN with signal if x < 0 (including -INF) ;
* log(+INF) is +INF; log(0) is -INF with signal;
* log(NaN) is that NaN with no signal.
*
* Accuracy:
* according to an error analysis, the error is always less than
* 1 ulp (unit 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 "endian.h"
#include "dla.h"
#include "mpa.h"
#include "MathLib.h"
void __mplog(mp_no *, mp_no *, int);
#include "math.h"
#include "math_private.h"
#define half Lg[8]
#define two Lg[9]
#ifdef __STDC__
static const double
#else
static double
#endif
ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */
Lg[] = {0.0,
6.666666666666735130e-01, /* 3FE55555 55555593 */
3.999999999940941908e-01, /* 3FD99999 9997FA04 */
2.857142874366239149e-01, /* 3FD24924 94229359 */
2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
1.818357216161805012e-01, /* 3FC74664 96CB03DE */
1.531383769920937332e-01, /* 3FC39A09 D078C69F */
1.479819860511658591e-01, /* 3FC2F112 DF3E5244 */
0.5,
2.0};
#ifdef __STDC__
static const double zero = 0.0;
#else
static double zero = 0.0;
#endif
/*********************************************************************/
/* An ultimate log routine. Given an IEEE double machine number x */
/* it computes the correctly rounded (to nearest) value of log(x). */
/*********************************************************************/
double __ieee754_log(double x) {
#define M 4
static const int pr[M]={8,10,18,32};
int i,j,k,n,ux,dx,p;
double dbl_n,u,p0,q,r0,w,nln2a,luai,lubi,lvaj,lvbj,
sij,ssij,ttij,A,B,B0,y,y1,y2,polI,polII,sa,sb,
t1,t2,t3,t4,t5,t6,t7,t8,t,ra,rb,ww,
a0,aa0,s1,s2,ss2,s3,ss3,a1,aa1,a,aa,b,bb,c;
number num;
mp_no mpx,mpy,mpy1,mpy2,mperr;
#ifdef __STDC__
double __ieee754_log(double x)
#else
double __ieee754_log(x)
double x;
#endif
{
double hfsq,f,s,z,R,w,dk,t11,t12,t21,t22,w2,zw2;
#ifdef DO_NOT_USE_THIS
double t1,t2;
#endif
int32_t k,hx,i,j;
u_int32_t lx;
#include "ulog.tbl"
#include "ulog.h"
EXTRACT_WORDS(hx,lx,x);
/* Treating special values of x ( x<=0, x=INF, x=NaN etc.). */
k=0;
if (hx < 0x00100000) { /* x < 2**-1022 */
if (((hx&0x7fffffff)|lx)==0)
return -two54/(x-x); /* log(+-0)=-inf */
if (hx<0) return (x-x)/(x-x); /* log(-#) = NaN */
k -= 54; x *= two54; /* subnormal number, scale up x */
GET_HIGH_WORD(hx,x);
}
if (hx >= 0x7ff00000) return x+x;
k += (hx>>20)-1023;
hx &= 0x000fffff;
i = (hx+0x95f64)&0x100000;
SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
k += (i>>20);
f = x-1.0;
if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */
if(f==zero) {
if(k==0) return zero; else {dk=(double)k;
return dk*ln2_hi+dk*ln2_lo;}
}
R = f*f*(half-0.33333333333333333*f);
if(k==0) return f-R; else {dk=(double)k;
return dk*ln2_hi-((R-dk*ln2_lo)-f);}
}
s = f/(two+f);
dk = (double)k;
z = s*s;
i = hx-0x6147a;
w = z*z;
j = 0x6b851-hx;
#ifdef DO_NOT_USE_THIS
t1= w*(Lg2+w*(Lg4+w*Lg6));
t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
R = t2+t1;
#else
t21 = Lg[5]+w*Lg[7]; w2=w*w;
t22 = Lg[1]+w*Lg[3]; zw2=z*w2;
t11 = Lg[4]+w*Lg[6];
t12 = w*Lg[2];
R = t12 + w2*t11 + z*t22 + zw2*t21;
#endif
i |= j;
if(i>0) {
hfsq=0.5*f*f;
if(k==0) return f-(hfsq-s*(hfsq+R)); else
return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
} else {
if(k==0) return f-s*(f-R); else
return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
}
num.d = x; ux = num.i[HIGH_HALF]; dx = num.i[LOW_HALF];
n=0;
if (ux < 0x00100000) {
if (((ux & 0x7fffffff) | dx) == 0) return MHALF/ZERO; /* return -INF */
if (ux < 0) return (x-x)/ZERO; /* return NaN */
n -= 54; x *= two54.d; /* scale x */
num.d = x;
}
if (ux >= 0x7ff00000) return x+x; /* INF or NaN */
/* Regular values of x */
w = x-ONE;
if (ABS(w) > U03) { goto case_03; }
/*--- Stage I, the case abs(x-1) < 0.03 */
t8 = MHALF*w;
EMULV(t8,w,a,aa,t1,t2,t3,t4,t5)
EADD(w,a,b,bb)
/* Evaluate polynomial II */
polII = (b0.d+w*(b1.d+w*(b2.d+w*(b3.d+w*(b4.d+
w*(b5.d+w*(b6.d+w*(b7.d+w*b8.d))))))))*w*w*w;
c = (aa+bb)+polII;
/* End stage I, case abs(x-1) < 0.03 */
if ((y=b+(c+b*E2)) == b+(c-b*E2)) return y;
/*--- Stage II, the case abs(x-1) < 0.03 */
a = d11.d+w*(d12.d+w*(d13.d+w*(d14.d+w*(d15.d+w*(d16.d+
w*(d17.d+w*(d18.d+w*(d19.d+w*d20.d))))))));
EMULV(w,a,s2,ss2,t1,t2,t3,t4,t5)
ADD2(d10.d,dd10.d,s2,ss2,s3,ss3,t1,t2)
MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(d9.d,dd9.d,s2,ss2,s3,ss3,t1,t2)
MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(d8.d,dd8.d,s2,ss2,s3,ss3,t1,t2)
MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(d7.d,dd7.d,s2,ss2,s3,ss3,t1,t2)
MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(d6.d,dd6.d,s2,ss2,s3,ss3,t1,t2)
MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(d5.d,dd5.d,s2,ss2,s3,ss3,t1,t2)
MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(d4.d,dd4.d,s2,ss2,s3,ss3,t1,t2)
MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(d3.d,dd3.d,s2,ss2,s3,ss3,t1,t2)
MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(d2.d,dd2.d,s2,ss2,s3,ss3,t1,t2)
MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(w,ZERO,s2,ss2,s3,ss3,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(w,ZERO, s3,ss3, b, bb,t1,t2)
/* End stage II, case abs(x-1) < 0.03 */
if ((y=b+(bb+b*E4)) == b+(bb-b*E4)) return y;
goto stage_n;
/*--- Stage I, the case abs(x-1) > 0.03 */
case_03:
/* Find n,u such that x = u*2**n, 1/sqrt(2) < u < sqrt(2) */
n += (num.i[HIGH_HALF] >> 20) - 1023;
num.i[HIGH_HALF] = (num.i[HIGH_HALF] & 0x000fffff) | 0x3ff00000;
if (num.d > SQRT_2) { num.d *= HALF; n++; }
u = num.d; dbl_n = (double) n;
/* Find i such that ui=1+(i-75)/2**8 is closest to u (i= 0,1,2,...,181) */
num.d += h1.d;
i = (num.i[HIGH_HALF] & 0x000fffff) >> 12;
/* Find j such that vj=1+(j-180)/2**16 is closest to v=u/ui (j= 0,...,361) */
num.d = u*Iu[i].d + h2.d;
j = (num.i[HIGH_HALF] & 0x000fffff) >> 4;
/* Compute w=(u-ui*vj)/(ui*vj) */
p0=(ONE+(i-75)*DEL_U)*(ONE+(j-180)*DEL_V);
q=u-p0; r0=Iu[i].d*Iv[j].d; w=q*r0;
/* Evaluate polynomial I */
polI = w+(a2.d+a3.d*w)*w*w;
/* Add up everything */
nln2a = dbl_n*LN2A;
luai = Lu[i][0].d; lubi = Lu[i][1].d;
lvaj = Lv[j][0].d; lvbj = Lv[j][1].d;
EADD(luai,lvaj,sij,ssij)
EADD(nln2a,sij,A ,ttij)
B0 = (((lubi+lvbj)+ssij)+ttij)+dbl_n*LN2B;
B = polI+B0;
/* End stage I, case abs(x-1) >= 0.03 */
if ((y=A+(B+E1)) == A+(B-E1)) return y;
/*--- Stage II, the case abs(x-1) > 0.03 */
/* Improve the accuracy of r0 */
EMULV(p0,r0,sa,sb,t1,t2,t3,t4,t5)
t=r0*((ONE-sa)-sb);
EADD(r0,t,ra,rb)
/* Compute w */
MUL2(q,ZERO,ra,rb,w,ww,t1,t2,t3,t4,t5,t6,t7,t8)
EADD(A,B0,a0,aa0)
/* Evaluate polynomial III */
s1 = (c3.d+(c4.d+c5.d*w)*w)*w;
EADD(c2.d,s1,s2,ss2)
MUL2(s2,ss2,w,ww,s3,ss3,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(s3,ss3,w,ww,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(s2,ss2,w,ww,s3,ss3,t1,t2)
ADD2(s3,ss3,a0,aa0,a1,aa1,t1,t2)
/* End stage II, case abs(x-1) >= 0.03 */
if ((y=a1+(aa1+E3)) == a1+(aa1-E3)) return y;
/* Final stages. Use multi-precision arithmetic. */
stage_n:
for (i=0; i<M; i++) {
p = pr[i];
dbl_mp(x,&mpx,p); dbl_mp(y,&mpy,p);
__mplog(&mpx,&mpy,p);
dbl_mp(e[i].d,&mperr,p);
add(&mpy,&mperr,&mpy1,p); sub(&mpy,&mperr,&mpy2,p);
mp_dbl(&mpy1,&y1,p); mp_dbl(&mpy2,&y2,p);
if (y1==y2) return y1;
}
return y1;
}

View File

@ -1,356 +1,328 @@
/* @(#)e_pow.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* 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.
* ====================================================
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25,
for performance improvement on pipelined processors.
*/
/***************************************************************************/
/* MODULE_NAME: upow.c */
/* */
/* FUNCTIONS: upow */
/* power1 */
/* log2 */
/* log1 */
/* checkint */
/* FILES NEEDED: dla.h endian.h mpa.h mydefs.h */
/* halfulp.c mpexp.c mplog.c slowexp.c slowpow.c mpa.c */
/* uexp.c upow.c */
/* root.tbl uexp.tbl upow.tbl */
/* An ultimate power routine. Given two IEEE double machine numbers y,x */
/* it computes the correctly rounded (to nearest) value of x^y. */
/* Assumption: Machine arithmetic operations are performed in */
/* round to nearest mode of IEEE 754 standard. */
/* */
/***************************************************************************/
#include "endian.h"
#include "upow.h"
#include "dla.h"
#include "mydefs.h"
#include "MathLib.h"
#include "upow.tbl"
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: e_pow.c,v 1.9 1995/05/12 04:57:32 jtc Exp $";
#endif
/* __ieee754_pow(x,y) return x**y
*
* n
* Method: Let x = 2 * (1+f)
* 1. Compute and return log2(x) in two pieces:
* log2(x) = w1 + w2,
* where w1 has 53-24 = 29 bit trailing zeros.
* 2. Perform y*log2(x) = n+y' by simulating muti-precision
* arithmetic, where |y'|<=0.5.
* 3. Return x**y = 2**n*exp(y'*log2)
*
* Special cases:
* 1. (anything) ** 0 is 1
* 2. (anything) ** 1 is itself
* 3. (anything) ** NAN is NAN
* 4. NAN ** (anything except 0) is NAN
* 5. +-(|x| > 1) ** +INF is +INF
* 6. +-(|x| > 1) ** -INF is +0
* 7. +-(|x| < 1) ** +INF is +0
* 8. +-(|x| < 1) ** -INF is +INF
* 9. +-1 ** +-INF is NAN
* 10. +0 ** (+anything except 0, NAN) is +0
* 11. -0 ** (+anything except 0, NAN, odd integer) is +0
* 12. +0 ** (-anything except 0, NAN) is +INF
* 13. -0 ** (-anything except 0, NAN, odd integer) is +INF
* 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
* 15. +INF ** (+anything except 0,NAN) is +INF
* 16. +INF ** (-anything except 0,NAN) is +0
* 17. -INF ** (anything) = -0 ** (-anything)
* 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
* 19. (-anything except 0 and inf) ** (non-integer) is NAN
*
* Accuracy:
* pow(x,y) returns x**y nearly rounded. In particular
* pow(integer,integer)
* always returns the correct integer provided it is
* representable.
*
* 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.
*/
double __exp1(double x, double xx, double error);
static double log1(double x, double *delta, double *error);
static double log2(double x, double *delta, double *error);
double slowpow(double x, double y,double z);
static double power1(double x, double y);
static int checkint(double x);
#include "math.h"
#include "math_private.h"
#define zero C[0]
#define one C[1]
#define two C[2]
#define two53 C[3]
#define huge C[4]
#define tiny C[5]
#define L1 C[6]
#define L2 C[7]
#define L3 C[8]
#define L4 C[9]
#define L5 C[10]
#define L6 C[11]
#define P1 C[12]
#define P2 C[13]
#define P3 C[14]
#define P4 C[15]
#define P5 C[16]
#define lg2 C[17]
#define lg2_h C[18]
#define lg2_l C[19]
#define ovt C[20]
#define cp C[21]
#define cp_h C[22]
#define cp_l C[23]
#define ivln2 C[24]
#define ivln2_h C[25]
#define ivln2_l C[26]
/***************************************************************************/
/* An ultimate power routine. Given two IEEE double machine numbers y,x */
/* it computes the correctly rounded (to nearest) value of X^y. */
/***************************************************************************/
double __ieee754_upow(double x, double y) {
double z,a,aa,error, t,a1,a2,y1,y2,gor=1.0;
mynumber u,v;
int k;
int4 qx,qy;
v.x=y;
u.x=x;
if (v.i[LOW_HALF] == 0) { /* of y */
qx = u.i[HIGH_HALF]&0x7fffffff;
/* Checking if x is not too small to compute */
if (((qx==0x7ff00000)&&(u.i[LOW_HALF]!=0))||(qx>0x7ff00000)) return NaNQ.x;
if (y == 1.0) return x;
if (y == 2.0) return x*x;
if (y == -1.0) return (x!=0)?1.0/x:NaNQ.x;
if (y == 0) return ((x>0)&&(qx<0x7ff00000))?1.0:NaNQ.x;
}
/* else */
if(((u.i[HIGH_HALF]>0 && u.i[HIGH_HALF]<0x7ff00000)|| /* x>0 and not x->0 */
(u.i[HIGH_HALF]==0 && u.i[LOW_HALF]!=0)) &&
/* 2^-1023< x<= 2^-1023 * 0x1.0000ffffffff */
(v.i[HIGH_HALF]&0x7fffffff) < 0x4ff00000) { /* if y<-1 or y>1 */
z = log1(x,&aa,&error); /* x^y =e^(y log (X)) */
t = y*134217729.0;
y1 = t - (t-y);
y2 = y - y1;
t = z*134217729.0;
a1 = t - (t-z);
a2 = (z - a1)+aa;
a = y1*a1;
aa = y2*a1 + y*a2;
a1 = a+aa;
a2 = (a-a1)+aa;
error = error*ABS(y);
t = __exp1(a1,a2,1.9e16*error); /* return -10 or 0 if wasn't computed exactly */
return (t>0)?t:power1(x,y);
}
#ifdef __STDC__
static const double
#else
static double
#endif
bp[] = {1.0, 1.5,},
dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
C[] = {
0.0,
1.0,
2.0,
9007199254740992.0 ,
1.0e300,
1.0e-300,
5.99999999999994648725e-01 ,
4.28571428578550184252e-01 ,
3.33333329818377432918e-01 ,
2.72728123808534006489e-01 ,
2.30660745775561754067e-01 ,
2.06975017800338417784e-01 ,
1.66666666666666019037e-01 ,
-2.77777777770155933842e-03 ,
6.61375632143793436117e-05 ,
-1.65339022054652515390e-06 ,
4.13813679705723846039e-08 ,
6.93147180559945286227e-01 ,
6.93147182464599609375e-01 ,
-1.90465429995776804525e-09 ,
8.0085662595372944372e-0017 ,
9.61796693925975554329e-01 ,
9.61796700954437255859e-01 ,
-7.02846165095275826516e-09 ,
1.44269504088896338700e+00 ,
1.44269502162933349609e+00 ,
1.92596299112661746887e-08 };
if (x == 0) {
if (ABS(y) > 1.0e20) return (y>0)?0:NaNQ.x;
k = checkint(y);
if (k == 0 || y < 0) return NaNQ.x;
else return (k==1)?0:x; /* return 0 */
}
/* if x<0 */
if (u.i[HIGH_HALF] < 0) {
k = checkint(y);
if (k==0) return NaNQ.x; /* y not integer and x<0 */
return (k==1)?upow(-x,y):-upow(-x,y); /* if y even or odd */
}
/* x>0 */
qx = u.i[HIGH_HALF]&0x7fffffff; /* no sign */
qy = v.i[HIGH_HALF]&0x7fffffff; /* no sign */
#ifdef __STDC__
double __ieee754_pow(double x, double y)
#else
double __ieee754_pow(x,y)
double x, y;
#endif
{
double z,ax,z_h,z_l,p_h,p_l;
double y1,t1,t2,r,s,t,u,v,w, t12,t14,r_1,r_2,r_3;
int32_t i,j,k,yisint,n;
int32_t hx,hy,ix,iy;
u_int32_t lx,ly;
if (qx > 0x7ff00000 || (qx == 0x7ff00000 && u.i[LOW_HALF] != 0)) return NaNQ.x;
/* if 0<x<2^-0x7fe */
if (qy > 0x7ff00000 || (qy == 0x7ff00000 && v.i[LOW_HALF] != 0)) return NaNQ.x;
/* if y<2^-0x7fe */
EXTRACT_WORDS(hx,lx,x);
EXTRACT_WORDS(hy,ly,y);
ix = hx&0x7fffffff; iy = hy&0x7fffffff;
if (qx == 0x7ff00000) /* x= 2^-0x3ff */
{if (y == 0) return NaNQ.x;
return (y>0)?x:0; }
/* y==zero: x**0 = 1 */
if((iy|ly)==0) return C[1];
if (qy > 0x45f00000 && qy < 0x7ff00000) {
if (x == 1.0) return 1.0;
if (y>0) return (x>1.0)?INF.x:0;
if (y<0) return (x<1.0)?INF.x:0;
}
/* x==+-1 */
if(x == 1.0) return C[1];
if(x == -1.0 && isinf(y)) return C[1];
/* +-NaN return x+y */
if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
return x+y;
/* determine if y is an odd int when x < 0
* yisint = 0 ... y is not an integer
* yisint = 1 ... y is an odd int
* yisint = 2 ... y is an even int
*/
yisint = 0;
if(hx<0) {
if(iy>=0x43400000) yisint = 2; /* even integer y */
else if(iy>=0x3ff00000) {
k = (iy>>20)-0x3ff; /* exponent */
if(k>20) {
j = ly>>(52-k);
if((u_int32_t)(j<<(52-k))==ly) yisint = 2-(j&1);
} else if(ly==0) {
j = iy>>(20-k);
if((int32_t)(j<<(20-k))==iy) yisint = 2-(j&1);
}
}
}
/* special value of y */
if(ly==0) {
if (iy==0x7ff00000) { /* y is +-inf */
if(((ix-0x3ff00000)|lx)==0)
return y - y; /* inf**+-1 is NaN */
else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
return (hy>=0)? y: C[0];
else /* (|x|<1)**-,+inf = inf,0 */
return (hy<0)?-y: C[0];
}
if(iy==0x3ff00000) { /* y is +-1 */
if(hy<0) return C[1]/x; else return x;
}
if(hy==0x40000000) return x*x; /* y is 2 */
if(hy==0x3fe00000) { /* y is 0.5 */
if(hx>=0) /* x >= +0 */
return __ieee754_sqrt(x);
}
}
ax = fabs(x);
/* special value of x */
if(lx==0) {
if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
z = ax; /*x is +-0,+-inf,+-1*/
if(hy<0) z = C[1]/z; /* z = (1/|x|) */
if(hx<0) {
if(((ix-0x3ff00000)|yisint)==0) {
z = (z-z)/(z-z); /* (-1)**non-int is NaN */
} else if(yisint==1)
z = -z; /* (x<0)**odd = -(|x|**odd) */
}
return z;
}
}
/* (x<0)**(non-int) is NaN */
if(((((u_int32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x);
/* |y| is huge */
if(iy>0x41e00000) { /* if |y| > 2**31 */
if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */
if(ix<=0x3fefffff) return (hy<0)? C[4]*C[4]:C[5]*C[5];
if(ix>=0x3ff00000) return (hy>0)? C[4]*C[4]:C[5]*C[5];
}
/* over/underflow if x is not close to one */
if(ix<0x3fefffff) return (hy<0)? C[4]*C[4]:C[5]*C[5];
if(ix>0x3ff00000) return (hy>0)? C[4]*C[4]:C[5]*C[5];
/* now |1-x| is tiny <= 2**-20, suffice to compute
log(x) by x-x^2/2+x^3/3-x^4/4 */
t = x-1; /* t has 20 trailing zeros */
w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
u = C[25]*t; /* ivln2_h has 21 sig. bits */
v = t*C[26]-w*C[24];
t1 = u+v;
SET_LOW_WORD(t1,0);
t2 = v-(t1-u);
} else {
double s2,s_h,s_l,t_h,t_l,s22,s24,s26,r1,r2,r3;
n = 0;
/* take care subnormal number */
if(ix<0x00100000)
{ax *= C[3]; n -= 53; GET_HIGH_WORD(ix,ax); }
n += ((ix)>>20)-0x3ff;
j = ix&0x000fffff;
/* determine interval */
ix = j|0x3ff00000; /* normalize ix */
if(j<=0x3988E) k=0; /* |x|<sqrt(3/2) */
else if(j<0xBB67A) k=1; /* |x|<sqrt(3) */
else {k=0;n+=1;ix -= 0x00100000;}
SET_HIGH_WORD(ax,ix);
/* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
v = C[1]/(ax+bp[k]);
s = u*v;
s_h = s;
SET_LOW_WORD(s_h,0);
/* t_h=ax+bp[k] High */
t_h = C[0];
SET_HIGH_WORD(t_h,((ix>>1)|0x20000000)+0x00080000+(k<<18));
t_l = ax - (t_h-bp[k]);
s_l = v*((u-s_h*t_h)-s_h*t_l);
/* compute log(ax) */
s2 = s*s;
#ifdef DO_NOT_USE_THIS
r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
#else
r1 = C[10]+s2*C[11]; s22=s2*s2;
r2 = C[8]+s2*C[9]; s24=s22*s22;
r3 = C[6]+s2*C[7]; s26=s24*s22;
r = r3*s22 + r2*s24 + r1*s26;
#endif
r += s_l*(s_h+s);
s2 = s_h*s_h;
t_h = 3.0+s2+r;
SET_LOW_WORD(t_h,0);
t_l = r-((t_h-3.0)-s2);
/* u+v = s*(1+...) */
u = s_h*t_h;
v = s_l*t_h+t_l*s;
/* 2/(3log2)*(s+...) */
p_h = u+v;
SET_LOW_WORD(p_h,0);
p_l = v-(p_h-u);
z_h = C[22]*p_h; /* cp_h+cp_l = 2/(3*log2) */
z_l = C[23]*p_h+p_l*C[21]+dp_l[k];
/* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
t = (double)n;
t1 = (((z_h+z_l)+dp_h[k])+t);
SET_LOW_WORD(t1,0);
t2 = z_l-(((t1-t)-dp_h[k])-z_h);
}
s = C[1]; /* s (sign of result -ve**odd) = -1 else = 1 */
if(((((u_int32_t)hx>>31)-1)|(yisint-1))==0)
s = -C[1];/* (-ve)**(odd int) */
/* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
y1 = y;
SET_LOW_WORD(y1,0);
p_l = (y-y1)*t1+y*t2;
p_h = y1*t1;
z = p_l+p_h;
EXTRACT_WORDS(j,i,z);
if (j>=0x40900000) { /* z >= 1024 */
if(((j-0x40900000)|i)!=0) /* if z > 1024 */
return s*C[4]*C[4]; /* overflow */
else {
if(p_l+C[20]>z-p_h) return s*C[4]*C[4]; /* overflow */
}
} else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */
if(((j-0xc090cc00)|i)!=0) /* z < -1075 */
return s*C[5]*C[5]; /* underflow */
else {
if(p_l<=z-p_h) return s*C[5]*C[5]; /* underflow */
}
}
/*
* compute 2**(p_h+p_l)
*/
i = j&0x7fffffff;
k = (i>>20)-0x3ff;
n = 0;
if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */
n = j+(0x00100000>>(k+1));
k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */
t = C[0];
SET_HIGH_WORD(t,n&~(0x000fffff>>k));
n = ((n&0x000fffff)|0x00100000)>>(20-k);
if(j<0) n = -n;
p_h -= t;
}
t = p_l+p_h;
SET_LOW_WORD(t,0);
u = t*C[18];
v = (p_l-(t-p_h))*C[17]+t*C[19];
z = u+v;
w = v-(z-u);
t = z*z;
#ifdef DO_NOT_USE_THIS
t1 = z - t*(C[12]+t*(C[13]+t*(C[14]+t*(C[15]+t*C[16]))));
#else
r_1 = C[15]+t*C[16]; t12 = t*t;
r_2 = C[13]+t*C[14]; t14 = t12*t12;
r_3 = t*C[12];
t1 = z - r_3 - t12*r_2 - t14*r_1;
#endif
r = (z*t1)/(t1-C[2])-(w+z*w);
z = C[1]-(r-z);
GET_HIGH_WORD(j,z);
j += (n<<20);
if((j>>20)<=0) z = __scalbn(z,n); /* subnormal output */
else SET_HIGH_WORD(z,j);
return s*z;
if (x == 1.0) return NaNQ.x;
if (y>0) return (x>1.0)?INF.x:0;
if (y<0) return (x<1.0)?INF.x:0;
return 0; /* unreachable, to make the compiler happy */
}
/**************************************************************************/
/* Computing x^y using more accurate but more slow log routine */
/**************************************************************************/
static double power1(double x, double y) {
double z,a,aa,error, t,a1,a2,y1,y2;
z = log2(x,&aa,&error);
t = y*134217729.0;
y1 = t - (t-y);
y2 = y - y1;
t = z*134217729.0;
a1 = t - (t-z);
a2 = z - a1;
a = y*z;
aa = ((y1*a1-a)+y1*a2+y2*a1)+y2*a2+aa*y;
a1 = a+aa;
a2 = (a-a1)+aa;
error = error*ABS(y);
t = __exp1(a1,a2,1.9e16*error);
return (t >= 0)?t:slowpow(x,y,z);
}
/****************************************************************************/
/* Computing log(x) (x is left argument). The result is the returned double */
/* + the parameter delta. */
/* The result is bounded by error (rightmost argument) */
/****************************************************************************/
static double log1(double x, double *delta, double *error) {
int i,j,m,n;
double uu,vv,eps,nx,e,e1,e2,t,t1,t2,res,cor,add=0;
mynumber u,v;
u.x = x;
m = u.i[HIGH_HALF];
*error = 0;
*delta = 0;
if (m < 0x00100000) /* 1<x<2^-1007 */
{ x = x*t52.x; add = -52.0; u.x = x; m = u.i[HIGH_HALF];}
if ((m&0x000fffff) < 0x0006a09e)
{u.i[HIGH_HALF] = (m&0x000fffff)|0x3ff00000; two52.i[LOW_HALF]=(m>>20); }
else
{u.i[HIGH_HALF] = (m&0x000fffff)|0x3fe00000; two52.i[LOW_HALF]=(m>>20)+1; }
v.x = u.x + bigu.x;
uu = v.x - bigu.x;
i = (v.i[LOW_HALF]&0x000003ff)<<2;
if (two52.i[LOW_HALF] == 1023) /* nx = 0 */
{
if (i > 1192 && i < 1208) /* |x-1| < 1.5*2**-10 */
{
t = x - 1.0;
t1 = (t+5.0e6)-5.0e6;
t2 = t-t1;
e1 = t - 0.5*t1*t1;
e2 = t*t*t*(r3+t*(r4+t*(r5+t*(r6+t*(r7+t*r8)))))-0.5*t2*(t+t1);
res = e1+e2;
*error = 1.0e-21*ABS(t);
*delta = (e1-res)+e2;
return res;
} /* |x-1| < 1.5*2**-10 */
else
{
v.x = u.x*(ui.x[i]+ui.x[i+1])+bigv.x;
vv = v.x-bigv.x;
j = v.i[LOW_HALF]&0x0007ffff;
j = j+j+j;
eps = u.x - uu*vv;
e1 = eps*ui.x[i];
e2 = eps*(ui.x[i+1]+vj.x[j]*(ui.x[i]+ui.x[i+1]));
e = e1+e2;
e2 = ((e1-e)+e2);
t=ui.x[i+2]+vj.x[j+1];
t1 = t+e;
t2 = (((t-t1)+e)+(ui.x[i+3]+vj.x[j+2]))+e2+e*e*(p2+e*(p3+e*p4));
res=t1+t2;
*error = 1.0e-24;
*delta = (t1-res)+t2;
return res;
}
} /* nx = 0 */
else /* nx != 0 */
{
eps = u.x - uu;
nx = (two52.x - two52e.x)+add;
e1 = eps*ui.x[i];
e2 = eps*ui.x[i+1];
e=e1+e2;
e2 = (e1-e)+e2;
t=nx*ln2a.x+ui.x[i+2];
t1=t+e;
t2=(((t-t1)+e)+nx*ln2b.x+ui.x[i+3]+e2)+e*e*(q2+e*(q3+e*(q4+e*(q5+e*q6))));
res = t1+t2;
*error = 1.0e-21;
*delta = (t1-res)+t2;
return res;
} /* nx != 0 */
}
/****************************************************************************/
/* More slow but more accurate routine of log */
/* Computing log(x)(x is left argument).The result is return double + delta.*/
/* The result is bounded by error (right argument) */
/****************************************************************************/
static double log2(double x, double *delta, double *error) {
int i,j,m,n;
double uu,vv,eps,nx,e,e1,e2,t,t1,t2,res,cor,add=0;
double ou1,ou2,lu1,lu2,ov,lv1,lv2,a,a1,a2;
double y,yy,z,zz,j1,j2,j3,j4,j5,j6,j7,j8;
mynumber u,v;
u.x = x;
m = u.i[HIGH_HALF];
*error = 0;
*delta = 0;
add=0;
if (m<0x00100000) { /* x < 2^-1022 */
x = x*t52.x; add = -52.0; u.x = x; m = u.i[HIGH_HALF]; }
if ((m&0x000fffff) < 0x0006a09e)
{u.i[HIGH_HALF] = (m&0x000fffff)|0x3ff00000; two52.i[LOW_HALF]=(m>>20); }
else
{u.i[HIGH_HALF] = (m&0x000fffff)|0x3fe00000; two52.i[LOW_HALF]=(m>>20)+1; }
v.x = u.x + bigu.x;
uu = v.x - bigu.x;
i = (v.i[LOW_HALF]&0x000003ff)<<2;
/*------------------------------------- |x-1| < 2**-11------------------------------- */
if ((two52.i[LOW_HALF] == 1023) && (i == 1200))
{
t = x - 1.0;
EMULV(t,s3,y,yy,j1,j2,j3,j4,j5);
ADD2(-0.5,0,y,yy,z,zz,j1,j2);
MUL2(t,0,z,zz,y,yy,j1,j2,j3,j4,j5,j6,j7,j8);
MUL2(t,0,y,yy,z,zz,j1,j2,j3,j4,j5,j6,j7,j8);
e1 = t+z;
e2 = (((t-e1)+z)+zz)+t*t*t*(ss3+t*(s4+t*(s5+t*(s6+t*(s7+t*s8)))));
res = e1+e2;
*error = 1.0e-25*ABS(t);
*delta = (e1-res)+e2;
return res;
}
/*----------------------------- |x-1| > 2**-11 -------------------------- */
else
{ /*Computing log(x) according to log table */
nx = (two52.x - two52e.x)+add;
ou1 = ui.x[i];
ou2 = ui.x[i+1];
lu1 = ui.x[i+2];
lu2 = ui.x[i+3];
v.x = u.x*(ou1+ou2)+bigv.x;
vv = v.x-bigv.x;
j = v.i[LOW_HALF]&0x0007ffff;
j = j+j+j;
eps = u.x - uu*vv;
ov = vj.x[j];
lv1 = vj.x[j+1];
lv2 = vj.x[j+2];
a = (ou1+ou2)*(1.0+ov);
a1 = (a+1.0e10)-1.0e10;
a2 = a*(1.0-a1*uu*vv);
e1 = eps*a1;
e2 = eps*a2;
e = e1+e2;
e2 = (e1-e)+e2;
t=nx*ln2a.x+lu1+lv1;
t1 = t+e;
t2 = (((t-t1)+e)+(lu2+lv2+nx*ln2b.x+e2))+e*e*(p2+e*(p3+e*p4));
res=t1+t2;
*error = 1.0e-27;
*delta = (t1-res)+t2;
return res;
}
}
/**********************************************************************/
/* Routine receives a double x and checks if it is an integer. If not */
/* it returns 0, else it returns 1 if even or -1 if odd. */
/**********************************************************************/
static int checkint(double x) {
union {int4 i[2]; double x;} u;
int k,l,m,n;
u.x = x;
m = u.i[HIGH_HALF]&0x7fffffff; /* no sign */
if (m >= 0x7ff00000) return 0; /* x is +/-inf or NaN */
if (m >= 0x43400000) return 1; /* |x| >= 2**53 */
if (m < 0x40000000) return 0; /* |x| < 2, can not be 0 or 1 */
n = u.i[LOW_HALF];
k = (m>>20)-1023; /* 1 <= k <= 52 */
if (k == 52) return (n&1)? -1:1; /* odd or even*/
if (k>20) {
if (n<<(k-20)) return 0; /* if not integer */
return (n<<(k-21))?-1:1;
}
if (n) return 0; /*if not integer*/
if (k == 20) return (m&1)? -1:1;
if (m<<(k+12)) return 0;
return (m<<(k+11))?-1:1;
}

View File

@ -1,80 +1,111 @@
/* @(#)e_remainder.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* 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.
* ====================================================
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/**************************************************************************/
/* MODULE_NAME urem.c */
/* */
/* FUNCTION: uremainder */
/* */
/* An ultimate remainder routine. Given two IEEE double machine numbers x */
/* ,y it computes the correctly rounded (to nearest) value of remainder */
/* of dividing x by y. */
/* Assumption: Machine arithmetic operations are performed in */
/* round to nearest mode of IEEE 754 standard. */
/* */
/* ************************************************************************/
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: e_remainder.c,v 1.8 1995/05/10 20:46:05 jtc Exp $";
#endif
#include "endian.h"
#include "mydefs.h"
#include "urem.h"
#include "MathLib.h"
/* __ieee754_remainder(x,p)
* Return :
* returns x REM p = x - [x/p]*p as if in infinite
* precise arithmetic, where [x/p] is the (infinite bit)
* integer nearest x/p (in half way case choose the even one).
* Method :
* Based on fmod() return x-[x/p]chopped*p exactlp.
*/
#include "math.h"
#include "math_private.h"
#ifdef __STDC__
static const double zero = 0.0;
#else
static double zero = 0.0;
#endif
#ifdef __STDC__
double __ieee754_remainder(double x, double p)
#else
double __ieee754_remainder(x,p)
double x,p;
#endif
/**************************************************************************/
/* An ultimate remainder routine. Given two IEEE double machine numbers x */
/* ,y it computes the correctly rounded (to nearest) value of remainder */
/**************************************************************************/
double __ieee754_remainder(double x, double y)
{
int32_t hx,hp;
u_int32_t sx,lx,lp;
double p_half;
double z,d,xx,yy;
int4 kx,ky,m,n,nn,n1,m1,l;
mynumber u,t,w={0,0},v={0,0},ww={0,0},r;
u.x=x;
t.x=y;
kx=u.i[HIGH_HALF]&0x7fffffff; /* no sign for x*/
t.i[HIGH_HALF]&=0x7fffffff; /*no sign for y */
ky=t.i[HIGH_HALF];
/*------ |x| < 2^1024 and 2^-970 < |y| < 2^1024 ------------------*/
if (kx<0x7ff00000 && ky<0x7ff00000 && ky>=0x03500000) {
if (kx+0x00100000<ky) return x;
if ((kx-0x01500000)<ky) {
z=x/t.x;
v.i[HIGH_HALF]=t.i[HIGH_HALF];
d=(z+big.x)-big.x;
xx=(x-d*v.x)-d*(t.x-v.x);
if (d-z!=0.5&&d-z!=-0.5) return (xx!=0)?xx:((x>0)?ZERO.x:nZERO.x);
else {
if (ABS(xx)>0.5*t.x) return (z>d)?xx-t.x:xx+t.x;
else return xx;
}
} /* (kx<(ky+0x01500000)) */
else {
r.x=1.0/t.x;
n=t.i[HIGH_HALF];
nn=(n&0x7ff00000)+0x01400000;
w.i[HIGH_HALF]=n;
ww.x=t.x-w.x;
l=(kx-nn)&0xfff00000;
n1=ww.i[HIGH_HALF];
m1=r.i[HIGH_HALF];
while (l>0) {
r.i[HIGH_HALF]=m1-l;
z=u.x*r.x;
w.i[HIGH_HALF]=n+l;
ww.i[HIGH_HALF]=(n1)?n1+l:n1;
d=(z+big.x)-big.x;
u.x=(u.x-d*w.x)-d*ww.x;
l=(u.i[HIGH_HALF]&0x7ff00000)-nn;
}
r.i[HIGH_HALF]=m1;
w.i[HIGH_HALF]=n;
ww.i[HIGH_HALF]=n1;
z=u.x*r.x;
d=(z+big.x)-big.x;
u.x=(u.x-d*w.x)-d*ww.x;
if (ABS(u.x)<0.5*t.x) return (u.x!=0)?u.x:((x>0)?ZERO.x:nZERO.x);
else
if (ABS(u.x)>0.5*t.x) return (d>z)?u.x+t.x:u.x-t.x;
else
{z=u.x/t.x; d=(z+big.x)-big.x; return ((u.x-d*w.x)-d*ww.x);}
}
EXTRACT_WORDS(hx,lx,x);
EXTRACT_WORDS(hp,lp,p);
sx = hx&0x80000000;
hp &= 0x7fffffff;
hx &= 0x7fffffff;
/* purge off exception values */
if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */
if((hx>=0x7ff00000)|| /* x not finite */
((hp>=0x7ff00000)&& /* p is NaN */
(((hp-0x7ff00000)|lp)!=0)))
return (x*p)/(x*p);
if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */
if (((hx-hp)|(lx-lp))==0) return zero*x;
x = fabs(x);
p = fabs(p);
if (hp<0x00200000) {
if(x+x>p) {
x-=p;
if(x+x>=p) x -= p;
}
} else {
p_half = 0.5*p;
if(x>p_half) {
x-=p;
if(x>=p_half) x -= p;
}
}
GET_HIGH_WORD(hx,x);
SET_HIGH_WORD(x,hx^sx);
return x;
} /* (kx<0x7ff00000&&ky<0x7ff00000&&ky>=0x03500000) */
else {
if (kx<0x7ff00000&&ky<0x7ff00000&&(ky>0||t.i[LOW_HALF]!=0)) {
y=ABS(y)*t128.x;
z=uremainder(x,y)*t128.x;
z=uremainder(z,y)*tm128.x;
return z;
}
else { /* if x is too big */
if (kx>=0x7ff00000||(ky==0&&t.i[LOW_HALF]==0)||ky>0x7ff00000||
(ky==0x7ff00000&&t.i[LOW_HALF]!=0))
return (u.i[HIGH_HALF]&0x80000000)?nNAN.x:NAN.x;
else return x;
}
}
}

View File

@ -1,452 +1,89 @@
/* @(#)e_sqrt.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* 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.
* ====================================================
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*********************************************************************/
/* MODULE_NAME: uroot.c */
/* */
/* FUNCTION: usqrt */
/* */
/* FILES NEEDED: dla.h endian.h mydefs.h uroot.h */
/* uroot.tbl */
/* */
/* An ultimate sqrt routine. Given an IEEE double machine number x */
/* it computes the correctly rounded (to nearest) value of square */
/* root of x. */
/* Assumption: Machine arithmetic operations are performed in */
/* round to nearest mode of IEEE 754 standard. */
/* */
/*********************************************************************/
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: e_sqrt.c,v 1.8 1995/05/10 20:46:17 jtc Exp $";
#endif
#include "endian.h"
#include "mydefs.h"
#include "dla.h"
#include "MathLib.h"
#include "root.tbl"
/* __ieee754_sqrt(x)
* Return correctly rounded sqrt.
* ------------------------------------------
* | Use the hardware sqrt if you have one |
* ------------------------------------------
* Method:
* Bit by bit method using integer arithmetic. (Slow, but portable)
* 1. Normalization
* Scale x to y in [1,4) with even powers of 2:
* find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
* sqrt(x) = 2^k * sqrt(y)
* 2. Bit by bit computation
* Let q = sqrt(y) truncated to i bit after binary point (q = 1),
* i 0
* i+1 2
* s = 2*q , and y = 2 * ( y - q ). (1)
* i i i i
*
* To compute q from q , one checks whether
* i+1 i
*
* -(i+1) 2
* (q + 2 ) <= y. (2)
* i
* -(i+1)
* If (2) is false, then q = q ; otherwise q = q + 2 .
* i+1 i i+1 i
*
* With some algebraic manipulation, it is not difficult to see
* that (2) is equivalent to
* -(i+1)
* s + 2 <= y (3)
* i i
*
* The advantage of (3) is that s and y can be computed by
* i i
* the following recurrence formula:
* if (3) is false
*
* s = s , y = y ; (4)
* i+1 i i+1 i
*
* otherwise,
* -i -(i+1)
* s = s + 2 , y = y - s - 2 (5)
* i+1 i i+1 i i
*
* One may easily use induction to prove (4) and (5).
* Note. Since the left hand side of (3) contain only i+2 bits,
* it does not necessary to do a full (53-bit) comparison
* in (3).
* 3. Final rounding
* After generating the 53 bits result, we compute one more bit.
* Together with the remainder, we can decide whether the
* result is exact, bigger than 1/2ulp, or less than 1/2ulp
* (it will never equal to 1/2ulp).
* The rounding mode can be detected by checking whether
* huge + tiny is equal to huge, and whether huge - tiny is
* equal to huge for some floating point number "huge" and "tiny".
*
* Special cases:
* sqrt(+-0) = +-0 ... exact
* sqrt(inf) = inf
* sqrt(-ve) = NaN ... with invalid signal
* sqrt(NaN) = NaN ... with invalid signal for signaling NaN
*
* Other methods : see the appended file at the end of the program below.
*---------------
*/
/*********************************************************************/
/* An ultimate aqrt routine. Given an IEEE double machine number x */
/* it computes the correctly rounded (to nearest) value of square */
/* root of x. */
/*********************************************************************/
double __ieee754_sqrt(double x) {
#include "uroot.h"
static const double
rt0 = 9.99999999859990725855365213134618E-01,
rt1 = 4.99999999495955425917856814202739E-01,
rt2 = 3.75017500867345182581453026130850E-01,
rt3 = 3.12523626554518656309172508769531E-01;
static const double big = 134217728.0, big1 = 134217729.0;
double y,t,del,res,res1,hy,z,zz,p,hx,tx,ty,s;
mynumber a,b,c={0,0};
int4 n,k;
#include "math.h"
#include "math_private.h"
#ifdef __STDC__
static const double one = 1.0, tiny=1.0e-300;
#else
static double one = 1.0, tiny=1.0e-300;
#endif
#ifdef __STDC__
double __ieee754_sqrt(double x)
#else
double __ieee754_sqrt(x)
double x;
#endif
{
double z;
int32_t sign = (int)0x80000000;
int32_t ix0,s0,q,m,t,i;
u_int32_t r,t1,s1,ix1,q1;
EXTRACT_WORDS(ix0,ix1,x);
/* take care of Inf and NaN */
if((ix0&0x7ff00000)==0x7ff00000) {
return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if(ix0<=0) {
if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
else if(ix0<0)
return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = (ix0>>20);
if(m==0) { /* subnormal x */
while(ix0==0) {
m -= 21;
ix0 |= (ix1>>11); ix1 <<= 21;
}
for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
m -= i-1;
ix0 |= (ix1>>(32-i));
ix1 <<= i;
}
m -= 1023; /* unbias exponent */
ix0 = (ix0&0x000fffff)|0x00100000;
if(m&1){ /* odd m, double x to make it even */
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
}
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
r = 0x00200000; /* r = moving bit from right to left */
while(r!=0) {
t = s0+r;
if(t<=ix0) {
s0 = t+r;
ix0 -= t;
q += r;
}
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
r>>=1;
}
r = sign;
while(r!=0) {
t1 = s1+r;
t = s0;
if((t<ix0)||((t==ix0)&&(t1<=ix1))) {
s1 = t1+r;
if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1;
ix0 -= t;
if (ix1 < t1) ix0 -= 1;
ix1 -= t1;
q1 += r;
}
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
r>>=1;
}
/* use floating add to find out rounding direction */
if((ix0|ix1)!=0) {
z = one-tiny; /* trigger inexact flag */
if (z>=one) {
z = one+tiny;
if (q1==(u_int32_t)0xffffffff) { q1=0; q += 1;}
else if (z>one) {
if (q1==(u_int32_t)0xfffffffe) q+=1;
q1+=2;
} else
q1 += (q1&1);
}
}
ix0 = (q>>1)+0x3fe00000;
ix1 = q1>>1;
if ((q&1)==1) ix1 |= sign;
ix0 += (m <<20);
INSERT_WORDS(z,ix0,ix1);
return z;
a.x=x;
k=a.i[HIGH_HALF];
a.i[HIGH_HALF]=(k&0x001fffff)|0x3fe00000;
t=inroot[(k&0x001fffff)>>14];
s=a.x;
/*----------------- 2^-1022 <= | x |< 2^1024 -----------------*/
if (k>0x000fffff && k<0x7ff00000) {
y=1.0-t*(t*s);
t=t*(rt0+y*(rt1+y*(rt2+y*rt3)));
c.i[HIGH_HALF]=0x20000000+((k&0x7fe00000)>>1);
y=t*s;
hy=(y+big)-big;
del=0.5*t*((s-hy*hy)-(y-hy)*(y+hy));
res=y+del;
if (res == (res+1.002*((y-res)+del))) return res*c.x;
else {
res1=res+1.5*((y-res)+del);
EMULV(res,res1,z,zz,p,hx,tx,hy,ty); /* (z+zz)=res*res1 */
return ((((z-s)+zz)<0)?max(res,res1):min(res,res1))*c.x;
}
}
else {
if (k>0x7ff00000) /* x -> infinity */
return (big1-big1)/(big-big);
if (k<0x00100000) { /* x -> -infinity */
if (x==0) return x;
if (k<0) return (big1-big1)/(big-big);
else return tm256.x*usqrt(x*t512.x);
}
else return (a.i[LOW_HALF]==0)?x:(big1-big1)/(big-big);
}
}
/*
Other methods (use floating-point arithmetic)
-------------
(This is a copy of a drafted paper by Prof W. Kahan
and K.C. Ng, written in May, 1986)
Two algorithms are given here to implement sqrt(x)
(IEEE double precision arithmetic) in software.
Both supply sqrt(x) correctly rounded. The first algorithm (in
Section A) uses newton iterations and involves four divisions.
The second one uses reciproot iterations to avoid division, but
requires more multiplications. Both algorithms need the ability
to chop results of arithmetic operations instead of round them,
and the INEXACT flag to indicate when an arithmetic operation
is executed exactly with no roundoff error, all part of the
standard (IEEE 754-1985). The ability to perform shift, add,
subtract and logical AND operations upon 32-bit words is needed
too, though not part of the standard.
A. sqrt(x) by Newton Iteration
(1) Initial approximation
Let x0 and x1 be the leading and the trailing 32-bit words of
a floating point number x (in IEEE double format) respectively
1 11 52 ...widths
------------------------------------------------------
x: |s| e | f |
------------------------------------------------------
msb lsb msb lsb ...order
------------------------ ------------------------
x0: |s| e | f1 | x1: | f2 |
------------------------ ------------------------
By performing shifts and subtracts on x0 and x1 (both regarded
as integers), we obtain an 8-bit approximation of sqrt(x) as
follows.
k := (x0>>1) + 0x1ff80000;
y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits
Here k is a 32-bit integer and T1[] is an integer array containing
correction terms. Now magically the floating value of y (y's
leading 32-bit word is y0, the value of its trailing word is 0)
approximates sqrt(x) to almost 8-bit.
Value of T1:
static int T1[32]= {
0, 1024, 3062, 5746, 9193, 13348, 18162, 23592,
29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215,
83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581,
16499, 12183, 8588, 5674, 3403, 1742, 661, 130,};
(2) Iterative refinement
Apply Heron's rule three times to y, we have y approximates
sqrt(x) to within 1 ulp (Unit in the Last Place):
y := (y+x/y)/2 ... almost 17 sig. bits
y := (y+x/y)/2 ... almost 35 sig. bits
y := y-(y-x/y)/2 ... within 1 ulp
Remark 1.
Another way to improve y to within 1 ulp is:
y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x)
y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x)
2
(x-y )*y
y := y + 2* ---------- ...within 1 ulp
2
3y + x
This formula has one division fewer than the one above; however,
it requires more multiplications and additions. Also x must be
scaled in advance to avoid spurious overflow in evaluating the
expression 3y*y+x. Hence it is not recommended uless division
is slow. If division is very slow, then one should use the
reciproot algorithm given in section B.
(3) Final adjustment
By twiddling y's last bit it is possible to force y to be
correctly rounded according to the prevailing rounding mode
as follows. Let r and i be copies of the rounding mode and
inexact flag before entering the square root program. Also we
use the expression y+-ulp for the next representable floating
numbers (up and down) of y. Note that y+-ulp = either fixed
point y+-1, or multiply y by nextafter(1,+-inf) in chopped
mode.
I := FALSE; ... reset INEXACT flag I
R := RZ; ... set rounding mode to round-toward-zero
z := x/y; ... chopped quotient, possibly inexact
If(not I) then { ... if the quotient is exact
if(z=y) {
I := i; ... restore inexact flag
R := r; ... restore rounded mode
return sqrt(x):=y.
} else {
z := z - ulp; ... special rounding
}
}
i := TRUE; ... sqrt(x) is inexact
If (r=RN) then z=z+ulp ... rounded-to-nearest
If (r=RP) then { ... round-toward-+inf
y = y+ulp; z=z+ulp;
}
y := y+z; ... chopped sum
y0:=y0-0x00100000; ... y := y/2 is correctly rounded.
I := i; ... restore inexact flag
R := r; ... restore rounded mode
return sqrt(x):=y.
(4) Special cases
Square root of +inf, +-0, or NaN is itself;
Square root of a negative number is NaN with invalid signal.
B. sqrt(x) by Reciproot Iteration
(1) Initial approximation
Let x0 and x1 be the leading and the trailing 32-bit words of
a floating point number x (in IEEE double format) respectively
(see section A). By performing shifs and subtracts on x0 and y0,
we obtain a 7.8-bit approximation of 1/sqrt(x) as follows.
k := 0x5fe80000 - (x0>>1);
y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits
Here k is a 32-bit integer and T2[] is an integer array
containing correction terms. Now magically the floating
value of y (y's leading 32-bit word is y0, the value of
its trailing word y1 is set to zero) approximates 1/sqrt(x)
to almost 7.8-bit.
Value of T2:
static int T2[64]= {
0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866,
0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,};
(2) Iterative refinement
Apply Reciproot iteration three times to y and multiply the
result by x to get an approximation z that matches sqrt(x)
to about 1 ulp. To be exact, we will have
-1ulp < sqrt(x)-z<1.0625ulp.
... set rounding mode to Round-to-nearest
y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x)
y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x)
... special arrangement for better accuracy
z := x*y ... 29 bits to sqrt(x), with z*y<1
z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x)
Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that
(a) the term z*y in the final iteration is always less than 1;
(b) the error in the final result is biased upward so that
-1 ulp < sqrt(x) - z < 1.0625 ulp
instead of |sqrt(x)-z|<1.03125ulp.
(3) Final adjustment
By twiddling y's last bit it is possible to force y to be
correctly rounded according to the prevailing rounding mode
as follows. Let r and i be copies of the rounding mode and
inexact flag before entering the square root program. Also we
use the expression y+-ulp for the next representable floating
numbers (up and down) of y. Note that y+-ulp = either fixed
point y+-1, or multiply y by nextafter(1,+-inf) in chopped
mode.
R := RZ; ... set rounding mode to round-toward-zero
switch(r) {
case RN: ... round-to-nearest
if(x<= z*(z-ulp)...chopped) z = z - ulp; else
if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp;
break;
case RZ:case RM: ... round-to-zero or round-to--inf
R:=RP; ... reset rounding mod to round-to-+inf
if(x<z*z ... rounded up) z = z - ulp; else
if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp;
break;
case RP: ... round-to-+inf
if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else
if(x>z*z ...chopped) z = z+ulp;
break;
}
Remark 3. The above comparisons can be done in fixed point. For
example, to compare x and w=z*z chopped, it suffices to compare
x1 and w1 (the trailing parts of x and w), regarding them as
two's complement integers.
...Is z an exact square root?
To determine whether z is an exact square root of x, let z1 be the
trailing part of z, and also let x0 and x1 be the leading and
trailing parts of x.
If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0
I := 1; ... Raise Inexact flag: z is not exact
else {
j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2
k := z1 >> 26; ... get z's 25-th and 26-th
fraction bits
I := i or (k&j) or ((k&(j+j+1))!=(x1&3));
}
R:= r ... restore rounded mode
return sqrt(x):=z.
If multiplication is cheaper then the foregoing red tape, the
Inexact flag can be evaluated by
I := i;
I := (z*z!=x) or I.
Note that z*z can overwrite I; this value must be sensed if it is
True.
Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be
zero.
--------------------
z1: | f2 |
--------------------
bit 31 bit 0
Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd
or even of logb(x) have the following relations:
-------------------------------------------------
bit 27,26 of z1 bit 1,0 of x1 logb(x)
-------------------------------------------------
00 00 odd and even
01 01 even
10 10 odd
10 00 even
11 01 even
-------------------------------------------------
(4) Special cases (see (4) of Section A).
*/

View File

@ -0,0 +1,11 @@
#include <endian.h>
#if __FLOAT_WORD_ORDER == __BIG_ENDIAN
#define HIGH_HALF 0
#define LOW_HALF 1
#else
#if __FLOAT_WORD_ORDER == __LITTLE_ENDIAN
#define HIGH_HALF 1
#define LOW_HALF 0
#endif
#endif

View File

@ -0,0 +1,124 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/************************************************************************/
/* */
/* MODULE_NAME:halfulp.c */
/* */
/* FUNCTIONS:halfulp */
/* FILES NEEDED: mydefs.h dla.h endian.h */
/* uroot.c */
/* */
/*Routine halfulp(double x, double y) computes x^y where result does */
/*not need rounding. If the result is closer to 0 than can be */
/*represented it returns 0. */
/* In the following cases the function does not compute anything */
/*and returns a negative number: */
/*1. if the result needs rounding, */
/*2. if y is outside the interval [0, 2^20-1], */
/*3. if x can be represented by x=2**n for some integer n. */
/************************************************************************/
#include "endian.h"
#include "mydefs.h"
#include "dla.h"
double usqrt(double x);
int4 tab54[32] = {
262143, 11585, 1782, 511, 210, 107, 63, 42,
30, 22, 17, 14, 12, 10, 9, 7,
7, 6, 5, 5, 5, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3 };
double halfulp(double x, double y)
{
mynumber v;
double z,u,uu,j1,j2,j3,j4,j5;
int4 k,l,m,n;
if (y <= 0) { /*if power is negative or zero */
v.x = y;
if (v.i[LOW_HALF] != 0) return -10.0;
v.x = x;
if (v.i[LOW_HALF] != 0) return -10.0;
if ((v.i[HIGH_HALF]&0x000fffff) != 0) return -10; /* if x =2 ^ n */
k = ((v.i[HIGH_HALF]&0x7fffffff)>>20)-1023; /* find this n */
z = (double) k;
return (z*y == -1075.0)?0: -10.0;
}
/* if y > 0 */
v.x = y;
if (v.i[LOW_HALF] != 0) return -10.0;
v.x=x;
/* case where x = 2**n for some integer n */
if (((v.i[HIGH_HALF]&0x000fffff)|v.i[LOW_HALF]) == 0) {
k=(v.i[HIGH_HALF]>>20)-1023;
return (((double) k)*y == -1075.0)?0:-10.0;
}
v.x = y;
k = v.i[HIGH_HALF];
m = k<<12;
l = 0;
while (m)
{m = m<<1; l++; }
n = (k&0x000fffff)|0x00100000;
n = n>>(20-l); /* n is the odd integer of y */
k = ((k>>20) -1023)-l; /* y = n*2**k */
if (k>5) return -10.0;
if (k>0) for (;k>0;k--) n *= 2;
if (n > 34) return -10.0;
k = -k;
if (k>5) return -10.0;
/* now treat x */
while (k>0) {
z = usqrt(x);
EMULV(z,z,u,uu,j1,j2,j3,j4,j5);
if (((u-x)+uu) != 0) break;
x = z;
k--;
}
if (k) return -10.0;
/* it is impossible that n == 2, so the mantissa of x must be short */
v.x = x;
if (v.i[LOW_HALF]) return -10.0;
k = v.i[HIGH_HALF];
m = k<<12;
l = 0;
while (m) {m = m<<1; l++; }
m = (k&0x000fffff)|0x00100000;
m = m>>(20-l); /* m is the odd integer of x */
/* now check whether the length of m**n is at most 54 bits */
if (m > tab54[n-3]) return -10.0;
/* yes, it is - now compute x**n by simple multiplications */
u = x;
for (k=1;k<n;k++) u = u*x;
return u;
}

View File

@ -1,107 +1 @@
/* @(#)k_cos.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* 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.
* ====================================================
*/
/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25,
for performance improvement on pipelined processors.
*/
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: k_cos.c,v 1.8 1995/05/10 20:46:22 jtc Exp $";
#endif
/*
* __kernel_cos( x, y )
* kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
* Input x is assumed to be bounded by ~pi/4 in magnitude.
* Input y is the tail of x.
*
* Algorithm
* 1. Since cos(-x) = cos(x), we need only to consider positive x.
* 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
* 3. cos(x) is approximated by a polynomial of degree 14 on
* [0,pi/4]
* 4 14
* cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
* where the remez error is
*
* | 2 4 6 8 10 12 14 | -58
* |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2
* | |
*
* 4 6 8 10 12 14
* 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then
* cos(x) = 1 - x*x/2 + r
* since cos(x+y) ~ cos(x) - sin(x)*y
* ~ cos(x) - x*y,
* a correction term is necessary in cos(x) and hence
* cos(x+y) = 1 - (x*x/2 - (r - x*y))
* For better accuracy when x > 0.3, let qx = |x|/4 with
* the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125.
* Then
* cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)).
* Note that 1-qx and (x*x/2-qx) is EXACT here, and the
* magnitude of the latter is at least a quarter of x*x/2,
* thus, reducing the rounding error in the subtraction.
*/
#include "math.h"
#include "math_private.h"
#ifdef __STDC__
static const double
#else
static double
#endif
C[] = {
1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
-1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
-2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
-1.13596475577881948265e-11}; /* 0xBDA8FAE9, 0xBE8838D4 */
#ifdef __STDC__
double __kernel_cos(double x, double y)
#else
double __kernel_cos(x, y)
double x,y;
#endif
{
double a,hz,z,r,qx,r1,r2,r3,z1,z2,z3;
int32_t ix;
z = x*x;
GET_HIGH_WORD(ix,x);
ix &= 0x7fffffff; /* ix = |x|'s high word*/
if(ix<0x3e400000) { /* if x < 2**27 */
if(((int)x)==0) return C[0]; /* generate inexact */
}
#ifdef DO_NOT_USE_THIS
r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
#else
r1=z*C[6];r1=r1+C[5];z1=z*z;
r2=z*C[4];r2=r2+C[3];z2=z1*z;
r3=z*C[2];r3=r3+C[1];z3=z2*z1;
r=z3*r1+z2*r2+z*r3;
#endif
if(ix < 0x3FD33333) /* if |x| < 0.3 */
return C[0] - (0.5*z - (z*r - x*y));
else {
if(ix > 0x3fe90000) { /* x > 0.78125 */
qx = 0.28125;
} else {
INSERT_WORDS(qx,ix-0x00200000,0); /* x/4 */
}
hz = 0.5*z-qx;
a = C[0]-qx;
return a - (hz - (z*r-x*y));
}
}
/* Not needed anymore. */

View File

@ -1,91 +1 @@
/* @(#)k_sin.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* 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.
* ====================================================
*/
/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25,
for performance improvement on pipelined processors.
*/
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: k_sin.c,v 1.8 1995/05/10 20:46:31 jtc Exp $";
#endif
/* __kernel_sin( x, y, iy)
* kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854
* Input x is assumed to be bounded by ~pi/4 in magnitude.
* Input y is the tail of x.
* Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
*
* Algorithm
* 1. Since sin(-x) = -sin(x), we need only to consider positive x.
* 2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0.
* 3. sin(x) is approximated by a polynomial of degree 13 on
* [0,pi/4]
* 3 13
* sin(x) ~ x + S1*x + ... + S6*x
* where
*
* |sin(x) 2 4 6 8 10 12 | -58
* |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2
* | x |
*
* 4. sin(x+y) = sin(x) + sin'(x')*y
* ~ sin(x) + (1-x*x/2)*y
* For better accuracy, let
* 3 2 2 2 2
* r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
* then 3 2
* sin(x) = x + (S1*x + (x *(r-y/2)+y))
*/
#include "math.h"
#include "math_private.h"
#ifdef __STDC__
static const double
#else
static double
#endif
S[] = {
5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
-1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
-1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
-2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
1.58969099521155010221e-10}; /* 0x3DE5D93A, 0x5ACFD57C */
#ifdef __STDC__
double __kernel_sin(double x, double y, int iy)
#else
double __kernel_sin(x, y, iy)
double x,y; int iy; /* iy=0 if y is zero */
#endif
{
double z,r,v,z1,r1,r2;
int32_t ix;
GET_HIGH_WORD(ix,x);
ix &= 0x7fffffff; /* high word of x */
if(ix<0x3e400000) /* |x| < 2**-27 */
{if((int)x==0) return x;} /* generate inexact */
z = x*x;
v = z*x;
#ifdef DO_NOT_USE_THIS
r = S2+z*(S3+z*(S4+z*(S5+z*S6)));
if(iy==0) return x+v*(S1+z*r);
else return x-((z*(half*y-v*r)-y)-v*S1);
#else
r1 = S[5]+z*S[6]; z1 = z*z*z;
r2 = S[3]+z*S[4];
r = S[2] + z*r2 + z1*r1;
if(iy==0) return x+v*(S[1]+z*r);
else return x-((z*(S[0]*y-v*r)-y)-v*S[1]);
#endif
}
/* Not needed anymore. */

View File

@ -0,0 +1,497 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/************************************************************************/
/* MODULE_NAME: mpa.c */
/* */
/* FUNCTIONS: */
/* mcr */
/* acr */
/* cr */
/* cpy */
/* cpymn */
/* norm */
/* denorm */
/* mp_dbl */
/* dbl_mp */
/* add_magnitudes */
/* sub_magnitudes */
/* add */
/* sub */
/* mul */
/* inv */
/* dvd */
/* */
/* Arithmetic functions for multiple precision numbers. */
/* Relative errors are bounded */
/************************************************************************/
#include "endian.h"
#include "mpa.h"
#include "mpa2.h"
/* mcr() compares the sizes of the mantissas of two multiple precision */
/* numbers. Mantissas are compared regardless of the signs of the */
/* numbers, even if x->d[0] or y->d[0] are zero. Exponents are also */
/* disregarded. */
static int mcr(const mp_no *x, const mp_no *y, int p) {
int i;
for (i=1; i<=p; i++) {
if (X[i] == Y[i]) continue;
else if (X[i] > Y[i]) return 1;
else return -1; }
return 0;
}
/* acr() compares the absolute values of two multiple precision numbers */
int acr(const mp_no *x, const mp_no *y, int p) {
int i;
if (X[0] == ZERO) {
if (Y[0] == ZERO) i= 0;
else i=-1;
}
else if (Y[0] == ZERO) i= 1;
else {
if (EX > EY) i= 1;
else if (EX < EY) i=-1;
else i= mcr(x,y,p);
}
return i;
}
/* cr90 compares the values of two multiple precision numbers */
int cr(const mp_no *x, const mp_no *y, int p) {
int i;
if (X[0] > Y[0]) i= 1;
else if (X[0] < Y[0]) i=-1;
else if (X[0] < ZERO ) i= acr(y,x,p);
else i= acr(x,y,p);
return i;
}
/* Copy a multiple precision number. Set *y=*x. x=y is permissible. */
void cpy(const mp_no *x, mp_no *y, int p) {
int i;
EY = EX;
for (i=0; i <= p; i++) Y[i] = X[i];
return;
}
/* Copy a multiple precision number x of precision m into a */
/* multiple precision number y of precision n. In case n>m, */
/* the digits of y beyond the m'th are set to zero. In case */
/* n<m, the digits of x beyond the n'th are ignored. */
/* x=y is permissible. */
void cpymn(const mp_no *x, int m, mp_no *y, int n) {
int i,k;
EY = EX; k=MIN(m,n);
for (i=0; i <= k; i++) Y[i] = X[i];
for ( ; i <= n; i++) Y[i] = ZERO;
return;
}
/* Convert a multiple precision number *x into a double precision */
/* number *y, normalized case (|x| >= 2**(-1022))) */
static void norm(const mp_no *x, double *y, int p)
{
#define R radixi.d
int i,k;
double a,c,u,v,z[5];
if (p<5) {
if (p==1) c = X[1];
else if (p==2) c = X[1] + R* X[2];
else if (p==3) c = X[1] + R*(X[2] + R* X[3]);
else if (p==4) c =(X[1] + R* X[2]) + R*R*(X[3] + R*X[4]);
}
else {
for (a=ONE, z[1]=X[1]; z[1] < TWO23; )
{a *= TWO; z[1] *= TWO; }
for (i=2; i<5; i++) {
z[i] = X[i]*a;
u = (z[i] + CUTTER)-CUTTER;
if (u > z[i]) u -= RADIX;
z[i] -= u;
z[i-1] += u*RADIXI;
}
u = (z[3] + TWO71) - TWO71;
if (u > z[3]) u -= TWO19;
v = z[3]-u;
if (v == TWO18) {
if (z[4] == ZERO) {
for (i=5; i <= p; i++) {
if (X[i] == ZERO) continue;
else {z[3] += ONE; break; }
}
}
else z[3] += ONE;
}
c = (z[1] + R *(z[2] + R * z[3]))/a;
}
c *= X[0];
for (i=1; i<EX; i++) c *= RADIX;
for (i=1; i>EX; i--) c *= RADIXI;
*y = c;
return;
#undef R
}
/* Convert a multiple precision number *x into a double precision */
/* number *y, denormalized case (|x| < 2**(-1022))) */
static void denorm(const mp_no *x, double *y, int p)
{
int i,k;
double a,c,u,v,z[5];
#define R radixi.d
if (EX<-44 || (EX==-44 && X[1]<TWO5))
{ *y=ZERO; return; }
if (p==1) {
if (EX==-42) {z[1]=X[1]+TWO10; z[2]=ZERO; z[3]=ZERO; k=3;}
else if (EX==-43) {z[1]= TWO10; z[2]=X[1]; z[3]=ZERO; k=2;}
else {z[1]= TWO10; z[2]=ZERO; z[3]=X[1]; k=1;}
}
else if (p==2) {
if (EX==-42) {z[1]=X[1]+TWO10; z[2]=X[2]; z[3]=ZERO; k=3;}
else if (EX==-43) {z[1]= TWO10; z[2]=X[1]; z[3]=X[2]; k=2;}
else {z[1]= TWO10; z[2]=ZERO; z[3]=X[1]; k=1;}
}
else {
if (EX==-42) {z[1]=X[1]+TWO10; z[2]=X[2]; k=3;}
else if (EX==-43) {z[1]= TWO10; z[2]=X[1]; k=2;}
else {z[1]= TWO10; z[2]=ZERO; k=1;}
z[3] = X[k];
}
u = (z[3] + TWO57) - TWO57;
if (u > z[3]) u -= TWO5;
if (u==z[3]) {
for (i=k+1; i <= p; i++) {
if (X[i] == ZERO) continue;
else {z[3] += ONE; break; }
}
}
c = X[0]*((z[1] + R*(z[2] + R*z[3])) - TWO10);
*y = c*TWOM1032;
return;
#undef R
}
/* Convert a multiple precision number *x into a double precision number *y. */
/* The result is correctly rounded to the nearest/even. *x is left unchanged */
void mp_dbl(const mp_no *x, double *y, int p) {
int i,k;
double a,c,u,v,z[5];
if (X[0] == ZERO) {*y = ZERO; return; }
if (EX> -42) norm(x,y,p);
else if (EX==-42 && X[1]>=TWO10) norm(x,y,p);
else denorm(x,y,p);
}
/* dbl_mp() converts a double precision number x into a multiple precision */
/* number *y. If the precision p is too small the result is truncated. x is */
/* left unchanged. */
void dbl_mp(double x, mp_no *y, int p) {
int i,n;
double u;
/* Sign */
if (x == ZERO) {Y[0] = ZERO; return; }
else if (x > ZERO) Y[0] = ONE;
else {Y[0] = MONE; x=-x; }
/* Exponent */
for (EY=ONE; x >= RADIX; EY += ONE) x *= RADIXI;
for ( ; x < ONE; EY -= ONE) x *= RADIX;
/* Digits */
n=MIN(p,4);
for (i=1; i<=n; i++) {
u = (x + TWO52) - TWO52;
if (u>x) u -= ONE;
Y[i] = u; x -= u; x *= RADIX; }
for ( ; i<=p; i++) Y[i] = ZERO;
return;
}
/* add_magnitudes() adds the magnitudes of *x & *y assuming that */
/* abs(*x) >= abs(*y) > 0. */
/* The sign of the sum *z is undefined. x&y may overlap but not x&z or y&z. */
/* No guard digit is used. The result equals the exact sum, truncated. */
/* *x & *y are left unchanged. */
static void add_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) {
int i,j,k;
EZ = EX;
i=p; j=p+ EY - EX; k=p+1;
if (j<1)
{cpy(x,z,p); return; }
else Z[k] = ZERO;
for (; j>0; i--,j--) {
Z[k] += X[i] + Y[j];
if (Z[k] >= RADIX) {
Z[k] -= RADIX;
Z[--k] = ONE; }
else
Z[--k] = ZERO;
}
for (; i>0; i--) {
Z[k] += X[i];
if (Z[k] >= RADIX) {
Z[k] -= RADIX;
Z[--k] = ONE; }
else
Z[--k] = ZERO;
}
if (Z[1] == ZERO) {
for (i=1; i<=p; i++) Z[i] = Z[i+1]; }
else EZ += ONE;
}
/* sub_magnitudes() subtracts the magnitudes of *x & *y assuming that */
/* abs(*x) > abs(*y) > 0. */
/* The sign of the difference *z is undefined. x&y may overlap but not x&z */
/* or y&z. One guard digit is used. The error is less than one ulp. */
/* *x & *y are left unchanged. */
static void sub_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) {
int i,j,k;
EZ = EX;
if (EX == EY) {
i=j=k=p;
Z[k] = Z[k+1] = ZERO; }
else {
j= EX - EY;
if (j > p) {cpy(x,z,p); return; }
else {
i=p; j=p+1-j; k=p;
if (Y[j] > ZERO) {
Z[k+1] = RADIX - Y[j--];
Z[k] = MONE; }
else {
Z[k+1] = ZERO;
Z[k] = ZERO; j--;}
}
}
for (; j>0; i--,j--) {
Z[k] += (X[i] - Y[j]);
if (Z[k] < ZERO) {
Z[k] += RADIX;
Z[--k] = MONE; }
else
Z[--k] = ZERO;
}
for (; i>0; i--) {
Z[k] += X[i];
if (Z[k] < ZERO) {
Z[k] += RADIX;
Z[--k] = MONE; }
else
Z[--k] = ZERO;
}
for (i=1; Z[i] == ZERO; i++) ;
EZ = EZ - i + 1;
for (k=1; i <= p+1; )
Z[k++] = Z[i++];
for (; k <= p; )
Z[k++] = ZERO;
return;
}
/* Add two multiple precision numbers. Set *z = *x + *y. x&y may overlap */
/* but not x&z or y&z. One guard digit is used. The error is less than */
/* one ulp. *x & *y are left unchanged. */
void add(const mp_no *x, const mp_no *y, mp_no *z, int p) {
int n;
if (X[0] == ZERO) {cpy(y,z,p); return; }
else if (Y[0] == ZERO) {cpy(x,z,p); return; }
if (X[0] == Y[0]) {
if (acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; }
else {add_magnitudes(y,x,z,p); Z[0] = Y[0]; }
}
else {
if ((n=acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; }
else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = Y[0]; }
else Z[0] = ZERO;
}
return;
}
/* Subtract two multiple precision numbers. *z is set to *x - *y. x&y may */
/* overlap but not x&z or y&z. One guard digit is used. The error is */
/* less than one ulp. *x & *y are left unchanged. */
void sub(const mp_no *x, const mp_no *y, mp_no *z, int p) {
int n;
if (X[0] == ZERO) {cpy(y,z,p); Z[0] = -Z[0]; return; }
else if (Y[0] == ZERO) {cpy(x,z,p); return; }
if (X[0] != Y[0]) {
if (acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; }
else {add_magnitudes(y,x,z,p); Z[0] = -Y[0]; }
}
else {
if ((n=acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; }
else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = -Y[0]; }
else Z[0] = ZERO;
}
return;
}
/* Multiply two multiple precision numbers. *z is set to *x * *y. x&y */
/* may overlap but not x&z or y&z. In case p=1,2,3 the exact result is */
/* truncated to p digits. In case p>3 the error is bounded by 1.001 ulp. */
/* *x & *y are left unchanged. */
void mul(const mp_no *x, const mp_no *y, mp_no *z, int p) {
int i, i1, i2, j, k, k2;
double u;
/* Is z=0? */
if (X[0]*Y[0]==ZERO)
{ Z[0]=ZERO; return; }
/* Multiply, add and carry */
k2 = (p<3) ? p+p : p+3;
Z[k2]=ZERO;
for (k=k2; k>1; ) {
if (k > p) {i1=k-p; i2=p+1; }
else {i1=1; i2=k; }
for (i=i1,j=i2-1; i<i2; i++,j--) Z[k] += X[i]*Y[j];
u = (Z[k] + CUTTER)-CUTTER;
if (u > Z[k]) u -= RADIX;
Z[k] -= u;
Z[--k] = u*RADIXI;
}
/* Is there a carry beyond the most significant digit? */
if (Z[1] == ZERO) {
for (i=1; i<=p; i++) Z[i]=Z[i+1];
EZ = EX + EY - 1; }
else
EZ = EX + EY;
Z[0] = X[0] * Y[0];
return;
}
/* Invert a multiple precision number. Set *y = 1 / *x. */
/* Relative error bound = 1.001*r**(1-p) for p=2, 1.063*r**(1-p) for p=3, */
/* 2.001*r**(1-p) for p>3. */
/* *x=0 is not permissible. *x is left unchanged. */
void inv(const mp_no *x, mp_no *y, int p) {
int i,l;
double t;
mp_no z,w;
static const int np1[] = {0,0,0,0,1,2,2,2,2,3,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4};
const mp_no mptwo = {1,1.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,};
cpy(x,&z,p); z.e=0; mp_dbl(&z,&t,p);
t=ONE/t; dbl_mp(t,y,p); EY -= EX;
for (i=0; i<np1[p]; i++) {
cpy(y,&w,p);
mul(x,&w,y,p);
sub(&mptwo,y,&z,p);
mul(&w,&z,y,p);
}
return;
}
/* Divide one multiple precision number by another.Set *z = *x / *y. *x & *y */
/* are left unchanged. x&y may overlap but not x&z or y&z. */
/* Relative error bound = 2.001*r**(1-p) for p=2, 2.063*r**(1-p) for p=3 */
/* and 3.001*r**(1-p) for p>3. *y=0 is not permissible. */
void dvd(const mp_no *x, const mp_no *y, mp_no *z, int p) {
mp_no w;
if (X[0] == ZERO) Z[0] = ZERO;
else {inv(y,&w,p); mul(x,&w,z,p);}
return;
}

View File

@ -0,0 +1,79 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/************************************************************************/
/* MODULE_NAME: mpa.h */
/* */
/* FUNCTIONS: */
/* mcr */
/* acr */
/* cr */
/* cpy */
/* cpymn */
/* mp_dbl */
/* dbl_mp */
/* add */
/* sub */
/* mul */
/* inv */
/* dvd */
/* */
/* Arithmetic functions for multiple precision numbers. */
/* Common types and definition */
/************************************************************************/
typedef struct {/* This structure holds the details of a multi-precision */
int e; /* floating point number, x: d[0] holds its sign (-1,0 or 1) */
double d[40]; /* e holds its exponent (...,-2,-1,0,1,2,...) and */
} mp_no; /* d[1]...d[p] hold its mantissa digits. The value of x is, */
/* x = d[1]*r**(e-1) + d[2]*r**(e-2) + ... + d[p]*r**(e-p). */
/* Here r = 2**24, 0 <= d[i] < r and 1 <= p <= 32. */
/* p is a global variable. A multi-precision number is */
/* always normalized. Namely, d[1] > 0. An exception is */
/* a zero which is characterized by d[0] = 0. The terms */
/* d[p+1], d[p+2], ... of a none zero number have no */
/* significance and so are the terms e, d[1],d[2],... */
/* of a zero. */
typedef union { int i[2]; double d; } number;
#define X x->d
#define Y y->d
#define Z z->d
#define EX x->e
#define EY y->e
#define EZ z->e
#define MAX(x,y) ((x) < (y) ? (y) : (x))
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#define ABS(x) ((x) < 0 ? -(x) : (x))
int acr(const mp_no *, const mp_no *, int);
int cr(const mp_no *, const mp_no *, int);
void cpy(const mp_no *, mp_no *, int);
void cpymn(const mp_no *, int, mp_no *, int);
void mp_dbl(const mp_no *, double *, int);
void dbl_mp(double, mp_no *, int);
void add(const mp_no *, const mp_no *, mp_no *, int);
void sub(const mp_no *, const mp_no *, mp_no *, int);
void mul(const mp_no *, const mp_no *, mp_no *, int);
void inv(const mp_no *, mp_no *, int);
void dvd(const mp_no *, const mp_no *, mp_no *, int);

View File

@ -0,0 +1,93 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/**************************************************************************/
/* */
/* MODULE_NAME:mpa2.h */
/* */
/* */
/* variables prototype and definition according to type of processor */
/* types definition */
/**************************************************************************/
#ifndef MPA2_H
#define MPA2_H
#ifdef BIG_ENDI
static const number
/**/ radix = {0x41700000, 0x00000000, }, /* 2**24 */
/**/ radixi = {0x3e700000, 0x00000000, }, /* 2**-24 */
/**/ cutter = {0x44b00000, 0x00000000, }, /* 2**76 */
/**/ zero = {0x00000000, 0x00000000, }, /* 0 */
/**/ one = {0x3ff00000, 0x00000000, }, /* 1 */
/**/ mone = {0xbff00000, 0x00000000, }, /* -1 */
/**/ two = {0x40000000, 0x00000000, }, /* 2 */
/**/ two5 = {0x40400000, 0x00000000, }, /* 2**5 */
/**/ two10 = {0x40900000, 0x00000000, }, /* 2**10 */
/**/ two18 = {0x41100000, 0x00000000, }, /* 2**18 */
/**/ two19 = {0x41200000, 0x00000000, }, /* 2**19 */
/**/ two23 = {0x41600000, 0x00000000, }, /* 2**23 */
/**/ two52 = {0x43300000, 0x00000000, }, /* 2**52 */
/**/ two57 = {0x43800000, 0x00000000, }, /* 2**57 */
/**/ two71 = {0x44600000, 0x00000000, }, /* 2**71 */
/**/ twom1032 = {0x00000400, 0x00000000, }; /* 2**-1032 */
#else
#ifdef LITTLE_ENDI
static const number
/**/ radix = {0x00000000, 0x41700000, }, /* 2**24 */
/**/ radixi = {0x00000000, 0x3e700000, }, /* 2**-24 */
/**/ cutter = {0x00000000, 0x44b00000, }, /* 2**76 */
/**/ zero = {0x00000000, 0x00000000, }, /* 0 */
/**/ one = {0x00000000, 0x3ff00000, }, /* 1 */
/**/ mone = {0x00000000, 0xbff00000, }, /* -1 */
/**/ two = {0x00000000, 0x40000000, }, /* 2 */
/**/ two5 = {0x00000000, 0x40400000, }, /* 2**5 */
/**/ two10 = {0x00000000, 0x40900000, }, /* 2**10 */
/**/ two18 = {0x00000000, 0x41100000, }, /* 2**18 */
/**/ two19 = {0x00000000, 0x41200000, }, /* 2**19 */
/**/ two23 = {0x00000000, 0x41600000, }, /* 2**23 */
/**/ two52 = {0x00000000, 0x43300000, }, /* 2**52 */
/**/ two57 = {0x00000000, 0x43800000, }, /* 2**57 */
/**/ two71 = {0x00000000, 0x44600000, }, /* 2**71 */
/**/ twom1032 = {0x00000000, 0x00000400, }; /* 2**-1032 */
#endif
#endif
#define RADIX radix.d
#define RADIXI radixi.d
#define CUTTER cutter.d
#define ZERO zero.d
#define ONE one.d
#define MONE mone.d
#define TWO two.d
#define TWO5 two5.d
#define TWO10 two10.d
#define TWO18 two18.d
#define TWO19 two19.d
#define TWO23 two23.d
#define TWO52 two52.d
#define TWO57 two57.d
#define TWO71 two71.d
#define TWOM1032 twom1032.d
#endif

View File

@ -0,0 +1,101 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* */
/* MODULE_NAME:mpatan.c */
/* */
/* FUNCTIONS:mpatan */
/* */
/* FILES NEEDED: mpa.h endian.h mpatan.h */
/* mpa.c */
/* */
/* Multi-Precision Atan function subroutine, for precision p >= 4.*/
/* The relative error of the result is bounded by 34.32*r**(1-p), */
/* where r=2**24. */
/******************************************************************/
#include "endian.h"
#include "mpa.h"
void mpsqrt(mp_no *, mp_no *, int);
void mpatan(mp_no *x, mp_no *y, int p) {
#include "mpatan.h"
int i,m,n;
double dx;
mp_no
mpone = {0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,},
mptwo = {0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,},
mptwoim1 = {0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,};
mp_no mps,mpsm,mpt,mpt1,mpt2,mpt3;
/* Choose m and initiate mpone, mptwo & mptwoim1 */
if (EX>0) m=7;
else if (EX<0) m=0;
else {
mp_dbl(x,&dx,p); dx=ABS(dx);
for (m=6; m>0; m--)
{if (dx>xm[m].d) break;}
}
mpone.e = mptwo.e = mptwoim1.e = 1;
mpone.d[0] = mpone.d[1] = mptwo.d[0] = mptwoim1.d[0] = ONE;
mptwo.d[1] = TWO;
/* Reduce x m times */
mul(x,x,&mpsm,p);
if (m==0) cpy(x,&mps,p);
else {
for (i=0; i<m; i++) {
add(&mpone,&mpsm,&mpt1,p);
mpsqrt(&mpt1,&mpt2,p);
add(&mpt2,&mpt2,&mpt1,p);
add(&mptwo,&mpsm,&mpt2,p);
add(&mpt1,&mpt2,&mpt3,p);
dvd(&mpsm,&mpt3,&mpt1,p);
cpy(&mpt1,&mpsm,p);
}
mpsqrt(&mpsm,&mps,p); mps.d[0] = X[0];
}
/* Evaluate a truncated power series for Atan(s) */
n=np[p]; mptwoim1.d[1] = twonm1[p].d;
dvd(&mpsm,&mptwoim1,&mpt,p);
for (i=n-1; i>1; i--) {
mptwoim1.d[1] -= TWO;
dvd(&mpsm,&mptwoim1,&mpt1,p);
mul(&mpsm,&mpt,&mpt2,p);
sub(&mpt1,&mpt2,&mpt,p);
}
mul(&mps,&mpt,&mpt1,p);
sub(&mps,&mpt1,&mpt,p);
/* Compute Atan(x) */
mptwoim1.d[1] = twom[m].d;
mul(&mptwoim1,&mpt,y,p);
return;
}

View File

@ -0,0 +1,172 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* */
/* MODULE_NAME:mpatan.h */
/* */
/* common data and variables prototype and definition */
/******************************************************************/
#ifndef MPATAN_H
#define MPATAN_H
#ifdef BIG_ENDI
static const number
xm[8] = { /* x[m] */
/**/ {0x00000000, 0x00000000, }, /* 0.0 */
/**/ {0x3f8930be, 0x00000000, }, /* 0.0123 */
/**/ {0x3f991687, 0x00000000, }, /* 0.0245 */
/**/ {0x3fa923a2, 0x00000000, }, /* 0.0491 */
/**/ {0x3fb930be, 0x00000000, }, /* 0.0984 */
/**/ {0x3fc95810, 0x00000000, }, /* 0.198 */
/**/ {0x3fda7ef9, 0x00000000, }, /* 0.414 */
/**/ {0x3ff00000, 0x00000000, }, /* 1.0 */
};
static const number
twonm1[33] = { /* 2n-1 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x40260000, 0x00000000, }, /* 11 */
/**/ {0x402e0000, 0x00000000, }, /* 15 */
/**/ {0x40330000, 0x00000000, }, /* 19 */
/**/ {0x40350000, 0x00000000, }, /* 21 */
/**/ {0x40390000, 0x00000000, }, /* 25 */
/**/ {0x403d0000, 0x00000000, }, /* 29 */
/**/ {0x40408000, 0x00000000, }, /* 33 */
/**/ {0x40428000, 0x00000000, }, /* 37 */
/**/ {0x40448000, 0x00000000, }, /* 41 */
/**/ {0x40468000, 0x00000000, }, /* 45 */
/**/ {0x40488000, 0x00000000, }, /* 49 */
/**/ {0x404a8000, 0x00000000, }, /* 53 */
/**/ {0x404b8000, 0x00000000, }, /* 55 */
/**/ {0x404d8000, 0x00000000, }, /* 59 */
/**/ {0x404f8000, 0x00000000, }, /* 63 */
/**/ {0x4050c000, 0x00000000, }, /* 67 */
/**/ {0x4051c000, 0x00000000, }, /* 71 */
/**/ {0x4052c000, 0x00000000, }, /* 75 */
/**/ {0x4053c000, 0x00000000, }, /* 79 */
/**/ {0x4054c000, 0x00000000, }, /* 83 */
/**/ {0x40554000, 0x00000000, }, /* 85 */
/**/ {0x40564000, 0x00000000, }, /* 89 */
/**/ {0x40574000, 0x00000000, }, /* 93 */
/**/ {0x40584000, 0x00000000, }, /* 97 */
/**/ {0x40594000, 0x00000000, }, /* 101 */
/**/ {0x405a4000, 0x00000000, }, /* 105 */
/**/ {0x405b4000, 0x00000000, }, /* 109 */
/**/ {0x405c4000, 0x00000000, }, /* 113 */
/**/ {0x405d4000, 0x00000000, }, /* 117 */
};
static const number
twom[8] = { /* 2**m */
/**/ {0x3ff00000, 0x00000000, }, /* 1.0 */
/**/ {0x40000000, 0x00000000, }, /* 2.0 */
/**/ {0x40100000, 0x00000000, }, /* 4.0 */
/**/ {0x40200000, 0x00000000, }, /* 8.0 */
/**/ {0x40300000, 0x00000000, }, /* 16.0 */
/**/ {0x40400000, 0x00000000, }, /* 32.0 */
/**/ {0x40500000, 0x00000000, }, /* 64.0 */
/**/ {0x40600000, 0x00000000, }, /* 128.0 */
};
static const number
/**/ one = {0x3ff00000, 0x00000000, }, /* 1 */
/**/ two = {0x40000000, 0x00000000, }; /* 2 */
#else
#ifdef LITTLE_ENDI
static const number
xm[8] = { /* x[m] */
/**/ {0x00000000, 0x00000000, }, /* 0.0 */
/**/ {0x00000000, 0x3f8930be, }, /* 0.0123 */
/**/ {0x00000000, 0x3f991687, }, /* 0.0245 */
/**/ {0x00000000, 0x3fa923a2, }, /* 0.0491 */
/**/ {0x00000000, 0x3fb930be, }, /* 0.0984 */
/**/ {0x00000000, 0x3fc95810, }, /* 0.198 */
/**/ {0x00000000, 0x3fda7ef9, }, /* 0.414 */
/**/ {0x00000000, 0x3ff00000, }, /* 1.0 */
};
static const number
twonm1[33] = { /* 2n-1 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x40260000, }, /* 11 */
/**/ {0x00000000, 0x402e0000, }, /* 15 */
/**/ {0x00000000, 0x40330000, }, /* 19 */
/**/ {0x00000000, 0x40350000, }, /* 21 */
/**/ {0x00000000, 0x40390000, }, /* 25 */
/**/ {0x00000000, 0x403d0000, }, /* 29 */
/**/ {0x00000000, 0x40408000, }, /* 33 */
/**/ {0x00000000, 0x40428000, }, /* 37 */
/**/ {0x00000000, 0x40448000, }, /* 41 */
/**/ {0x00000000, 0x40468000, }, /* 45 */
/**/ {0x00000000, 0x40488000, }, /* 49 */
/**/ {0x00000000, 0x404a8000, }, /* 53 */
/**/ {0x00000000, 0x404b8000, }, /* 55 */
/**/ {0x00000000, 0x404d8000, }, /* 59 */
/**/ {0x00000000, 0x404f8000, }, /* 63 */
/**/ {0x00000000, 0x4050c000, }, /* 67 */
/**/ {0x00000000, 0x4051c000, }, /* 71 */
/**/ {0x00000000, 0x4052c000, }, /* 75 */
/**/ {0x00000000, 0x4053c000, }, /* 79 */
/**/ {0x00000000, 0x4054c000, }, /* 83 */
/**/ {0x00000000, 0x40554000, }, /* 85 */
/**/ {0x00000000, 0x40564000, }, /* 89 */
/**/ {0x00000000, 0x40574000, }, /* 93 */
/**/ {0x00000000, 0x40584000, }, /* 97 */
/**/ {0x00000000, 0x40594000, }, /* 101 */
/**/ {0x00000000, 0x405a4000, }, /* 105 */
/**/ {0x00000000, 0x405b4000, }, /* 109 */
/**/ {0x00000000, 0x405c4000, }, /* 113 */
/**/ {0x00000000, 0x405d4000, }, /* 117 */
};
static const number
twom[8] = { /* 2**m */
/**/ {0x00000000, 0x3ff00000, }, /* 1.0 */
/**/ {0x00000000, 0x40000000, }, /* 2.0 */
/**/ {0x00000000, 0x40100000, }, /* 4.0 */
/**/ {0x00000000, 0x40200000, }, /* 8.0 */
/**/ {0x00000000, 0x40300000, }, /* 16.0 */
/**/ {0x00000000, 0x40400000, }, /* 32.0 */
/**/ {0x00000000, 0x40500000, }, /* 64.0 */
/**/ {0x00000000, 0x40600000, }, /* 128.0 */
};
static const number
/**/ one = {0x00000000, 0x3ff00000, }, /* 1 */
/**/ two = {0x00000000, 0x40000000, }; /* 2 */
#endif
#endif
#define ONE one.d
#define TWO two.d
static const int
np[33] = { 0, 0, 0, 0, 6, 8,10,11,13,15,17,19,21,23,25,27,28,
30,32,34,36,38,40,42,43,45,47,49,51,53,55,57,59};
#endif

View File

@ -0,0 +1,69 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* MODULE_NAME: mpatan2.c */
/* */
/* FUNCTIONS:mpatan2 */
/* */
/* FILES NEEDED: mpa.h */
/* mpa.c mpatan.c mpsqrt.c */
/* */
/* Multi-Precision Atan2(y,x) function subroutine, */
/* for precision p >= 4. */
/* y=0 is not permitted if x<=0. No error messages are given. */
/* The relative error of the result is bounded by 44.84*r**(1-p) */
/* if x <= 0, y != 0 and by 37.33*r**(1-p) if x>0. here r=2**24. */
/* */
/******************************************************************/
#include "mpa.h"
void mpsqrt(mp_no *, mp_no *, int);
void mpatan(mp_no *, mp_no *, int);
/* Multi-Precision Atan2(y,x) function subroutine, for p >= 4. */
/* y=0 is not permitted if x<=0. No error messages are given. */
void mpatan2(mp_no *y, mp_no *x, mp_no *z, int p) {
static const double ZERO = 0.0, ONE = 1.0;
mp_no mpone = {0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,};
mp_no mpt1,mpt2,mpt3;
if (X[0] <= ZERO) {
mpone.e = 1; mpone.d[0] = mpone.d[1] = ONE;
dvd(x,y,&mpt1,p); mul(&mpt1,&mpt1,&mpt2,p);
if (mpt1.d[0] != ZERO) mpt1.d[0] = ONE;
add(&mpt2,&mpone,&mpt3,p); mpsqrt(&mpt3,&mpt2,p);
add(&mpt1,&mpt2,&mpt3,p); mpt3.d[0]=Y[0];
mpatan(&mpt3,&mpt1,p); add(&mpt1,&mpt1,z,p);
}
else
{ dvd(y,x,&mpt1,p);
mpatan(&mpt1,z,p);
}
return;
}

View File

@ -0,0 +1,105 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*************************************************************************/
/* MODULE_NAME:mpexp.c */
/* */
/* FUNCTIONS: mpexp */
/* */
/* FILES NEEDED: mpa.h endian.h mpexp.h */
/* mpa.c */
/* */
/* Multi-Precision exponential function subroutine */
/* ( for p >= 4, 2**(-55) <= abs(x) <= 1024 ). */
/*************************************************************************/
#include "endian.h"
#include "mpa.h"
#include "mpexp.h"
/* Multi-Precision exponential function subroutine (for p >= 4, */
/* 2**(-55) <= abs(x) <= 1024). */
void mpexp(mp_no *x, mp_no *y, int p) {
int i,j,k,m,m1,m2,n;
double a,b;
static const int np[33] = {0,0,0,0,3,3,4,4,5,4,4,5,5,5,6,6,6,6,6,6,
6,6,6,6,7,7,7,7,8,8,8,8,8};
static const int m1p[33]= {0,0,0,0,17,23,23,28,27,38,42,39,43,47,43,47,50,54,
57,60,64,67,71,74,68,71,74,77,70,73,76,78,81};
static const int m1np[7][18] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0,36,48,60,72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0,24,32,40,48,56,64,72, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0,17,23,29,35,41,47,53,59,65, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0,23,28,33,38,42,47,52,57,62,66, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0,27, 0, 0,39,43,47,51,55,59,63},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,43,47,50,54}};
mp_no mpone = {0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,};
mp_no mpk = {0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,};
mp_no mps,mpak,mpt1,mpt2;
/* Choose m,n and compute a=2**(-m) */
n = np[p]; m1 = m1p[p]; a = twomm1[p].d;
for (i=0; i<EX; i++) a *= RADIXI;
for ( ; i>EX; i--) a *= RADIX;
b = X[1]*RADIXI; m2 = 24*EX;
for (; b<HALF; m2--) { a *= TWO; b *= TWO; }
if (b == HALF) {
for (i=2; i<=p; i++) { if (X[i]!=ZERO) break; }
if (i==p+1) { m2--; a *= TWO; }
}
if ((m=m1+m2) <= 0) {
m=0; a=ONE;
for (i=n-1; i>0; i--,n--) { if (m1np[i][p]+m2>0) break; }
}
/* Compute s=x*2**(-m). Put result in mps */
dbl_mp(a,&mpt1,p);
mul(x,&mpt1,&mps,p);
/* Evaluate the polynomial. Put result in mpt2 */
mpone.e=1; mpone.d[0]=ONE; mpone.d[1]=ONE;
mpk.e = 1; mpk.d[0] = ONE; mpk.d[1]=nn[n].d;
dvd(&mps,&mpk,&mpt1,p);
add(&mpone,&mpt1,&mpak,p);
for (k=n-1; k>1; k--) {
mul(&mps,&mpak,&mpt1,p);
mpk.d[1]=nn[k].d;
dvd(&mpt1,&mpk,&mpt2,p);
add(&mpone,&mpt2,&mpak,p);
}
mul(&mps,&mpak,&mpt1,p);
add(&mpone,&mpt1,&mpt2,p);
/* Raise polynomial value to the power of 2**m. Put result in y */
for (k=0,j=0; k<m; ) {
mul(&mpt2,&mpt2,&mpt1,p); k++;
if (k==m) { j=1; break; }
mul(&mpt1,&mpt1,&mpt2,p); k++;
}
if (j) cpy(&mpt1,y,p);
else cpy(&mpt2,y,p);
return;
}

View File

@ -0,0 +1,157 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* */
/* MODULE_NAME:mpexp.h */
/* */
/* common data and variables prototype and definition */
/******************************************************************/
#ifndef MPEXP_H
#define MPEXP_H
#ifdef BIG_ENDI
static const number
twomm1[33] = { /* 2**-m1 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x3ee00000, 0x00000000, }, /* 2**-17 */
/**/ {0x3e800000, 0x00000000, }, /* 2**-23 */
/**/ {0x3e800000, 0x00000000, }, /* 2**-23 */
/**/ {0x3e300000, 0x00000000, }, /* 2**-28 */
/**/ {0x3e400000, 0x00000000, }, /* 2**-27 */
/**/ {0x3d900000, 0x00000000, }, /* 2**-38 */
/**/ {0x3d500000, 0x00000000, }, /* 2**-42 */
/**/ {0x3d800000, 0x00000000, }, /* 2**-39 */
/**/ {0x3d400000, 0x00000000, }, /* 2**-43 */
/**/ {0x3d000000, 0x00000000, }, /* 2**-47 */
/**/ {0x3d400000, 0x00000000, }, /* 2**-43 */
/**/ {0x3d000000, 0x00000000, }, /* 2**-47 */
/**/ {0x3cd00000, 0x00000000, }, /* 2**-50 */
/**/ {0x3c900000, 0x00000000, }, /* 2**-54 */
/**/ {0x3c600000, 0x00000000, }, /* 2**-57 */
/**/ {0x3c300000, 0x00000000, }, /* 2**-60 */
/**/ {0x3bf00000, 0x00000000, }, /* 2**-64 */
/**/ {0x3bc00000, 0x00000000, }, /* 2**-67 */
/**/ {0x3b800000, 0x00000000, }, /* 2**-71 */
/**/ {0x3b500000, 0x00000000, }, /* 2**-74 */
/**/ {0x3bb00000, 0x00000000, }, /* 2**-68 */
/**/ {0x3b800000, 0x00000000, }, /* 2**-71 */
/**/ {0x3b500000, 0x00000000, }, /* 2**-74 */
/**/ {0x3b200000, 0x00000000, }, /* 2**-77 */
/**/ {0x3b900000, 0x00000000, }, /* 2**-70 */
/**/ {0x3b600000, 0x00000000, }, /* 2**-73 */
/**/ {0x3b300000, 0x00000000, }, /* 2**-76 */
/**/ {0x3b100000, 0x00000000, }, /* 2**-78 */
/**/ {0x3ae00000, 0x00000000, }, /* 2**-81 */
};
static const number
nn[9]={ /* n */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x3ff00000, 0x00000000, }, /* 1 */
/**/ {0x40000000, 0x00000000, }, /* 2 */
/**/ {0x40080000, 0x00000000, }, /* 3 */
/**/ {0x40100000, 0x00000000, }, /* 4 */
/**/ {0x40140000, 0x00000000, }, /* 5 */
/**/ {0x40180000, 0x00000000, }, /* 6 */
/**/ {0x401c0000, 0x00000000, }, /* 7 */
/**/ {0x40200000, 0x00000000, }, /* 8 */
};
static const number
/**/ radix = {0x41700000, 0x00000000, }, /* 2**24 */
/**/ radixi = {0x3e700000, 0x00000000, }, /* 2**-24 */
/**/ zero = {0x00000000, 0x00000000, }, /* 0 */
/**/ one = {0x3ff00000, 0x00000000, }, /* 1 */
/**/ two = {0x40000000, 0x00000000, }, /* 2 */
/**/ half = {0x3fe00000, 0x00000000, }; /* 1/2 */
#else
#ifdef LITTLE_ENDI
static const number
twomm1[33] = { /* 2**-m1 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x3ee00000, }, /* 2**-17 */
/**/ {0x00000000, 0x3e800000, }, /* 2**-23 */
/**/ {0x00000000, 0x3e800000, }, /* 2**-23 */
/**/ {0x00000000, 0x3e300000, }, /* 2**-28 */
/**/ {0x00000000, 0x3e400000, }, /* 2**-27 */
/**/ {0x00000000, 0x3d900000, }, /* 2**-38 */
/**/ {0x00000000, 0x3d500000, }, /* 2**-42 */
/**/ {0x00000000, 0x3d800000, }, /* 2**-39 */
/**/ {0x00000000, 0x3d400000, }, /* 2**-43 */
/**/ {0x00000000, 0x3d000000, }, /* 2**-47 */
/**/ {0x00000000, 0x3d400000, }, /* 2**-43 */
/**/ {0x00000000, 0x3d000000, }, /* 2**-47 */
/**/ {0x00000000, 0x3cd00000, }, /* 2**-50 */
/**/ {0x00000000, 0x3c900000, }, /* 2**-54 */
/**/ {0x00000000, 0x3c600000, }, /* 2**-57 */
/**/ {0x00000000, 0x3c300000, }, /* 2**-60 */
/**/ {0x00000000, 0x3bf00000, }, /* 2**-64 */
/**/ {0x00000000, 0x3bc00000, }, /* 2**-67 */
/**/ {0x00000000, 0x3b800000, }, /* 2**-71 */
/**/ {0x00000000, 0x3b500000, }, /* 2**-74 */
/**/ {0x00000000, 0x3bb00000, }, /* 2**-68 */
/**/ {0x00000000, 0x3b800000, }, /* 2**-71 */
/**/ {0x00000000, 0x3b500000, }, /* 2**-74 */
/**/ {0x00000000, 0x3b200000, }, /* 2**-77 */
/**/ {0x00000000, 0x3b900000, }, /* 2**-70 */
/**/ {0x00000000, 0x3b600000, }, /* 2**-73 */
/**/ {0x00000000, 0x3b300000, }, /* 2**-76 */
/**/ {0x00000000, 0x3b100000, }, /* 2**-78 */
/**/ {0x00000000, 0x3ae00000, }, /* 2**-81 */
};
static const number
nn[9]={ /* n */
/**/ {0x00000000, 0x00000000, }, /* 0 */
/**/ {0x00000000, 0x3ff00000, }, /* 1 */
/**/ {0x00000000, 0x40000000, }, /* 2 */
/**/ {0x00000000, 0x40080000, }, /* 3 */
/**/ {0x00000000, 0x40100000, }, /* 4 */
/**/ {0x00000000, 0x40140000, }, /* 5 */
/**/ {0x00000000, 0x40180000, }, /* 6 */
/**/ {0x00000000, 0x401c0000, }, /* 7 */
/**/ {0x00000000, 0x40200000, }, /* 8 */
};
static const number
/**/ radix = {0x00000000, 0x41700000, }, /* 2**24 */
/**/ radixi = {0x00000000, 0x3e700000, }, /* 2**-24 */
/**/ zero = {0x00000000, 0x00000000, }, /* 0 */
/**/ one = {0x00000000, 0x3ff00000, }, /* 1 */
/**/ two = {0x00000000, 0x40000000, }, /* 2 */
/**/ half = {0x00000000, 0x3fe00000, }; /* 1/2 */
#endif
#endif
#define RADIX radix.d
#define RADIXI radixi.d
#define ZERO zero.d
#define ONE one.d
#define TWO two.d
#define HALF half.d
#endif

View File

@ -0,0 +1,68 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/************************************************************************/
/* */
/* MODULE_NAME:mplog.c */
/* */
/* FUNCTIONS: mplog */
/* */
/* FILES NEEDED: endian.h mpa.h mplog.h */
/* mpexp.c */
/* */
/* Multi-Precision logarithm function subroutine (for precision p >= 4, */
/* 2**(-1024) < x < 2**1024) and x is outside of the interval */
/* [1-2**(-54),1+2**(-54)]. Upon entry, x should be set to the */
/* multi-precision value of the input and y should be set into a multi- */
/* precision value of an approximation of log(x) with relative error */
/* bound of at most 2**(-52). The routine improves the accuracy of y. */
/* */
/************************************************************************/
#include "endian.h"
#include "mpa.h"
void mpexp(mp_no *, mp_no *, int);
void mplog(mp_no *x, mp_no *y, int p) {
#include "mplog.h"
int i,j,k,m,m1,m2,n;
double a,b;
static const int mp[33] = {0,0,0,0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,4,4,4,4,4,4};
mp_no mpone = {0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,};
mp_no mpt1,mpt2;
/* Choose m and initiate mpone */
m = mp[p]; mpone.e = 1; mpone.d[0]=mpone.d[1]=ONE;
/* Perform m newton iterations to solve for y: exp(y)-x=0. */
/* The iterations formula is: y(n+1)=y(n)+(x*exp(-y(n))-1). */
cpy(y,&mpt1,p);
for (i=0; i<m; i++) {
mpt1.d[0]=-mpt1.d[0];
mpexp(&mpt1,&mpt2,p);
mul(x,&mpt2,&mpt1,p);
sub(&mpt1,&mpone,&mpt2,p);
add(y,&mpt2,&mpt1,p);
cpy(&mpt1,y,p);
}
return;
}

View File

@ -0,0 +1,44 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* */
/* MODULE_NAME:mplog.h */
/* */
/* common data and variables prototype and definition */
/******************************************************************/
#ifndef MPLOG_H
#define MPLOG_H
#ifdef BIG_ENDI
static const number
/**/ one = {0x3ff00000, 0x00000000, }; /* 1 */
#else
#ifdef LITTLE_ENDI
static const number
/**/ one = {0x00000000, 0x3ff00000, }; /* 1 */
#endif
#endif
#define ONE one.d
#endif

View File

@ -0,0 +1,102 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************/
/* MODULE_NAME:mpsqrt.c */
/* */
/* FUNCTION:mpsqrt */
/* fastiroot */
/* */
/* FILES NEEDED:endian.h mpa.h mpsqrt.h */
/* mpa.c */
/* Multi-Precision square root function subroutine for precision p >= 4. */
/* The relative error is bounded by 3.501*r**(1-p), where r=2**24. */
/* */
/****************************************************************************/
#include "endian.h"
#include "mpa.h"
/****************************************************************************/
/* Multi-Precision square root function subroutine for precision p >= 4. */
/* The relative error is bounded by 3.501*r**(1-p), where r=2**24. */
/* Routine receives two pointers to Multi Precision numbers: */
/* x (left argument) and y (next argument). Routine also receives precision */
/* p as integer. Routine computes sqrt(*x) and stores result in *y */
/****************************************************************************/
double fastiroot(double);
void mpsqrt(mp_no *x, mp_no *y, int p) {
#include "mpsqrt.h"
int i,m,ex,ey;
double dx,dy;
mp_no
mphalf = {0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,},
mp3halfs = {0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,};
mp_no mpxn,mpz,mpu,mpt1,mpt2;
/* Prepare multi-precision 1/2 and 3/2 */
mphalf.e =0; mphalf.d[0] =ONE; mphalf.d[1] =HALFRAD;
mp3halfs.e=1; mp3halfs.d[0]=ONE; mp3halfs.d[1]=ONE; mp3halfs.d[2]=HALFRAD;
ex=EX; ey=EX/2; cpy(x,&mpxn,p); mpxn.e -= (ey+ey);
mp_dbl(&mpxn,&dx,p); dy=fastiroot(dx); dbl_mp(dy,&mpu,p);
mul(&mpxn,&mphalf,&mpz,p);
m=mp[p];
for (i=0; i<m; i++) {
mul(&mpu,&mpu,&mpt1,p);
mul(&mpt1,&mpz,&mpt2,p);
sub(&mp3halfs,&mpt2,&mpt1,p);
mul(&mpu,&mpt1,&mpt2,p);
cpy(&mpt2,&mpu,p);
}
mul(&mpxn,&mpu,y,p); EY += ey;
return;
}
/***********************************************************/
/* Compute a double precision approximation for 1/sqrt(x) */
/* with the relative error bounded by 2**-51. */
/***********************************************************/
double fastiroot(double x) {
union {long i[2]; double d;} p,q;
double y,z, t;
long n;
static const double c0 = 0.99674, c1 = -0.53380, c2 = 0.45472, c3 = -0.21553;
p.d = x;
p.i[HIGH_HALF] = (p.i[HIGH_HALF] & 0x3FFFFFFF ) | 0x3FE00000 ;
q.d = x;
y = p.d;
z = y -1.0;
n = (q.i[HIGH_HALF] - p.i[HIGH_HALF])>>1;
z = ((c3*z + c2)*z + c1)*z + c0; /* 2**-7 */
z = z*(1.5 - 0.5*y*z*z); /* 2**-14 */
p.d = z*(1.5 - 0.5*y*z*z); /* 2**-28 */
p.i[HIGH_HALF] -= n;
t = x*p.d;
return p.d*(1.5 - 0.5*p.d*t);
}

View File

@ -0,0 +1,50 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* */
/* MODULE_NAME:mpatan.h */
/* */
/* common data and variables prototype and definition */
/******************************************************************/
#ifndef MPSQRT_H
#define MPSQRT_H
#ifdef BIG_ENDI
static const number
/**/ one = {0x3ff00000, 0x00000000, }, /* 1 */
/**/ halfrad = {0x41600000, 0x00000000, }; /* 2**23 */
#else
#ifdef LITTLE_ENDI
static const number
/**/ one = {0x00000000, 0x3ff00000, }, /* 1 */
/**/ halfrad = {0x00000000, 0x41600000, }; /* 2**23 */
#endif
#endif
#define ONE one.d
#define HALFRAD halfrad.d
static const int mp[33] = {0,0,0,0,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4};
#endif

View File

@ -0,0 +1,59 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/**********************************************************************/
/* MODULE_NAME:mptan.c */
/* */
/* FUNCTION: mptan */
/* */
/* FILES NEEDED: endian.h mpa.h */
/* mpa.c sincos32.c branred.c */
/* */
/* Multi-Precision tan() function subroutine, for p=32. It is based */
/* on the routines mpranred() and c32(). mpranred() performs range */
/* reduction of a double number x into a multiple precision number */
/* y, such that y=x-n*pi/2, abs(y)<pi/4, n=0,+-1,+-2,.... c32() */
/* computes both sin(y), cos(y). tan(x) is either sin(y)/cos(y) */
/* or -cos(y)/sin(y). The precision of the result is of about 559 */
/* significant bits. */
/* */
/**********************************************************************/
#include "endian.h"
#include "mpa.h"
int mpranred(double, mp_no *, int);
void c32(mp_no *, mp_no *, mp_no *, int);
void mptan(double x, mp_no *mpy, int p) {
static const double MONE = -1.0;
int n;
mp_no mpw, mpc, mps;
n = mpranred(x, &mpw, p) & 0x00000001; /* negative or positive result */
c32(&mpw, &mpc, &mps, p); /* computing sin(x) and cos(x) */
if (n) /* second or fourth quarter of unit circle */
{ dvd(&mpc,&mps,mpy,p);
mpy->d[0] *= MONE;
} /* tan is negative in this area */
else dvd(&mps,&mpc,mpy,p);
return;
}

View File

@ -0,0 +1,37 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* */
/* MODULE_NAME:mydefs.h */
/* */
/* common data and definition */
/******************************************************************/
#ifndef MY_H
#define MY_H
typedef int int4;
typedef union {int4 i[2]; double x;} mynumber;
#define ABS(x) (((x)>0)?(x):-(x))
#define max(x,y) (((y)>(x))?(y):(x))
#define min(x,y) (((y)<(x))?(y):(x))
#endif

View File

@ -0,0 +1,12 @@
/****************************************************************/
/* TABLES FOR THE upow() FUNCTION */
/****************************************************************/
static const double powtwo[] = { 1.0, 2.0, 4.0,
8.0, 16.0, 32.0, 64.0, 128.0,
256.0, 512.0, 1024.0, 2048.0, 4096.0,
8192.0, 16384.0, 32768.0, 65536.0, 131072.0,
262144.0, 524288.0, 1048576.0, 2097152.0, 4194304.0,
8388608.0, 16777216.0, 33554432.0, 67108864.0, 134217728.0 };

View File

@ -0,0 +1,38 @@
/****************************************************************/
/* TABLES FOR THE usqrt() FUNCTION */
/****************************************************************/
static const double inroot[128] = {
1.40872145012100, 1.39792649065766, 1.38737595123859, 1.37706074531819,
1.36697225234682, 1.35710228748795, 1.34744307370643, 1.33798721601135,
1.32872767765984, 1.31965775814772, 1.31077107283046, 1.30206153403386,
1.29352333352711, 1.28515092624400, 1.27693901514820, 1.26888253714903,
1.26097664998256, 1.25321671998073, 1.24559831065844, 1.23811717205462,
1.23076923076923, 1.22355058064300, 1.21645747403153, 1.20948631362953,
1.20263364480453, 1.19589614840310, 1.18927063399547, 1.18275403352732,
1.17634339535009, 1.17003587860341, 1.16382874792529, 1.15771936846787,
1.15170520119791, 1.14578379846309, 1.13995279980655, 1.13420992801334,
1.12855298537376, 1.12297985014975, 1.11748847323133, 1.11207687497107,
1.10674314218572, 1.10148542531442, 1.09630193572405, 1.09119094315276,
1.08615077328341, 1.08117980543918, 1.07627647039410, 1.07143924829188,
1.06666666666667, 1.06195729855996, 1.05730976072814, 1.05272271193563,
1.04819485132867, 1.04372491688551, 1.03931168393861, 1.03495396376504,
1.03065060224133, 1.02640047855933, 1.02220250399990, 1.01805562076124,
1.01395880083916, 1.00991104495649, 1.00591138153909, 1.00195886573624,
0.99611649018350, 0.98848330114434, 0.98102294317595, 0.97372899112030,
0.96659534932828, 0.95961623024651, 0.95278613468066, 0.94609983358253,
0.93955235122353, 0.93313894963169, 0.92685511418159, 0.92069654023750,
0.91465912076005, 0.90873893479530, 0.90293223677296, 0.89723544654727,
0.89164514012056, 0.88615804099474, 0.88077101210109, 0.87548104826333,
0.87028526915267, 0.86518091269740, 0.86016532891275, 0.85523597411976,
0.85039040552437, 0.84562627613070, 0.84094132996422, 0.83633339758291,
0.83180039185606, 0.82734030399203, 0.82295119979782, 0.81863121615464,
0.81437855769486, 0.81019149366693, 0.80606835497581, 0.80200753138734,
0.79800746888611, 0.79406666717674, 0.79018367731967, 0.78635709949278,
0.78258558087123, 0.77886781361798, 0.77520253297841, 0.77158851547266,
0.76802457717971, 0.76450957210799, 0.76104239064719, 0.75762195809661,
0.75424723326565, 0.75091720714229, 0.74763090162560, 0.74438736831878,
0.74118568737933, 0.73802496642311, 0.73490433947940, 0.73182296599416,
0.72878002987884, 0.72577473860242, 0.72280632232420, 0.71987403306536,
0.71697714391715, 0.71411494828392, 0.71128675915902, 0.70849190843208 };

View File

@ -1,163 +1,221 @@
/* @(#)s_atan.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* 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.
* ====================================================
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25,
for performance improvement on pipelined processors.
*/
/************************************************************************/
/* MODULE_NAME: atnat.c */
/* */
/* FUNCTIONS: uatan */
/* atanMp */
/* signArctan */
/* */
/* */
/* FILES NEEDED: dla.h endian.h mpa.h mydefs.h atnat.h */
/* mpatan.c mpatan2.c mpsqrt.c */
/* uatan.tbl */
/* */
/* An ultimate atan() routine. Given an IEEE double machine number x */
/* it computes the correctly rounded (to nearest) value of atan(x). */
/* */
/* Assumption: Machine arithmetic operations are performed in */
/* round to nearest mode of IEEE 754 standard. */
/* */
/************************************************************************/
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: s_atan.c,v 1.8 1995/05/10 20:46:45 jtc Exp $";
#endif
#include "dla.h"
#include "mpa.h"
#include "MathLib.h"
#include "uatan.tbl"
#include "atnat.h"
/* atan(x)
* Method
* 1. Reduce x to positive by atan(x) = -atan(-x).
* 2. According to the integer k=4t+0.25 chopped, t=x, the argument
* is further reduced to one of the following intervals and the
* arctangent of t is evaluated by the corresponding formula:
*
* [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
* [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
* [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
* [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
* [39/16,INF] atan(x) = atan(INF) + atan( -1/t )
*
* 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.
*/
void __mpatan(mp_no *,mp_no *,int); /* see definition in mpatan.c */
static double atanMp(double,const int[]);
double __signArctan(double,double);
/* An ultimate atan() routine. Given an IEEE double machine number x, */
/* routine computes the correctly rounded (to nearest) value of atan(x). */
double atan(double x) {
#include "math.h"
#include "math_private.h"
#ifdef __STDC__
static const double atanhi[] = {
#else
static double atanhi[] = {
#endif
4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
};
double cor,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,u,u2,u3,
v,vv,w,ww,y,yy,y1,y2,z,zz;
int i,ux,dx,p;
static const int pr[M]={6,8,10,32};
number num;
#ifdef __STDC__
static const double atanlo[] = {
#else
static double atanlo[] = {
#endif
2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
};
mp_no mpt1,mpx,mpy,mpy1,mpy2,mperr;
#ifdef __STDC__
static const double aT[] = {
#else
static double aT[] = {
#endif
3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
-1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
-1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
-7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
-5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
-3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
};
num.d = x; ux = num.i[HIGH_HALF]; dx = num.i[LOW_HALF];
#ifdef __STDC__
static const double
#else
static double
#endif
one = 1.0,
huge = 1.0e300;
/* x=NaN */
if (((ux&0x7ff00000)==0x7ff00000) && (((ux&0x000fffff)|dx)!=0x00000000))
return x+x;
#ifdef __STDC__
double __atan(double x)
#else
double __atan(x)
double x;
#endif
{
double w,s1,z,s,w2,w4,s11,s12,s13,s21,s22,s23;
int32_t ix,hx,id;
/* Regular values of x, including denormals +-0 and +-INF */
u = (x<ZERO) ? -x : x;
if (u<C) {
if (u<B) {
if (u<A) { /* u < A */
return x; }
else { /* A <= u < B */
v=x*x; yy=x*v*(d3.d+v*(d5.d+v*(d7.d+v*(d9.d+v*(d11.d+v*d13.d)))));
if ((y=x+(yy-U1*x)) == x+(yy+U1*x)) return y;
EMULV(x,x,v,vv,t1,t2,t3,t4,t5) /* v+vv=x^2 */
s1=v*(f11.d+v*(f13.d+v*(f15.d+v*(f17.d+v*f19.d))));
ADD2(f9.d,ff9.d,s1,ZERO,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f7.d,ff7.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f5.d,ff5.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f3.d,ff3.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(x,ZERO,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(x,ZERO,s2,ss2,s1,ss1,t1,t2)
if ((y=s1+(ss1-U5*s1)) == s1+(ss1+U5*s1)) return y;
return atanMp(x,pr);
} }
else { /* B <= u < C */
i=(TWO52+TWO8*u)-TWO52; i-=16;
z=u-cij[i][0].d;
yy=z*(cij[i][2].d+z*(cij[i][3].d+z*(cij[i][4].d+
z*(cij[i][5].d+z* cij[i][6].d))));
t1=cij[i][1].d;
if (i<112) {
if (i<48) u2=U21; /* u < 1/4 */
else u2=U22; } /* 1/4 <= u < 1/2 */
else {
if (i<176) u2=U23; /* 1/2 <= u < 3/4 */
else u2=U24; } /* 3/4 <= u <= 1 */
if ((y=t1+(yy-u2*t1)) == t1+(yy+u2*t1)) return __signArctan(x,y);
z=u-hij[i][0].d;
s1=z*(hij[i][11].d+z*(hij[i][12].d+z*(hij[i][13].d+
z*(hij[i][14].d+z* hij[i][15].d))));
ADD2(hij[i][9].d,hij[i][10].d,s1,ZERO,s2,ss2,t1,t2)
MUL2(z,ZERO,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][7].d,hij[i][8].d,s1,ss1,s2,ss2,t1,t2)
MUL2(z,ZERO,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][5].d,hij[i][6].d,s1,ss1,s2,ss2,t1,t2)
MUL2(z,ZERO,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][3].d,hij[i][4].d,s1,ss1,s2,ss2,t1,t2)
MUL2(z,ZERO,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][1].d,hij[i][2].d,s1,ss1,s2,ss2,t1,t2)
if ((y=s2+(ss2-U6*s2)) == s2+(ss2+U6*s2)) return __signArctan(x,y);
return atanMp(x,pr);
}
}
else {
if (u<D) { /* C <= u < D */
w=ONE/u;
EMULV(w,u,t1,t2,t3,t4,t5,t6,t7)
ww=w*((ONE-t1)-t2);
i=(TWO52+TWO8*w)-TWO52; i-=16;
z=(w-cij[i][0].d)+ww;
yy=HPI1-z*(cij[i][2].d+z*(cij[i][3].d+z*(cij[i][4].d+
z*(cij[i][5].d+z* cij[i][6].d))));
t1=HPI-cij[i][1].d;
if (i<112) u3=U31; /* w < 1/2 */
else u3=U32; /* w >= 1/2 */
if ((y=t1+(yy-u3)) == t1+(yy+u3)) return __signArctan(x,y);
DIV2(ONE,ZERO,u,ZERO,w,ww,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
t1=w-hij[i][0].d;
EADD(t1,ww,z,zz)
s1=z*(hij[i][11].d+z*(hij[i][12].d+z*(hij[i][13].d+
z*(hij[i][14].d+z* hij[i][15].d))));
ADD2(hij[i][9].d,hij[i][10].d,s1,ZERO,s2,ss2,t1,t2)
MUL2(z,zz,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][7].d,hij[i][8].d,s1,ss1,s2,ss2,t1,t2)
MUL2(z,zz,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][5].d,hij[i][6].d,s1,ss1,s2,ss2,t1,t2)
MUL2(z,zz,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][3].d,hij[i][4].d,s1,ss1,s2,ss2,t1,t2)
MUL2(z,zz,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(hij[i][1].d,hij[i][2].d,s1,ss1,s2,ss2,t1,t2)
SUB2(HPI,HPI1,s2,ss2,s1,ss1,t1,t2)
if ((y=s1+(ss1-U7)) == s1+(ss1+U7)) return __signArctan(x,y);
return atanMp(x,pr);
}
else {
if (u<E) { /* D <= u < E */
w=ONE/u; v=w*w;
EMULV(w,u,t1,t2,t3,t4,t5,t6,t7)
yy=w*v*(d3.d+v*(d5.d+v*(d7.d+v*(d9.d+v*(d11.d+v*d13.d)))));
ww=w*((ONE-t1)-t2);
ESUB(HPI,w,t3,cor)
yy=((HPI1+cor)-ww)-yy;
if ((y=t3+(yy-U4)) == t3+(yy+U4)) return __signArctan(x,y);
DIV2(ONE,ZERO,u,ZERO,w,ww,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
MUL2(w,ww,w,ww,v,vv,t1,t2,t3,t4,t5,t6,t7,t8)
s1=v*(f11.d+v*(f13.d+v*(f15.d+v*(f17.d+v*f19.d))));
ADD2(f9.d,ff9.d,s1,ZERO,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f7.d,ff7.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f5.d,ff5.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(f3.d,ff3.d,s1,ss1,s2,ss2,t1,t2)
MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(w,ww,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(w,ww,s2,ss2,s1,ss1,t1,t2)
SUB2(HPI,HPI1,s1,ss1,s2,ss2,t1,t2)
if ((y=s2+(ss2-U8)) == s2+(ss2+U8)) return __signArctan(x,y);
return atanMp(x,pr);
}
else {
/* u >= E */
if (x>0) return HPI;
else return MHPI; }
}
}
GET_HIGH_WORD(hx,x);
ix = hx&0x7fffffff;
if(ix>=0x44100000) { /* if |x| >= 2^66 */
u_int32_t low;
GET_LOW_WORD(low,x);
if(ix>0x7ff00000||
(ix==0x7ff00000&&(low!=0)))
return x+x; /* NaN */
if(hx>0) return atanhi[3]+atanlo[3];
else return -atanhi[3]-atanlo[3];
} if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
if (ix < 0x3e200000) { /* |x| < 2^-29 */
if(huge+x>one) return x; /* raise inexact */
}
id = -1;
} else {
x = fabs(x);
if (ix < 0x3ff30000) { /* |x| < 1.1875 */
if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */
id = 0; x = (2.0*x-one)/(2.0+x);
} else { /* 11/16<=|x|< 19/16 */
id = 1; x = (x-one)/(x+one);
}
} else {
if (ix < 0x40038000) { /* |x| < 2.4375 */
id = 2; x = (x-1.5)/(one+1.5*x);
} else { /* 2.4375 <= |x| < 2^66 */
id = 3; x = -1.0/x;
}
}}
/* end of argument reduction */
z = x*x;
w = z*z;
/* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
#ifdef DO_NOT_USE_THIS
s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
if (id<0) return x - x*(s1+s2);
else {
z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
return (hx<0)? -z:z;
}
#else
s11 = aT[8]+w*aT[10]; w2=w*w;
s12 = aT[4]+w*aT[6]; w4=w2*w2;
s13 = aT[0]+w*aT[2];
s21 = aT[7]+w*aT[9];
s22 = aT[3]+w*aT[5];
s23 = w*aT[1];
s1 = s13 + w2*s12 + w4*s11;
s = s23 + w2*s22 + w4*s21 + z*s1;
if (id<0) return x - x*(s);
else {
z = atanhi[id] - ((x*(s) - atanlo[id]) - x);
return (hx<0)? -z:z;
}
#endif
}
weak_alias (__atan, atan)
/* Fix the sign of y and return */
double __signArctan(double x,double y){
if (x<ZERO) return -y;
else return y;
}
/* Final stages. Compute atan(x) by multiple precision arithmetic */
static double atanMp(double x,const int pr[]){
mp_no mpx,mpy,mpy2,mperr,mpt1,mpy1;
double y1,y2;
int i,p;
for (i=0; i<M; i++) {
p = pr[i];
dbl_mp(x,&mpx,p); __mpatan(&mpx,&mpy,p);
dbl_mp(u9[i].d,&mpt1,p); mul(&mpy,&mpt1,&mperr,p);
add(&mpy,&mperr,&mpy1,p); sub(&mpy,&mperr,&mpy2,p);
mp_dbl(&mpy1,&y1,p); mp_dbl(&mpy2,&y2,p);
if (y1==y2) return y1;
}
return y1; /*if unpossible to do exact computing */
}
#ifdef NO_LONG_DOUBLE
strong_alias (__atan, __atanl)
weak_alias (__atan, atanl)
weak_alias (atan, atanl)
#endif

View File

@ -1,87 +1 @@
/* @(#)s_cos.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* 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.
* ====================================================
*/
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: s_cos.c,v 1.7 1995/05/10 20:47:02 jtc Exp $";
#endif
/* cos(x)
* Return cosine function of x.
*
* kernel function:
* __kernel_sin ... sine function on [-pi/4,pi/4]
* __kernel_cos ... cosine function on [-pi/4,pi/4]
* __ieee754_rem_pio2 ... argument reduction routine
*
* Method.
* Let S,C and T denote the sin, cos and tan respectively on
* [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
* in [-pi/4 , +pi/4], and let n = k mod 4.
* We have
*
* n sin(x) cos(x) tan(x)
* ----------------------------------------------------------
* 0 S C T
* 1 C -S -1/T
* 2 -S -C T
* 3 -C S -1/T
* ----------------------------------------------------------
*
* Special cases:
* Let trig be any of sin, cos, or tan.
* trig(+-INF) is NaN, with signals;
* trig(NaN) is that NaN;
*
* Accuracy:
* TRIG(x) returns trig(x) nearly rounded
*/
#include "math.h"
#include "math_private.h"
#ifdef __STDC__
double __cos(double x)
#else
double __cos(x)
double x;
#endif
{
double y[2],z=0.0;
int32_t n, ix;
/* High word of x. */
GET_HIGH_WORD(ix,x);
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if(ix <= 0x3fe921fb) return __kernel_cos(x,z);
/* cos(Inf or NaN) is NaN */
else if (ix>=0x7ff00000) return x-x;
/* argument reduction needed */
else {
n = __ieee754_rem_pio2(x,y);
switch(n&3) {
case 0: return __kernel_cos(y[0],y[1]);
case 1: return -__kernel_sin(y[0],y[1],1);
case 2: return -__kernel_cos(y[0],y[1]);
default:
return __kernel_sin(y[0],y[1],1);
}
}
}
weak_alias (__cos, cos)
#ifdef NO_LONG_DOUBLE
strong_alias (__cos, __cosl)
weak_alias (__cos, cosl)
#endif
/* In s_sin.c. */

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Compute sine and cosine of argument.
Copyright (C) 1997 Free Software Foundation, Inc.
Copyright (C) 1997, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -33,42 +33,15 @@ __sincos (double x, double *sinx, double *cosx)
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if (ix <= 0x3fe921fb)
{
*sinx = __kernel_sin (x, 0.0, 0);
*cosx = __kernel_cos (x, 0.0);
}
else if (ix>=0x7ff00000)
if (ix>=0x7ff00000)
{
/* sin(Inf or NaN) is NaN */
*sinx = *cosx = x - x;
}
else
{
/* Argument reduction needed. */
double y[2];
int n;
n = __ieee754_rem_pio2 (x, y);
switch (n & 3)
{
case 0:
*sinx = __kernel_sin (y[0], y[1], 1);
*cosx = __kernel_cos (y[0], y[1]);
break;
case 1:
*sinx = __kernel_cos (y[0], y[1]);
*cosx = -__kernel_sin (y[0], y[1], 1);
break;
case 2:
*sinx = -__kernel_sin (y[0], y[1], 1);
*cosx = -__kernel_cos (y[0], y[1]);
break;
default:
*sinx = -__kernel_cos (y[0], y[1]);
*cosx = __kernel_sin (y[0], y[1], 1);
break;
}
*sinx = sin (x);
*cosx = cos (x);
}
}
weak_alias (__sincos, sincos)

View File

@ -1,81 +1,480 @@
/* @(#)s_tan.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* 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.
* ====================================================
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*********************************************************************/
/* MODULE_NAME: utan.c */
/* */
/* FUNCTIONS: utan */
/* tanMp */
/* */
/* FILES NEEDED:dla.h endian.h mpa.h mydefs.h utan.h */
/* branred.c sincos32.c mptan.c */
/* utan.tbl */
/* */
/* An ultimate tan routine. Given an IEEE double machine number x */
/* it computes the correctly rounded (to nearest) value of tan(x). */
/* Assumption: Machine arithmetic operations are performed in */
/* round to nearest mode of IEEE 754 standard. */
/* */
/*********************************************************************/
#include "endian.h"
#include "dla.h"
#include "mpa.h"
#include "MathLib.h"
static double tanMp(double);
void __mptan(double, mp_no *, int);
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: s_tan.c,v 1.7 1995/05/10 20:48:18 jtc Exp $";
#endif
double tan(double x) {
#include "utan.h"
#include "utan.tbl"
/* tan(x)
* Return tangent function of x.
*
* kernel function:
* __kernel_tan ... tangent function on [-pi/4,pi/4]
* __ieee754_rem_pio2 ... argument reduction routine
*
* Method.
* Let S,C and T denote the sin, cos and tan respectively on
* [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
* in [-pi/4 , +pi/4], and let n = k mod 4.
* We have
*
* n sin(x) cos(x) tan(x)
* ----------------------------------------------------------
* 0 S C T
* 1 C -S -1/T
* 2 -S -C T
* 3 -C S -1/T
* ----------------------------------------------------------
*
* Special cases:
* Let trig be any of sin, cos, or tan.
* trig(+-INF) is NaN, with signals;
* trig(NaN) is that NaN;
*
* Accuracy:
* TRIG(x) returns trig(x) nearly rounded
*/
int ux,i,n;
double a,da,a2,b,db,c,dc,c1,cc1,c2,cc2,c3,cc3,fi,ffi,gi,pz,s,sy,
t,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,w,x2,xn,xx2,y,ya,yya,z0,z,zz,z2,zz2;
int p;
number num,v;
mp_no mpa,mpy,mpt1,mpt2;
#include "math.h"
#include "math_private.h"
int branred(double, double *, double *);
int mpranred(double, mp_no *, int);
#ifdef __STDC__
double __tan(double x)
#else
double __tan(x)
double x;
#endif
{
double y[2],z=0.0;
int32_t n, ix;
/* x=+-INF, x=NaN */
num.d = x; ux = num.i[HIGH_HALF];
if ((ux&0x7ff00000)==0x7ff00000) return x-x;
/* High word of x. */
GET_HIGH_WORD(ix,x);
w=(x<ZERO) ? -x : x;
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1);
/* (I) The case abs(x) <= 1.259e-8 */
if (w<=g1.d) return x;
/* tan(Inf or NaN) is NaN */
else if (ix>=0x7ff00000) return x-x; /* NaN */
/* (II) The case 1.259e-8 < abs(x) <= 0.0608 */
if (w<=g2.d) {
/* argument reduction needed */
else {
n = __ieee754_rem_pio2(x,y);
return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even
-1 -- n odd */
}
/* First stage */
x2 = x*x;
t2 = x*x2*(d3.d+x2*(d5.d+x2*(d7.d+x2*(d9.d+x2*d11.d))));
if ((y=x+(t2-u1.d*t2)) == x+(t2+u1.d*t2)) return y;
/* Second stage */
c1 = x2*(a15.d+x2*(a17.d+x2*(a19.d+x2*(a21.d+x2*(a23.d+x2*(a25.d+
x2*a27.d))))));
EMULV(x,x,x2,xx2,t1,t2,t3,t4,t5)
ADD2(a13.d,aa13.d,c1,zero.d,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a11.d,aa11.d,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a9.d ,aa9.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a7.d ,aa7.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a5.d ,aa5.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a3.d ,aa3.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(x ,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(x ,zero.d,c2,cc2,c1,cc1,t1,t2)
if ((y=c1+(cc1-u2.d*c1)) == c1+(cc1+u2.d*c1)) return y;
return tanMp(x);
}
/* (III) The case 0.0608 < abs(x) <= 0.787 */
if (w<=g3.d) {
/* First stage */
i = ((int) (mfftnhf.d+TWO8*w));
z = w-xfg[i][0].d; z2 = z*z; s = (x<ZERO) ? MONE : ONE;
pz = z+z*z2*(e0.d+z2*e1.d);
fi = xfg[i][1].d; gi = xfg[i][2].d; t2 = pz*(gi+fi)/(gi-pz);
if ((y=fi+(t2-fi*u3.d))==fi+(t2+fi*u3.d)) return (s*y);
t3 = (t2<ZERO) ? -t2 : t2;
if ((y=fi+(t2-(t4=fi*ua3.d+t3*ub3.d)))==fi+(t2+t4)) return (s*y);
/* Second stage */
ffi = xfg[i][3].d;
c1 = z2*(a7.d+z2*(a9.d+z2*a11.d));
EMULV(z,z,z2,zz2,t1,t2,t3,t4,t5)
ADD2(a5.d,aa5.d,c1,zero.d,c2,cc2,t1,t2)
MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a3.d,aa3.d,c1,cc1,c2,cc2,t1,t2)
MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(z ,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(z ,zero.d,c2,cc2,c1,cc1,t1,t2)
ADD2(fi ,ffi,c1,cc1,c2,cc2,t1,t2)
MUL2(fi ,ffi,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8)
SUB2(one.d,zero.d,c3,cc3,c1,cc1,t1,t2)
DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
if ((y=c3+(cc3-u4.d*c3))==c3+(cc3+u4.d*c3)) return (s*y);
return tanMp(x);
}
/* (---) The case 0.787 < abs(x) <= 25 */
if (w<=g4.d) {
/* Range reduction by algorithm i */
t = (x*hpinv.d + toint.d);
xn = t - toint.d;
v.d = t;
t1 = (x - xn*mp1.d) - xn*mp2.d;
n =v.i[LOW_HALF] & 0x00000001;
da = xn*mp3.d;
a=t1-da;
da = (t1-a)-da;
if (a<ZERO) {ya=-a; yya=-da; sy=MONE;}
else {ya= a; yya= da; sy= ONE;}
/* (IV),(V) The case 0.787 < abs(x) <= 25, abs(y) <= 1e-7 */
if (ya<=gy1.d) return tanMp(x);
/* (VI) The case 0.787 < abs(x) <= 25, 1e-7 < abs(y) <= 0.0608 */
if (ya<=gy2.d) {
a2 = a*a;
t2 = da+a*a2*(d3.d+a2*(d5.d+a2*(d7.d+a2*(d9.d+a2*d11.d))));
if (n) {
/* First stage -cot */
EADD(a,t2,b,db)
DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
if ((y=c+(dc-u6.d*c))==c+(dc+u6.d*c)) return (-y); }
else {
/* First stage tan */
if ((y=a+(t2-u5.d*a))==a+(t2+u5.d*a)) return y; }
/* Second stage */
/* Range reduction by algorithm ii */
t = (x*hpinv.d + toint.d);
xn = t - toint.d;
v.d = t;
t1 = (x - xn*mp1.d) - xn*mp2.d;
n =v.i[LOW_HALF] & 0x00000001;
da = xn*pp3.d;
t=t1-da;
da = (t1-t)-da;
t1 = xn*pp4.d;
a = t - t1;
da = ((t-a)-t1)+da;
/* Second stage */
EADD(a,da,t1,t2) a=t1; da=t2;
MUL2(a,da,a,da,x2,xx2,t1,t2,t3,t4,t5,t6,t7,t8)
c1 = x2*(a15.d+x2*(a17.d+x2*(a19.d+x2*(a21.d+x2*(a23.d+x2*(a25.d+
x2*a27.d))))));
ADD2(a13.d,aa13.d,c1,zero.d,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a11.d,aa11.d,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a9.d ,aa9.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a7.d ,aa7.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a5.d ,aa5.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a3.d ,aa3.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(a ,da ,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a ,da ,c2,cc2,c1,cc1,t1,t2)
if (n) {
/* Second stage -cot */
DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
if ((y=c2+(cc2-u8.d*c2)) == c2+(cc2+u8.d*c2)) return (-y); }
else {
/* Second stage tan */
if ((y=c1+(cc1-u7.d*c1)) == c1+(cc1+u7.d*c1)) return y; }
return tanMp(x);
}
/* (VII) The case 0.787 < abs(x) <= 25, 0.0608 < abs(y) <= 0.787 */
/* First stage */
i = ((int) (mfftnhf.d+TWO8*ya));
z = (z0=(ya-xfg[i][0].d))+yya; z2 = z*z;
pz = z+z*z2*(e0.d+z2*e1.d);
fi = xfg[i][1].d; gi = xfg[i][2].d;
if (n) {
/* -cot */
t2 = pz*(fi+gi)/(fi+pz);
if ((y=gi-(t2-gi*u10.d))==gi-(t2+gi*u10.d)) return (-sy*y);
t3 = (t2<ZERO) ? -t2 : t2;
if ((y=gi-(t2-(t4=gi*ua10.d+t3*ub10.d)))==gi-(t2+t4)) return (-sy*y); }
else {
/* tan */
t2 = pz*(gi+fi)/(gi-pz);
if ((y=fi+(t2-fi*u9.d))==fi+(t2+fi*u9.d)) return (sy*y);
t3 = (t2<ZERO) ? -t2 : t2;
if ((y=fi+(t2-(t4=fi*ua9.d+t3*ub9.d)))==fi+(t2+t4)) return (sy*y); }
/* Second stage */
ffi = xfg[i][3].d;
EADD(z0,yya,z,zz)
MUL2(z,zz,z,zz,z2,zz2,t1,t2,t3,t4,t5,t6,t7,t8)
c1 = z2*(a7.d+z2*(a9.d+z2*a11.d));
ADD2(a5.d,aa5.d,c1,zero.d,c2,cc2,t1,t2)
MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a3.d,aa3.d,c1,cc1,c2,cc2,t1,t2)
MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(z ,zz ,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(z ,zz ,c2,cc2,c1,cc1,t1,t2)
ADD2(fi ,ffi,c1,cc1,c2,cc2,t1,t2)
MUL2(fi ,ffi,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8)
SUB2(one.d,zero.d,c3,cc3,c1,cc1,t1,t2)
if (n) {
/* -cot */
DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
if ((y=c3+(cc3-u12.d*c3))==c3+(cc3+u12.d*c3)) return (-sy*y); }
else {
/* tan */
DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
if ((y=c3+(cc3-u11.d*c3))==c3+(cc3+u11.d*c3)) return (sy*y); }
return tanMp(x);
}
/* (---) The case 25 < abs(x) <= 1e8 */
if (w<=g5.d) {
/* Range reduction by algorithm ii */
t = (x*hpinv.d + toint.d);
xn = t - toint.d;
v.d = t;
t1 = (x - xn*mp1.d) - xn*mp2.d;
n =v.i[LOW_HALF] & 0x00000001;
da = xn*pp3.d;
t=t1-da;
da = (t1-t)-da;
t1 = xn*pp4.d;
a = t - t1;
da = ((t-a)-t1)+da;
EADD(a,da,t1,t2) a=t1; da=t2;
if (a<ZERO) {ya=-a; yya=-da; sy=MONE;}
else {ya= a; yya= da; sy= ONE;}
/* (+++) The case 25 < abs(x) <= 1e8, abs(y) <= 1e-7 */
if (ya<=gy1.d) return tanMp(x);
/* (VIII) The case 25 < abs(x) <= 1e8, 1e-7 < abs(y) <= 0.0608 */
if (ya<=gy2.d) {
a2 = a*a;
t2 = da+a*a2*(d3.d+a2*(d5.d+a2*(d7.d+a2*(d9.d+a2*d11.d))));
if (n) {
/* First stage -cot */
EADD(a,t2,b,db)
DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
if ((y=c+(dc-u14.d*c))==c+(dc+u14.d*c)) return (-y); }
else {
/* First stage tan */
if ((y=a+(t2-u13.d*a))==a+(t2+u13.d*a)) return y; }
/* Second stage */
MUL2(a,da,a,da,x2,xx2,t1,t2,t3,t4,t5,t6,t7,t8)
c1 = x2*(a15.d+x2*(a17.d+x2*(a19.d+x2*(a21.d+x2*(a23.d+x2*(a25.d+
x2*a27.d))))));
ADD2(a13.d,aa13.d,c1,zero.d,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a11.d,aa11.d,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a9.d ,aa9.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a7.d ,aa7.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a5.d ,aa5.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a3.d ,aa3.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(a ,da ,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a ,da ,c2,cc2,c1,cc1,t1,t2)
if (n) {
/* Second stage -cot */
DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
if ((y=c2+(cc2-u16.d*c2)) == c2+(cc2+u16.d*c2)) return (-y); }
else {
/* Second stage tan */
if ((y=c1+(cc1-u15.d*c1)) == c1+(cc1+u15.d*c1)) return (y); }
return tanMp(x);
}
/* (IX) The case 25 < abs(x) <= 1e8, 0.0608 < abs(y) <= 0.787 */
/* First stage */
i = ((int) (mfftnhf.d+TWO8*ya));
z = (z0=(ya-xfg[i][0].d))+yya; z2 = z*z;
pz = z+z*z2*(e0.d+z2*e1.d);
fi = xfg[i][1].d; gi = xfg[i][2].d;
if (n) {
/* -cot */
t2 = pz*(fi+gi)/(fi+pz);
if ((y=gi-(t2-gi*u18.d))==gi-(t2+gi*u18.d)) return (-sy*y);
t3 = (t2<ZERO) ? -t2 : t2;
if ((y=gi-(t2-(t4=gi*ua18.d+t3*ub18.d)))==gi-(t2+t4)) return (-sy*y); }
else {
/* tan */
t2 = pz*(gi+fi)/(gi-pz);
if ((y=fi+(t2-fi*u17.d))==fi+(t2+fi*u17.d)) return (sy*y);
t3 = (t2<ZERO) ? -t2 : t2;
if ((y=fi+(t2-(t4=fi*ua17.d+t3*ub17.d)))==fi+(t2+t4)) return (sy*y); }
/* Second stage */
ffi = xfg[i][3].d;
EADD(z0,yya,z,zz)
MUL2(z,zz,z,zz,z2,zz2,t1,t2,t3,t4,t5,t6,t7,t8)
c1 = z2*(a7.d+z2*(a9.d+z2*a11.d));
ADD2(a5.d,aa5.d,c1,zero.d,c2,cc2,t1,t2)
MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a3.d,aa3.d,c1,cc1,c2,cc2,t1,t2)
MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(z ,zz ,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(z ,zz ,c2,cc2,c1,cc1,t1,t2)
ADD2(fi ,ffi,c1,cc1,c2,cc2,t1,t2)
MUL2(fi ,ffi,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8)
SUB2(one.d,zero.d,c3,cc3,c1,cc1,t1,t2)
if (n) {
/* -cot */
DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
if ((y=c3+(cc3-u20.d*c3))==c3+(cc3+u20.d*c3)) return (-sy*y); }
else {
/* tan */
DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
if ((y=c3+(cc3-u19.d*c3))==c3+(cc3+u19.d*c3)) return (sy*y); }
return tanMp(x);
}
/* (---) The case 1e8 < abs(x) < 2**1024 */
/* Range reduction by algorithm iii */
n = (branred(x,&a,&da)) & 0x00000001;
EADD(a,da,t1,t2) a=t1; da=t2;
if (a<ZERO) {ya=-a; yya=-da; sy=MONE;}
else {ya= a; yya= da; sy= ONE;}
/* (+++) The case 1e8 < abs(x) < 2**1024, abs(y) <= 1e-7 */
if (ya<=gy1.d) return tanMp(x);
/* (X) The case 1e8 < abs(x) < 2**1024, 1e-7 < abs(y) <= 0.0608 */
if (ya<=gy2.d) {
a2 = a*a;
t2 = da+a*a2*(d3.d+a2*(d5.d+a2*(d7.d+a2*(d9.d+a2*d11.d))));
if (n) {
/* First stage -cot */
EADD(a,t2,b,db)
DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
if ((y=c+(dc-u22.d*c))==c+(dc+u22.d*c)) return (-y); }
else {
/* First stage tan */
if ((y=a+(t2-u21.d*a))==a+(t2+u21.d*a)) return y; }
/* Second stage */
/* Reduction by algorithm iv */
p=10; n = (mpranred(x,&mpa,p)) & 0x00000001;
mp_dbl(&mpa,&a,p); dbl_mp(a,&mpt1,p);
sub(&mpa,&mpt1,&mpt2,p); mp_dbl(&mpt2,&da,p);
MUL2(a,da,a,da,x2,xx2,t1,t2,t3,t4,t5,t6,t7,t8)
c1 = x2*(a15.d+x2*(a17.d+x2*(a19.d+x2*(a21.d+x2*(a23.d+x2*(a25.d+
x2*a27.d))))));
ADD2(a13.d,aa13.d,c1,zero.d,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a11.d,aa11.d,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a9.d ,aa9.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a7.d ,aa7.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a5.d ,aa5.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a3.d ,aa3.d ,c1,cc1,c2,cc2,t1,t2)
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(a ,da ,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a ,da ,c2,cc2,c1,cc1,t1,t2)
if (n) {
/* Second stage -cot */
DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
if ((y=c2+(cc2-u24.d*c2)) == c2+(cc2+u24.d*c2)) return (-y); }
else {
/* Second stage tan */
if ((y=c1+(cc1-u23.d*c1)) == c1+(cc1+u23.d*c1)) return y; }
return tanMp(x);
}
/* (XI) The case 1e8 < abs(x) < 2**1024, 0.0608 < abs(y) <= 0.787 */
/* First stage */
i = ((int) (mfftnhf.d+TWO8*ya));
z = (z0=(ya-xfg[i][0].d))+yya; z2 = z*z;
pz = z+z*z2*(e0.d+z2*e1.d);
fi = xfg[i][1].d; gi = xfg[i][2].d;
if (n) {
/* -cot */
t2 = pz*(fi+gi)/(fi+pz);
if ((y=gi-(t2-gi*u26.d))==gi-(t2+gi*u26.d)) return (-sy*y);
t3 = (t2<ZERO) ? -t2 : t2;
if ((y=gi-(t2-(t4=gi*ua26.d+t3*ub26.d)))==gi-(t2+t4)) return (-sy*y); }
else {
/* tan */
t2 = pz*(gi+fi)/(gi-pz);
if ((y=fi+(t2-fi*u25.d))==fi+(t2+fi*u25.d)) return (sy*y);
t3 = (t2<ZERO) ? -t2 : t2;
if ((y=fi+(t2-(t4=fi*ua25.d+t3*ub25.d)))==fi+(t2+t4)) return (sy*y); }
/* Second stage */
ffi = xfg[i][3].d;
EADD(z0,yya,z,zz)
MUL2(z,zz,z,zz,z2,zz2,t1,t2,t3,t4,t5,t6,t7,t8)
c1 = z2*(a7.d+z2*(a9.d+z2*a11.d));
ADD2(a5.d,aa5.d,c1,zero.d,c2,cc2,t1,t2)
MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(a3.d,aa3.d,c1,cc1,c2,cc2,t1,t2)
MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(z ,zz ,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(z ,zz ,c2,cc2,c1,cc1,t1,t2)
ADD2(fi ,ffi,c1,cc1,c2,cc2,t1,t2)
MUL2(fi ,ffi,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8)
SUB2(one.d,zero.d,c3,cc3,c1,cc1,t1,t2)
if (n) {
/* -cot */
DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
if ((y=c3+(cc3-u28.d*c3))==c3+(cc3+u28.d*c3)) return (-sy*y); }
else {
/* tan */
DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
if ((y=c3+(cc3-u27.d*c3))==c3+(cc3+u27.d*c3)) return (sy*y); }
return tanMp(x);
}
weak_alias (__tan, tan)
/* multiple precision stage */
/* Convert x to multi precision number,compute tan(x) by mptan() routine */
/* and converts result back to double */
static double tanMp(double x)
{
int p;
double y;
mp_no mpy;
p=32;
__mptan(x, &mpy, p);
__mp_dbl(&mpy,&y,p);
return y;
}
#ifdef NO_LONG_DOUBLE
strong_alias (__tan, __tanl)
weak_alias (__tan, tanl)
weak_alias (tan, tanl)
#endif

View File

@ -0,0 +1,892 @@
/****************************************************************/
/* TABLES FOR THE usin() and ucos() FUNCTION */
/****************************************************************/
#ifdef BIG_ENDI
static const union {int4 i[880]; double x[40];}sincos = {
/**/ 0x00000000, 0x00000000,
/**/ 0x00000000, 0x00000000,
/**/ 0x3FF00000, 0x00000000,
/**/ 0x00000000, 0x00000000,
/**/ 0x3F7FFFEA, 0xAAAEEEEF,
/**/ 0xBC1E45E2, 0xEC67B77C,
/**/ 0x3FEFFFC0, 0x00155552,
/**/ 0x3C8F4A01, 0xA0196DAE,
/**/ 0x3F8FFFAA, 0xAAEEEED5,
/**/ 0xBC02AB63, 0x9A9F0777,
/**/ 0x3FEFFF00, 0x0155549F,
/**/ 0x3C828A28, 0xA03A5EF3,
/**/ 0x3F97FF70, 0x01033255,
/**/ 0x3BFEFE2B, 0x51527336,
/**/ 0x3FEFFDC0, 0x06BFF7E6,
/**/ 0x3C8AE6DA, 0xE86977BD,
/**/ 0x3F9FFEAA, 0xAEEEE86F,
/**/ 0xBC3CD406, 0xFB224AE2,
/**/ 0x3FEFFC00, 0x155527D3,
/**/ 0xBC83B544, 0x92D89B5B,
/**/ 0x3FA3FEB2, 0xB12D45D5,
/**/ 0x3C34EC54, 0x203D1C11,
/**/ 0x3FEFF9C0, 0x3414A7BA,
/**/ 0x3C6991F4, 0xBE6C59BF,
/**/ 0x3FA7FDC0, 0x1032FBA9,
/**/ 0xBC4599BD, 0xF46E997A,
/**/ 0x3FEFF700, 0x6BFDF99F,
/**/ 0xBC78B3B5, 0x60648D5F,
/**/ 0x3FABFC6D, 0x78586DAC,
/**/ 0x3C18E4FD, 0x03DBF236,
/**/ 0x3FEFF3C0, 0xC8103A31,
/**/ 0x3C74856D, 0xBDDC0E66,
/**/ 0x3FAFFAAA, 0xEEED4EDB,
/**/ 0xBC42D16D, 0x32684B69,
/**/ 0x3FEFF001, 0x5549F4D3,
/**/ 0x3C832838, 0x7B99426F,
/**/ 0x3FB1FC34, 0x3D808BEF,
/**/ 0xBC5F3D32, 0xE6F3BE4F,
/**/ 0x3FEFEBC2, 0x22A8EF9F,
/**/ 0x3C579349, 0x34F54C77,
/**/ 0x3FB3FACB, 0x12D1755B,
/**/ 0xBC592191, 0x5299468C,
/**/ 0x3FEFE703, 0x4129EF6F,
/**/ 0xBC6CBF43, 0x37C96F97,
/**/ 0x3FB5F911, 0xFD10B737,
/**/ 0xBC50184F, 0x02BE9102,
/**/ 0x3FEFE1C4, 0xC3C873EB,
/**/ 0xBC35A9C9, 0x057C4A02,
/**/ 0x3FB7F701, 0x032550E4,
/**/ 0x3C3AFC2D, 0x1800501A,
/**/ 0x3FEFDC06, 0xBF7E6B9B,
/**/ 0x3C831902, 0xB535F8DB,
/**/ 0x3FB9F490, 0x2D55D1F9,
/**/ 0x3C52696D, 0x7EAC1DC1,
/**/ 0x3FEFD5C9, 0x4B43E000,
/**/ 0xBC62E768, 0xCB4F92F9,
/**/ 0x3FBBF1B7, 0x8568391D,
/**/ 0x3C5E9184, 0x1DEA4CC8,
/**/ 0x3FEFCF0C, 0x800E99B1,
/**/ 0x3C6EA3D7, 0x86D186AC,
/**/ 0x3FBDEE6F, 0x16C1CCE6,
/**/ 0xBC450F8E, 0x2FB71673,
/**/ 0x3FEFC7D0, 0x78D1BC88,
/**/ 0x3C8075D2, 0x447DB685,
/**/ 0x3FBFEAAE, 0xEE86EE36,
/**/ 0xBC4AFCB2, 0xBCC6F03B,
/**/ 0x3FEFC015, 0x527D5BD3,
/**/ 0x3C8B68F3, 0x5094EFB8,
/**/ 0x3FC0F337, 0x8DDD71D1,
/**/ 0x3C6D8468, 0x724F0F9E,
/**/ 0x3FEFB7DB, 0x2BFE0695,
/**/ 0x3C821DAD, 0xF4F65AB1,
/**/ 0x3FC1F0D3, 0xD7AFCEAF,
/**/ 0xBC66EF95, 0x099769A5,
/**/ 0x3FEFAF22, 0x263C4BD3,
/**/ 0xBC552ACE, 0x133A2769,
/**/ 0x3FC2EE28, 0x5E4AB88F,
/**/ 0xBC6E4D0F, 0x05DEE058,
/**/ 0x3FEFA5EA, 0x641C36F2,
/**/ 0x3C404DA6, 0xED17CC7C,
/**/ 0x3FC3EB31, 0x2C5D66CB,
/**/ 0x3C647D66, 0x6B66CB91,
/**/ 0x3FEF9C34, 0x0A7CC428,
/**/ 0x3C8C5B6B, 0x063B7462,
/**/ 0x3FC4E7EA, 0x4DC5F27B,
/**/ 0x3C5949DB, 0x2AC072FC,
/**/ 0x3FEF91FF, 0x40374D01,
/**/ 0xBC67D03F, 0x4D3A9E4C,
/**/ 0x3FC5E44F, 0xCFA126F3,
/**/ 0xBC66F443, 0x063F89B6,
/**/ 0x3FEF874C, 0x2E1EECF6,
/**/ 0xBC8C6514, 0xE1332B16,
/**/ 0x3FC6E05D, 0xC05A4D4C,
/**/ 0xBBD32C5C, 0x8B81C940,
/**/ 0x3FEF7C1A, 0xFEFFDE24,
/**/ 0xBC78F55B, 0xC47540B1,
/**/ 0x3FC7DC10, 0x2FBAF2B5,
/**/ 0x3C45AB50, 0xE23C97C3,
/**/ 0x3FEF706B, 0xDF9ECE1C,
/**/ 0xBC8698C8, 0x0C36DCB4,
/**/ 0x3FC8D763, 0x2EFAA944,
/**/ 0xBC620FA2, 0x62CBB953,
/**/ 0x3FEF643E, 0xFEB82ACD,
/**/ 0x3C76B00A, 0xC1FE28AC,
/**/ 0x3FC9D252, 0xD0CEC312,
/**/ 0x3C59C43D, 0x80B1137D,
/**/ 0x3FEF5794, 0x8CFF6797,
/**/ 0x3C6E3A0D, 0x3E03B1D5,
/**/ 0x3FCACCDB, 0x297A0765,
/**/ 0xBC59883B, 0x57D6CDEB,
/**/ 0x3FEF4A6C, 0xBD1E3A79,
/**/ 0x3C813DF0, 0xEDAEBB57,
/**/ 0x3FCBC6F8, 0x4EDC6199,
/**/ 0x3C69C1A5, 0x6A7B0CAB,
/**/ 0x3FEF3CC7, 0xC3B3D16E,
/**/ 0xBC621A3A, 0xD28A3494,
/**/ 0x3FCCC0A6, 0x588289A3,
/**/ 0xBC6868D0, 0x9BC87C6B,
/**/ 0x3FEF2EA5, 0xD753FFED,
/**/ 0x3C8CC421, 0x5F56D583,
/**/ 0x3FCDB9E1, 0x5FB5A5D0,
/**/ 0xBC632E20, 0xD6CC6FC2,
/**/ 0x3FEF2007, 0x3086649F,
/**/ 0x3C7B9404, 0x16C1984B,
/**/ 0x3FCEB2A5, 0x7F8AE5A3,
/**/ 0xBC60BE06, 0xAF572CEB,
/**/ 0x3FEF10EC, 0x09C5873B,
/**/ 0x3C8D9072, 0x762C1283,
/**/ 0x3FCFAAEE, 0xD4F31577,
/**/ 0xBC615D88, 0x508E32B8,
/**/ 0x3FEF0154, 0x9F7DEEA1,
/**/ 0x3C8D3C1E, 0x99E5CAFD,
/**/ 0x3FD0515C, 0xBF65155C,
/**/ 0xBC79B8C2, 0x9DFD8EC8,
/**/ 0x3FEEF141, 0x300D2F26,
/**/ 0xBC82AA1B, 0x08DED372,
/**/ 0x3FD0CD00, 0xCEF36436,
/**/ 0xBC79FB0A, 0x0C93E2B5,
/**/ 0x3FEEE0B1, 0xFBC0F11C,
/**/ 0xBC4BFD23, 0x80BBC3B1,
/**/ 0x3FD14861, 0xAA94DDEB,
/**/ 0xBC6BE881, 0xB5B615A4,
/**/ 0x3FEECFA7, 0x44D5EFA1,
/**/ 0xBC556D0A, 0x4AF541D0,
/**/ 0x3FD1C37D, 0x64C6B876,
/**/ 0x3C746076, 0xFE0DCFF5,
/**/ 0x3FEEBE21, 0x4F76EFA8,
/**/ 0xBC802F9F, 0x12BA543E,
/**/ 0x3FD23E52, 0x111AAF36,
/**/ 0xBC74F080, 0x334EFF18,
/**/ 0x3FEEAC20, 0x61BBAF4F,
/**/ 0x3C62C1D5, 0x3E94658D,
/**/ 0x3FD2B8DD, 0xC43EB49F,
/**/ 0x3C615538, 0x99F2D807,
/**/ 0x3FEE99A4, 0xC3A7CD83,
/**/ 0xBC82264B, 0x1BC53CE8,
/**/ 0x3FD3331E, 0x94049F87,
/**/ 0x3C7E0CB6, 0xB40C302C,
/**/ 0x3FEE86AE, 0xBF29A9ED,
/**/ 0x3C89397A, 0xFDBB58A7,
/**/ 0x3FD3AD12, 0x9769D3D8,
/**/ 0x3C003D55, 0x04878398,
/**/ 0x3FEE733E, 0xA0193D40,
/**/ 0xBC86428B, 0x3546CE13,
/**/ 0x3FD426B7, 0xE69EE697,
/**/ 0xBC7F09C7, 0x5705C59F,
/**/ 0x3FEE5F54, 0xB436E9D0,
/**/ 0x3C87EB0F, 0xD02FC8BC,
/**/ 0x3FD4A00C, 0x9B0F3D20,
/**/ 0x3C7823BA, 0x6BB08EAD,
/**/ 0x3FEE4AF1, 0x4B2A449C,
/**/ 0xBC868CA0, 0x2E8A6833,
/**/ 0x3FD5190E, 0xCF68A77A,
/**/ 0x3C7B3571, 0x55EEF0F3,
/**/ 0x3FEE3614, 0xB680D6A5,
/**/ 0xBC727793, 0xAA015237,
/**/ 0x3FD591BC, 0x9FA2F597,
/**/ 0x3C67C74B, 0xAC3FE0CB,
/**/ 0x3FEE20BF, 0x49ACD6C1,
/**/ 0xBC5660AE, 0xC7EF636C,
/**/ 0x3FD60A14, 0x29078775,
/**/ 0x3C5B1FD8, 0x0BA89133,
/**/ 0x3FEE0AF1, 0x5A03DBCE,
/**/ 0x3C5FE8E7, 0x02771AE6,
/**/ 0x3FD68213, 0x8A38D7F7,
/**/ 0xBC7D8892, 0x02444AAD,
/**/ 0x3FEDF4AB, 0x3EBD875E,
/**/ 0xBC8E2D8A, 0x7E6736C4,
/**/ 0x3FD6F9B8, 0xE33A0255,
/**/ 0x3C742BC1, 0x4EE9DA0D,
/**/ 0x3FEDDDED, 0x50F228D6,
/**/ 0xBC6E80C8, 0xD42BA2BF,
/**/ 0x3FD77102, 0x55764214,
/**/ 0xBC66EAD7, 0x314BB6CE,
/**/ 0x3FEDC6B7, 0xEB995912,
/**/ 0x3C54B364, 0x776DCD35,
/**/ 0x3FD7E7EE, 0x03C86D4E,
/**/ 0xBC7B63BC, 0xDABF5AF2,
/**/ 0x3FEDAF0B, 0x6B888E83,
/**/ 0x3C8A249E, 0x2B5E5CEA,
/**/ 0x3FD85E7A, 0x12826949,
/**/ 0x3C78A40E, 0x9B5FACE0,
/**/ 0x3FED96E8, 0x2F71A9DC,
/**/ 0x3C8FF61B, 0xD5D2039D,
/**/ 0x3FD8D4A4, 0xA774992F,
/**/ 0x3C744A02, 0xEA766326,
/**/ 0x3FED7E4E, 0x97E17B4A,
/**/ 0xBC63B770, 0x352BED94,
/**/ 0x3FD94A6B, 0xE9F546C5,
/**/ 0xBC769CE1, 0x3E683F58,
/**/ 0x3FED653F, 0x073E4040,
/**/ 0xBC876236, 0x434BEC37,
/**/ 0x3FD9BFCE, 0x02E80510,
/**/ 0x3C709E39, 0xA320B0A4,
/**/ 0x3FED4BB9, 0xE1C619E0,
/**/ 0x3C8F34BB, 0x77858F61,
/**/ 0x3FDA34C9, 0x1CC50CCA,
/**/ 0xBC5A310E, 0x3B50CECD,
/**/ 0x3FED31BF, 0x8D8D7C06,
/**/ 0x3C7E60DD, 0x3089CBDD,
/**/ 0x3FDAA95B, 0x63A09277,
/**/ 0xBC66293E, 0xB13C0381,
/**/ 0x3FED1750, 0x727D94F0,
/**/ 0x3C80D52B, 0x1EC1A48E,
/**/ 0x3FDB1D83, 0x05321617,
/**/ 0xBC7AE242, 0xCB99F519,
/**/ 0x3FECFC6C, 0xFA52AD9F,
/**/ 0x3C88B5B5, 0x508F2A0D,
/**/ 0x3FDB913E, 0x30DBAC43,
/**/ 0xBC7E38AD, 0x2F6C3FF1,
/**/ 0x3FECE115, 0x909A82E5,
/**/ 0x3C81F139, 0xBB31109A,
/**/ 0x3FDC048B, 0x17B140A3,
/**/ 0x3C619FE6, 0x757E9FA7,
/**/ 0x3FECC54A, 0xA2B2972E,
/**/ 0x3C64EE16, 0x2BA83A98,
/**/ 0x3FDC7767, 0xEC7FD19E,
/**/ 0xBC5EB14D, 0x1A3D5826,
/**/ 0x3FECA90C, 0x9FC67D0B,
/**/ 0xBC646A81, 0x485E3462,
/**/ 0x3FDCE9D2, 0xE3D4A51F,
/**/ 0xBC62FC8A, 0x12DAE298,
/**/ 0x3FEC8C5B, 0xF8CE1A84,
/**/ 0x3C7AB3D1, 0xA1590123,
/**/ 0x3FDD5BCA, 0x34047661,
/**/ 0x3C728A44, 0xA75FC29C,
/**/ 0x3FEC6F39, 0x208BE53B,
/**/ 0xBC8741DB, 0xFBAADB42,
/**/ 0x3FDDCD4C, 0x15329C9A,
/**/ 0x3C70D4C6, 0xE171FD9A,
/**/ 0x3FEC51A4, 0x8B8B175E,
/**/ 0xBC61BBB4, 0x3B9AA880,
/**/ 0x3FDE3E56, 0xC1582A69,
/**/ 0xBC50A482, 0x1099F88F,
/**/ 0x3FEC339E, 0xB01DDD81,
/**/ 0xBC8CAAF5, 0xEE82C5C0,
/**/ 0x3FDEAEE8, 0x744B05F0,
/**/ 0xBC5789B4, 0x3C9B027D,
/**/ 0x3FEC1528, 0x065B7D50,
/**/ 0xBC889211, 0x1312E828,
/**/ 0x3FDF1EFF, 0x6BC4F97B,
/**/ 0x3C717212, 0xF8A7525C,
/**/ 0x3FEBF641, 0x081E7536,
/**/ 0x3C8B7BD7, 0x1628A9A1,
/**/ 0x3FDF8E99, 0xE76ABC97,
/**/ 0x3C59D950, 0xAF2D00A3,
/**/ 0x3FEBD6EA, 0x310294F5,
/**/ 0x3C731BBC, 0xC88C109D,
/**/ 0x3FDFFDB6, 0x28D2F57A,
/**/ 0x3C6F4A99, 0x2E905B6A,
/**/ 0x3FEBB723, 0xFE630F32,
/**/ 0x3C772BD2, 0x452D0A39,
/**/ 0x3FE03629, 0x39C69955,
/**/ 0xBC82D8CD, 0x78397B01,
/**/ 0x3FEB96EE, 0xEF58840E,
/**/ 0x3C545A3C, 0xC78FADE0,
/**/ 0x3FE06D36, 0x86946E5B,
/**/ 0x3C83F5AE, 0x4538FF1B,
/**/ 0x3FEB764B, 0x84B704C2,
/**/ 0xBC8F5848, 0xC21B389B,
/**/ 0x3FE0A402, 0x1E9E1001,
/**/ 0xBC86F643, 0xA13914F6,
/**/ 0x3FEB553A, 0x410C104E,
/**/ 0x3C58FF79, 0x47027A16,
/**/ 0x3FE0DA8B, 0x26B5672E,
/**/ 0xBC8A58DE, 0xF0BEE909,
/**/ 0x3FEB33BB, 0xA89C8948,
/**/ 0x3C8EA6A5, 0x1D1F6CA9,
/**/ 0x3FE110D0, 0xC4B69C3B,
/**/ 0x3C8D9189, 0x98809981,
/**/ 0x3FEB11D0, 0x4162A4C6,
/**/ 0x3C71DD56, 0x1EFBC0C2,
/**/ 0x3FE146D2, 0x1F8B7F82,
/**/ 0x3C7BF953, 0x5E2739A8,
/**/ 0x3FEAEF78, 0x930BD275,
/**/ 0xBC7F8362, 0x79746F94,
/**/ 0x3FE17C8E, 0x5F2EEDB0,
/**/ 0x3C635E57, 0x102E2488,
/**/ 0x3FEACCB5, 0x26F69DE5,
/**/ 0x3C88FB6A, 0x8DD6B6CC,
/**/ 0x3FE1B204, 0xACB02FDD,
/**/ 0xBC5F190C, 0x70CBB5FF,
/**/ 0x3FEAA986, 0x88308913,
/**/ 0xBC0B83D6, 0x07CD5070,
/**/ 0x3FE1E734, 0x3236574C,
/**/ 0x3C722A3F, 0xA4F41D5A,
/**/ 0x3FEA85ED, 0x4373E02D,
/**/ 0x3C69BE06, 0x385EC792,
/**/ 0x3FE21C1C, 0x1B0394CF,
/**/ 0x3C5E5B32, 0x4B23AA31,
/**/ 0x3FEA61E9, 0xE72586AF,
/**/ 0x3C858330, 0xE2FD453F,
/**/ 0x3FE250BB, 0x93788BBB,
/**/ 0x3C7EA3D0, 0x2457BCCE,
/**/ 0x3FEA3D7D, 0x0352BDCF,
/**/ 0xBC868DBA, 0xECA19669,
/**/ 0x3FE28511, 0xC917A067,
/**/ 0xBC801DF1, 0xD9A16B70,
/**/ 0x3FEA18A7, 0x29AEE445,
/**/ 0x3C395E25, 0x736C0358,
/**/ 0x3FE2B91D, 0xEA88421E,
/**/ 0xBC8FA371, 0xDB216AB0,
/**/ 0x3FE9F368, 0xED912F85,
/**/ 0xBC81D200, 0xC5791606,
/**/ 0x3FE2ECDF, 0x279A3082,
/**/ 0x3C8D3557, 0xE0E7E37E,
/**/ 0x3FE9CDC2, 0xE3F25E5C,
/**/ 0x3C83F991, 0x12993F62,
/**/ 0x3FE32054, 0xB148BC4F,
/**/ 0x3C8F6B42, 0x095A135B,
/**/ 0x3FE9A7B5, 0xA36A6514,
/**/ 0x3C8722CF, 0xCC9FA7A9,
/**/ 0x3FE3537D, 0xB9BE0367,
/**/ 0x3C6B327E, 0x7AF040F0,
/**/ 0x3FE98141, 0xC42E1310,
/**/ 0x3C8D1FF8, 0x0488F08D,
/**/ 0x3FE38659, 0x7456282B,
/**/ 0xBC710FAD, 0xA93B07A8,
/**/ 0x3FE95A67, 0xE00CB1FD,
/**/ 0xBC80BEFD, 0xA21F862D,
/**/ 0x3FE3B8E7, 0x15A2840A,
/**/ 0xBC797653, 0xA7D2F07B,
/**/ 0x3FE93328, 0x926D9E92,
/**/ 0xBC8BB770, 0x03600CDA,
/**/ 0x3FE3EB25, 0xD36CD53A,
/**/ 0xBC5BE570, 0xE1570FC0,
/**/ 0x3FE90B84, 0x784DDAF7,
/**/ 0xBC70FEB1, 0x0AB93B87,
/**/ 0x3FE41D14, 0xE4BA6790,
/**/ 0x3C84608F, 0xD287ECF5,
/**/ 0x3FE8E37C, 0x303D9AD1,
/**/ 0xBC6463A4, 0xB53D4BF8,
/**/ 0x3FE44EB3, 0x81CF386B,
/**/ 0xBC83ED6C, 0x1E6A5505,
/**/ 0x3FE8BB10, 0x5A5DC900,
/**/ 0x3C8863E0, 0x3E9474C1,
/**/ 0x3FE48000, 0xE431159F,
/**/ 0xBC8B194A, 0x7463ED10,
/**/ 0x3FE89241, 0x985D871F,
/**/ 0x3C8C48D9, 0xC413ED84,
/**/ 0x3FE4B0FC, 0x46AAB761,
/**/ 0x3C20DA05, 0x738CC59A,
/**/ 0x3FE86910, 0x8D77A6C6,
/**/ 0x3C7338FF, 0xE2BFE9DD,
/**/ 0x3FE4E1A4, 0xE54ED51B,
/**/ 0xBC8A492F, 0x89B7C76A,
/**/ 0x3FE83F7D, 0xDE701CA0,
/**/ 0xBC4152CF, 0x609BC6E8,
/**/ 0x3FE511F9, 0xFD7B351C,
/**/ 0xBC85C0E8, 0x61C48831,
/**/ 0x3FE8158A, 0x31916D5D,
/**/ 0xBC6DE8B9, 0x0B8228DE,
/**/ 0x3FE541FA, 0xCDDBB724,
/**/ 0x3C7232C2, 0x8520D391,
/**/ 0x3FE7EB36, 0x2EAA1488,
/**/ 0x3C5A1D65, 0xA4A5959F,
/**/ 0x3FE571A6, 0x966D59B3,
/**/ 0x3C5C843B, 0x4D0FB198,
/**/ 0x3FE7C082, 0x7F09E54F,
/**/ 0xBC6C73D6, 0xD72AEE68,
/**/ 0x3FE5A0FC, 0x98813A12,
/**/ 0xBC8D82E2, 0xB7D4227B,
/**/ 0x3FE7956F, 0xCD7F6543,
/**/ 0xBC8AB276, 0xE9D45AE4,
/**/ 0x3FE5CFFC, 0x16BF8F0D,
/**/ 0x3C896CB3, 0x70EB578A,
/**/ 0x3FE769FE, 0xC655211F,
/**/ 0xBC6827D5, 0xCF8C68C5,
/**/ 0x3FE5FEA4, 0x552A9E57,
/**/ 0x3C80B6CE, 0xF7EE20B7,
/**/ 0x3FE73E30, 0x174EFBA1,
/**/ 0xBC65D3AE, 0x3D94AD5F,
/**/ 0x3FE62CF4, 0x9921AC79,
/**/ 0xBC8EDD98, 0x55B6241A,
/**/ 0x3FE71204, 0x6FA77678,
/**/ 0x3C8425B0, 0xA5029C81,
/**/ 0x3FE65AEC, 0x2963E755,
/**/ 0x3C8126F9, 0x6B71053C,
/**/ 0x3FE6E57C, 0x800CF55E,
/**/ 0x3C860286, 0xDEDBD0A6,
/**/ 0x3FE6888A, 0x4E134B2F,
/**/ 0xBC86B7D3, 0x7644D5E6,
/**/ 0x3FE6B898, 0xFA9EFB5D,
/**/ 0x3C715AC7, 0x86CCF4B2,
/**/ 0x3FE6B5CE, 0x50B7821A,
/**/ 0xBC65D515, 0x8F702E0F,
/**/ 0x3FE68B5A, 0x92EB6253,
/**/ 0xBC89A91A, 0xD985F89C,
/**/ 0x3FE6E2B7, 0x7C40BDE1,
/**/ 0xBC70E729, 0x857FAD53,
/**/ 0x3FE65DC1, 0xFDEB8CBA,
/**/ 0xBC597C1B, 0x47337C77,
/**/ 0x3FE70F45, 0x1D0A8C40,
/**/ 0x3C697EDE, 0x3885770D,
/**/ 0x3FE62FCF, 0xF20191C7,
/**/ 0x3C6D9143, 0x895756EF,
/**/ 0x3FE73B76, 0x80DEA578,
/**/ 0xBC722483, 0x06DC12A2,
/**/ 0x3FE60185, 0x26F563DF,
/**/ 0x3C846CA5, 0xE0E432D0,
/**/ 0x3FE7674A, 0xF6F7B524,
/**/ 0x3C7E9D3F, 0x94AC84A8,
/**/ 0x3FE5D2E2, 0x55F1F17A,
/**/ 0x3C803141, 0x04C8892B,
/**/ 0x3FE792C1, 0xD0041D52,
/**/ 0xBC8ABF05, 0xEEB354EB,
/**/ 0x3FE5A3E8, 0x39824077,
/**/ 0x3C8428AA, 0x2759BE62,
/**/ 0x3FE7BDDA, 0x5E28B3C2,
/**/ 0x3C4AD119, 0x7CCD0393,
/**/ 0x3FE57497, 0x8D8E83F2,
/**/ 0x3C8F4714, 0xAF282D23,
/**/ 0x3FE7E893, 0xF5037959,
/**/ 0x3C80EEFB, 0xAA650C4C,
/**/ 0x3FE544F1, 0x0F592CA5,
/**/ 0xBC8E7AE8, 0xE6C7A62F,
/**/ 0x3FE812ED, 0xE9AE4BA4,
/**/ 0xBC87830A, 0xDF402DDA,
/**/ 0x3FE514F5, 0x7D7BF3DA,
/**/ 0x3C747A10, 0x8073C259 };
#else
#ifdef LITTLE_ENDI
static const union {int4 i[880]; double x[440];} sincos = {
/**/ 0x00000000, 0x00000000,
/**/ 0x00000000, 0x00000000,
/**/ 0x00000000, 0x3FF00000,
/**/ 0x00000000, 0x00000000,
/**/ 0xAAAEEEEF, 0x3F7FFFEA,
/**/ 0xEC67B77C, 0xBC1E45E2,
/**/ 0x00155552, 0x3FEFFFC0,
/**/ 0xA0196DAE, 0x3C8F4A01,
/**/ 0xAAEEEED5, 0x3F8FFFAA,
/**/ 0x9A9F0777, 0xBC02AB63,
/**/ 0x0155549F, 0x3FEFFF00,
/**/ 0xA03A5EF3, 0x3C828A28,
/**/ 0x01033255, 0x3F97FF70,
/**/ 0x51527336, 0x3BFEFE2B,
/**/ 0x06BFF7E6, 0x3FEFFDC0,
/**/ 0xE86977BD, 0x3C8AE6DA,
/**/ 0xAEEEE86F, 0x3F9FFEAA,
/**/ 0xFB224AE2, 0xBC3CD406,
/**/ 0x155527D3, 0x3FEFFC00,
/**/ 0x92D89B5B, 0xBC83B544,
/**/ 0xB12D45D5, 0x3FA3FEB2,
/**/ 0x203D1C11, 0x3C34EC54,
/**/ 0x3414A7BA, 0x3FEFF9C0,
/**/ 0xBE6C59BF, 0x3C6991F4,
/**/ 0x1032FBA9, 0x3FA7FDC0,
/**/ 0xF46E997A, 0xBC4599BD,
/**/ 0x6BFDF99F, 0x3FEFF700,
/**/ 0x60648D5F, 0xBC78B3B5,
/**/ 0x78586DAC, 0x3FABFC6D,
/**/ 0x03DBF236, 0x3C18E4FD,
/**/ 0xC8103A31, 0x3FEFF3C0,
/**/ 0xBDDC0E66, 0x3C74856D,
/**/ 0xEEED4EDB, 0x3FAFFAAA,
/**/ 0x32684B69, 0xBC42D16D,
/**/ 0x5549F4D3, 0x3FEFF001,
/**/ 0x7B99426F, 0x3C832838,
/**/ 0x3D808BEF, 0x3FB1FC34,
/**/ 0xE6F3BE4F, 0xBC5F3D32,
/**/ 0x22A8EF9F, 0x3FEFEBC2,
/**/ 0x34F54C77, 0x3C579349,
/**/ 0x12D1755B, 0x3FB3FACB,
/**/ 0x5299468C, 0xBC592191,
/**/ 0x4129EF6F, 0x3FEFE703,
/**/ 0x37C96F97, 0xBC6CBF43,
/**/ 0xFD10B737, 0x3FB5F911,
/**/ 0x02BE9102, 0xBC50184F,
/**/ 0xC3C873EB, 0x3FEFE1C4,
/**/ 0x057C4A02, 0xBC35A9C9,
/**/ 0x032550E4, 0x3FB7F701,
/**/ 0x1800501A, 0x3C3AFC2D,
/**/ 0xBF7E6B9B, 0x3FEFDC06,
/**/ 0xB535F8DB, 0x3C831902,
/**/ 0x2D55D1F9, 0x3FB9F490,
/**/ 0x7EAC1DC1, 0x3C52696D,
/**/ 0x4B43E000, 0x3FEFD5C9,
/**/ 0xCB4F92F9, 0xBC62E768,
/**/ 0x8568391D, 0x3FBBF1B7,
/**/ 0x1DEA4CC8, 0x3C5E9184,
/**/ 0x800E99B1, 0x3FEFCF0C,
/**/ 0x86D186AC, 0x3C6EA3D7,
/**/ 0x16C1CCE6, 0x3FBDEE6F,
/**/ 0x2FB71673, 0xBC450F8E,
/**/ 0x78D1BC88, 0x3FEFC7D0,
/**/ 0x447DB685, 0x3C8075D2,
/**/ 0xEE86EE36, 0x3FBFEAAE,
/**/ 0xBCC6F03B, 0xBC4AFCB2,
/**/ 0x527D5BD3, 0x3FEFC015,
/**/ 0x5094EFB8, 0x3C8B68F3,
/**/ 0x8DDD71D1, 0x3FC0F337,
/**/ 0x724F0F9E, 0x3C6D8468,
/**/ 0x2BFE0695, 0x3FEFB7DB,
/**/ 0xF4F65AB1, 0x3C821DAD,
/**/ 0xD7AFCEAF, 0x3FC1F0D3,
/**/ 0x099769A5, 0xBC66EF95,
/**/ 0x263C4BD3, 0x3FEFAF22,
/**/ 0x133A2769, 0xBC552ACE,
/**/ 0x5E4AB88F, 0x3FC2EE28,
/**/ 0x05DEE058, 0xBC6E4D0F,
/**/ 0x641C36F2, 0x3FEFA5EA,
/**/ 0xED17CC7C, 0x3C404DA6,
/**/ 0x2C5D66CB, 0x3FC3EB31,
/**/ 0x6B66CB91, 0x3C647D66,
/**/ 0x0A7CC428, 0x3FEF9C34,
/**/ 0x063B7462, 0x3C8C5B6B,
/**/ 0x4DC5F27B, 0x3FC4E7EA,
/**/ 0x2AC072FC, 0x3C5949DB,
/**/ 0x40374D01, 0x3FEF91FF,
/**/ 0x4D3A9E4C, 0xBC67D03F,
/**/ 0xCFA126F3, 0x3FC5E44F,
/**/ 0x063F89B6, 0xBC66F443,
/**/ 0x2E1EECF6, 0x3FEF874C,
/**/ 0xE1332B16, 0xBC8C6514,
/**/ 0xC05A4D4C, 0x3FC6E05D,
/**/ 0x8B81C940, 0xBBD32C5C,
/**/ 0xFEFFDE24, 0x3FEF7C1A,
/**/ 0xC47540B1, 0xBC78F55B,
/**/ 0x2FBAF2B5, 0x3FC7DC10,
/**/ 0xE23C97C3, 0x3C45AB50,
/**/ 0xDF9ECE1C, 0x3FEF706B,
/**/ 0x0C36DCB4, 0xBC8698C8,
/**/ 0x2EFAA944, 0x3FC8D763,
/**/ 0x62CBB953, 0xBC620FA2,
/**/ 0xFEB82ACD, 0x3FEF643E,
/**/ 0xC1FE28AC, 0x3C76B00A,
/**/ 0xD0CEC312, 0x3FC9D252,
/**/ 0x80B1137D, 0x3C59C43D,
/**/ 0x8CFF6797, 0x3FEF5794,
/**/ 0x3E03B1D5, 0x3C6E3A0D,
/**/ 0x297A0765, 0x3FCACCDB,
/**/ 0x57D6CDEB, 0xBC59883B,
/**/ 0xBD1E3A79, 0x3FEF4A6C,
/**/ 0xEDAEBB57, 0x3C813DF0,
/**/ 0x4EDC6199, 0x3FCBC6F8,
/**/ 0x6A7B0CAB, 0x3C69C1A5,
/**/ 0xC3B3D16E, 0x3FEF3CC7,
/**/ 0xD28A3494, 0xBC621A3A,
/**/ 0x588289A3, 0x3FCCC0A6,
/**/ 0x9BC87C6B, 0xBC6868D0,
/**/ 0xD753FFED, 0x3FEF2EA5,
/**/ 0x5F56D583, 0x3C8CC421,
/**/ 0x5FB5A5D0, 0x3FCDB9E1,
/**/ 0xD6CC6FC2, 0xBC632E20,
/**/ 0x3086649F, 0x3FEF2007,
/**/ 0x16C1984B, 0x3C7B9404,
/**/ 0x7F8AE5A3, 0x3FCEB2A5,
/**/ 0xAF572CEB, 0xBC60BE06,
/**/ 0x09C5873B, 0x3FEF10EC,
/**/ 0x762C1283, 0x3C8D9072,
/**/ 0xD4F31577, 0x3FCFAAEE,
/**/ 0x508E32B8, 0xBC615D88,
/**/ 0x9F7DEEA1, 0x3FEF0154,
/**/ 0x99E5CAFD, 0x3C8D3C1E,
/**/ 0xBF65155C, 0x3FD0515C,
/**/ 0x9DFD8EC8, 0xBC79B8C2,
/**/ 0x300D2F26, 0x3FEEF141,
/**/ 0x08DED372, 0xBC82AA1B,
/**/ 0xCEF36436, 0x3FD0CD00,
/**/ 0x0C93E2B5, 0xBC79FB0A,
/**/ 0xFBC0F11C, 0x3FEEE0B1,
/**/ 0x80BBC3B1, 0xBC4BFD23,
/**/ 0xAA94DDEB, 0x3FD14861,
/**/ 0xB5B615A4, 0xBC6BE881,
/**/ 0x44D5EFA1, 0x3FEECFA7,
/**/ 0x4AF541D0, 0xBC556D0A,
/**/ 0x64C6B876, 0x3FD1C37D,
/**/ 0xFE0DCFF5, 0x3C746076,
/**/ 0x4F76EFA8, 0x3FEEBE21,
/**/ 0x12BA543E, 0xBC802F9F,
/**/ 0x111AAF36, 0x3FD23E52,
/**/ 0x334EFF18, 0xBC74F080,
/**/ 0x61BBAF4F, 0x3FEEAC20,
/**/ 0x3E94658D, 0x3C62C1D5,
/**/ 0xC43EB49F, 0x3FD2B8DD,
/**/ 0x99F2D807, 0x3C615538,
/**/ 0xC3A7CD83, 0x3FEE99A4,
/**/ 0x1BC53CE8, 0xBC82264B,
/**/ 0x94049F87, 0x3FD3331E,
/**/ 0xB40C302C, 0x3C7E0CB6,
/**/ 0xBF29A9ED, 0x3FEE86AE,
/**/ 0xFDBB58A7, 0x3C89397A,
/**/ 0x9769D3D8, 0x3FD3AD12,
/**/ 0x04878398, 0x3C003D55,
/**/ 0xA0193D40, 0x3FEE733E,
/**/ 0x3546CE13, 0xBC86428B,
/**/ 0xE69EE697, 0x3FD426B7,
/**/ 0x5705C59F, 0xBC7F09C7,
/**/ 0xB436E9D0, 0x3FEE5F54,
/**/ 0xD02FC8BC, 0x3C87EB0F,
/**/ 0x9B0F3D20, 0x3FD4A00C,
/**/ 0x6BB08EAD, 0x3C7823BA,
/**/ 0x4B2A449C, 0x3FEE4AF1,
/**/ 0x2E8A6833, 0xBC868CA0,
/**/ 0xCF68A77A, 0x3FD5190E,
/**/ 0x55EEF0F3, 0x3C7B3571,
/**/ 0xB680D6A5, 0x3FEE3614,
/**/ 0xAA015237, 0xBC727793,
/**/ 0x9FA2F597, 0x3FD591BC,
/**/ 0xAC3FE0CB, 0x3C67C74B,
/**/ 0x49ACD6C1, 0x3FEE20BF,
/**/ 0xC7EF636C, 0xBC5660AE,
/**/ 0x29078775, 0x3FD60A14,
/**/ 0x0BA89133, 0x3C5B1FD8,
/**/ 0x5A03DBCE, 0x3FEE0AF1,
/**/ 0x02771AE6, 0x3C5FE8E7,
/**/ 0x8A38D7F7, 0x3FD68213,
/**/ 0x02444AAD, 0xBC7D8892,
/**/ 0x3EBD875E, 0x3FEDF4AB,
/**/ 0x7E6736C4, 0xBC8E2D8A,
/**/ 0xE33A0255, 0x3FD6F9B8,
/**/ 0x4EE9DA0D, 0x3C742BC1,
/**/ 0x50F228D6, 0x3FEDDDED,
/**/ 0xD42BA2BF, 0xBC6E80C8,
/**/ 0x55764214, 0x3FD77102,
/**/ 0x314BB6CE, 0xBC66EAD7,
/**/ 0xEB995912, 0x3FEDC6B7,
/**/ 0x776DCD35, 0x3C54B364,
/**/ 0x03C86D4E, 0x3FD7E7EE,
/**/ 0xDABF5AF2, 0xBC7B63BC,
/**/ 0x6B888E83, 0x3FEDAF0B,
/**/ 0x2B5E5CEA, 0x3C8A249E,
/**/ 0x12826949, 0x3FD85E7A,
/**/ 0x9B5FACE0, 0x3C78A40E,
/**/ 0x2F71A9DC, 0x3FED96E8,
/**/ 0xD5D2039D, 0x3C8FF61B,
/**/ 0xA774992F, 0x3FD8D4A4,
/**/ 0xEA766326, 0x3C744A02,
/**/ 0x97E17B4A, 0x3FED7E4E,
/**/ 0x352BED94, 0xBC63B770,
/**/ 0xE9F546C5, 0x3FD94A6B,
/**/ 0x3E683F58, 0xBC769CE1,
/**/ 0x073E4040, 0x3FED653F,
/**/ 0x434BEC37, 0xBC876236,
/**/ 0x02E80510, 0x3FD9BFCE,
/**/ 0xA320B0A4, 0x3C709E39,
/**/ 0xE1C619E0, 0x3FED4BB9,
/**/ 0x77858F61, 0x3C8F34BB,
/**/ 0x1CC50CCA, 0x3FDA34C9,
/**/ 0x3B50CECD, 0xBC5A310E,
/**/ 0x8D8D7C06, 0x3FED31BF,
/**/ 0x3089CBDD, 0x3C7E60DD,
/**/ 0x63A09277, 0x3FDAA95B,
/**/ 0xB13C0381, 0xBC66293E,
/**/ 0x727D94F0, 0x3FED1750,
/**/ 0x1EC1A48E, 0x3C80D52B,
/**/ 0x05321617, 0x3FDB1D83,
/**/ 0xCB99F519, 0xBC7AE242,
/**/ 0xFA52AD9F, 0x3FECFC6C,
/**/ 0x508F2A0D, 0x3C88B5B5,
/**/ 0x30DBAC43, 0x3FDB913E,
/**/ 0x2F6C3FF1, 0xBC7E38AD,
/**/ 0x909A82E5, 0x3FECE115,
/**/ 0xBB31109A, 0x3C81F139,
/**/ 0x17B140A3, 0x3FDC048B,
/**/ 0x757E9FA7, 0x3C619FE6,
/**/ 0xA2B2972E, 0x3FECC54A,
/**/ 0x2BA83A98, 0x3C64EE16,
/**/ 0xEC7FD19E, 0x3FDC7767,
/**/ 0x1A3D5826, 0xBC5EB14D,
/**/ 0x9FC67D0B, 0x3FECA90C,
/**/ 0x485E3462, 0xBC646A81,
/**/ 0xE3D4A51F, 0x3FDCE9D2,
/**/ 0x12DAE298, 0xBC62FC8A,
/**/ 0xF8CE1A84, 0x3FEC8C5B,
/**/ 0xA1590123, 0x3C7AB3D1,
/**/ 0x34047661, 0x3FDD5BCA,
/**/ 0xA75FC29C, 0x3C728A44,
/**/ 0x208BE53B, 0x3FEC6F39,
/**/ 0xFBAADB42, 0xBC8741DB,
/**/ 0x15329C9A, 0x3FDDCD4C,
/**/ 0xE171FD9A, 0x3C70D4C6,
/**/ 0x8B8B175E, 0x3FEC51A4,
/**/ 0x3B9AA880, 0xBC61BBB4,
/**/ 0xC1582A69, 0x3FDE3E56,
/**/ 0x1099F88F, 0xBC50A482,
/**/ 0xB01DDD81, 0x3FEC339E,
/**/ 0xEE82C5C0, 0xBC8CAAF5,
/**/ 0x744B05F0, 0x3FDEAEE8,
/**/ 0x3C9B027D, 0xBC5789B4,
/**/ 0x065B7D50, 0x3FEC1528,
/**/ 0x1312E828, 0xBC889211,
/**/ 0x6BC4F97B, 0x3FDF1EFF,
/**/ 0xF8A7525C, 0x3C717212,
/**/ 0x081E7536, 0x3FEBF641,
/**/ 0x1628A9A1, 0x3C8B7BD7,
/**/ 0xE76ABC97, 0x3FDF8E99,
/**/ 0xAF2D00A3, 0x3C59D950,
/**/ 0x310294F5, 0x3FEBD6EA,
/**/ 0xC88C109D, 0x3C731BBC,
/**/ 0x28D2F57A, 0x3FDFFDB6,
/**/ 0x2E905B6A, 0x3C6F4A99,
/**/ 0xFE630F32, 0x3FEBB723,
/**/ 0x452D0A39, 0x3C772BD2,
/**/ 0x39C69955, 0x3FE03629,
/**/ 0x78397B01, 0xBC82D8CD,
/**/ 0xEF58840E, 0x3FEB96EE,
/**/ 0xC78FADE0, 0x3C545A3C,
/**/ 0x86946E5B, 0x3FE06D36,
/**/ 0x4538FF1B, 0x3C83F5AE,
/**/ 0x84B704C2, 0x3FEB764B,
/**/ 0xC21B389B, 0xBC8F5848,
/**/ 0x1E9E1001, 0x3FE0A402,
/**/ 0xA13914F6, 0xBC86F643,
/**/ 0x410C104E, 0x3FEB553A,
/**/ 0x47027A16, 0x3C58FF79,
/**/ 0x26B5672E, 0x3FE0DA8B,
/**/ 0xF0BEE909, 0xBC8A58DE,
/**/ 0xA89C8948, 0x3FEB33BB,
/**/ 0x1D1F6CA9, 0x3C8EA6A5,
/**/ 0xC4B69C3B, 0x3FE110D0,
/**/ 0x98809981, 0x3C8D9189,
/**/ 0x4162A4C6, 0x3FEB11D0,
/**/ 0x1EFBC0C2, 0x3C71DD56,
/**/ 0x1F8B7F82, 0x3FE146D2,
/**/ 0x5E2739A8, 0x3C7BF953,
/**/ 0x930BD275, 0x3FEAEF78,
/**/ 0x79746F94, 0xBC7F8362,
/**/ 0x5F2EEDB0, 0x3FE17C8E,
/**/ 0x102E2488, 0x3C635E57,
/**/ 0x26F69DE5, 0x3FEACCB5,
/**/ 0x8DD6B6CC, 0x3C88FB6A,
/**/ 0xACB02FDD, 0x3FE1B204,
/**/ 0x70CBB5FF, 0xBC5F190C,
/**/ 0x88308913, 0x3FEAA986,
/**/ 0x07CD5070, 0xBC0B83D6,
/**/ 0x3236574C, 0x3FE1E734,
/**/ 0xA4F41D5A, 0x3C722A3F,
/**/ 0x4373E02D, 0x3FEA85ED,
/**/ 0x385EC792, 0x3C69BE06,
/**/ 0x1B0394CF, 0x3FE21C1C,
/**/ 0x4B23AA31, 0x3C5E5B32,
/**/ 0xE72586AF, 0x3FEA61E9,
/**/ 0xE2FD453F, 0x3C858330,
/**/ 0x93788BBB, 0x3FE250BB,
/**/ 0x2457BCCE, 0x3C7EA3D0,
/**/ 0x0352BDCF, 0x3FEA3D7D,
/**/ 0xECA19669, 0xBC868DBA,
/**/ 0xC917A067, 0x3FE28511,
/**/ 0xD9A16B70, 0xBC801DF1,
/**/ 0x29AEE445, 0x3FEA18A7,
/**/ 0x736C0358, 0x3C395E25,
/**/ 0xEA88421E, 0x3FE2B91D,
/**/ 0xDB216AB0, 0xBC8FA371,
/**/ 0xED912F85, 0x3FE9F368,
/**/ 0xC5791606, 0xBC81D200,
/**/ 0x279A3082, 0x3FE2ECDF,
/**/ 0xE0E7E37E, 0x3C8D3557,
/**/ 0xE3F25E5C, 0x3FE9CDC2,
/**/ 0x12993F62, 0x3C83F991,
/**/ 0xB148BC4F, 0x3FE32054,
/**/ 0x095A135B, 0x3C8F6B42,
/**/ 0xA36A6514, 0x3FE9A7B5,
/**/ 0xCC9FA7A9, 0x3C8722CF,
/**/ 0xB9BE0367, 0x3FE3537D,
/**/ 0x7AF040F0, 0x3C6B327E,
/**/ 0xC42E1310, 0x3FE98141,
/**/ 0x0488F08D, 0x3C8D1FF8,
/**/ 0x7456282B, 0x3FE38659,
/**/ 0xA93B07A8, 0xBC710FAD,
/**/ 0xE00CB1FD, 0x3FE95A67,
/**/ 0xA21F862D, 0xBC80BEFD,
/**/ 0x15A2840A, 0x3FE3B8E7,
/**/ 0xA7D2F07B, 0xBC797653,
/**/ 0x926D9E92, 0x3FE93328,
/**/ 0x03600CDA, 0xBC8BB770,
/**/ 0xD36CD53A, 0x3FE3EB25,
/**/ 0xE1570FC0, 0xBC5BE570,
/**/ 0x784DDAF7, 0x3FE90B84,
/**/ 0x0AB93B87, 0xBC70FEB1,
/**/ 0xE4BA6790, 0x3FE41D14,
/**/ 0xD287ECF5, 0x3C84608F,
/**/ 0x303D9AD1, 0x3FE8E37C,
/**/ 0xB53D4BF8, 0xBC6463A4,
/**/ 0x81CF386B, 0x3FE44EB3,
/**/ 0x1E6A5505, 0xBC83ED6C,
/**/ 0x5A5DC900, 0x3FE8BB10,
/**/ 0x3E9474C1, 0x3C8863E0,
/**/ 0xE431159F, 0x3FE48000,
/**/ 0x7463ED10, 0xBC8B194A,
/**/ 0x985D871F, 0x3FE89241,
/**/ 0xC413ED84, 0x3C8C48D9,
/**/ 0x46AAB761, 0x3FE4B0FC,
/**/ 0x738CC59A, 0x3C20DA05,
/**/ 0x8D77A6C6, 0x3FE86910,
/**/ 0xE2BFE9DD, 0x3C7338FF,
/**/ 0xE54ED51B, 0x3FE4E1A4,
/**/ 0x89B7C76A, 0xBC8A492F,
/**/ 0xDE701CA0, 0x3FE83F7D,
/**/ 0x609BC6E8, 0xBC4152CF,
/**/ 0xFD7B351C, 0x3FE511F9,
/**/ 0x61C48831, 0xBC85C0E8,
/**/ 0x31916D5D, 0x3FE8158A,
/**/ 0x0B8228DE, 0xBC6DE8B9,
/**/ 0xCDDBB724, 0x3FE541FA,
/**/ 0x8520D391, 0x3C7232C2,
/**/ 0x2EAA1488, 0x3FE7EB36,
/**/ 0xA4A5959F, 0x3C5A1D65,
/**/ 0x966D59B3, 0x3FE571A6,
/**/ 0x4D0FB198, 0x3C5C843B,
/**/ 0x7F09E54F, 0x3FE7C082,
/**/ 0xD72AEE68, 0xBC6C73D6,
/**/ 0x98813A12, 0x3FE5A0FC,
/**/ 0xB7D4227B, 0xBC8D82E2,
/**/ 0xCD7F6543, 0x3FE7956F,
/**/ 0xE9D45AE4, 0xBC8AB276,
/**/ 0x16BF8F0D, 0x3FE5CFFC,
/**/ 0x70EB578A, 0x3C896CB3,
/**/ 0xC655211F, 0x3FE769FE,
/**/ 0xCF8C68C5, 0xBC6827D5,
/**/ 0x552A9E57, 0x3FE5FEA4,
/**/ 0xF7EE20B7, 0x3C80B6CE,
/**/ 0x174EFBA1, 0x3FE73E30,
/**/ 0x3D94AD5F, 0xBC65D3AE,
/**/ 0x9921AC79, 0x3FE62CF4,
/**/ 0x55B6241A, 0xBC8EDD98,
/**/ 0x6FA77678, 0x3FE71204,
/**/ 0xA5029C81, 0x3C8425B0,
/**/ 0x2963E755, 0x3FE65AEC,
/**/ 0x6B71053C, 0x3C8126F9,
/**/ 0x800CF55E, 0x3FE6E57C,
/**/ 0xDEDBD0A6, 0x3C860286,
/**/ 0x4E134B2F, 0x3FE6888A,
/**/ 0x7644D5E6, 0xBC86B7D3,
/**/ 0xFA9EFB5D, 0x3FE6B898,
/**/ 0x86CCF4B2, 0x3C715AC7,
/**/ 0x50B7821A, 0x3FE6B5CE,
/**/ 0x8F702E0F, 0xBC65D515,
/**/ 0x92EB6253, 0x3FE68B5A,
/**/ 0xD985F89C, 0xBC89A91A,
/**/ 0x7C40BDE1, 0x3FE6E2B7,
/**/ 0x857FAD53, 0xBC70E729,
/**/ 0xFDEB8CBA, 0x3FE65DC1,
/**/ 0x47337C77, 0xBC597C1B,
/**/ 0x1D0A8C40, 0x3FE70F45,
/**/ 0x3885770D, 0x3C697EDE,
/**/ 0xF20191C7, 0x3FE62FCF,
/**/ 0x895756EF, 0x3C6D9143,
/**/ 0x80DEA578, 0x3FE73B76,
/**/ 0x06DC12A2, 0xBC722483,
/**/ 0x26F563DF, 0x3FE60185,
/**/ 0xE0E432D0, 0x3C846CA5,
/**/ 0xF6F7B524, 0x3FE7674A,
/**/ 0x94AC84A8, 0x3C7E9D3F,
/**/ 0x55F1F17A, 0x3FE5D2E2,
/**/ 0x04C8892B, 0x3C803141,
/**/ 0xD0041D52, 0x3FE792C1,
/**/ 0xEEB354EB, 0xBC8ABF05,
/**/ 0x39824077, 0x3FE5A3E8,
/**/ 0x2759BE62, 0x3C8428AA,
/**/ 0x5E28B3C2, 0x3FE7BDDA,
/**/ 0x7CCD0393, 0x3C4AD119,
/**/ 0x8D8E83F2, 0x3FE57497,
/**/ 0xAF282D23, 0x3C8F4714,
/**/ 0xF5037959, 0x3FE7E893,
/**/ 0xAA650C4C, 0x3C80EEFB,
/**/ 0x0F592CA5, 0x3FE544F1,
/**/ 0xE6C7A62F, 0xBC8E7AE8,
/**/ 0xE9AE4BA4, 0x3FE812ED,
/**/ 0xDF402DDA, 0xBC87830A,
/**/ 0x7D7BF3DA, 0x3FE514F5,
/**/ 0x8073C259, 0x3C747A10 };
#endif
#endif

View File

@ -0,0 +1,339 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************/
/* MODULE_NAME: sincos32.c */
/* */
/* FUNCTIONS: ss32 */
/* cc32 */
/* c32 */
/* sin32 */
/* cos32 */
/* mpsin */
/* mpcos */
/* mpranred */
/* mpsin1 */
/* mpcos1 */
/* */
/* FILES NEEDED: endian.h mpa.h sincos32.h */
/* mpa.c */
/* */
/* Multi Precision sin() and cos() function with p=32 for sin()*/
/* cos() arcsin() and arccos() routines */
/* In addition mpranred() routine performs range reduction of */
/* a double number x into multi precision number y, */
/* such that y=x-n*pi/2, abs(y)<pi/4, n=0,+-1,+-2,.... */
/****************************************************************/
#include "endian.h"
#include "mpa.h"
#include "sincos32.h"
/****************************************************************/
/* Compute Multi-Precision sin() function for given p. Receive */
/* Multi Precision number x and result stored at y */
/****************************************************************/
void ss32(mp_no *x, mp_no *y, int p) {
int i;
double a,b;
static const mp_no mpone = {1,1.0,1.0};
mp_no mpt1,mpt2,x2,gor,sum ,mpk={1,1.0};
for (i=1;i<=p;i++) mpk.d[i]=0;
mul(x,x,&x2,p);
cpy(&oofac27,&gor,p);
cpy(&gor,&sum,p);
for (a=27.0;a>1.0;a-=2.0) {
mpk.d[1]=a*(a-1.0);
mul(&gor,&mpk,&mpt1,p);
cpy(&mpt1,&gor,p);
mul(&x2,&sum,&mpt1,p);
sub(&gor,&mpt1,&sum,p);
}
mul(x,&sum,y,p);
}
/**********************************************************************/
/* Compute Multi-Precision cos() function for given p. Receive Multi */
/* Precision number x and result stored at y */
/**********************************************************************/
void cc32(mp_no *x, mp_no *y, int p) {
int i;
double a,b;
static const mp_no mpone = {1,1.0,1.0};
mp_no mpt1,mpt2,x2,gor,sum ,mpk={1,1.0};
for (i=1;i<=p;i++) mpk.d[i]=0;
mul(x,x,&x2,p);
mpk.d[1]=27.0;
mul(&oofac27,&mpk,&gor,p);
cpy(&gor,&sum,p);
for (a=26.0;a>2.0;a-=2.0) {
mpk.d[1]=a*(a-1.0);
mul(&gor,&mpk,&mpt1,p);
cpy(&mpt1,&gor,p);
mul(&x2,&sum,&mpt1,p);
sub(&gor,&mpt1,&sum,p);
}
mul(&x2,&sum,y,p);
}
/***************************************************************************/
/* c32() computes both sin(x), cos(x) as Multi precision numbers */
/***************************************************************************/
void c32(mp_no *x, mp_no *y, mp_no *z, int p) {
static const mp_no mpt={1,1.0,2.0}, one={1,1.0,1.0};
mp_no u,t,t1,t2,c,s;
int i;
cpy(x,&u,p);
u.e=u.e-1;
cc32(&u,&c,p);
ss32(&u,&s,p);
for (i=0;i<24;i++) {
mul(&c,&s,&t,p);
sub(&s,&t,&t1,p);
add(&t1,&t1,&s,p);
sub(&mpt,&c,&t1,p);
mul(&t1,&c,&t2,p);
add(&t2,&t2,&c,p);
}
sub(&one,&c,y,p);
cpy(&s,z,p);
}
/************************************************************************/
/*Routine receive double x and two double results of sin(x) and return */
/*result which is more accurate */
/*Computing sin(x) with multi precision routine c32 */
/************************************************************************/
double sin32(double x, double res, double res1) {
int p;
mp_no a,b,c;
p=32;
dbl_mp(res,&a,p);
dbl_mp(0.5*(res1-res),&b,p);
add(&a,&b,&c,p);
if (x>0.8)
{ sub(&hp,&c,&a,p);
c32(&a,&b,&c,p);
}
else c32(&c,&a,&b,p); /* b=sin(0.5*(res+res1)) */
dbl_mp(x,&c,p); /* c = x */
sub(&b,&c,&a,p);
/* if a>0 return min(res,res1), otherwise return max(res,res1) */
if (a.d[0]>0) return (res<res1)?res:res1;
else return (res>res1)?res:res1;
}
/************************************************************************/
/*Routine receive double x and two double results of cos(x) and return */
/*result which is more accurate */
/*Computing cos(x) with multi precision routine c32 */
/************************************************************************/
double cos32(double x, double res, double res1) {
int p;
mp_no a,b,c;
p=32;
dbl_mp(res,&a,p);
dbl_mp(0.5*(res1-res),&b,p);
add(&a,&b,&c,p);
if (x>2.4)
{ sub(&pi,&c,&a,p);
c32(&a,&b,&c,p);
b.d[0]=-b.d[0];
}
else if (x>0.8)
{ sub(&hp,&c,&a,p);
c32(&a,&c,&b,p);
}
else c32(&c,&b,&a,p); /* b=cos(0.5*(res+res1)) */
dbl_mp(x,&c,p); /* c = x */
sub(&b,&c,&a,p);
/* if a>0 return max(res,res1), otherwise return min(res,res1) */
if (a.d[0]>0) return (res>res1)?res:res1;
else return (res<res1)?res:res1;
}
/*******************************************************************/
/*Compute sin(x+dx) as Multi Precision number and return result as */
/* double */
/*******************************************************************/
double mpsin(double x, double dx) {
int p;
double y;
mp_no a,b,c;
p=32;
dbl_mp(x,&a,p);
dbl_mp(dx,&b,p);
add(&a,&b,&c,p);
if (x>0.8) { sub(&hp,&c,&a,p); c32(&a,&b,&c,p); }
else c32(&c,&a,&b,p); /* b = sin(x+dx) */
mp_dbl(&b,&y,p);
return y;
}
/*******************************************************************/
/* Compute cos()of double-length number (x+dx) as Multi Precision */
/* number and return result as double */
/*******************************************************************/
double mpcos(double x, double dx) {
int p;
double y;
mp_no a,b,c;
p=32;
dbl_mp(x,&a,p);
dbl_mp(dx,&b,p);
add(&a,&b,&c,p);
if (x>0.8)
{ sub(&hp,&c,&b,p);
c32(&b,&a,&c,p);
}
else c32(&c,&a,&b,p); /* a = cos(x+dx) */
mp_dbl(&a,&y,p);
return y;
}
/******************************************************************/
/* mpranred() performs range reduction of a double number x into */
/* multi precision number y, such that y=x-n*pi/2, abs(y)<pi/4, */
/* n=0,+-1,+-2,.... */
/* Return int which indicates in which quarter of circle x is */
/******************************************************************/
int mpranred(double x, mp_no *y, int p)
{
number v;
double t,xn;
int i,k,n;
static const mp_no one = {1,1.0,1.0};
mp_no a,b,c;
if (ABS(x) < 2.8e14) {
t = (x*hpinv.d + toint.d);
xn = t - toint.d;
v.d = t;
n =v.i[LOW_HALF]&3;
dbl_mp(xn,&a,p);
mul(&a,&hp,&b,p);
dbl_mp(x,&c,p);
sub(&c,&b,y,p);
return n;
}
else { /* if x is very big more precision required */
dbl_mp(x,&a,p);
a.d[0]=1.0;
k = a.e-5;
if (k < 0) k=0;
b.e = -k;
b.d[0] = 1.0;
for (i=0;i<p;i++) b.d[i+1] = toverp[i+k];
mul(&a,&b,&c,p);
t = c.d[c.e];
for (i=1;i<=p-c.e;i++) c.d[i]=c.d[i+c.e];
for (i=p+1-c.e;i<=p;i++) c.d[i]=0;
c.e=0;
if (c.d[1] >= 8388608.0)
{ t +=1.0;
sub(&c,&one,&b,p);
mul(&b,&hp,y,p);
}
else mul(&c,&hp,y,p);
n = (int) t;
if (x < 0) { y->d[0] = - y->d[0]; n = -n; }
return (n&3);
}
}
/*******************************************************************/
/* Multi-Precision sin() function subroutine, for p=32. It is */
/* based on the routines mpranred() and c32(). */
/*******************************************************************/
double mpsin1(double x)
{
int p;
int n;
mp_no u,s,c;
double y;
p=32;
n=mpranred(x,&u,p); /* n is 0, 1, 2 or 3 */
c32(&u,&c,&s,p);
switch (n) { /* in which quarter of unit circle y is*/
case 0:
mp_dbl(&s,&y,p);
return y;
break;
case 2:
mp_dbl(&s,&y,p);
return -y;
break;
case 1:
mp_dbl(&c,&y,p);
return y;
break;
case 3:
mp_dbl(&c,&y,p);
return -y;
break;
}
return 0; /* unreachable, to make the compiler happy */
}
/*****************************************************************/
/* Multi-Precision cos() function subroutine, for p=32. It is */
/* based on the routines mpranred() and c32(). */
/*****************************************************************/
double mpcos1(double x)
{
int p;
int n;
mp_no u,s,c;
double y;
p=32;
n=mpranred(x,&u,p); /* n is 0, 1, 2 or 3 */
c32(&u,&c,&s,p);
switch (n) { /* in what quarter of unit circle y is*/
case 0:
mp_dbl(&c,&y,p);
return y;
break;
case 2:
mp_dbl(&c,&y,p);
return -y;
break;
case 1:
mp_dbl(&s,&y,p);
return -y;
break;
case 3:
mp_dbl(&s,&y,p);
return y;
break;
}
return 0; /* unreachable, to make the compiler happy */
}
/******************************************************************/

View File

@ -0,0 +1,81 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* */
/* MODULE_NAME:sincos32.h */
/* */
/* common data and variables prototype and definition */
/******************************************************************/
#ifndef SINCOS32_H
#define SINCCOS32_H
#ifdef BIG_ENDI
static const number
/**/ hpinv = {0x3FE45F30, 0x6DC9C883 }, /* 0.63661977236758138 */
/**/ toint = {0x43380000, 0x00000000 }; /* 6755399441055744 */
#else
#ifdef LITTLE_ENDI
static const number
/**/ hpinv = {0x6DC9C883, 0x3FE45F30 }, /* 0.63661977236758138 */
/**/ toint = {0x00000000, 0x43380000 }; /* 6755399441055744 */
#endif
#endif
static const mp_no
oofac27 = {-3, 1.0,7.0,4631664.0,12006312.0,13118056.0,6538613.0,646354.0,
8508025.0,9131256.0,7548776.0,2529842.0,8864927.0,660489.0,15595125.0,12777885.0,
11618489.0,13348664.0,5486686.0,514518.0,11275535.0,4727621.0,3575562.0,
13579710.0,5829745.0,7531862.0,9507898.0,6915060.0,4079264.0,1907586.0,
6078398.0,13789314.0,5504104.0,14136.0},
pi = {1,1.0,3.0,
2375530.0,8947107.0,578323.0,1673774.0,225395.0,4498441.0,3678761.0,
10432976.0,536314.0,10021966.0,7113029.0,2630118.0,3723283.0,7847508.0,
6737716.0,15273068.0,12626985.0,12044668.0,5299519.0,8705461.0,11880201.0,
1544726.0,14014857.0,7994139.0,13709579.0,10918111.0,11906095.0,16610011.0,
13638367.0,12040417.0,11529578.0,2522774.0},
hp = {1, 1.0, 1.0,
9576373.0,4473553.0,8677769.0,9225495.0,112697.0,10637828.0,
10227988.0,13605096.0,268157.0,5010983.0,3556514.0,9703667.0,
1861641.0,12312362.0,3368858.0,7636534.0,6313492.0,14410942.0,
2649759.0,12741338.0,14328708.0,9160971.0,7007428.0,12385677.0,
15243397.0,13847663.0,14341655.0,16693613.0,15207791.0,14408816.0,
14153397.0,1261387.0,6110792.0,2291862.0,4181138.0,5295267.0};
static const double toverp[75] = {
10680707.0, 7228996.0, 1387004.0, 2578385.0, 16069853.0,
12639074.0, 9804092.0, 4427841.0, 16666979.0, 11263675.0,
12935607.0, 2387514.0, 4345298.0, 14681673.0, 3074569.0,
13734428.0, 16653803.0, 1880361.0, 10960616.0, 8533493.0,
3062596.0, 8710556.0, 7349940.0, 6258241.0, 3772886.0,
3769171.0, 3798172.0, 8675211.0, 12450088.0, 3874808.0,
9961438.0, 366607.0, 15675153.0, 9132554.0, 7151469.0,
3571407.0, 2607881.0, 12013382.0, 4155038.0, 6285869.0,
7677882.0, 13102053.0, 15825725.0, 473591.0, 9065106.0,
15363067.0, 6271263.0, 9264392.0, 5636912.0, 4652155.0,
7056368.0, 13614112.0, 10155062.0, 1944035.0, 9527646.0,
15080200.0, 6658437.0, 6231200.0, 6832269.0, 16767104.0,
5075751.0, 3212806.0, 1398474.0, 7579849.0, 6349435.0,
12618859.0, 4703257.0, 12806093.0, 14477321.0, 2786137.0,
12875403.0, 9837734.0, 14528324.0, 13719321.0, 343717.0 };
#endif

View File

@ -0,0 +1,60 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/**************************************************************************/
/* MODULE_NAME:slowexp.c */
/* */
/* FUNCTION:slowexp */
/* */
/* FILES NEEDED:mpa.h */
/* mpa.c mpexp.c */
/* */
/*Converting from double precision to Multi-precision and calculating */
/* e^x */
/**************************************************************************/
#include "mpa.h"
void mpexp(mp_no *x, mp_no *y, int p);
/*Converting from double precision to Multi-precision and calculating e^x */
double slowexp(double x) {
double y,w,z,res,eps=3.0e-26;
int orig,i,p;
mp_no mpx, mpy, mpz,mpw,mpeps,mpcor;
p=6;
dbl_mp(x,&mpx,p); /* Convert a double precision number x */
/* into a multiple precision number mpx with prec. p. */
mpexp(&mpx, &mpy, p); /* Multi-Precision exponential function */
dbl_mp(eps,&mpeps,p);
mul(&mpeps,&mpy,&mpcor,p);
add(&mpy,&mpcor,&mpw,p);
sub(&mpy,&mpcor,&mpz,p);
mp_dbl(&mpw, &w, p);
mp_dbl(&mpz, &z, p);
if (w == z) return w;
else { /* if calculating is not exactly */
p = 32;
dbl_mp(x,&mpx,p);
mpexp(&mpx, &mpy, p);
mp_dbl(&mpy, &res, p);
return res;
}
}

View File

@ -0,0 +1,73 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*************************************************************************/
/* MODULE_NAME:slowpow.c */
/* */
/* FUNCTION:slowpow */
/* */
/*FILES NEEDED:mpa.h */
/* mpa.c mpexp.c mplog.c halfulp.c */
/* */
/* Given two IEEE double machine numbers y,x , routine computes the */
/* correctly rounded (to nearest) value of x^y. Result calculated by */
/* multiplication (in halfulp.c) or if result isn't accurate enough */
/* then routine converts x and y into multi-precision doubles and */
/* calls to mpexp routine */
/*************************************************************************/
#include "mpa.h"
void mpexp(mp_no *x, mp_no *y, int p);
void mplog(mp_no *x, mp_no *y, int p);
double ulog(double);
double halfulp(double x,double y);
double slowpow(double x, double y, double z) {
double res,res1;
mp_no mpx, mpy, mpz,mpw,mpp,mpr,mpr1;
static const mp_no eps = {-3,1.0,4.0};
int p;
res = halfulp(x,y); /* halfulp() returns -10 or x^y */
if (res >= 0) return res; /* if result was really computed by halfulp */
/* else, if result was not really computed by halfulp */
p = 10; /* p=precision */
dbl_mp(x,&mpx,p);
dbl_mp(y,&mpy,p);
dbl_mp(z,&mpz,p);
mplog(&mpx, &mpz, p); /* log(x) = z */
mul(&mpy,&mpz,&mpw,p); /* y * z =w */
mpexp(&mpw, &mpp, p); /* e^w =pp */
add(&mpp,&eps,&mpr,p); /* pp+eps =r */
mp_dbl(&mpr, &res, p);
sub(&mpp,&eps,&mpr1,p); /* pp -eps =r1 */
mp_dbl(&mpr1, &res1, p); /* converting into double precision */
if (res == res1) return res;
p = 32; /* if we get here result wasn't calculated exactly, continue */
dbl_mp(x,&mpx,p); /* for more exact calculation */
dbl_mp(y,&mpy,p);
dbl_mp(z,&mpz,p);
mplog(&mpx, &mpz, p); /* log(c)=z */
mul(&mpy,&mpz,&mpw,p); /* y*z =w */
mpexp(&mpw, &mpp, p); /* e^w=pp */
mp_dbl(&mpp, &res, p); /* converting into double precision */
return res;
}

View File

@ -0,0 +1,69 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* */
/* MODULE_NAME:uasncs.h */
/* */
/* common data and variables prototype and definition */
/******************************************************************/
#ifndef UANSNCS_H
#define UANSNCS_H
#ifdef BIG_ENDI
static const mynumber
/**/ a1 = {0x3FC55580, 0x00000000 }, /* 0.1666717529296875 */
/**/ a2 = {0xBED55555, 0x55552330 }, /* -5.0862630208224597e-06 */
/**/ hp0 = {0x3FF921FB, 0x54442D18 }, /* 1.5707963267948966 */
/**/ hp1 = {0x3C91A626, 0x33145C07 }; /* 6.123233995736766e-17 */
#else
#ifdef LITTLE_ENDI
static const mynumber
/**/ a1 = {0x00000000, 0x3FC55580 }, /* 0.1666717529296875 */
/**/ a2 = {0x55552330, 0xBED55555 }, /* -5.0862630208224597e-06 */
/**/ hp0 = {0x54442D18, 0x3FF921FB }, /* 1.5707963267948966 */
/**/ hp1 = {0x33145C07, 0x3C91A626 }; /* 6.123233995736766e-17 */
#endif
#endif
static const double
f1 = 1.66666666666664110590506577996662E-01,
f2 = 7.50000000026122686814431784722623E-02,
f3 = 4.46428561421059750978517350006940E-02,
f4 = 3.03821268582119319911193410625235E-02,
f5 = 2.23551211026525610742786300334557E-02,
f6 = 1.81382903404565056280372531963613E-02;
static const double
c2 = 0.74999999999985410757087492918602258E-01,
c3 = 0.44642857150311968932423372477866076E-01,
c4 = 0.30381942574778615766200591683810471E-01,
c5 = 0.22372413472984868331447708777000650E-01,
c6 = 0.17333630246451830686009693735025490E-01,
c7 = 0.14710362893628210269950864741085777E-01;
static const double big = 103079215104.0, t24 = 16777216.0, t27 = 134217728.0;
static const double
rt0 = 9.99999999859990725855365213134618E-01,
rt1 = 4.99999999495955425917856814202739E-01,
rt2 = 3.75017500867345182581453026130850E-01,
rt3 = 3.12523626554518656309172508769531E-01;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* */
/* MODULE_NAME:uexp.h */
/* */
/* common data and variables prototype and definition */
/******************************************************************/
#ifndef UEXP_H
#define UEXP_H
#include "mydefs.h"
const static double one = 1.0, zero = 0.0, hhuge = 1.0e300, tiny = 1.0e-300,
err_0 = 1.000014, err_1 = 0.000016;
const static int4 bigint = 0x40862002,
badint = 0x40876000,smallint = 0x3C8fffff;
const static int4 hugeint = 0x7FFFFFFF, infint = 0x7ff00000;
#ifdef BIG_ENDI
const static mynumber inf = {0x7FF00000, 0}; /* inf */
const static mynumber t256 = {0x4ff00000, 0}; /* 2^256 */
const static mynumber ln_two1 = { 0x3FE62E42, 0xFEFA3800 };/*0.69314718055989033 */
const static mynumber ln_two2 = { 0x3D2EF357, 0x93C76730 };/*5.4979230187083712e-14*/
const static mynumber log2e = { 0x3FF71547, 0x652B82FE };/* 1.4426950408889634 */
const static mynumber p2 = { 0x3FE00000, 0x000004DC };/* 0.50000000000013811 */
const static mynumber p3 = { 0x3FC55555, 0x55555A0F };/* 0.16666666666670024 */
const static mynumber three33 = { 0x42180000, 0 }; /* 25769803776 */
const static mynumber three51 = { 0x43380000, 0 }; /* 6755399441055744 */
#else
#ifdef LITTLE_ENDI
const static mynumber inf = {0, 0x7FF00000}; /* inf */
const static mynumber t256 = {0, 0x4ff00000}; /* 2^256 */
const static mynumber ln_two1 = { 0xFEFA3800, 0x3FE62E42 };/*0.69314718055989033 */
const static mynumber ln_two2 = { 0x93C76730, 0x3D2EF357 };/*5.4979230187083712e-14*/
const static mynumber log2e = { 0x652B82FE, 0x3FF71547 };/* 1.4426950408889634 */
const static mynumber p2 = { 0x000004DC, 0x3FE00000 };/* 0.50000000000013811 */
const static mynumber p3 = { 0x55555A0F, 0x3FC55555 };/* 0.16666666666670024 */
const static mynumber three33 = { 0, 0x42180000 }; /* 25769803776 */
const static mynumber three51 = { 0, 0x43380000 }; /* 6755399441055744 */
#endif
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,195 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* */
/* MODULE_NAME:ulog.h */
/* */
/* common data and variables prototype and definition */
/******************************************************************/
#ifndef ULOG_H
#define ULOG_H
#ifdef BIG_ENDI
static const number
/* polynomial I */
/**/ a2 = {0xbfe00000, 0x0001aa8f, }, /* -0.500... */
/**/ a3 = {0x3fd55555, 0x55588d2e, }, /* 0.333... */
/* polynomial II */
/**/ b0 = {0x3fd55555, 0x55555555, }, /* 0.333... */
/**/ b1 = {0xbfcfffff, 0xffffffbb, }, /* -0.249... */
/**/ b2 = {0x3fc99999, 0x9999992f, }, /* 0.199... */
/**/ b3 = {0xbfc55555, 0x556503fd, }, /* -0.166... */
/**/ b4 = {0x3fc24924, 0x925b3d62, }, /* 0.142... */
/**/ b5 = {0xbfbffffe, 0x160472fc, }, /* -0.124... */
/**/ b6 = {0x3fbc71c5, 0x25db58ac, }, /* 0.111... */
/**/ b7 = {0xbfb9a4ac, 0x11a2a61c, }, /* -0.100... */
/**/ b8 = {0x3fb75077, 0x0df2b591, }, /* 0.091... */
/* polynomial III */
/**/ c1 = {0x3ff00000, 0x00000000, }, /* 1 */
/**/ c2 = {0xbfe00000, 0x00000000, }, /* -1/2 */
/**/ c3 = {0x3fd55555, 0x55555555, }, /* 1/3 */
/**/ c4 = {0xbfd00000, 0x00000000, }, /* -1/4 */
/**/ c5 = {0x3fc99999, 0x9999999a, }, /* 1/5 */
/* polynomial IV */
/**/ d2 = {0xbfe00000, 0x00000000, }, /* -1/2 */
/**/ dd2 = {0x00000000, 0x00000000, }, /* -1/2-d2 */
/**/ d3 = {0x3fd55555, 0x55555555, }, /* 1/3 */
/**/ dd3 = {0x3c755555, 0x55555555, }, /* 1/3-d3 */
/**/ d4 = {0xbfd00000, 0x00000000, }, /* -1/4 */
/**/ dd4 = {0x00000000, 0x00000000, }, /* -1/4-d4 */
/**/ d5 = {0x3fc99999, 0x9999999a, }, /* 1/5 */
/**/ dd5 = {0xbc699999, 0x9999999a, }, /* 1/5-d5 */
/**/ d6 = {0xbfc55555, 0x55555555, }, /* -1/6 */
/**/ dd6 = {0xbc655555, 0x55555555, }, /* -1/6-d6 */
/**/ d7 = {0x3fc24924, 0x92492492, }, /* 1/7 */
/**/ dd7 = {0x3c624924, 0x92492492, }, /* 1/7-d7 */
/**/ d8 = {0xbfc00000, 0x00000000, }, /* -1/8 */
/**/ dd8 = {0x00000000, 0x00000000, }, /* -1/8-d8 */
/**/ d9 = {0x3fbc71c7, 0x1c71c71c, }, /* 1/9 */
/**/ dd9 = {0x3c5c71c7, 0x1c71c71c, }, /* 1/9-d9 */
/**/ d10 = {0xbfb99999, 0x9999999a, }, /* -1/10 */
/**/ dd10 = {0x3c599999, 0x9999999a, }, /* -1/10-d10 */
/**/ d11 = {0x3fb745d1, 0x745d1746, }, /* 1/11 */
/**/ d12 = {0xbfb55555, 0x55555555, }, /* -1/12 */
/**/ d13 = {0x3fb3b13b, 0x13b13b14, }, /* 1/13 */
/**/ d14 = {0xbfb24924, 0x92492492, }, /* -1/14 */
/**/ d15 = {0x3fb11111, 0x11111111, }, /* 1/15 */
/**/ d16 = {0xbfb00000, 0x00000000, }, /* -1/16 */
/**/ d17 = {0x3fae1e1e, 0x1e1e1e1e, }, /* 1/17 */
/**/ d18 = {0xbfac71c7, 0x1c71c71c, }, /* -1/18 */
/**/ d19 = {0x3faaf286, 0xbca1af28, }, /* 1/19 */
/**/ d20 = {0xbfa99999, 0x9999999a, }, /* -1/20 */
/* constants */
/**/ zero = {0x00000000, 0x00000000, }, /* 0 */
/**/ one = {0x3ff00000, 0x00000000, }, /* 1 */
/**/ half = {0x3fe00000, 0x00000000, }, /* 1/2 */
/**/ mhalf = {0xbfe00000, 0x00000000, }, /* -1/2 */
/**/ sqrt_2 = {0x3ff6a09e, 0x667f3bcc, }, /* sqrt(2) */
/**/ h1 = {0x3fd2e000, 0x00000000, }, /* 151/2**9 */
/**/ h2 = {0x3f669000, 0x00000000, }, /* 361/2**17 */
/**/ delu = {0x3f700000, 0x00000000, }, /* 1/2**8 */
/**/ delv = {0x3ef00000, 0x00000000, }, /* 1/2**16 */
/**/ ln2a = {0x3fe62e42, 0xfefa3800, }, /* ln(2) 43 bits */
/**/ ln2b = {0x3d2ef357, 0x93c76730, }, /* ln(2)-ln2a */
/**/ e1 = {0x3bbcc868, 0x00000000, }, /* 6.095e-21 */
/**/ e2 = {0x3c1138ce, 0x00000000, }, /* 2.334e-19 */
/**/ e3 = {0x3aa1565d, 0x00000000, }, /* 2.801e-26 */
/**/ e4 = {0x39809d88, 0x00000000, }, /* 1.024e-31 */
/**/ e[M] ={{0x37da223a, 0x00000000, }, /* 1.2e-39 */
/**/ {0x35c851c4, 0x00000000, }, /* 1.3e-49 */
/**/ {0x2ab85e51, 0x00000000, }, /* 6.8e-103 */
/**/ {0x17383827, 0x00000000, }},/* 8.1e-197 */
/**/ two54 = {0x43500000, 0x00000000, }, /* 2**54 */
/**/ u03 = {0x3f9eb851, 0xeb851eb8, }; /* 0.03 */
#else
#ifdef LITTLE_ENDI
static const number
/* polynomial I */
/**/ a2 = {0x0001aa8f, 0xbfe00000, }, /* -0.500... */
/**/ a3 = {0x55588d2e, 0x3fd55555, }, /* 0.333... */
/* polynomial II */
/**/ b0 = {0x55555555, 0x3fd55555, }, /* 0.333... */
/**/ b1 = {0xffffffbb, 0xbfcfffff, }, /* -0.249... */
/**/ b2 = {0x9999992f, 0x3fc99999, }, /* 0.199... */
/**/ b3 = {0x556503fd, 0xbfc55555, }, /* -0.166... */
/**/ b4 = {0x925b3d62, 0x3fc24924, }, /* 0.142... */
/**/ b5 = {0x160472fc, 0xbfbffffe, }, /* -0.124... */
/**/ b6 = {0x25db58ac, 0x3fbc71c5, }, /* 0.111... */
/**/ b7 = {0x11a2a61c, 0xbfb9a4ac, }, /* -0.100... */
/**/ b8 = {0x0df2b591, 0x3fb75077, }, /* 0.091... */
/* polynomial III */
/**/ c1 = {0x00000000, 0x3ff00000, }, /* 1 */
/**/ c2 = {0x00000000, 0xbfe00000, }, /* -1/2 */
/**/ c3 = {0x55555555, 0x3fd55555, }, /* 1/3 */
/**/ c4 = {0x00000000, 0xbfd00000, }, /* -1/4 */
/**/ c5 = {0x9999999a, 0x3fc99999, }, /* 1/5 */
/* polynomial IV */
/**/ d2 = {0x00000000, 0xbfe00000, }, /* -1/2 */
/**/ dd2 = {0x00000000, 0x00000000, }, /* -1/2-d2 */
/**/ d3 = {0x55555555, 0x3fd55555, }, /* 1/3 */
/**/ dd3 = {0x55555555, 0x3c755555, }, /* 1/3-d3 */
/**/ d4 = {0x00000000, 0xbfd00000, }, /* -1/4 */
/**/ dd4 = {0x00000000, 0x00000000, }, /* -1/4-d4 */
/**/ d5 = {0x9999999a, 0x3fc99999, }, /* 1/5 */
/**/ dd5 = {0x9999999a, 0xbc699999, }, /* 1/5-d5 */
/**/ d6 = {0x55555555, 0xbfc55555, }, /* -1/6 */
/**/ dd6 = {0x55555555, 0xbc655555, }, /* -1/6-d6 */
/**/ d7 = {0x92492492, 0x3fc24924, }, /* 1/7 */
/**/ dd7 = {0x92492492, 0x3c624924, }, /* 1/7-d7 */
/**/ d8 = {0x00000000, 0xbfc00000, }, /* -1/8 */
/**/ dd8 = {0x00000000, 0x00000000, }, /* -1/8-d8 */
/**/ d9 = {0x1c71c71c, 0x3fbc71c7, }, /* 1/9 */
/**/ dd9 = {0x1c71c71c, 0x3c5c71c7, }, /* 1/9-d9 */
/**/ d10 = {0x9999999a, 0xbfb99999, }, /* -1/10 */
/**/ dd10 = {0x9999999a, 0x3c599999, }, /* -1/10-d10 */
/**/ d11 = {0x745d1746, 0x3fb745d1, }, /* 1/11 */
/**/ d12 = {0x55555555, 0xbfb55555, }, /* -1/12 */
/**/ d13 = {0x13b13b14, 0x3fb3b13b, }, /* 1/13 */
/**/ d14 = {0x92492492, 0xbfb24924, }, /* -1/14 */
/**/ d15 = {0x11111111, 0x3fb11111, }, /* 1/15 */
/**/ d16 = {0x00000000, 0xbfb00000, }, /* -1/16 */
/**/ d17 = {0x1e1e1e1e, 0x3fae1e1e, }, /* 1/17 */
/**/ d18 = {0x1c71c71c, 0xbfac71c7, }, /* -1/18 */
/**/ d19 = {0xbca1af28, 0x3faaf286, }, /* 1/19 */
/**/ d20 = {0x9999999a, 0xbfa99999, }, /* -1/20 */
/* constants */
/**/ zero = {0x00000000, 0x00000000, }, /* 0 */
/**/ one = {0x00000000, 0x3ff00000, }, /* 1 */
/**/ half = {0x00000000, 0x3fe00000, }, /* 1/2 */
/**/ mhalf = {0x00000000, 0xbfe00000, }, /* -1/2 */
/**/ sqrt_2 = {0x667f3bcc, 0x3ff6a09e, }, /* sqrt(2) */
/**/ h1 = {0x00000000, 0x3fd2e000, }, /* 151/2**9 */
/**/ h2 = {0x00000000, 0x3f669000, }, /* 361/2**17 */
/**/ delu = {0x00000000, 0x3f700000, }, /* 1/2**8 */
/**/ delv = {0x00000000, 0x3ef00000, }, /* 1/2**16 */
/**/ ln2a = {0xfefa3800, 0x3fe62e42, }, /* ln(2) 43 bits */
/**/ ln2b = {0x93c76730, 0x3d2ef357, }, /* ln(2)-ln2a */
/**/ e1 = {0x00000000, 0x3bbcc868, }, /* 6.095e-21 */
/**/ e2 = {0x00000000, 0x3c1138ce, }, /* 2.334e-19 */
/**/ e3 = {0x00000000, 0x3aa1565d, }, /* 2.801e-26 */
/**/ e4 = {0x00000000, 0x39809d88, }, /* 1.024e-31 */
/**/ e[M] ={{0x00000000, 0x37da223a, }, /* 1.2e-39 */
/**/ {0x00000000, 0x35c851c4, }, /* 1.3e-49 */
/**/ {0x00000000, 0x2ab85e51, }, /* 6.8e-103 */
/**/ {0x00000000, 0x17383827, }},/* 8.1e-197 */
/**/ two54 = {0x00000000, 0x43500000, }, /* 2**54 */
/**/ u03 = {0xeb851eb8, 0x3f9eb851, }; /* 0.03 */
#endif
#endif
#define ZERO zero.d
#define ONE one.d
#define HALF half.d
#define MHALF mhalf.d
#define SQRT_2 sqrt_2.d
#define DEL_U delu.d
#define DEL_V delv.d
#define LN2A ln2a.d
#define LN2B ln2b.d
#define E1 e1.d
#define E2 e2.d
#define E3 e3.d
#define E4 e4.d
#define U03 u03.d
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,82 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* */
/* MODULE_NAME:upow.h */
/* */
/* common data and variables prototype and definition */
/******************************************************************/
#ifndef UPOW_H
#define UPOW_H
#include "mydefs.h"
#ifdef BIG_ENDI
const static mynumber
/**/ INF = {0x7ff00000, 0x00000000 }, /* INF */
/**/ NaNQ = {0x7ff80000, 0x00000000 }, /* NaNQ */
/**/ sqrt_2 = {0x3ff6a09e, 0x667f3bcc }, /* sqrt(2) */
/**/ ln2a = {0x3fe62e42, 0xfefa3800 }, /* ln(2) 43 bits */
/**/ ln2b = {0x3d2ef357, 0x93c76730 }, /* ln(2)-ln2a */
/**/ bigu = {0x4297ffff, 0xfffffd2c }, /* 1.5*2**42 -724*2**-10 */
/**/ bigv = {0x4207ffff, 0xfff8016a }, /* 1.5*2**33-1+362*2**-19 */
/**/ t52 = {0x43300000, 0x00000000 }, /* 2**52 */
/**/ two52e = {0x43300000, 0x000003ff }; /* 2**52' */
mynumber
/**/ two52 = {0x43300000, 0x00000000 }; /* 2**52 */
#else
#ifdef LITTLE_ENDI
const static mynumber
/**/ INF = {0x00000000, 0x7ff00000 }, /* INF */
/**/ NaNQ = {0x00000000, 0x7ff80000 }, /* NaNQ */
/**/ sqrt_2 = {0x667f3bcc, 0x3ff6a09e }, /* sqrt(2) */
/**/ ln2a = {0xfefa3800, 0x3fe62e42 }, /* ln(2) 43 bits */
/**/ ln2b = {0x93c76730, 0x3d2ef357 }, /* ln(2)-ln2a */
/**/ bigu = {0xfffffd2c, 0x4297ffff }, /* 1.5*2**42 -724*2**-10 */
/**/ bigv = {0xfff8016a, 0x4207ffff }, /* 1.5*2**33-1+362*2**-19 */
/**/ t52 = {0x00000000, 0x43300000 }, /* 2**52 */
/**/ two52e = {0x000003ff, 0x43300000 }; /* 2**52' */
mynumber
/**/ two52 = {0x00000000, 0x43300000 }; /* 2**52 */
#endif
#endif
const static double p2=-0.5, p3 = 3.3333333333333333333e-1, p4 = -0.25,
q2 = -0.5, q3 = 3.3333333333331404e-01, q4 = -2.4999999999996436e-01,
q5 = 2.0000010500004459e-01, q6 = -1.6666678916688004e-01,
r3 = 3.33333333333333333372884096563030E-01,
r4 = -2.50000000000000000213574153875908E-01,
r5 = 1.99999999999683593814072199830603E-01,
r6 = -1.66666666666065494878165510225378E-01,
r7 = 1.42857517857114380606360005067609E-01,
r8 = -1.25000449999974370683775964001702E-01,
s3 = 0.333251953125000000e0,
ss3 = 8.138020833333333333e-05,
s4 = -2.500000000000000000e-01,
s5 = 1.999999999999960937e-01,
s6 = -1.666666666666592447e-01,
s7 = 1.428571845238194705e-01,
s8 = -1.250000500000149097e-01;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/************************************************************************/
/* MODULE_NAME: urem.h */
/* */
/* */
/* common data and variables definition for BIG or LITTLE ENDIAN */
/************************************************************************/
#ifndef UREM_H
#define UREM_H
#ifdef BIG_ENDI
static const mynumber big = {0x43380000, 0}, /* 6755399441055744 */
t128 = {0x47f00000, 0}, /* 2^ 128 */
tm128 = {0x37f00000, 0}, /* 2^-128 */
ZERO = {0, 0}, /* 0.0 */
nZERO = {0x80000000, 0}, /* -0.0 */
NAN = {0x7ff80000, 0}, /* NaN */
nNAN = {0xfff80000, 0}; /* -NaN */
#else
#ifdef LITTLE_ENDI
static const mynumber big = {0, 0x43380000}, /* 6755399441055744 */
t128 = {0, 0x47f00000}, /* 2^ 128 */
tm128 = {0, 0x37f00000}, /* 2^-128 */
ZERO = {0, 0}, /* 0.0 */
nZERO = {0, 0x80000000}, /* -0.0 */
NAN = {0, 0x7ff80000}, /* NaN */
nNAN = {0, 0xfff80000}; /* -NaN */
#endif
#endif
#endif

View File

@ -0,0 +1,43 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* */
/* MODULE_NAME:uroot.h */
/* */
/* common data and variables prototype and definition */
/******************************************************************/
#ifndef UROOT_H
#define UROOT_H
#ifdef BIG_ENDI
static const mynumber
/**/ t512 = {0x5ff00000, 0x00000000 }, /* 2^512 */
/**/ tm256 = {0x2ff00000, 0x00000000 }; /* 2^-256 */
#else
#ifdef LITTLE_ENDI
static const mynumber
/**/ t512 = {0x00000000, 0x5ff00000 }, /* 2^512 */
/**/ tm256 = {0x00000000, 0x2ff00000 }; /* 2^-256 */
#endif
#endif
#endif

View File

@ -0,0 +1,79 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/************************************************************************/
/* MODULE_NAME: dosincos.h */
/* */
/* */
/* common data and variables definition for BIG or LITTLE ENDIAN */
/************************************************************************/
#ifndef USNCS_H
#define USNCS_H
#ifdef BIG_ENDI
static const mynumber
/**/ NAN = {0x7ff80000, 0x00000000 }, /* NaN */
/**/ s1 = {0xBFC55555, 0x55555555 }, /* -0.16666666666666666 */
/**/ s2 = {0x3F811111, 0x11110ECE }, /* 0.0083333333333323288 */
/**/ s3 = {0xBF2A01A0, 0x19DB08B8 }, /* -0.00019841269834414642 */
/**/ s4 = {0x3EC71DE2, 0x7B9A7ED9 }, /* 2.755729806860771e-06 */
/**/ s5 = {0xBE5ADDFF, 0xC2FCDF59 }, /* -2.5022014848318398e-08 */
/**/ aa = {0xBFC55580, 0x00000000 }, /* -0.1666717529296875 */
/**/ bb = {0x3ED55555, 0x55556E24 }, /* 5.0862630208387126e-06 */
/**/ big = {0x42c80000, 0x00000000 }, /* 52776558133248 */
/**/ hp0 = {0x3FF921FB, 0x54442D18 }, /* 1.5707963267948966 */
/**/ hp1 = {0x3C91A626, 0x33145C07 }, /* 6.123233995736766e-17 */
/**/ mp1 = {0x3FF921FB, 0x58000000 }, /* 1.5707963407039642 */
/**/ mp2 = {0xBE4DDE97, 0x3C000000 }, /* -1.3909067564377153e-08 */
/**/ mp3 = {0xBC8CB3B3, 0x99D747F2 }, /* -4.9789962505147994e-17 */
/**/ pp3 = {0xBC8CB3B3, 0x98000000 }, /* -4.9789962314799099e-17 */
/**/ pp4 = {0xbacd747f, 0x23e32ed7 }, /* -1.9034889620193266e-25 */
/**/ hpinv = {0x3FE45F30, 0x6DC9C883 }, /* 0.63661977236758138 */
/**/ toint = {0x43380000, 0x00000000 }; /* 6755399441055744 */
#else
#ifdef LITTLE_ENDI
static const mynumber
/**/ NAN = {0x00000000, 0x7ff80000 },/* NaN */
/**/ s1 = {0x55555555, 0xBFC55555 },/* -0.16666666666666666 */
/**/ s2 = {0x11110ECE, 0x3F811111 },/* 0.0083333333333323288 */
/**/ s3 = {0x19DB08B8, 0xBF2A01A0 },/* -0.00019841269834414642 */
/**/ s4 = {0x7B9A7ED9, 0x3EC71DE2 },/* 2.755729806860771e-06 */
/**/ s5 = {0xC2FCDF59, 0xBE5ADDFF },/* -2.5022014848318398e-08 */
/**/ aa = {0x00000000, 0xBFC55580 },/* -0.1666717529296875 */
/**/ bb = {0x55556E24, 0x3ED55555 },/* 5.0862630208387126e-06 */
/**/ big = {0x00000000, 0x42c80000 },/* 52776558133248 */
/**/ hp0 = {0x54442D18, 0x3FF921FB },/* 1.5707963267948966 */
/**/ hp1 = {0x33145C07, 0x3C91A626 },/* 6.123233995736766e-17 */
/**/ mp1 = {0x58000000, 0x3FF921FB },/* 1.5707963407039642 */
/**/ mp2 = {0x3C000000, 0xBE4DDE97 },/* -1.3909067564377153e-08 */
/**/ mp3 = {0x99D747F2, 0xBC8CB3B3 },/* -4.9789962505147994e-17 */
/**/ pp3 = {0x98000000, 0xBC8CB3B3 },/* -4.9789962314799099e-17 */
/**/ pp4 = {0x23e32ed7, 0xbacd747f },/* -1.9034889620193266e-25 */
/**/ hpinv = {0x6DC9C883, 0x3FE45F30 },/* 0.63661977236758138 */
/**/ toint = {0x00000000, 0x43380000 };/* 6755399441055744 */
#endif
#endif
#endif

View File

@ -0,0 +1,251 @@
/*
* IBM Accurate Mathematical Library
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************************/
/* */
/* MODULE_NAME:utan.h */
/* */
/* common data and variables prototype and definition */
/******************************************************************/
#ifndef UTAN_H
#define UTAN_H
#ifdef BIG_ENDI
static const number
/* polynomial I */
/**/ d3 = {0x3FD55555, 0x55555555, }, /* 0.333... */
/**/ d5 = {0x3FC11111, 0x111107C6, }, /* 0.133... */
/**/ d7 = {0x3FABA1BA, 0x1CDB8745, }, /* . */
/**/ d9 = {0x3F9664ED, 0x49CFC666, }, /* . */
/**/ d11 = {0x3F82385A, 0x3CF2E4EA, }, /* . */
/* polynomial II */
/**/ a3 = {0x3fd55555, 0x55555555, }, /* 1/3 */
/**/ aa3 = {0x3c755555, 0x55555555, }, /* 1/3-a3 */
/**/ a5 = {0x3fc11111, 0x11111111, }, /* 2/15 */
/**/ aa5 = {0x3c411111, 0x11111111, }, /* 2/15-a5 */
/**/ a7 = {0x3faba1ba, 0x1ba1ba1c, }, /* 17/315 */
/**/ aa7 = {0xbc479179, 0x17917918, }, /* ()-a7 */
/**/ a9 = {0x3f9664f4, 0x882c10fa, }, /* 62/2835 */
/**/ aa9 = {0xbc09a528, 0x8b6c44fd, }, /* ()-a9 */
/**/ a11 = {0x3f8226e3, 0x55e6c23d, }, /* . */
/**/ aa11 = {0xbc2c292b, 0x8f1a2c13, }, /* . */
/**/ a13 = {0x3f6d6d3d, 0x0e157de0, }, /* . */
/**/ aa13 = {0xbc0280cf, 0xc968d971, }, /* . */
/**/ a15 = {0x3f57da36, 0x452b75e3, }, /* . */
/**/ aa15 = {0xbbf25789, 0xb285d2ed, }, /* . */
/**/ a17 = {0x3f435582, 0x48036744, }, /* . */
/**/ aa17 = {0x3be488d9, 0x563f1f23, }, /* . */
/**/ a19 = {0x3f2f57d7, 0x734d1664, }, /* . */
/**/ aa19 = {0x3bb0d55a, 0x913ccb50, }, /* . */
/**/ a21 = {0x3f1967e1, 0x8afcafad, }, /* . */
/**/ aa21 = {0xbbbd7614, 0xa42d44e6, }, /* . */
/**/ a23 = {0x3f0497d8, 0xeea25259, }, /* . */
/**/ aa23 = {0x3b99f2d0, 0x2e4d2863, }, /* . */
/**/ a25 = {0x3ef0b132, 0xd39a6050, }, /* . */
/**/ aa25 = {0x3b93b274, 0xc2c19614, }, /* . */
/**/ a27 = {0x3edb0f72, 0xd3ee24e9, }, /* . */
/**/ aa27 = {0x3b61688d, 0xdd595609, }, /* . */
/* polynomial III */
/**/ e0 = {0x3FD55555, 0x55554DBD, }, /* . */
/**/ e1 = {0x3FC11112, 0xE0A6B45F, }, /* . */
/* constants */
/**/ zero = {0x00000000, 0x00000000, }, /* 0 */
/**/ one = {0x3ff00000, 0x00000000, }, /* 1 */
/**/ mone = {0xbff00000, 0x00000000, }, /*-1 */
/**/ mfftnhf = {0xc02f0000, 0x00000000, }, /*-15.5 */
/**/ two8 = {0x40700000, 0x00000000, }, /* 256 */
/**/ g1 = {0x3e4b096c, 0x00000000, }, /* 1.259e-8 */
/**/ g2 = {0x3faf212d, 0x00000000, }, /* 0.0608 */
/**/ g3 = {0x3fe92f1a, 0x00000000, }, /* 0.787 */
/**/ g4 = {0x40390000, 0x00000000, }, /* 25.0 */
/**/ g5 = {0x4197d784, 0x00000000, }, /* 1e8 */
/**/ gy1 = {0x3e7ad7f2, 0x9abcaf48, }, /* 1e-7 */
/**/ gy2 = {0x3faf212d, 0x00000000, }, /* 0.0608 */
/**/ u1 = {0x3cc8c33a, 0x00000000, }, /* 6.873e-16 */
/**/ u2 = {0x3983dc4d, 0x00000000, }, /* 1.224e-31 */
/**/ u3 = {0x3c78e14b, 0x00000000, }, /* 2.158e-17 */
/**/ ua3 = {0x3bfd8b58, 0x00000000, }, /* 1.001e-19 */
/**/ ub3 = {0x3cc81898, 0x00000000, }, /* 6.688e-16 */
/**/ u4 = {0x399856c2, 0x00000000, }, /* 3e-31 */
/**/ u5 = {0x3c39d80a, 0x00000000, }, /* 1.401e-18 */
/**/ u6 = {0x3c374c5a, 0x00000000, }, /* 1.263e-18 */
/**/ u7 = {0x39903beb, 0x00000000, }, /* 2.001e-31 */
/**/ u8 = {0x399c56ae, 0x00000000, }, /* 3.493e-31 */
/**/ u9 = {0x3c7d0ac7, 0x00000000, }, /* 2.519e-17 */
/**/ ua9 = {0x3bfd8b58, 0x00000000, }, /* 1.001e-19 */
/**/ ub9 = {0x3ccc2375, 0x00000000, }, /* 7.810e-16 */
/**/ u10 = {0x3c7e40af, 0x00000000, }, /* 2.624e-17 */
/**/ ua10 = {0x3bfd8b58, 0x00000000, }, /* 1.001e-19 */
/**/ ub10 = {0x3ccc6405, 0x00000000, }, /* 7.880e-16 */
/**/ u11 = {0x39e509b6, 0x00000000, }, /* 8.298e-30 */
/**/ u12 = {0x39e509b6, 0x00000000, }, /* 8.298e-30 */
/**/ u13 = {0x3c39d80a, 0x00000000, }, /* 1.401e-18 */
/**/ u14 = {0x3c374c5a, 0x00000000, }, /* 1.263e-18 */
/**/ u15 = {0x3ab5767a, 0x00000000, }, /* 6.935e-26 */
/**/ u16 = {0x3ab57744, 0x00000000, }, /* 6.936e-26 */
/**/ u17 = {0x3c7d0ac7, 0x00000000, }, /* 2.519e-17 */
/**/ ua17 = {0x3bfdb11f, 0x00000000, }, /* 1.006e-19 */
/**/ ub17 = {0x3ccc2375, 0x00000000, }, /* 7.810e-16 */
/**/ u18 = {0x3c7e40af, 0x00000000, }, /* 2.624e-17 */
/**/ ua18 = {0x3bfdb11f, 0x00000000, }, /* 1.006e-19 */
/**/ ub18 = {0x3ccc6405, 0x00000000, }, /* 7.880e-16 */
/**/ u19 = {0x39a13b61, 0x00000000, }, /* 4.248e-31 */
/**/ u20 = {0x39a13b61, 0x00000000, }, /* 4.248e-31 */
/**/ u21 = {0x3c3bb9b8, 0x00000000, }, /* 1.503e-18 */
/**/ u22 = {0x3c392e08, 0x00000000, }, /* 1.365e-18 */
/**/ u23 = {0x3a0ce706, 0x00000000, }, /* 4.560e-29 */
/**/ u24 = {0x3a0cff5d, 0x00000000, }, /* 4.575e-29 */
/**/ u25 = {0x3c7d0ac7, 0x00000000, }, /* 2.519e-17 */
/**/ ua25 = {0x3bfd8b58, 0x00000000, }, /* 1.001e-19 */
/**/ ub25 = {0x3ccc2375, 0x00000000, }, /* 7.810e-16 */
/**/ u26 = {0x3c7e40af, 0x00000000, }, /* 2.624e-17 */
/**/ ua26 = {0x3bfd8b58, 0x00000000, }, /* 1.001e-19 */
/**/ ub26 = {0x3ccc6405, 0x00000000, }, /* 7.880e-16 */
/**/ u27 = {0x3ad421cb, 0x00000000, }, /* 2.602e-25 */
/**/ u28 = {0x3ad421cb, 0x00000000, }, /* 2.602e-25 */
/**/ mp1 = {0x3FF921FB, 0x58000000, },
/**/ mp2 = {0xBE4DDE97, 0x3C000000, },
/**/ mp3 = {0xBC8CB3B3, 0x99D747F2, },
/**/ pp3 = {0xBC8CB3B3, 0x98000000, },
/**/ pp4 = {0xbacd747f, 0x23e32ed7, },
/**/ hpinv = {0x3FE45F30, 0x6DC9C883, },
/**/ toint = {0x43380000, 0x00000000, };
#else
#ifdef LITTLE_ENDI
static const number
/* polynomial I */
/**/ d3 = {0x55555555, 0x3FD55555, }, /* 0.333... */
/**/ d5 = {0x111107C6, 0x3FC11111, }, /* 0.133... */
/**/ d7 = {0x1CDB8745, 0x3FABA1BA, }, /* . */
/**/ d9 = {0x49CFC666, 0x3F9664ED, }, /* . */
/**/ d11 = {0x3CF2E4EA, 0x3F82385A, }, /* . */
/* polynomial II */
/**/ a3 = {0x55555555, 0x3fd55555, }, /* 1/3 */
/**/ aa3 = {0x55555555, 0x3c755555, }, /* 1/3-a3 */
/**/ a5 = {0x11111111, 0x3fc11111, }, /* 2/15 */
/**/ aa5 = {0x11111111, 0x3c411111, }, /* 2/15-a5 */
/**/ a7 = {0x1ba1ba1c, 0x3faba1ba, }, /* 17/315 */
/**/ aa7 = {0x17917918, 0xbc479179, }, /* ()-a7 */
/**/ a9 = {0x882c10fa, 0x3f9664f4, }, /* 62/2835 */
/**/ aa9 = {0x8b6c44fd, 0xbc09a528, }, /* ()-a9 */
/**/ a11 = {0x55e6c23d, 0x3f8226e3, }, /* . */
/**/ aa11 = {0x8f1a2c13, 0xbc2c292b, }, /* . */
/**/ a13 = {0x0e157de0, 0x3f6d6d3d, }, /* . */
/**/ aa13 = {0xc968d971, 0xbc0280cf, }, /* . */
/**/ a15 = {0x452b75e3, 0x3f57da36, }, /* . */
/**/ aa15 = {0xb285d2ed, 0xbbf25789, }, /* . */
/**/ a17 = {0x48036744, 0x3f435582, }, /* . */
/**/ aa17 = {0x563f1f23, 0x3be488d9, }, /* . */
/**/ a19 = {0x734d1664, 0x3f2f57d7, }, /* . */
/**/ aa19 = {0x913ccb50, 0x3bb0d55a, }, /* . */
/**/ a21 = {0x8afcafad, 0x3f1967e1, }, /* . */
/**/ aa21 = {0xa42d44e6, 0xbbbd7614, }, /* . */
/**/ a23 = {0xeea25259, 0x3f0497d8, }, /* . */
/**/ aa23 = {0x2e4d2863, 0x3b99f2d0, }, /* . */
/**/ a25 = {0xd39a6050, 0x3ef0b132, }, /* . */
/**/ aa25 = {0xc2c19614, 0x3b93b274, }, /* . */
/**/ a27 = {0xd3ee24e9, 0x3edb0f72, }, /* . */
/**/ aa27 = {0xdd595609, 0x3b61688d, }, /* . */
/* polynomial III */
/**/ e0 = {0x55554DBD, 0x3FD55555, }, /* . */
/**/ e1 = {0xE0A6B45F, 0x3FC11112, }, /* . */
/* constants */
/**/ zero = {0x00000000, 0x00000000, }, /* 0 */
/**/ one = {0x00000000, 0x3ff00000, }, /* 1 */
/**/ mone = {0x00000000, 0xbff00000, }, /*-1 */
/**/ mfftnhf = {0x00000000, 0xc02f0000, }, /*-15.5 */
/**/ two8 = {0x00000000, 0x40700000, }, /* 256 */
/**/ g1 = {0x00000000, 0x3e4b096c, }, /* 1.259e-8 */
/**/ g2 = {0x00000000, 0x3faf212d, }, /* 0.0608 */
/**/ g3 = {0x00000000, 0x3fe92f1a, }, /* 0.787 */
/**/ g4 = {0x00000000, 0x40390000, }, /* 25.0 */
/**/ g5 = {0x00000000, 0x4197d784, }, /* 1e8 */
/**/ gy1 = {0x9abcaf48, 0x3e7ad7f2, }, /* 1e-7 */
/**/ gy2 = {0x00000000, 0x3faf212d, }, /* 0.0608 */
/**/ u1 = {0x00000000, 0x3cc8c33a, }, /* 6.873e-16 */
/**/ u2 = {0x00000000, 0x3983dc4d, }, /* 1.224e-31 */
/**/ u3 = {0x00000000, 0x3c78e14b, }, /* 2.158e-17 */
/**/ ua3 = {0x00000000, 0x3bfd8b58, }, /* 1.001e-19 */
/**/ ub3 = {0x00000000, 0x3cc81898, }, /* 6.688e-16 */
/**/ u4 = {0x00000000, 0x399856c2, }, /* 3e-31 */
/**/ u5 = {0x00000000, 0x3c39d80a, }, /* 1.401e-18 */
/**/ u6 = {0x00000000, 0x3c374c5a, }, /* 1.263e-18 */
/**/ u7 = {0x00000000, 0x39903beb, }, /* 2.001e-31 */
/**/ u8 = {0x00000000, 0x399c56ae, }, /* 3.493e-31 */
/**/ u9 = {0x00000000, 0x3c7d0ac7, }, /* 2.519e-17 */
/**/ ua9 = {0x00000000, 0x3bfd8b58, }, /* 1.001e-19 */
/**/ ub9 = {0x00000000, 0x3ccc2375, }, /* 7.810e-16 */
/**/ u10 = {0x00000000, 0x3c7e40af, }, /* 2.624e-17 */
/**/ ua10 = {0x00000000, 0x3bfd8b58, }, /* 1.001e-19 */
/**/ ub10 = {0x00000000, 0x3ccc6405, }, /* 7.880e-16 */
/**/ u11 = {0x00000000, 0x39e509b6, }, /* 8.298e-30 */
/**/ u12 = {0x00000000, 0x39e509b6, }, /* 8.298e-30 */
/**/ u13 = {0x00000000, 0x3c39d80a, }, /* 1.401e-18 */
/**/ u14 = {0x00000000, 0x3c374c5a, }, /* 1.263e-18 */
/**/ u15 = {0x00000000, 0x3ab5767a, }, /* 6.935e-26 */
/**/ u16 = {0x00000000, 0x3ab57744, }, /* 6.936e-26 */
/**/ u17 = {0x00000000, 0x3c7d0ac7, }, /* 2.519e-17 */
/**/ ua17 = {0x00000000, 0x3bfdb11f, }, /* 1.006e-19 */
/**/ ub17 = {0x00000000, 0x3ccc2375, }, /* 7.810e-16 */
/**/ u18 = {0x00000000, 0x3c7e40af, }, /* 2.624e-17 */
/**/ ua18 = {0x00000000, 0x3bfdb11f, }, /* 1.006e-19 */
/**/ ub18 = {0x00000000, 0x3ccc6405, }, /* 7.880e-16 */
/**/ u19 = {0x00000000, 0x39a13b61, }, /* 4.248e-31 */
/**/ u20 = {0x00000000, 0x39a13b61, }, /* 4.248e-31 */
/**/ u21 = {0x00000000, 0x3c3bb9b8, }, /* 1.503e-18 */
/**/ u22 = {0x00000000, 0x3c392e08, }, /* 1.365e-18 */
/**/ u23 = {0x00000000, 0x3a0ce706, }, /* 4.560e-29 */
/**/ u24 = {0x00000000, 0x3a0cff5d, }, /* 4.575e-29 */
/**/ u25 = {0x00000000, 0x3c7d0ac7, }, /* 2.519e-17 */
/**/ ua25 = {0x00000000, 0x3bfd8b58, }, /* 1.001e-19 */
/**/ ub25 = {0x00000000, 0x3ccc2375, }, /* 7.810e-16 */
/**/ u26 = {0x00000000, 0x3c7e40af, }, /* 2.624e-17 */
/**/ ua26 = {0x00000000, 0x3bfd8b58, }, /* 1.001e-19 */
/**/ ub26 = {0x00000000, 0x3ccc6405, }, /* 7.880e-16 */
/**/ u27 = {0x00000000, 0x3ad421cb, }, /* 2.602e-25 */
/**/ u28 = {0x00000000, 0x3ad421cb, }, /* 2.602e-25 */
/**/ mp1 = {0x58000000, 0x3FF921FB, },
/**/ mp2 = {0x3C000000, 0xBE4DDE97, },
/**/ mp3 = {0x99D747F2, 0xBC8CB3B3, },
/**/ pp3 = {0x98000000, 0xBC8CB3B3, },
/**/ pp4 = {0x23e32ed7, 0xbacd747f, },
/**/ hpinv = {0x6DC9C883, 0x3FE45F30, },
/**/ toint = {0x00000000, 0x43380000, };
#endif
#endif
#define ZERO zero.d
#define ONE one.d
#define MONE mone.d
#define TWO8 two8.d
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

View File

@ -0,0 +1 @@
/* Not needed. */

1
sysdeps/m68k/fpu/mpa.c Normal file
View File

@ -0,0 +1 @@
/* Not needed. */

Some files were not shown because too many files have changed in this diff Show More