summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/cmath.rst120
-rw-r--r--Doc/library/math.rst47
-rw-r--r--Include/Python.h1
-rw-r--r--Include/complexobject.h2
-rw-r--r--Include/floatobject.h11
-rw-r--r--Include/pymath.h182
-rw-r--r--Include/pyport.h126
-rw-r--r--Lib/test/cmath_testcases.txt2355
-rw-r--r--Lib/test/ieee754.txt183
-rwxr-xr-xLib/test/test_cmath.py338
-rw-r--r--Lib/test/test_float.py21
-rw-r--r--Lib/test/test_math.py241
-rw-r--r--Makefile.pre.in2
-rw-r--r--Modules/cmathmodule.c1019
-rw-r--r--Modules/mathmodule.c449
-rw-r--r--Objects/complexobject.c64
-rw-r--r--Objects/doubledigits.c601
-rw-r--r--Objects/floatobject.c201
-rw-r--r--Objects/longobject.c12
-rw-r--r--PC/VC6/pythoncore.dsp4
-rw-r--r--PC/VS7.1/pythoncore.vcproj3
-rw-r--r--PC/VS8.0/pythoncore.vcproj4
-rw-r--r--PC/pyconfig.h5
-rw-r--r--PCbuild/pythoncore.vcproj8
-rw-r--r--Python/hypot.c25
-rw-r--r--Python/pymath.c232
-rwxr-xr-xconfigure2
27 files changed, 5096 insertions, 1162 deletions
diff --git a/Doc/library/cmath.rst b/Doc/library/cmath.rst
index 5a9ae05..f78f69c 100644
--- a/Doc/library/cmath.rst
+++ b/Doc/library/cmath.rst
@@ -14,8 +14,81 @@ method: these methods are used to convert the object to a complex or
floating-point number, respectively, and the function is then applied to the
result of the conversion.
-The functions are:
+.. note::
+ On platforms with hardware and system-level support for signed
+ zeros, functions involving branch cuts are continuous on *both*
+ sides of the branch cut: the sign of the zero distinguishes one
+ side of the branch cut from the other. On platforms that do not
+ support signed zeros the continuity is as specified below.
+
+
+Complex coordinates
+-------------------
+
+Complex numbers can be expressed by two important coordinate systems.
+Python's :class:`complex` type uses rectangular coordinates where a number
+on the complex plain is defined by two floats, the real part and the imaginary
+part.
+
+Definition::
+
+ z = x + 1j * y
+
+ x := real(z)
+ y := imag(z)
+
+In engineering the polar coordinate system is popular for complex numbers. In
+polar coordinates a complex number is defined by the radius *r* and the phase
+angle *φ*. The radius *r* is the absolute value of the complex, which can be
+viewed as distance from (0, 0). The radius *r* is always 0 or a positive float.
+The phase angle *φ* is the counter clockwise angle from the positive x axis,
+e.g. *1* has the angle *0*, *1j* has the angle *π/2* and *-1* the angle *-π*.
+
+.. note::
+ While :func:`phase` and func:`polar` return *+π* for a negative real they
+ may return *-π* for a complex with a very small negative imaginary
+ part, e.g. *-1-1E-300j*.
+
+
+Definition::
+
+ z = r * exp(1j * φ)
+ z = r * cis(φ)
+
+ r := abs(z) := sqrt(real(z)**2 + imag(z)**2)
+ phi := phase(z) := atan2(imag(z), real(z))
+ cis(φ) := cos(φ) + 1j * sin(φ)
+
+
+.. function:: phase(x)
+
+ Return phase, also known as the argument, of a complex.
+
+ .. versionadded:: 2.6
+
+
+.. function:: polar(x)
+
+ Convert a :class:`complex` from rectangular coordinates to polar
+ coordinates. The function returns a tuple with the two elements
+ *r* and *phi*. *r* is the distance from 0 and *phi* the phase
+ angle.
+
+ .. versionadded:: 2.6
+
+
+.. function:: rect(r, phi)
+
+ Convert from polar coordinates to rectangular coordinates and return
+ a :class:`complex`.
+
+ .. versionadded:: 2.6
+
+
+
+cmath functions
+---------------
.. function:: acos(x)
@@ -37,30 +110,35 @@ The functions are:
.. function:: asinh(x)
- Return the hyperbolic arc sine of *x*. There are two branch cuts, extending
- left from ``±1j`` to ``±∞j``, both continuous from above. These branch cuts
- should be considered a bug to be corrected in a future release. The correct
- branch cuts should extend along the imaginary axis, one from ``1j`` up to
- ``∞j`` and continuous from the right, and one from ``-1j`` down to ``-∞j``
- and continuous from the left.
+ Return the hyperbolic arc sine of *x*. There are two branch cuts:
+ One extends from ``1j`` along the imaginary axis to ``∞j``,
+ continuous from the right. The other extends from ``-1j`` along
+ the imaginary axis to ``-∞j``, continuous from the left.
+
+ .. versionchanged:: 2.6
+ branch cuts moved to match those recommended by the C99 standard
.. function:: atan(x)
Return the arc tangent of *x*. There are two branch cuts: One extends from
- ``1j`` along the imaginary axis to ``∞j``, continuous from the left. The
+ ``1j`` along the imaginary axis to ``∞j``, continuous from the right. The
other extends from ``-1j`` along the imaginary axis to ``-∞j``, continuous
- from the left. (This should probably be changed so the upper cut becomes
- continuous from the other side.)
+ from the left.
+
+ .. versionchanged:: 2.6
+ direction of continuity of upper cut reversed
.. function:: atanh(x)
Return the hyperbolic arc tangent of *x*. There are two branch cuts: One
- extends from ``1`` along the real axis to ``∞``, continuous from above. The
+ extends from ``1`` along the real axis to ``∞``, continuous from below. The
other extends from ``-1`` along the real axis to ``-∞``, continuous from
- above. (This should probably be changed so the right cut becomes continuous
- from the other side.)
+ above.
+
+ .. versionchanged:: 2.6
+ direction of continuity of right cut reversed
.. function:: cos(x)
@@ -78,6 +156,21 @@ The functions are:
Return the exponential value ``e**x``.
+.. function:: isinf(x)
+
+ Return *True* if the real or the imaginary part of x is positive
+ or negative infinity.
+
+ .. versionadded:: 2.6
+
+
+.. function:: isnan(x)
+
+ Return *True* if the real or imaginary part of x is not a number (NaN).
+
+ .. versionadded:: 2.6
+
+
.. function:: log(x[, base])
Returns the logarithm of *x* to the given *base*. If the *base* is not
@@ -151,3 +244,4 @@ cuts for numerical purposes, a good reference should be the following:
nothing's sign bit. In Iserles, A., and Powell, M. (eds.), The state of the art
in numerical analysis. Clarendon Press (1987) pp165-211.
+
diff --git a/Doc/library/math.rst b/Doc/library/math.rst
index f69c0a0..024897f 100644
--- a/Doc/library/math.rst
+++ b/Doc/library/math.rst
@@ -128,6 +128,14 @@ Power and logarithmic functions:
return the natural logarithm of *x* (that is, the logarithm to base *e*).
+.. function:: log1p(x)
+
+ Return the natural logarithm of *1+x* (base *e*). The
+ result is calculated in a way which is accurate for *x* near zero.
+
+ .. versionadded:: 2.6
+
+
.. function:: log10(x)
Return the base-10 logarithm of *x*.
@@ -135,7 +143,11 @@ Power and logarithmic functions:
.. function:: pow(x, y)
- Return ``x**y``.
+ Return ``x**y``. ``1.0**y`` returns *1.0*, even for ``1.0**nan``. ``0**y``
+ returns *0.* for all positive *y*, *0* and *NAN*.
+
+ .. versionchanged:: 2.6
+ The outcome of ``1**nan`` and ``0**nan`` was undefined.
.. function:: sqrt(x)
@@ -186,6 +198,13 @@ Trigonometric functions:
Return the sine of *x* radians.
+.. function:: asinh(x)
+
+ Return the inverse hyperbolic sine of *x*, in radians.
+
+ .. versionadded:: 2.6
+
+
.. function:: tan(x)
Return the tangent of *x* radians.
@@ -210,6 +229,13 @@ Hyperbolic functions:
Return the hyperbolic cosine of *x*.
+.. function:: acosh(x)
+
+ Return the inverse hyperbolic cosine of *x*, in radians.
+
+ .. versionadded:: 2.6
+
+
.. function:: sinh(x)
Return the hyperbolic sine of *x*.
@@ -219,6 +245,14 @@ Hyperbolic functions:
Return the hyperbolic tangent of *x*.
+
+.. function:: atanh(x)
+
+ Return the inverse hyperbolic tangent of *x*, in radians.
+
+ .. versionadded:: 2.6
+
+
The module also defines two mathematical constants:
@@ -231,6 +265,7 @@ The module also defines two mathematical constants:
The mathematical constant *e*.
+
.. note::
The :mod:`math` module consists mostly of thin wrappers around the platform C
@@ -244,9 +279,17 @@ The module also defines two mathematical constants:
:exc:`OverflowError` isn't defined, and in cases where ``math.log(0)`` raises
:exc:`OverflowError`, ``math.log(0L)`` may raise :exc:`ValueError` instead.
+ All functions return a quite *NaN* if at least one of the args is *NaN*.
+ Signaling *NaN*s raise an exception. The exception type still depends on the
+ platform and libm implementation. It's usually :exc:`ValueError` for *EDOM*
+ and :exc:`OverflowError` for errno *ERANGE*.
+
+ ..versionchanged:: 2.6
+ In earlier versions of Python the outcome of an operation with NaN as
+ input depended on platform and libm implementation.
+
.. seealso::
Module :mod:`cmath`
Complex number versions of many of these functions.
-
diff --git a/Include/Python.h b/Include/Python.h
index b241c86..53f7f59 100644
--- a/Include/Python.h
+++ b/Include/Python.h
@@ -57,6 +57,7 @@
#if defined(PYMALLOC_DEBUG) && !defined(WITH_PYMALLOC)
#error "PYMALLOC_DEBUG requires WITH_PYMALLOC"
#endif
+#include "pymath.h"
#include "pymem.h"
#include "object.h"
diff --git a/Include/complexobject.h b/Include/complexobject.h
index b036444..84b6d8b 100644
--- a/Include/complexobject.h
+++ b/Include/complexobject.h
@@ -19,6 +19,7 @@ typedef struct {
#define c_prod _Py_c_prod
#define c_quot _Py_c_quot
#define c_pow _Py_c_pow
+#define c_abs _Py_c_abs
PyAPI_FUNC(Py_complex) c_sum(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) c_diff(Py_complex, Py_complex);
@@ -26,6 +27,7 @@ PyAPI_FUNC(Py_complex) c_neg(Py_complex);
PyAPI_FUNC(Py_complex) c_prod(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) c_quot(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) c_pow(Py_complex, Py_complex);
+PyAPI_FUNC(double) c_abs(Py_complex);
/* Complex object interface */
diff --git a/Include/floatobject.h b/Include/floatobject.h
index 459b029..2021313 100644
--- a/Include/floatobject.h
+++ b/Include/floatobject.h
@@ -21,6 +21,17 @@ PyAPI_DATA(PyTypeObject) PyFloat_Type;
#define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type)
#define PyFloat_CheckExact(op) (Py_TYPE(op) == &PyFloat_Type)
+#ifdef Py_NAN
+#define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN)
+#endif
+
+#define Py_RETURN_INF(sign) do \
+ if (copysign(1., sign) == 1.) { \
+ return PyFloat_FromDouble(Py_HUGE_VAL); \
+ } else { \
+ return PyFloat_FromDouble(-Py_HUGE_VAL); \
+ } while(0)
+
PyAPI_FUNC(double) PyFloat_GetMax(void);
PyAPI_FUNC(double) PyFloat_GetMin(void);
PyAPI_FUNC(PyObject *) PyFloat_GetInfo(void);
diff --git a/Include/pymath.h b/Include/pymath.h
new file mode 100644
index 0000000..a3735c2
--- /dev/null
+++ b/Include/pymath.h
@@ -0,0 +1,182 @@
+#ifndef Py_PYMATH_H
+#define Py_PYMATH_H
+
+#include "pyconfig.h" /* include for defines */
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+/**************************************************************************
+Symbols and macros to supply platform-independent interfaces to mathematical
+functions and constants
+**************************************************************************/
+
+/* Python provides implementations for copysign, acosh, asinh, atanh,
+ * log1p and hypot in Python/pymath.c just in case your math library doesn't
+ * provide the functions.
+ *
+ *Note: PC/pyconfig.h defines copysign as _copysign
+ */
+#ifndef HAVE_COPYSIGN
+extern double copysign(doube, double);
+#endif
+
+#ifndef HAVE_ACOSH
+extern double acosh(double);
+#endif
+
+#ifndef HAVE_ASINH
+extern double asinh(double);
+#endif
+
+#ifndef HAVE_ATANH
+extern double atanh(double);
+#endif
+
+#ifndef HAVE_LOG1P
+extern double log1p(double);
+#endif
+
+#ifndef HAVE_HYPOT
+extern double hypot(double, double);
+#endif
+
+/* extra declarations */
+#ifndef _MSC_VER
+#ifndef __STDC__
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double modf (double, double *);
+extern double pow(double, double);
+#endif /* __STDC__ */
+#endif /* _MSC_VER */
+
+#ifdef _OSF_SOURCE
+/* OSF1 5.1 doesn't make these available with XOPEN_SOURCE_EXTENDED defined */
+extern int finite(double);
+extern double copysign(double, double);
+#endif
+
+/* High precision defintion of pi and e (Euler)
+ * The values are taken from libc6's math.h.
+ */
+#ifndef Py_MATH_PIl
+#define Py_MATH_PIl 3.1415926535897932384626433832795029L
+#endif
+#ifndef Py_MATH_PI
+#define Py_MATH_PI 3.14159265358979323846
+#endif
+
+#ifndef Py_MATH_El
+#define Py_MATH_El 2.7182818284590452353602874713526625L
+#endif
+
+#ifndef Py_MATH_E
+#define Py_MATH_E 2.7182818284590452354
+#endif
+
+/* Py_IS_NAN(X)
+ * Return 1 if float or double arg is a NaN, else 0.
+ * Caution:
+ * X is evaluated more than once.
+ * This may not work on all platforms. Each platform has *some*
+ * way to spell this, though -- override in pyconfig.h if you have
+ * a platform where it doesn't work.
+ * Note: PC/pyconfig.h defines Py_IS_NAN as _isnan
+ */
+#ifndef Py_IS_NAN
+#ifdef HAVE_ISNAN
+#define Py_IS_NAN(X) isnan(X)
+#else
+#define Py_IS_NAN(X) ((X) != (X))
+#endif
+#endif
+
+/* Py_IS_INFINITY(X)
+ * Return 1 if float or double arg is an infinity, else 0.
+ * Caution:
+ * X is evaluated more than once.
+ * This implementation may set the underflow flag if |X| is very small;
+ * it really can't be implemented correctly (& easily) before C99.
+ * Override in pyconfig.h if you have a better spelling on your platform.
+ * Note: PC/pyconfig.h defines Py_IS_INFINITY as _isinf
+ */
+#ifndef Py_IS_INFINITY
+#ifdef HAVE_ISINF
+#define Py_IS_INFINITY(X) isinf(X)
+#else
+#define Py_IS_INFINITY(X) ((X) && (X)*0.5 == (X))
+#endif
+#endif
+
+/* Py_IS_FINITE(X)
+ * Return 1 if float or double arg is neither infinite nor NAN, else 0.
+ * Some compilers (e.g. VisualStudio) have intrisics for this, so a special
+ * macro for this particular test is useful
+ * Note: PC/pyconfig.h defines Py_IS_FINITE as _finite
+ */
+#ifndef Py_IS_FINITE
+#ifdef HAVE_FINITE
+#define Py_IS_FINITE(X) finite(X)
+#else
+#define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X))
+#endif
+#endif
+
+/* HUGE_VAL is supposed to expand to a positive double infinity. Python
+ * uses Py_HUGE_VAL instead because some platforms are broken in this
+ * respect. We used to embed code in pyport.h to try to worm around that,
+ * but different platforms are broken in conflicting ways. If you're on
+ * a platform where HUGE_VAL is defined incorrectly, fiddle your Python
+ * config to #define Py_HUGE_VAL to something that works on your platform.
+ */
+#ifndef Py_HUGE_VAL
+#define Py_HUGE_VAL HUGE_VAL
+#endif
+
+/* Py_NAN
+ * A value that evaluates to a NaN. On IEEE 754 platforms INF*0 or
+ * INF/INF works. Define Py_NO_NAN in pyconfig.h if your platform
+ * doesn't support NaNs.
+ */
+#if !defined(Py_NAN) && !defined(Py_NO_NAN)
+#define Py_NAN (Py_HUGE_VAL * 0.)
+#endif
+
+/* Py_OVERFLOWED(X)
+ * Return 1 iff a libm function overflowed. Set errno to 0 before calling
+ * a libm function, and invoke this macro after, passing the function
+ * result.
+ * Caution:
+ * This isn't reliable. C99 no longer requires libm to set errno under
+ * any exceptional condition, but does require +- HUGE_VAL return
+ * values on overflow. A 754 box *probably* maps HUGE_VAL to a
+ * double infinity, and we're cool if that's so, unless the input
+ * was an infinity and an infinity is the expected result. A C89
+ * system sets errno to ERANGE, so we check for that too. We're
+ * out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or
+ * if the returned result is a NaN, or if a C89 box returns HUGE_VAL
+ * in non-overflow cases.
+ * X is evaluated more than once.
+ * Some platforms have better way to spell this, so expect some #ifdef'ery.
+ *
+ * OpenBSD uses 'isinf()' because a compiler bug on that platform causes
+ * the longer macro version to be mis-compiled. This isn't optimal, and
+ * should be removed once a newer compiler is available on that platform.
+ * The system that had the failure was running OpenBSD 3.2 on Intel, with
+ * gcc 2.95.3.
+ *
+ * According to Tim's checkin, the FreeBSD systems use isinf() to work
+ * around a FPE bug on that platform.
+ */
+#if defined(__FreeBSD__) || defined(__OpenBSD__)
+#define Py_OVERFLOWED(X) isinf(X)
+#else
+#define Py_OVERFLOWED(X) ((X) != 0.0 && (errno == ERANGE || \
+ (X) == Py_HUGE_VAL || \
+ (X) == -Py_HUGE_VAL))
+#endif
+
+#endif /* Py_PYMATH_H */
diff --git a/Include/pyport.h b/Include/pyport.h
index 3755e38..18bdb0c 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -336,123 +336,6 @@ extern "C" {
#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE)
#endif
-/* High precision defintion of pi and e (Euler)
- * The values are taken from libc6's math.h.
- */
-#ifndef Py_MATH_PIl
-#define Py_MATH_PIl 3.1415926535897932384626433832795029L
-#endif
-#ifndef Py_MATH_PI
-#define Py_MATH_PI 3.14159265358979323846
-#endif
-
-#ifndef Py_MATH_El
-#define Py_MATH_El 2.7182818284590452353602874713526625L
-#endif
-
-#ifndef Py_MATH_E
-#define Py_MATH_E 2.7182818284590452354
-#endif
-
-/* Py_IS_NAN(X)
- * Return 1 if float or double arg is a NaN, else 0.
- * Caution:
- * X is evaluated more than once.
- * This may not work on all platforms. Each platform has *some*
- * way to spell this, though -- override in pyconfig.h if you have
- * a platform where it doesn't work.
- */
-#ifndef Py_IS_NAN
-#ifdef HAVE_ISNAN
-#define Py_IS_NAN(X) isnan(X)
-#else
-#define Py_IS_NAN(X) ((X) != (X))
-#endif
-#endif
-
-/* Py_IS_INFINITY(X)
- * Return 1 if float or double arg is an infinity, else 0.
- * Caution:
- * X is evaluated more than once.
- * This implementation may set the underflow flag if |X| is very small;
- * it really can't be implemented correctly (& easily) before C99.
- * Override in pyconfig.h if you have a better spelling on your platform.
- */
-#ifndef Py_IS_INFINITY
-#ifdef HAVE_ISINF
-#define Py_IS_INFINITY(X) isinf(X)
-#else
-#define Py_IS_INFINITY(X) ((X) && (X)*0.5 == (X))
-#endif
-#endif
-
-/* Py_IS_FINITE(X)
- * Return 1 if float or double arg is neither infinite nor NAN, else 0.
- * Some compilers (e.g. VisualStudio) have intrisics for this, so a special
- * macro for this particular test is useful
- */
-#ifndef Py_IS_FINITE
-#ifdef HAVE_FINITE
-#define Py_IS_FINITE(X) finite(X)
-#else
-#define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X))
-#endif
-#endif
-
-/* HUGE_VAL is supposed to expand to a positive double infinity. Python
- * uses Py_HUGE_VAL instead because some platforms are broken in this
- * respect. We used to embed code in pyport.h to try to worm around that,
- * but different platforms are broken in conflicting ways. If you're on
- * a platform where HUGE_VAL is defined incorrectly, fiddle your Python
- * config to #define Py_HUGE_VAL to something that works on your platform.
- */
-#ifndef Py_HUGE_VAL
-#define Py_HUGE_VAL HUGE_VAL
-#endif
-
-/* Py_NAN
- * A value that evaluates to a NaN. On IEEE 754 platforms INF*0 or
- * INF/INF works. Define Py_NO_NAN in pyconfig.h if your platform
- * doesn't support NaNs.
- */
-#if !defined(Py_NAN) && !defined(Py_NO_NAN)
-#define Py_NAN (Py_HUGE_VAL * 0.)
-#endif
-
-/* Py_OVERFLOWED(X)
- * Return 1 iff a libm function overflowed. Set errno to 0 before calling
- * a libm function, and invoke this macro after, passing the function
- * result.
- * Caution:
- * This isn't reliable. C99 no longer requires libm to set errno under
- * any exceptional condition, but does require +- HUGE_VAL return
- * values on overflow. A 754 box *probably* maps HUGE_VAL to a
- * double infinity, and we're cool if that's so, unless the input
- * was an infinity and an infinity is the expected result. A C89
- * system sets errno to ERANGE, so we check for that too. We're
- * out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or
- * if the returned result is a NaN, or if a C89 box returns HUGE_VAL
- * in non-overflow cases.
- * X is evaluated more than once.
- * Some platforms have better way to spell this, so expect some #ifdef'ery.
- *
- * OpenBSD uses 'isinf()' because a compiler bug on that platform causes
- * the longer macro version to be mis-compiled. This isn't optimal, and
- * should be removed once a newer compiler is available on that platform.
- * The system that had the failure was running OpenBSD 3.2 on Intel, with
- * gcc 2.95.3.
- *
- * According to Tim's checkin, the FreeBSD systems use isinf() to work
- * around a FPE bug on that platform.
- */
-#if defined(__FreeBSD__) || defined(__OpenBSD__)
-#define Py_OVERFLOWED(X) isinf(X)
-#else
-#define Py_OVERFLOWED(X) ((X) != 0.0 && (errno == ERANGE || \
- (X) == Py_HUGE_VAL || \
- (X) == -Py_HUGE_VAL))
-#endif
-
/* Py_SET_ERRNO_ON_MATH_ERROR(x)
* If a libm function did not set errno, but it looks like the result
* overflowed or not-a-number, set errno to ERANGE or EDOM. Set errno
@@ -559,15 +442,6 @@ extern pid_t forkpty(int *, char *, struct termios *, struct winsize *);
#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
-/************************
- * WRAPPER FOR <math.h> *
- ************************/
-
-#ifndef HAVE_HYPOT
-extern double hypot(double, double);
-#endif
-
-
/* On 4.4BSD-descendants, ctype functions serves the whole range of
* wchar_t character set rather than single byte code points only.
* This characteristic can break some operations of string object
diff --git a/Lib/test/cmath_testcases.txt b/Lib/test/cmath_testcases.txt
new file mode 100644
index 0000000..2fabebf
--- /dev/null
+++ b/Lib/test/cmath_testcases.txt
@@ -0,0 +1,2355 @@
+-- Testcases for functions in cmath.
+--
+-- Each line takes the form:
+--
+-- <testid> <function> <input_value> -> <output_value> <flags>
+--
+-- where:
+--
+-- <testid> is a short name identifying the test,
+--
+-- <function> is the function to be tested (exp, cos, asinh, ...),
+--
+-- <input_value> is a pair of floats separated by whitespace
+-- representing real and imaginary parts of a complex number, and
+--
+-- <output_value> is the expected (ideal) output value, again
+-- represented as a pair of floats.
+--
+-- <flags> is a list of the floating-point flags required by C99
+--
+-- The possible flags are:
+--
+-- divide-by-zero : raised when a finite input gives a
+-- mathematically infinite result.
+--
+-- overflow : raised when a finite input gives a finite result whose
+-- real or imaginary part is too large to fit in the usual range
+-- of an IEEE 754 double.
+--
+-- invalid : raised for invalid inputs.
+--
+-- ignore-real-sign : indicates that the sign of the real part of
+-- the result is unspecified; if the real part of the result is
+-- given as inf, then both -inf and inf should be accepted as
+-- correct.
+--
+-- ignore-imag-sign : indicates that the sign of the imaginary part
+-- of the result is unspecified.
+--
+-- Flags may appear in any order.
+--
+-- Lines beginning with '--' (like this one) start a comment, and are
+-- ignored. Blank lines, or lines containing only whitespace, are also
+-- ignored.
+
+
+--------------------------
+-- acos: Inverse cosine --
+--------------------------
+
+-- zeros
+acos0000 acos 0.0 0.0 -> 1.5707963267948966 -0.0
+acos0001 acos 0.0 -0.0 -> 1.5707963267948966 0.0
+acos0002 acos -0.0 0.0 -> 1.5707963267948966 -0.0
+acos0003 acos -0.0 -0.0 -> 1.5707963267948966 0.0
+
+-- branch points: +/-1
+acos0010 acos 1.0 0.0 -> 0.0 -0.0
+acos0011 acos 1.0 -0.0 -> 0.0 0.0
+acos0012 acos -1.0 0.0 -> 3.1415926535897931 -0.0
+acos0013 acos -1.0 -0.0 -> 3.1415926535897931 0.0
+
+-- values along both sides of real axis
+acos0020 acos -9.8813129168249309e-324 0.0 -> 1.5707963267948966 -0.0
+acos0021 acos -9.8813129168249309e-324 -0.0 -> 1.5707963267948966 0.0
+acos0022 acos -1e-305 0.0 -> 1.5707963267948966 -0.0
+acos0023 acos -1e-305 -0.0 -> 1.5707963267948966 0.0
+acos0024 acos -1e-150 0.0 -> 1.5707963267948966 -0.0
+acos0025 acos -1e-150 -0.0 -> 1.5707963267948966 0.0
+acos0026 acos -9.9999999999999998e-17 0.0 -> 1.5707963267948968 -0.0
+acos0027 acos -9.9999999999999998e-17 -0.0 -> 1.5707963267948968 0.0
+acos0028 acos -0.001 0.0 -> 1.5717963269615634 -0.0
+acos0029 acos -0.001 -0.0 -> 1.5717963269615634 0.0
+acos0030 acos -0.57899999999999996 0.0 -> 2.1882979816120667 -0.0
+acos0031 acos -0.57899999999999996 -0.0 -> 2.1882979816120667 0.0
+acos0032 acos -0.99999999999999989 0.0 -> 3.1415926386886319 -0.0
+acos0033 acos -0.99999999999999989 -0.0 -> 3.1415926386886319 0.0
+acos0034 acos -1.0000000000000002 0.0 -> 3.1415926535897931 -2.1073424255447014e-08
+acos0035 acos -1.0000000000000002 -0.0 -> 3.1415926535897931 2.1073424255447014e-08
+acos0036 acos -1.0009999999999999 0.0 -> 3.1415926535897931 -0.044717633608306849
+acos0037 acos -1.0009999999999999 -0.0 -> 3.1415926535897931 0.044717633608306849
+acos0038 acos -2.0 0.0 -> 3.1415926535897931 -1.3169578969248168
+acos0039 acos -2.0 -0.0 -> 3.1415926535897931 1.3169578969248168
+acos0040 acos -23.0 0.0 -> 3.1415926535897931 -3.8281684713331012
+acos0041 acos -23.0 -0.0 -> 3.1415926535897931 3.8281684713331012
+acos0042 acos -10000000000000000.0 0.0 -> 3.1415926535897931 -37.534508668464674
+acos0043 acos -10000000000000000.0 -0.0 -> 3.1415926535897931 37.534508668464674
+acos0044 acos -9.9999999999999998e+149 0.0 -> 3.1415926535897931 -346.08091112966679
+acos0045 acos -9.9999999999999998e+149 -0.0 -> 3.1415926535897931 346.08091112966679
+acos0046 acos -1.0000000000000001e+299 0.0 -> 3.1415926535897931 -689.16608998577965
+acos0047 acos -1.0000000000000001e+299 -0.0 -> 3.1415926535897931 689.16608998577965
+acos0048 acos 9.8813129168249309e-324 0.0 -> 1.5707963267948966 -0.0
+acos0049 acos 9.8813129168249309e-324 -0.0 -> 1.5707963267948966 0.0
+acos0050 acos 1e-305 0.0 -> 1.5707963267948966 -0.0
+acos0051 acos 1e-305 -0.0 -> 1.5707963267948966 0.0
+acos0052 acos 1e-150 0.0 -> 1.5707963267948966 -0.0
+acos0053 acos 1e-150 -0.0 -> 1.5707963267948966 0.0
+acos0054 acos 9.9999999999999998e-17 0.0 -> 1.5707963267948966 -0.0
+acos0055 acos 9.9999999999999998e-17 -0.0 -> 1.5707963267948966 0.0
+acos0056 acos 0.001 0.0 -> 1.56979632662823 -0.0
+acos0057 acos 0.001 -0.0 -> 1.56979632662823 0.0
+acos0058 acos 0.57899999999999996 0.0 -> 0.95329467197772655 -0.0
+acos0059 acos 0.57899999999999996 -0.0 -> 0.95329467197772655 0.0
+acos0060 acos 0.99999999999999989 0.0 -> 1.4901161193847656e-08 -0.0
+acos0061 acos 0.99999999999999989 -0.0 -> 1.4901161193847656e-08 0.0
+acos0062 acos 1.0000000000000002 0.0 -> 0.0 -2.1073424255447014e-08
+acos0063 acos 1.0000000000000002 -0.0 -> 0.0 2.1073424255447014e-08
+acos0064 acos 1.0009999999999999 0.0 -> 0.0 -0.044717633608306849
+acos0065 acos 1.0009999999999999 -0.0 -> 0.0 0.044717633608306849
+acos0066 acos 2.0 0.0 -> 0.0 -1.3169578969248168
+acos0067 acos 2.0 -0.0 -> 0.0 1.3169578969248168
+acos0068 acos 23.0 0.0 -> 0.0 -3.8281684713331012
+acos0069 acos 23.0 -0.0 -> 0.0 3.8281684713331012
+acos0070 acos 10000000000000000.0 0.0 -> 0.0 -37.534508668464674
+acos0071 acos 10000000000000000.0 -0.0 -> 0.0 37.534508668464674
+acos0072 acos 9.9999999999999998e+149 0.0 -> 0.0 -346.08091112966679
+acos0073 acos 9.9999999999999998e+149 -0.0 -> 0.0 346.08091112966679
+acos0074 acos 1.0000000000000001e+299 0.0 -> 0.0 -689.16608998577965
+acos0075 acos 1.0000000000000001e+299 -0.0 -> 0.0 689.16608998577965
+
+-- random inputs
+acos0100 acos -3.3307113324596682 -10.732007530863266 -> 1.8706085694482339 3.113986806554613
+acos0101 acos -2863.952991743291 -2681013315.2571239 -> 1.5707973950301699 22.402607843274758
+acos0102 acos -0.33072639793220088 -0.85055464658253055 -> 1.8219426895922601 0.79250166729311966
+acos0103 acos -2.5722325842097802 -12.703940809821574 -> 1.7699942413107408 3.2565170156527325
+acos0104 acos -42.495233785459583 -0.54039320751337161 -> 3.1288732573153304 4.4424815519735601
+acos0105 acos -1.1363818625856401 9641.1325498630376 -> 1.5709141948820049 -9.8669410553254284
+acos0106 acos -2.4398426824157866e-11 0.33002051890266165 -> 1.570796326818066 -0.32430578041578667
+acos0107 acos -1.3521340428186552 2.9369737912076772 -> 1.9849059192339338 -1.8822893674117942
+acos0108 acos -1.827364706477915 1.0355459232147557 -> 2.5732246307960032 -1.4090688267854969
+acos0109 acos -0.25978373706403546 10.09712669185833 -> 1.5963940386378306 -3.0081673050196063
+acos0110 acos 0.33561778471072551 -4587350.6823999118 -> 1.5707962536333251 16.031960402579539
+acos0111 acos 0.49133444610998445 -0.8071422362990015 -> 1.1908761712801788 0.78573345813187867
+acos0112 acos 0.42196734507823974 -2.4812965431745115 -> 1.414091186100692 1.651707260988172
+acos0113 acos 2.961426210100655 -219.03295695248664 -> 1.5572768319822778 6.0824659885827304
+acos0114 acos 2.886209063652641 -20.38011207220606 -> 1.4302765252297889 3.718201853147642
+acos0115 acos 0.4180568075276509 1.4833433990823484 -> 1.3393834558303042 -1.2079847758301576
+acos0116 acos 52.376111405924718 0.013930429001941001 -> 0.00026601761804024188 -4.6515066691204714
+acos0117 acos 41637948387.625969 1.563418292894041 -> 3.7547918507883548e-11 -25.145424989809381
+acos0118 acos 0.061226659122249526 0.8447234394615154 -> 1.5240280306367315 -0.76791798971140812
+acos0119 acos 2.4480466420442959e+26 0.18002339201384662 -> 7.353756620564798e-28 -61.455650015996376
+
+-- values near infinity
+acos0200 acos 1.6206860518683021e+308 1.0308426226285283e+308 -> 0.56650826093826223 -710.54206874241561
+acos0201 acos 1.2067735875070062e+308 -1.3429173724390276e+308 -> 0.83874369390864889 710.48017794027498
+acos0202 acos -7.4130145132549047e+307 1.1759130543927645e+308 -> 2.1332729346478536 -710.21871115698752
+acos0203 acos -8.6329426442257249e+307 -1.2316282952184133e+308 -> 2.1821511032444838 710.29752145697148
+acos0204 acos 0.0 1.4289713855849746e+308 -> 1.5707963267948966 -710.24631069738996
+acos0205 acos -0.0 1.3153524545987432e+308 -> 1.5707963267948966 -710.1634604787539
+acos0206 acos 0.0 -9.6229037669269321e+307 -> 1.5707963267948966 709.85091679573691
+acos0207 acos -0.0 -4.9783616421107088e+307 -> 1.5707963267948966 709.19187157911233
+acos0208 acos 1.3937541925739389e+308 0.0 -> 0.0 -710.22135678707264
+acos0209 acos 9.1362388967371536e+307 -0.0 -> 0.0 709.79901953124613
+acos0210 acos -1.3457361220697436e+308 0.0 -> 3.1415926535897931 -710.18629698871848
+acos0211 acos -5.4699090056144284e+307 -0.0 -> 3.1415926535897931 709.28603271085649
+acos0212 acos 1.5880716932358901e+308 5.5638401252339929 -> 3.503519487773873e-308 -710.35187633140583
+acos0213 acos 1.2497211663463164e+308 -3.0456477717911024 -> 2.4370618453197486e-308 710.11227628223412
+acos0214 acos -9.9016224006029528e+307 4.9570427340789056 -> 3.1415926535897931 -709.87946935229468
+acos0215 acos -1.5854071066874139e+308 -4.4233577741497783 -> 3.1415926535897931 710.35019704672004
+acos0216 acos 9.3674623083647628 1.5209559051877979e+308 -> 1.5707963267948966 -710.30869484491086
+acos0217 acos 8.1773832021784383 -6.6093445795000056e+307 -> 1.5707963267948966 709.4752552227792
+acos0218 acos -3.1845935000665104 1.5768856396650893e+308 -> 1.5707963267948966 -710.34480761042687
+acos0219 acos -1.0577303880953903 -6.4574626815735613e+307 -> 1.5707963267948966 709.45200719662046
+
+-- values near 0
+acos0220 acos 1.8566986970714045e-320 3.1867234156760402e-321 -> 1.5707963267948966 -3.1867234156760402e-321
+acos0221 acos 7.9050503334599447e-323 -8.8931816251424378e-323 -> 1.5707963267948966 8.8931816251424378e-323
+acos0222 acos -4.4465908125712189e-323 2.4654065097222727e-311 -> 1.5707963267948966 -2.4654065097222727e-311
+acos0223 acos -6.1016916408192619e-311 -2.4703282292062327e-323 -> 1.5707963267948966 2.4703282292062327e-323
+acos0224 acos 0.0 3.4305783621842729e-311 -> 1.5707963267948966 -3.4305783621842729e-311
+acos0225 acos -0.0 1.6117409498633145e-319 -> 1.5707963267948966 -1.6117409498633145e-319
+acos0226 acos 0.0 -4.9900630229965901e-322 -> 1.5707963267948966 4.9900630229965901e-322
+acos0227 acos -0.0 -4.4889279210592818e-311 -> 1.5707963267948966 4.4889279210592818e-311
+acos0228 acos 5.3297678681477214e-312 0.0 -> 1.5707963267948966 -0.0
+acos0229 acos 6.2073425897211614e-313 -0.0 -> 1.5707963267948966 0.0
+acos0230 acos -4.9406564584124654e-324 0.0 -> 1.5707963267948966 -0.0
+acos0231 acos -1.7107517052899003e-318 -0.0 -> 1.5707963267948966 0.0
+
+-- special values
+acos1000 acos 0.0 0.0 -> 1.5707963267948966 -0.0
+acos1001 acos 0.0 -0.0 -> 1.5707963267948966 0.0
+acos1002 acos -0.0 0.0 -> 1.5707963267948966 -0.0
+acos1003 acos -0.0 -0.0 -> 1.5707963267948966 0.0
+acos1004 acos 0.0 nan -> 1.5707963267948966 nan
+acos1005 acos -0.0 nan -> 1.5707963267948966 nan
+acos1006 acos -2.3 inf -> 1.5707963267948966 -inf
+acos1007 acos -0.0 inf -> 1.5707963267948966 -inf
+acos1008 acos 0.0 inf -> 1.5707963267948966 -inf
+acos1009 acos 2.3 inf -> 1.5707963267948966 -inf
+acos1010 acos -2.3 nan -> nan nan
+acos1011 acos 2.3 nan -> nan nan
+acos1012 acos -inf 2.3 -> 3.1415926535897931 -inf
+acos1013 acos -inf 0.0 -> 3.1415926535897931 -inf
+acos1014 acos inf 2.3 -> 0.0 -inf
+acos1015 acos inf 0.0 -> 0.0 -inf
+acos1016 acos -inf inf -> 2.3561944901923448 -inf
+acos1017 acos inf inf -> 0.78539816339744828 -inf
+acos1018 acos inf nan -> nan inf ignore-imag-sign
+acos1019 acos -inf nan -> nan inf ignore-imag-sign
+acos1020 acos nan 0.0 -> nan nan
+acos1021 acos nan 2.3 -> nan nan
+acos1022 acos nan inf -> nan -inf
+acos1023 acos nan nan -> nan nan
+acos1024 acos -2.3 -inf -> 1.5707963267948966 inf
+acos1025 acos -0.0 -inf -> 1.5707963267948966 inf
+acos1026 acos 0.0 -inf -> 1.5707963267948966 inf
+acos1027 acos 2.3 -inf -> 1.5707963267948966 inf
+acos1028 acos -inf -2.3 -> 3.1415926535897931 inf
+acos1029 acos -inf -0.0 -> 3.1415926535897931 inf
+acos1030 acos inf -2.3 -> 0.0 inf
+acos1031 acos inf -0.0 -> 0.0 inf
+acos1032 acos -inf -inf -> 2.3561944901923448 inf
+acos1033 acos inf -inf -> 0.78539816339744828 inf
+acos1034 acos nan -0.0 -> nan nan
+acos1035 acos nan -2.3 -> nan nan
+acos1036 acos nan -inf -> nan inf
+
+
+--------------------------------------
+-- acosh: Inverse hyperbolic cosine --
+--------------------------------------
+
+-- zeros
+acosh0000 acosh 0.0 0.0 -> 0.0 1.5707963267948966
+acosh0001 acosh 0.0 -0.0 -> 0.0 -1.5707963267948966
+acosh0002 acosh -0.0 0.0 -> 0.0 1.5707963267948966
+acosh0003 acosh -0.0 -0.0 -> 0.0 -1.5707963267948966
+
+-- branch points: +/-1
+acosh0010 acosh 1.0 0.0 -> 0.0 0.0
+acosh0011 acosh 1.0 -0.0 -> 0.0 -0.0
+acosh0012 acosh -1.0 0.0 -> 0.0 3.1415926535897931
+acosh0013 acosh -1.0 -0.0 -> 0.0 -3.1415926535897931
+
+-- values along both sides of real axis
+acosh0020 acosh -9.8813129168249309e-324 0.0 -> 0.0 1.5707963267948966
+acosh0021 acosh -9.8813129168249309e-324 -0.0 -> 0.0 -1.5707963267948966
+acosh0022 acosh -1e-305 0.0 -> 0.0 1.5707963267948966
+acosh0023 acosh -1e-305 -0.0 -> 0.0 -1.5707963267948966
+acosh0024 acosh -1e-150 0.0 -> 0.0 1.5707963267948966
+acosh0025 acosh -1e-150 -0.0 -> 0.0 -1.5707963267948966
+acosh0026 acosh -9.9999999999999998e-17 0.0 -> 0.0 1.5707963267948968
+acosh0027 acosh -9.9999999999999998e-17 -0.0 -> 0.0 -1.5707963267948968
+acosh0028 acosh -0.001 0.0 -> 0.0 1.5717963269615634
+acosh0029 acosh -0.001 -0.0 -> 0.0 -1.5717963269615634
+acosh0030 acosh -0.57899999999999996 0.0 -> 0.0 2.1882979816120667
+acosh0031 acosh -0.57899999999999996 -0.0 -> 0.0 -2.1882979816120667
+acosh0032 acosh -0.99999999999999989 0.0 -> 0.0 3.1415926386886319
+acosh0033 acosh -0.99999999999999989 -0.0 -> 0.0 -3.1415926386886319
+acosh0034 acosh -1.0000000000000002 0.0 -> 2.1073424255447014e-08 3.1415926535897931
+acosh0035 acosh -1.0000000000000002 -0.0 -> 2.1073424255447014e-08 -3.1415926535897931
+acosh0036 acosh -1.0009999999999999 0.0 -> 0.044717633608306849 3.1415926535897931
+acosh0037 acosh -1.0009999999999999 -0.0 -> 0.044717633608306849 -3.1415926535897931
+acosh0038 acosh -2.0 0.0 -> 1.3169578969248168 3.1415926535897931
+acosh0039 acosh -2.0 -0.0 -> 1.3169578969248168 -3.1415926535897931
+acosh0040 acosh -23.0 0.0 -> 3.8281684713331012 3.1415926535897931
+acosh0041 acosh -23.0 -0.0 -> 3.8281684713331012 -3.1415926535897931
+acosh0042 acosh -10000000000000000.0 0.0 -> 37.534508668464674 3.1415926535897931
+acosh0043 acosh -10000000000000000.0 -0.0 -> 37.534508668464674 -3.1415926535897931
+acosh0044 acosh -9.9999999999999998e+149 0.0 -> 346.08091112966679 3.1415926535897931
+acosh0045 acosh -9.9999999999999998e+149 -0.0 -> 346.08091112966679 -3.1415926535897931
+acosh0046 acosh -1.0000000000000001e+299 0.0 -> 689.16608998577965 3.1415926535897931
+acosh0047 acosh -1.0000000000000001e+299 -0.0 -> 689.16608998577965 -3.1415926535897931
+acosh0048 acosh 9.8813129168249309e-324 0.0 -> 0.0 1.5707963267948966
+acosh0049 acosh 9.8813129168249309e-324 -0.0 -> 0.0 -1.5707963267948966
+acosh0050 acosh 1e-305 0.0 -> 0.0 1.5707963267948966
+acosh0051 acosh 1e-305 -0.0 -> 0.0 -1.5707963267948966
+acosh0052 acosh 1e-150 0.0 -> 0.0 1.5707963267948966
+acosh0053 acosh 1e-150 -0.0 -> 0.0 -1.5707963267948966
+acosh0054 acosh 9.9999999999999998e-17 0.0 -> 0.0 1.5707963267948966
+acosh0055 acosh 9.9999999999999998e-17 -0.0 -> 0.0 -1.5707963267948966
+acosh0056 acosh 0.001 0.0 -> 0.0 1.56979632662823
+acosh0057 acosh 0.001 -0.0 -> 0.0 -1.56979632662823
+acosh0058 acosh 0.57899999999999996 0.0 -> 0.0 0.95329467197772655
+acosh0059 acosh 0.57899999999999996 -0.0 -> 0.0 -0.95329467197772655
+acosh0060 acosh 0.99999999999999989 0.0 -> 0.0 1.4901161193847656e-08
+acosh0061 acosh 0.99999999999999989 -0.0 -> 0.0 -1.4901161193847656e-08
+acosh0062 acosh 1.0000000000000002 0.0 -> 2.1073424255447014e-08 0.0
+acosh0063 acosh 1.0000000000000002 -0.0 -> 2.1073424255447014e-08 -0.0
+acosh0064 acosh 1.0009999999999999 0.0 -> 0.044717633608306849 0.0
+acosh0065 acosh 1.0009999999999999 -0.0 -> 0.044717633608306849 -0.0
+acosh0066 acosh 2.0 0.0 -> 1.3169578969248168 0.0
+acosh0067 acosh 2.0 -0.0 -> 1.3169578969248168 -0.0
+acosh0068 acosh 23.0 0.0 -> 3.8281684713331012 0.0
+acosh0069 acosh 23.0 -0.0 -> 3.8281684713331012 -0.0
+acosh0070 acosh 10000000000000000.0 0.0 -> 37.534508668464674 0.0
+acosh0071 acosh 10000000000000000.0 -0.0 -> 37.534508668464674 -0.0
+acosh0072 acosh 9.9999999999999998e+149 0.0 -> 346.08091112966679 0.0
+acosh0073 acosh 9.9999999999999998e+149 -0.0 -> 346.08091112966679 -0.0
+acosh0074 acosh 1.0000000000000001e+299 0.0 -> 689.16608998577965 0.0
+acosh0075 acosh 1.0000000000000001e+299 -0.0 -> 689.16608998577965 -0.0
+
+-- random inputs
+acosh0100 acosh -1.4328589581250843 -1.8370347775558309 -> 1.5526962646549587 -2.190250168435786
+acosh0101 acosh -0.31075819156220957 -1.0772555786839297 -> 0.95139168286193709 -1.7812228089636479
+acosh0102 acosh -1.9044776578070453 -20.485370158932124 -> 3.7177411088932359 -1.6633888745861227
+acosh0103 acosh -0.075642506000858742 -21965976320.873051 -> 24.505907742881991 -1.5707963267983402
+acosh0104 acosh -1.6162271181056307 -3.0369343458696099 -> 1.9407057262861227 -2.0429549461750209
+acosh0105 acosh -0.3103780280298063 0.00018054880018078987 -> 0.00018992877058761416 1.886386995096728
+acosh0106 acosh -9159468751.5897655 5.8014747664273649 -> 23.631201197959193 3.1415926529564078
+acosh0107 acosh -0.037739157550933884 0.21841357493510705 -> 0.21685844960602488 1.6076735133449402
+acosh0108 acosh -8225991.0508394297 0.28318543008913644 -> 16.615956520420287 3.1415926191641019
+acosh0109 acosh -35.620070502302639 0.31303237005015 -> 4.2658980006943965 3.1328013255541873
+acosh0110 acosh 96.729939906820917 -0.029345228372365334 -> 5.2650434775863548 -0.00030338895866972843
+acosh0111 acosh 0.59656024007966491 -2.0412294654163978 -> 1.4923002024287835 -1.312568421900338
+acosh0112 acosh 109.29384112677828 -0.00015454863061533812 -> 5.3871662961545477 -1.4141245154061214e-06
+acosh0113 acosh 8.6705651969361597 -3.6723631649787465 -> 2.9336180958363545 -0.40267362031872861
+acosh0114 acosh 1.8101646445052686 -0.012345132721855478 -> 1.1997148566285769 -0.0081813912760150265
+acosh0115 acosh 52.56897195025288 0.001113916065985443 -> 4.6551827622264135 2.1193445872040307e-05
+acosh0116 acosh 0.28336786164214739 355643992457.40485 -> 27.290343226816528 1.5707963267940999
+acosh0117 acosh 0.73876621291911437 2.8828594541104322e-20 -> 4.2774820978159067e-20 0.73955845836827927
+acosh0118 acosh 0.025865471781718878 37125746064318.492 -> 31.938478989418012 1.5707963267948959
+acosh0119 acosh 2.2047353511780132 0.074712248143489271 -> 1.4286403248698021 0.037997904971626598
+
+-- values near infinity
+acosh0200 acosh 8.1548592876467785e+307 9.0943779335951128e+307 -> 710.08944620800605 0.83981165425478954
+acosh0201 acosh 1.4237229680972531e+308 -1.0336966617874858e+308 -> 710.4543331094759 -0.6279972876348755
+acosh0202 acosh -1.5014526899738939e+308 1.5670700378448792e+308 -> 710.66420706795464 2.3348137299106697
+acosh0203 acosh -1.0939040375213928e+308 -1.0416960351127978e+308 -> 710.30182863115886 -2.380636147787027
+acosh0204 acosh 0.0 1.476062433559588e+308 -> 710.27873384716929 1.5707963267948966
+acosh0205 acosh -0.0 6.2077210326221094e+307 -> 709.41256457484769 1.5707963267948966
+acosh0206 acosh 0.0 -1.5621899909968308e+308 -> 710.33544449990734 -1.5707963267948966
+acosh0207 acosh -0.0 -8.3556624833839122e+307 -> 709.70971018048317 -1.5707963267948966
+acosh0208 acosh 1.3067079752499342e+308 0.0 -> 710.15686680107228 0.0
+acosh0209 acosh 1.5653640340214026e+308 -0.0 -> 710.33747422926706 -0.0
+acosh0210 acosh -6.9011375992290636e+307 0.0 -> 709.51845699719922 3.1415926535897931
+acosh0211 acosh -9.9539576809926973e+307 -0.0 -> 709.88474095870185 -3.1415926535897931
+acosh0212 acosh 7.6449598518914925e+307 9.5706540768268358 -> 709.62081731754802 1.2518906916769345e-307
+acosh0213 acosh 5.4325410972602197e+307 -7.8064807816522706 -> 709.279177727925 -1.4369851312471974e-307
+acosh0214 acosh -1.1523626112360465e+308 7.0617510038869336 -> 710.03117010216909 3.1415926535897931
+acosh0215 acosh -1.1685027786862599e+308 -5.1568558357925625 -> 710.04507907571417 -3.1415926535897931
+acosh0216 acosh 3.0236370339788721 1.7503248720096417e+308 -> 710.44915723458064 1.5707963267948966
+acosh0217 acosh 6.6108007926031149 -9.1469968225806149e+307 -> 709.80019633903328 -1.5707963267948966
+acosh0218 acosh -5.1096262905623959 6.4484926785412395e+307 -> 709.45061713997973 1.5707963267948966
+acosh0219 acosh -2.8080920608735846 -1.7716118836519368e+308 -> 710.46124562363445 -1.5707963267948966
+
+-- values near 0
+acosh0220 acosh 4.5560530326699304e-317 7.3048989121436657e-318 -> 7.3048989121436657e-318 1.5707963267948966
+acosh0221 acosh 4.8754274133585331e-314 -9.8469794897684199e-315 -> 9.8469794897684199e-315 -1.5707963267948966
+acosh0222 acosh -4.6748876009960097e-312 9.7900342887557606e-318 -> 9.7900342887557606e-318 1.5707963267948966
+acosh0223 acosh -4.3136871538399236e-320 -4.9406564584124654e-323 -> 4.9406564584124654e-323 -1.5707963267948966
+acosh0224 acosh 0.0 4.3431013866496774e-314 -> 4.3431013866496774e-314 1.5707963267948966
+acosh0225 acosh -0.0 6.0147334335829184e-317 -> 6.0147334335829184e-317 1.5707963267948966
+acosh0226 acosh 0.0 -1.2880291387081297e-320 -> 1.2880291387081297e-320 -1.5707963267948966
+acosh0227 acosh -0.0 -1.4401563976534621e-317 -> 1.4401563976534621e-317 -1.5707963267948966
+acosh0228 acosh 1.3689680570863091e-313 0.0 -> 0.0 1.5707963267948966
+acosh0229 acosh 1.5304346893494371e-312 -0.0 -> 0.0 -1.5707963267948966
+acosh0230 acosh -3.7450175954766488e-320 0.0 -> 0.0 1.5707963267948966
+acosh0231 acosh -8.4250563080885801e-311 -0.0 -> 0.0 -1.5707963267948966
+
+-- special values
+acosh1000 acosh 0.0 0.0 -> 0.0 1.5707963267948966
+acosh1001 acosh -0.0 0.0 -> 0.0 1.5707963267948966
+acosh1002 acosh 0.0 inf -> inf 1.5707963267948966
+acosh1003 acosh 2.3 inf -> inf 1.5707963267948966
+acosh1004 acosh -0.0 inf -> inf 1.5707963267948966
+acosh1005 acosh -2.3 inf -> inf 1.5707963267948966
+acosh1006 acosh 0.0 nan -> nan nan
+acosh1007 acosh 2.3 nan -> nan nan
+acosh1008 acosh -0.0 nan -> nan nan
+acosh1009 acosh -2.3 nan -> nan nan
+acosh1010 acosh -inf 0.0 -> inf 3.1415926535897931
+acosh1011 acosh -inf 2.3 -> inf 3.1415926535897931
+acosh1012 acosh inf 0.0 -> inf 0.0
+acosh1013 acosh inf 2.3 -> inf 0.0
+acosh1014 acosh -inf inf -> inf 2.3561944901923448
+acosh1015 acosh inf inf -> inf 0.78539816339744828
+acosh1016 acosh inf nan -> inf nan
+acosh1017 acosh -inf nan -> inf nan
+acosh1018 acosh nan 0.0 -> nan nan
+acosh1019 acosh nan 2.3 -> nan nan
+acosh1020 acosh nan inf -> inf nan
+acosh1021 acosh nan nan -> nan nan
+acosh1022 acosh 0.0 -0.0 -> 0.0 -1.5707963267948966
+acosh1023 acosh -0.0 -0.0 -> 0.0 -1.5707963267948966
+acosh1024 acosh 0.0 -inf -> inf -1.5707963267948966
+acosh1025 acosh 2.3 -inf -> inf -1.5707963267948966
+acosh1026 acosh -0.0 -inf -> inf -1.5707963267948966
+acosh1027 acosh -2.3 -inf -> inf -1.5707963267948966
+acosh1028 acosh -inf -0.0 -> inf -3.1415926535897931
+acosh1029 acosh -inf -2.3 -> inf -3.1415926535897931
+acosh1030 acosh inf -0.0 -> inf -0.0
+acosh1031 acosh inf -2.3 -> inf -0.0
+acosh1032 acosh -inf -inf -> inf -2.3561944901923448
+acosh1033 acosh inf -inf -> inf -0.78539816339744828
+acosh1034 acosh nan -0.0 -> nan nan
+acosh1035 acosh nan -2.3 -> nan nan
+acosh1036 acosh nan -inf -> inf nan
+
+
+------------------------
+-- asin: Inverse sine --
+------------------------
+
+-- zeros
+asin0000 asin 0.0 0.0 -> 0.0 0.0
+asin0001 asin 0.0 -0.0 -> 0.0 -0.0
+asin0002 asin -0.0 0.0 -> -0.0 0.0
+asin0003 asin -0.0 -0.0 -> -0.0 -0.0
+
+-- branch points: +/-1
+asin0010 asin 1.0 0.0 -> 1.5707963267948966 0.0
+asin0011 asin 1.0 -0.0 -> 1.5707963267948966 -0.0
+asin0012 asin -1.0 0.0 -> -1.5707963267948966 0.0
+asin0013 asin -1.0 -0.0 -> -1.5707963267948966 -0.0
+
+-- values along both sides of real axis
+asin0020 asin -9.8813129168249309e-324 0.0 -> -9.8813129168249309e-324 0.0
+asin0021 asin -9.8813129168249309e-324 -0.0 -> -9.8813129168249309e-324 -0.0
+asin0022 asin -1e-305 0.0 -> -1e-305 0.0
+asin0023 asin -1e-305 -0.0 -> -1e-305 -0.0
+asin0024 asin -1e-150 0.0 -> -1e-150 0.0
+asin0025 asin -1e-150 -0.0 -> -1e-150 -0.0
+asin0026 asin -9.9999999999999998e-17 0.0 -> -9.9999999999999998e-17 0.0
+asin0027 asin -9.9999999999999998e-17 -0.0 -> -9.9999999999999998e-17 -0.0
+asin0028 asin -0.001 0.0 -> -0.0010000001666667416 0.0
+asin0029 asin -0.001 -0.0 -> -0.0010000001666667416 -0.0
+asin0030 asin -0.57899999999999996 0.0 -> -0.61750165481717001 0.0
+asin0031 asin -0.57899999999999996 -0.0 -> -0.61750165481717001 -0.0
+asin0032 asin -0.99999999999999989 0.0 -> -1.5707963118937354 0.0
+asin0033 asin -0.99999999999999989 -0.0 -> -1.5707963118937354 -0.0
+asin0034 asin -1.0000000000000002 0.0 -> -1.5707963267948966 2.1073424255447014e-08
+asin0035 asin -1.0000000000000002 -0.0 -> -1.5707963267948966 -2.1073424255447014e-08
+asin0036 asin -1.0009999999999999 0.0 -> -1.5707963267948966 0.044717633608306849
+asin0037 asin -1.0009999999999999 -0.0 -> -1.5707963267948966 -0.044717633608306849
+asin0038 asin -2.0 0.0 -> -1.5707963267948966 1.3169578969248168
+asin0039 asin -2.0 -0.0 -> -1.5707963267948966 -1.3169578969248168
+asin0040 asin -23.0 0.0 -> -1.5707963267948966 3.8281684713331012
+asin0041 asin -23.0 -0.0 -> -1.5707963267948966 -3.8281684713331012
+asin0042 asin -10000000000000000.0 0.0 -> -1.5707963267948966 37.534508668464674
+asin0043 asin -10000000000000000.0 -0.0 -> -1.5707963267948966 -37.534508668464674
+asin0044 asin -9.9999999999999998e+149 0.0 -> -1.5707963267948966 346.08091112966679
+asin0045 asin -9.9999999999999998e+149 -0.0 -> -1.5707963267948966 -346.08091112966679
+asin0046 asin -1.0000000000000001e+299 0.0 -> -1.5707963267948966 689.16608998577965
+asin0047 asin -1.0000000000000001e+299 -0.0 -> -1.5707963267948966 -689.16608998577965
+asin0048 asin 9.8813129168249309e-324 0.0 -> 9.8813129168249309e-324 0.0
+asin0049 asin 9.8813129168249309e-324 -0.0 -> 9.8813129168249309e-324 -0.0
+asin0050 asin 1e-305 0.0 -> 1e-305 0.0
+asin0051 asin 1e-305 -0.0 -> 1e-305 -0.0
+asin0052 asin 1e-150 0.0 -> 1e-150 0.0
+asin0053 asin 1e-150 -0.0 -> 1e-150 -0.0
+asin0054 asin 9.9999999999999998e-17 0.0 -> 9.9999999999999998e-17 0.0
+asin0055 asin 9.9999999999999998e-17 -0.0 -> 9.9999999999999998e-17 -0.0
+asin0056 asin 0.001 0.0 -> 0.0010000001666667416 0.0
+asin0057 asin 0.001 -0.0 -> 0.0010000001666667416 -0.0
+asin0058 asin 0.57899999999999996 0.0 -> 0.61750165481717001 0.0
+asin0059 asin 0.57899999999999996 -0.0 -> 0.61750165481717001 -0.0
+asin0060 asin 0.99999999999999989 0.0 -> 1.5707963118937354 0.0
+asin0061 asin 0.99999999999999989 -0.0 -> 1.5707963118937354 -0.0
+asin0062 asin 1.0000000000000002 0.0 -> 1.5707963267948966 2.1073424255447014e-08
+asin0063 asin 1.0000000000000002 -0.0 -> 1.5707963267948966 -2.1073424255447014e-08
+asin0064 asin 1.0009999999999999 0.0 -> 1.5707963267948966 0.044717633608306849
+asin0065 asin 1.0009999999999999 -0.0 -> 1.5707963267948966 -0.044717633608306849
+asin0066 asin 2.0 0.0 -> 1.5707963267948966 1.3169578969248168
+asin0067 asin 2.0 -0.0 -> 1.5707963267948966 -1.3169578969248168
+asin0068 asin 23.0 0.0 -> 1.5707963267948966 3.8281684713331012
+asin0069 asin 23.0 -0.0 -> 1.5707963267948966 -3.8281684713331012
+asin0070 asin 10000000000000000.0 0.0 -> 1.5707963267948966 37.534508668464674
+asin0071 asin 10000000000000000.0 -0.0 -> 1.5707963267948966 -37.534508668464674
+asin0072 asin 9.9999999999999998e+149 0.0 -> 1.5707963267948966 346.08091112966679
+asin0073 asin 9.9999999999999998e+149 -0.0 -> 1.5707963267948966 -346.08091112966679
+asin0074 asin 1.0000000000000001e+299 0.0 -> 1.5707963267948966 689.16608998577965
+asin0075 asin 1.0000000000000001e+299 -0.0 -> 1.5707963267948966 -689.16608998577965
+
+-- random inputs
+asin0100 asin -1.5979555835086083 -0.15003009814595247 -> -1.4515369557405788 -1.0544476399790823
+asin0101 asin -0.57488225895317679 -9.6080397838952743e-13 -> -0.61246024460412851 -1.174238005400403e-12
+asin0102 asin -3.6508087930516249 -0.36027527093220152 -> -1.4685890605305874 -1.9742273007152038
+asin0103 asin -1.5238659792326819 -1.1360813516996364 -> -0.86080051691147275 -1.3223742205689195
+asin0104 asin -1592.0639045555306 -0.72362427935018236 -> -1.5703418071175179 -8.0659336918729228
+asin0105 asin -0.19835471371312019 4.2131508416697709 -> -0.045777831019935149 2.1461732751933171
+asin0106 asin -1.918471054430213 0.40603305079779234 -> -1.3301396585791556 1.30263642314981
+asin0107 asin -254495.01623373642 0.71084414434470822 -> -1.5707935336394359 13.140183712762321
+asin0108 asin -0.31315882715691157 3.9647994288429866 -> -0.076450403840916004 2.0889762138713457
+asin0109 asin -0.90017064284720816 1.2530659485907105 -> -0.53466509741943447 1.1702811557577
+asin0110 asin 2.1615181696571075 -0.14058647488229523 -> 1.4976166323896871 -1.4085811039334604
+asin0111 asin 1.2104749210707795 -0.85732484485298999 -> 0.83913071588343924 -1.0681719250525901
+asin0112 asin 1.7059733185128891 -0.84032966373156581 -> 1.0510900815816229 -1.2967979791361652
+asin0113 asin 9.9137085017290687 -1.4608383970250893 -> 1.4237704820128891 -2.995414677560686
+asin0114 asin 117.12344751041495 -5453908091.5334015 -> 2.1475141411392012e-08 -23.112745450217066
+asin0115 asin 0.081041187798029227 0.067054349860173196 -> 0.080946786856771813 0.067223991060639698
+asin0116 asin 46.635472322049949 2.3835190718056678 -> 1.5197194940010779 4.5366989600972083
+asin0117 asin 3907.0687961127105 19.144021886390181 -> 1.5658965233083235 8.9637018715924217
+asin0118 asin 1.0889312322308273 509.01577883554768 -> 0.0021392803817829316 6.9256294494524706
+asin0119 asin 0.10851518277509224 1.5612510908217476 -> 0.058491014243902621 1.2297075725621327
+
+-- values near infinity
+asin0200 asin 1.5230241998821499e+308 5.5707228994084525e+307 -> 1.2201446370892068 710.37283486535966
+asin0201 asin 8.1334317698672204e+307 -9.2249425197872451e+307 -> 0.72259991284020042 -710.0962453049026
+asin0202 asin -9.9138506659241768e+307 6.701544526434995e+307 -> -0.97637511742194594 710.06887486671371
+asin0203 asin -1.4141298868173842e+308 -5.401505134514191e+307 -> -1.2059319055160587 -710.30396478954628
+asin0204 asin 0.0 9.1618092977897431e+307 -> 0.0 709.80181441050593
+asin0205 asin -0.0 6.8064342551939755e+307 -> -0.0 709.50463910853489
+asin0206 asin 0.0 -6.4997516454798215e+307 -> 0.0 -709.45853469751592
+asin0207 asin -0.0 -1.6767449053345242e+308 -> -0.0 -710.4062101803022
+asin0208 asin 5.4242749957378916e+307 0.0 -> 1.5707963267948966 709.27765497888902
+asin0209 asin 9.5342145121164749e+307 -0.0 -> 1.5707963267948966 -709.84165758595907
+asin0210 asin -7.0445698006201847e+307 0.0 -> -1.5707963267948966 709.53902780872136
+asin0211 asin -1.0016025569769706e+308 -0.0 -> -1.5707963267948966 -709.89095709697881
+asin0212 asin 1.6552203778877204e+308 0.48761543336249491 -> 1.5707963267948966 710.39328998153474
+asin0213 asin 1.2485712830384869e+308 -4.3489311161278899 -> 1.5707963267948966 -710.1113557467786
+asin0214 asin -1.5117842813353125e+308 5.123452666102434 -> -1.5707963267948966 710.30264641923031
+asin0215 asin -1.3167634313008016e+308 -0.52939679793528982 -> -1.5707963267948966 -710.16453260239768
+asin0216 asin 0.80843929176985907 1.0150851827767876e+308 -> 7.9642507396113875e-309 709.90432835561637
+asin0217 asin 8.2544809829680901 -1.7423548140539474e+308 -> 4.7375430746865733e-308 -710.44459336242164
+asin0218 asin -5.2499000118824295 4.6655578977512214e+307 -> -1.1252459249113292e-307 709.1269781491103
+asin0219 asin -5.9904782760833433 -4.7315689314781163e+307 -> -1.2660659419394637e-307 -709.14102757522312
+
+-- special values
+asin1000 asin -0.0 0.0 -> -0.0 0.0
+asin1001 asin 0.0 0.0 -> 0.0 0.0
+asin1002 asin -0.0 -0.0 -> -0.0 -0.0
+asin1003 asin 0.0 -0.0 -> 0.0 -0.0
+asin1004 asin -inf 0.0 -> -1.5707963267948966 inf
+asin1005 asin -inf 2.2999999999999998 -> -1.5707963267948966 inf
+asin1006 asin nan 0.0 -> nan nan
+asin1007 asin nan 2.2999999999999998 -> nan nan
+asin1008 asin -0.0 inf -> -0.0 inf
+asin1009 asin -2.2999999999999998 inf -> -0.0 inf
+asin1010 asin -inf inf -> -0.78539816339744828 inf
+asin1011 asin nan inf -> nan inf
+asin1012 asin -0.0 nan -> -0.0 nan
+asin1013 asin -2.2999999999999998 nan -> nan nan
+asin1014 asin -inf nan -> nan inf ignore-imag-sign
+asin1015 asin nan nan -> nan nan
+asin1016 asin inf 0.0 -> 1.5707963267948966 inf
+asin1017 asin inf 2.2999999999999998 -> 1.5707963267948966 inf
+asin1018 asin 0.0 inf -> 0.0 inf
+asin1019 asin 2.2999999999999998 inf -> 0.0 inf
+asin1020 asin inf inf -> 0.78539816339744828 inf
+asin1021 asin 0.0 nan -> 0.0 nan
+asin1022 asin 2.2999999999999998 nan -> nan nan
+asin1023 asin inf nan -> nan inf ignore-imag-sign
+asin1024 asin inf -0.0 -> 1.5707963267948966 -inf
+asin1025 asin inf -2.2999999999999998 -> 1.5707963267948966 -inf
+asin1026 asin nan -0.0 -> nan nan
+asin1027 asin nan -2.2999999999999998 -> nan nan
+asin1028 asin 0.0 -inf -> 0.0 -inf
+asin1029 asin 2.2999999999999998 -inf -> 0.0 -inf
+asin1030 asin inf -inf -> 0.78539816339744828 -inf
+asin1031 asin nan -inf -> nan -inf
+asin1032 asin -inf -0.0 -> -1.5707963267948966 -inf
+asin1033 asin -inf -2.2999999999999998 -> -1.5707963267948966 -inf
+asin1034 asin -0.0 -inf -> -0.0 -inf
+asin1035 asin -2.2999999999999998 -inf -> -0.0 -inf
+asin1036 asin -inf -inf -> -0.78539816339744828 -inf
+
+
+------------------------------------
+-- asinh: Inverse hyperbolic sine --
+------------------------------------
+
+-- zeros
+asinh0000 asinh 0.0 0.0 -> 0.0 0.0
+asinh0001 asinh 0.0 -0.0 -> 0.0 -0.0
+asinh0002 asinh -0.0 0.0 -> -0.0 0.0
+asinh0003 asinh -0.0 -0.0 -> -0.0 -0.0
+
+-- branch points: +/-i
+asinh0010 asinh 0.0 1.0 -> 0.0 1.5707963267948966
+asinh0011 asinh 0.0 -1.0 -> 0.0 -1.5707963267948966
+asinh0012 asinh -0.0 1.0 -> -0.0 1.5707963267948966
+asinh0013 asinh -0.0 -1.0 -> -0.0 -1.5707963267948966
+
+-- values along both sides of imaginary axis
+asinh0020 asinh 0.0 -9.8813129168249309e-324 -> 0.0 -9.8813129168249309e-324
+asinh0021 asinh -0.0 -9.8813129168249309e-324 -> -0.0 -9.8813129168249309e-324
+asinh0022 asinh 0.0 -1e-305 -> 0.0 -1e-305
+asinh0023 asinh -0.0 -1e-305 -> -0.0 -1e-305
+asinh0024 asinh 0.0 -1e-150 -> 0.0 -1e-150
+asinh0025 asinh -0.0 -1e-150 -> -0.0 -1e-150
+asinh0026 asinh 0.0 -9.9999999999999998e-17 -> 0.0 -9.9999999999999998e-17
+asinh0027 asinh -0.0 -9.9999999999999998e-17 -> -0.0 -9.9999999999999998e-17
+asinh0028 asinh 0.0 -0.001 -> 0.0 -0.0010000001666667416
+asinh0029 asinh -0.0 -0.001 -> -0.0 -0.0010000001666667416
+asinh0030 asinh 0.0 -0.57899999999999996 -> 0.0 -0.61750165481717001
+asinh0031 asinh -0.0 -0.57899999999999996 -> -0.0 -0.61750165481717001
+asinh0032 asinh 0.0 -0.99999999999999989 -> 0.0 -1.5707963118937354
+asinh0033 asinh -0.0 -0.99999999999999989 -> -0.0 -1.5707963118937354
+asinh0034 asinh 0.0 -1.0000000000000002 -> 2.1073424255447014e-08 -1.5707963267948966
+asinh0035 asinh -0.0 -1.0000000000000002 -> -2.1073424255447014e-08 -1.5707963267948966
+asinh0036 asinh 0.0 -1.0009999999999999 -> 0.044717633608306849 -1.5707963267948966
+asinh0037 asinh -0.0 -1.0009999999999999 -> -0.044717633608306849 -1.5707963267948966
+asinh0038 asinh 0.0 -2.0 -> 1.3169578969248168 -1.5707963267948966
+asinh0039 asinh -0.0 -2.0 -> -1.3169578969248168 -1.5707963267948966
+asinh0040 asinh 0.0 -20.0 -> 3.6882538673612966 -1.5707963267948966
+asinh0041 asinh -0.0 -20.0 -> -3.6882538673612966 -1.5707963267948966
+asinh0042 asinh 0.0 -10000000000000000.0 -> 37.534508668464674 -1.5707963267948966
+asinh0043 asinh -0.0 -10000000000000000.0 -> -37.534508668464674 -1.5707963267948966
+asinh0044 asinh 0.0 -9.9999999999999998e+149 -> 346.08091112966679 -1.5707963267948966
+asinh0045 asinh -0.0 -9.9999999999999998e+149 -> -346.08091112966679 -1.5707963267948966
+asinh0046 asinh 0.0 -1.0000000000000001e+299 -> 689.16608998577965 -1.5707963267948966
+asinh0047 asinh -0.0 -1.0000000000000001e+299 -> -689.16608998577965 -1.5707963267948966
+asinh0048 asinh 0.0 9.8813129168249309e-324 -> 0.0 9.8813129168249309e-324
+asinh0049 asinh -0.0 9.8813129168249309e-324 -> -0.0 9.8813129168249309e-324
+asinh0050 asinh 0.0 1e-305 -> 0.0 1e-305
+asinh0051 asinh -0.0 1e-305 -> -0.0 1e-305
+asinh0052 asinh 0.0 1e-150 -> 0.0 1e-150
+asinh0053 asinh -0.0 1e-150 -> -0.0 1e-150
+asinh0054 asinh 0.0 9.9999999999999998e-17 -> 0.0 9.9999999999999998e-17
+asinh0055 asinh -0.0 9.9999999999999998e-17 -> -0.0 9.9999999999999998e-17
+asinh0056 asinh 0.0 0.001 -> 0.0 0.0010000001666667416
+asinh0057 asinh -0.0 0.001 -> -0.0 0.0010000001666667416
+asinh0058 asinh 0.0 0.57899999999999996 -> 0.0 0.61750165481717001
+asinh0059 asinh -0.0 0.57899999999999996 -> -0.0 0.61750165481717001
+asinh0060 asinh 0.0 0.99999999999999989 -> 0.0 1.5707963118937354
+asinh0061 asinh -0.0 0.99999999999999989 -> -0.0 1.5707963118937354
+asinh0062 asinh 0.0 1.0000000000000002 -> 2.1073424255447014e-08 1.5707963267948966
+asinh0063 asinh -0.0 1.0000000000000002 -> -2.1073424255447014e-08 1.5707963267948966
+asinh0064 asinh 0.0 1.0009999999999999 -> 0.044717633608306849 1.5707963267948966
+asinh0065 asinh -0.0 1.0009999999999999 -> -0.044717633608306849 1.5707963267948966
+asinh0066 asinh 0.0 2.0 -> 1.3169578969248168 1.5707963267948966
+asinh0067 asinh -0.0 2.0 -> -1.3169578969248168 1.5707963267948966
+asinh0068 asinh 0.0 20.0 -> 3.6882538673612966 1.5707963267948966
+asinh0069 asinh -0.0 20.0 -> -3.6882538673612966 1.5707963267948966
+asinh0070 asinh 0.0 10000000000000000.0 -> 37.534508668464674 1.5707963267948966
+asinh0071 asinh -0.0 10000000000000000.0 -> -37.534508668464674 1.5707963267948966
+asinh0072 asinh 0.0 9.9999999999999998e+149 -> 346.08091112966679 1.5707963267948966
+asinh0073 asinh -0.0 9.9999999999999998e+149 -> -346.08091112966679 1.5707963267948966
+asinh0074 asinh 0.0 1.0000000000000001e+299 -> 689.16608998577965 1.5707963267948966
+asinh0075 asinh -0.0 1.0000000000000001e+299 -> -689.16608998577965 1.5707963267948966
+
+-- random inputs
+asinh0100 asinh -0.5946402853710423 -0.044506548910000145 -> -0.56459775392653022 -0.038256221441536356
+asinh0101 asinh -0.19353958046180916 -0.017489624793193454 -> -0.19237926804196651 -0.017171741895336792
+asinh0102 asinh -0.033117585138955893 -8.5256414015933757 -> -2.8327758348650969 -1.5668848791092411
+asinh0103 asinh -1.5184043184035716 -0.73491245339073275 -> -1.2715891419764005 -0.39204624408542355
+asinh0104 asinh -0.60716120271208818 -0.28900743958436542 -> -0.59119299421187232 -0.24745931678118135
+asinh0105 asinh -0.0237177865112429 2.8832601052166313 -> -1.7205820772413236 1.5620261702963094
+asinh0106 asinh -2.3906812342743979 2.6349216848574013 -> -1.9609636249445124 0.8142142660574706
+asinh0107 asinh -0.0027605019787620517 183.85588476550555 -> -5.9072920005445066 1.5707813120847871
+asinh0108 asinh -0.99083661164404713 0.028006797051617648 -> -0.8750185251283995 0.019894099615994653
+asinh0109 asinh -3.0362951937986393 0.86377266758504867 -> -1.8636030714685221 0.26475058859950168
+asinh0110 asinh 0.34438464536152769 -0.71603790174885029 -> 0.43985415690734164 -0.71015037409294324
+asinh0111 asinh 4.4925124413876256 -60604595352.871613 -> 25.520783738612078 -1.5707963267207683
+asinh0112 asinh 2.3213991428170337 -7.5459667007307258 -> 2.7560464993451643 -1.270073210856117
+asinh0113 asinh 0.21291939741682028 -1.2720428814784408 -> 0.77275088137338266 -1.3182099250896895
+asinh0114 asinh 6.6447359379455957 -0.97196191666946996 -> 2.602830695139672 -0.14368247412319965
+asinh0115 asinh 7.1326256655083746 2.1516360452706857 -> 2.7051146374367212 0.29051701669727581
+asinh0116 asinh 0.18846550905063442 3.4705348585339832 -> 1.917697875799296 1.514155593347924
+asinh0117 asinh 0.19065075303281598 0.26216814548222012 -> 0.19603050785932474 0.26013422809614117
+asinh0118 asinh 2.0242004665739719 0.70510281647495787 -> 1.4970366212896002 0.30526007200481453
+asinh0119 asinh 37.336596461576057 717.29157391678234 -> 7.269981997945294 1.5187910219576033
+
+-- values near infinity
+asinh0200 asinh 1.0760517500874541e+308 1.1497786241240167e+308 -> 710.34346055651815 0.81850936961793475
+asinh0201 asinh 1.1784839328845529e+308 -1.6478429586716638e+308 -> 710.59536255783678 -0.94996311735607697
+asinh0202 asinh -4.8777682248909193e+307 1.4103736217538474e+308 -> -710.28970147376992 1.2378239519096443
+asinh0203 asinh -1.2832478903233108e+308 -1.5732392613155698e+308 -> -710.59750164290745 -0.88657181439322452
+asinh0204 asinh 0.0 6.8431383856345372e+307 -> 709.51001718444604 1.5707963267948966
+asinh0205 asinh -0.0 8.601822432238051e+307 -> -709.73874482126689 1.5707963267948966
+asinh0206 asinh 0.0 -5.5698396067303782e+307 -> 709.30413698733742 -1.5707963267948966
+asinh0207 asinh -0.0 -7.1507777734621804e+307 -> -709.55399186002705 -1.5707963267948966
+asinh0208 asinh 1.6025136110019349e+308 0.0 -> 710.3609292261076 0.0
+asinh0209 asinh 1.3927819858239114e+308 -0.0 -> 710.22065899832899 -0.0
+asinh0210 asinh -6.0442994056210995e+307 0.0 -> -709.38588631057621 0.0
+asinh0211 asinh -1.2775271979042634e+308 -0.0 -> -710.13428215553972 -0.0
+asinh0212 asinh 1.0687496260268489e+308 1.0255615699476961 -> 709.95584521407841 9.5959010882679093e-309
+asinh0213 asinh 1.0050967333370962e+308 -0.87668970117333433 -> 709.89443961168183 -8.7224410556242882e-309
+asinh0214 asinh -5.7161452814862392e+307 8.2377808413450122 -> -709.33006540611166 1.4411426644501116e-307
+asinh0215 asinh -8.2009040727653315e+307 -6.407409526654976 -> -709.69101513070109 -7.8130526461510088e-308
+asinh0216 asinh 6.4239368496483982 1.6365990821551427e+308 -> 710.38197618101287 1.5707963267948966
+asinh0217 asinh 5.4729111423315882 -1.1227237438144211e+308 -> 710.00511346983546 -1.5707963267948966
+asinh0218 asinh -8.3455818297412723 1.443172020182019e+308 -> -710.25619930551818 1.5707963267948966
+asinh0219 asinh -2.6049726230372441 -1.7952291144022702e+308 -> -710.47448847685644 -1.5707963267948966
+
+-- values near 0
+asinh0220 asinh 1.2940113339664088e-314 6.9169190417774516e-323 -> 1.2940113339664088e-314 6.9169190417774516e-323
+asinh0221 asinh 2.3848478863874649e-315 -3.1907655025717717e-310 -> 2.3848478863874649e-315 -3.1907655025717717e-310
+asinh0222 asinh -3.0097643679641622e-316 4.6936236354918422e-322 -> -3.0097643679641622e-316 4.6936236354918422e-322
+asinh0223 asinh -1.787997087755751e-308 -8.5619622834902341e-310 -> -1.787997087755751e-308 -8.5619622834902341e-310
+asinh0224 asinh 0.0 1.2491433448427325e-314 -> 0.0 1.2491433448427325e-314
+asinh0225 asinh -0.0 2.5024072154538062e-308 -> -0.0 2.5024072154538062e-308
+asinh0226 asinh 0.0 -2.9643938750474793e-323 -> 0.0 -2.9643938750474793e-323
+asinh0227 asinh -0.0 -2.9396905927554169e-320 -> -0.0 -2.9396905927554169e-320
+asinh0228 asinh 5.64042930029359e-317 0.0 -> 5.64042930029359e-317 0.0
+asinh0229 asinh 3.3833911866596068e-318 -0.0 -> 3.3833911866596068e-318 -0.0
+asinh0230 asinh -4.9406564584124654e-324 0.0 -> -4.9406564584124654e-324 0.0
+asinh0231 asinh -2.2211379227994845e-308 -0.0 -> -2.2211379227994845e-308 -0.0
+
+-- special values
+asinh1000 asinh 0.0 0.0 -> 0.0 0.0
+asinh1001 asinh 0.0 -0.0 -> 0.0 -0.0
+asinh1002 asinh -0.0 0.0 -> -0.0 0.0
+asinh1003 asinh -0.0 -0.0 -> -0.0 -0.0
+asinh1004 asinh 0.0 inf -> inf 1.5707963267948966
+asinh1005 asinh 2.3 inf -> inf 1.5707963267948966
+asinh1006 asinh 0.0 nan -> nan nan
+asinh1007 asinh 2.3 nan -> nan nan
+asinh1008 asinh inf 0.0 -> inf 0.0
+asinh1009 asinh inf 2.3 -> inf 0.0
+asinh1010 asinh inf inf -> inf 0.78539816339744828
+asinh1011 asinh inf nan -> inf nan
+asinh1012 asinh nan 0.0 -> nan 0.0
+asinh1013 asinh nan 2.3 -> nan nan
+asinh1014 asinh nan inf -> inf nan ignore-real-sign
+asinh1015 asinh nan nan -> nan nan
+asinh1016 asinh 0.0 -inf -> inf -1.5707963267948966
+asinh1017 asinh 2.3 -inf -> inf -1.5707963267948966
+asinh1018 asinh inf -0.0 -> inf -0.0
+asinh1019 asinh inf -2.3 -> inf -0.0
+asinh1020 asinh inf -inf -> inf -0.78539816339744828
+asinh1021 asinh nan -0.0 -> nan -0.0
+asinh1022 asinh nan -2.3 -> nan nan
+asinh1023 asinh nan -inf -> inf nan ignore-real-sign
+asinh1024 asinh -0.0 -inf -> -inf -1.5707963267948966
+asinh1025 asinh -2.3 -inf -> -inf -1.5707963267948966
+asinh1026 asinh -0.0 nan -> nan nan
+asinh1027 asinh -2.3 nan -> nan nan
+asinh1028 asinh -inf -0.0 -> -inf -0.0
+asinh1029 asinh -inf -2.3 -> -inf -0.0
+asinh1030 asinh -inf -inf -> -inf -0.78539816339744828
+asinh1031 asinh -inf nan -> -inf nan
+asinh1032 asinh -0.0 inf -> -inf 1.5707963267948966
+asinh1033 asinh -2.3 inf -> -inf 1.5707963267948966
+asinh1034 asinh -inf 0.0 -> -inf 0.0
+asinh1035 asinh -inf 2.3 -> -inf 0.0
+asinh1036 asinh -inf inf -> -inf 0.78539816339744828
+
+
+---------------------------
+-- atan: Inverse tangent --
+---------------------------
+
+-- zeros
+atan0000 atan 0.0 0.0 -> 0.0 0.0
+atan0001 atan 0.0 -0.0 -> 0.0 -0.0
+atan0002 atan -0.0 0.0 -> -0.0 0.0
+atan0003 atan -0.0 -0.0 -> -0.0 -0.0
+
+-- values along both sides of imaginary axis
+atan0010 atan 0.0 -9.8813129168249309e-324 -> 0.0 -9.8813129168249309e-324
+atan0011 atan -0.0 -9.8813129168249309e-324 -> -0.0 -9.8813129168249309e-324
+atan0012 atan 0.0 -1e-305 -> 0.0 -1e-305
+atan0013 atan -0.0 -1e-305 -> -0.0 -1e-305
+atan0014 atan 0.0 -1e-150 -> 0.0 -1e-150
+atan0015 atan -0.0 -1e-150 -> -0.0 -1e-150
+atan0016 atan 0.0 -9.9999999999999998e-17 -> 0.0 -9.9999999999999998e-17
+atan0017 atan -0.0 -9.9999999999999998e-17 -> -0.0 -9.9999999999999998e-17
+atan0018 atan 0.0 -0.001 -> 0.0 -0.0010000003333335333
+atan0019 atan -0.0 -0.001 -> -0.0 -0.0010000003333335333
+atan0020 atan 0.0 -0.57899999999999996 -> 0.0 -0.6609570902866303
+atan0021 atan -0.0 -0.57899999999999996 -> -0.0 -0.6609570902866303
+atan0022 atan 0.0 -0.99999999999999989 -> 0.0 -18.714973875118524
+atan0023 atan -0.0 -0.99999999999999989 -> -0.0 -18.714973875118524
+atan0024 atan 0.0 -1.0000000000000002 -> 1.5707963267948966 -18.36840028483855
+atan0025 atan -0.0 -1.0000000000000002 -> -1.5707963267948966 -18.36840028483855
+atan0026 atan 0.0 -1.0009999999999999 -> 1.5707963267948966 -3.8007011672919218
+atan0027 atan -0.0 -1.0009999999999999 -> -1.5707963267948966 -3.8007011672919218
+atan0028 atan 0.0 -2.0 -> 1.5707963267948966 -0.54930614433405489
+atan0029 atan -0.0 -2.0 -> -1.5707963267948966 -0.54930614433405489
+atan0030 atan 0.0 -20.0 -> 1.5707963267948966 -0.050041729278491265
+atan0031 atan -0.0 -20.0 -> -1.5707963267948966 -0.050041729278491265
+atan0032 atan 0.0 -10000000000000000.0 -> 1.5707963267948966 -9.9999999999999998e-17
+atan0033 atan -0.0 -10000000000000000.0 -> -1.5707963267948966 -9.9999999999999998e-17
+atan0034 atan 0.0 -9.9999999999999998e+149 -> 1.5707963267948966 -1e-150
+atan0035 atan -0.0 -9.9999999999999998e+149 -> -1.5707963267948966 -1e-150
+atan0036 atan 0.0 -1.0000000000000001e+299 -> 1.5707963267948966 -9.9999999999999999e-300
+atan0037 atan -0.0 -1.0000000000000001e+299 -> -1.5707963267948966 -9.9999999999999999e-300
+atan0038 atan 0.0 9.8813129168249309e-324 -> 0.0 9.8813129168249309e-324
+atan0039 atan -0.0 9.8813129168249309e-324 -> -0.0 9.8813129168249309e-324
+atan0040 atan 0.0 1e-305 -> 0.0 1e-305
+atan0041 atan -0.0 1e-305 -> -0.0 1e-305
+atan0042 atan 0.0 1e-150 -> 0.0 1e-150
+atan0043 atan -0.0 1e-150 -> -0.0 1e-150
+atan0044 atan 0.0 9.9999999999999998e-17 -> 0.0 9.9999999999999998e-17
+atan0045 atan -0.0 9.9999999999999998e-17 -> -0.0 9.9999999999999998e-17
+atan0046 atan 0.0 0.001 -> 0.0 0.0010000003333335333
+atan0047 atan -0.0 0.001 -> -0.0 0.0010000003333335333
+atan0048 atan 0.0 0.57899999999999996 -> 0.0 0.6609570902866303
+atan0049 atan -0.0 0.57899999999999996 -> -0.0 0.6609570902866303
+atan0050 atan 0.0 0.99999999999999989 -> 0.0 18.714973875118524
+atan0051 atan -0.0 0.99999999999999989 -> -0.0 18.714973875118524
+atan0052 atan 0.0 1.0000000000000002 -> 1.5707963267948966 18.36840028483855
+atan0053 atan -0.0 1.0000000000000002 -> -1.5707963267948966 18.36840028483855
+atan0054 atan 0.0 1.0009999999999999 -> 1.5707963267948966 3.8007011672919218
+atan0055 atan -0.0 1.0009999999999999 -> -1.5707963267948966 3.8007011672919218
+atan0056 atan 0.0 2.0 -> 1.5707963267948966 0.54930614433405489
+atan0057 atan -0.0 2.0 -> -1.5707963267948966 0.54930614433405489
+atan0058 atan 0.0 20.0 -> 1.5707963267948966 0.050041729278491265
+atan0059 atan -0.0 20.0 -> -1.5707963267948966 0.050041729278491265
+atan0060 atan 0.0 10000000000000000.0 -> 1.5707963267948966 9.9999999999999998e-17
+atan0061 atan -0.0 10000000000000000.0 -> -1.5707963267948966 9.9999999999999998e-17
+atan0062 atan 0.0 9.9999999999999998e+149 -> 1.5707963267948966 1e-150
+atan0063 atan -0.0 9.9999999999999998e+149 -> -1.5707963267948966 1e-150
+atan0064 atan 0.0 1.0000000000000001e+299 -> 1.5707963267948966 9.9999999999999999e-300
+atan0065 atan -0.0 1.0000000000000001e+299 -> -1.5707963267948966 9.9999999999999999e-300
+
+-- random inputs
+atan0100 atan -0.32538873661060214 -1.5530461550412578 -> -1.3682728427554227 -0.69451401598762041
+atan0101 atan -0.45863393495197929 -4799.1747094903594 -> -1.5707963068820623 -0.00020836916050636145
+atan0102 atan -8.3006999685976162 -2.6788890251790938 -> -1.4619862771810199 -0.034811669653327826
+atan0103 atan -1.8836307682985314 -1.1441976638861771 -> -1.1839984370871612 -0.20630956157312796
+atan0104 atan -0.00063230482407491669 -4.9312520961829485 -> -1.5707692093223147 -0.20563867743008304
+atan0105 atan -0.84278137150065946 179012.37493146997 -> -1.5707963267685969 5.5862059836425272e-06
+atan0106 atan -0.95487853984049287 14.311334539886177 -> -1.5661322859434561 0.069676024526232005
+atan0107 atan -1.3513252539663239 6.0500727021632198e-08 -> -0.93371676315220975 2.140800269742656e-08
+atan0108 atan -0.20566254458595795 0.11933771944159823 -> -0.20556463711174916 0.11493405387141732
+atan0109 atan -0.58563718795408559 0.64438965423212868 -> -0.68361089300233124 0.46759762751800249
+atan0110 atan 48.479267751948292 -78.386382460112543 -> 1.5650888770910523 -0.0092276811373297584
+atan0111 atan 1.0575373914056061 -0.75988012377296987 -> 0.94430886722043594 -0.31915698126703118
+atan0112 atan 4444810.4314677203 -0.56553404593942558 -> 1.5707961018134231 -2.8625446437701909e-14
+atan0113 atan 0.010101405082520009 -0.032932668550282478 -> 0.01011202676646334 -0.032941214776834996
+atan0114 atan 1.5353585300154911 -2.1947099346796519 -> 1.3400310739206394 -0.29996003607449045
+atan0115 atan 0.21869457055670882 9.9915684254007093 -> 1.5685846078876444 0.1003716881759439
+atan0116 atan 0.17783290150246836 0.064334689863650957 -> 0.17668728064286277 0.062435808728873846
+atan0117 atan 15.757474087615918 383.57262142534 -> 1.5706894060369621 0.0026026817278826603
+atan0118 atan 10.587017408533317 0.21720238081843438 -> 1.4766594681336236 0.0019199097383010061
+atan0119 atan 0.86026078678781204 0.1230148609359502 -> 0.7147259322534929 0.070551221954286605
+
+-- values near infinity
+atan0200 atan 7.8764397011195798e+307 8.1647921137746308e+307 -> 1.5707963267948966 6.3439446939604493e-309
+atan0201 atan 1.5873698696131487e+308 -1.0780367422960641e+308 -> 1.5707963267948966 -2.9279309368530781e-309
+atan0202 atan -1.5844551864825834e+308 1.0290657809098675e+308 -> -1.5707963267948966 2.8829614736961417e-309
+atan0203 atan -1.3168792562524032e+308 -9.088432341614825e+307 -> -1.5707963267948966 -3.5499373057390056e-309
+atan0204 atan 0.0 1.0360465742258337e+308 -> 1.5707963267948966 9.6520757355646018e-309
+atan0205 atan -0.0 1.0045063210373196e+308 -> -1.5707963267948966 9.955138947929503e-309
+atan0206 atan 0.0 -9.5155296715763696e+307 -> 1.5707963267948966 -1.050913648020118e-308
+atan0207 atan -0.0 -1.5565700490496501e+308 -> -1.5707963267948966 -6.4243816114189071e-309
+atan0208 atan 1.2956339389525244e+308 0.0 -> 1.5707963267948966 0.0
+atan0209 atan 1.4408126243772151e+308 -0.0 -> 1.5707963267948966 -0.0
+atan0210 atan -1.0631786461936417e+308 0.0 -> -1.5707963267948966 0.0
+atan0211 atan -1.0516056964171069e+308 -0.0 -> -1.5707963267948966 -0.0
+atan0212 atan 1.236162319603838e+308 4.6827953496242936 -> 1.5707963267948966 0.0
+atan0213 atan 7.000516472897218e+307 -5.8631608017844163 -> 1.5707963267948966 -0.0
+atan0214 atan -1.5053444003338508e+308 5.1199197268420313 -> -1.5707963267948966 0.0
+atan0215 atan -1.399172518147259e+308 -3.5687766472913673 -> -1.5707963267948966 -0.0
+atan0216 atan 8.1252833070803021 6.2782953917343822e+307 -> 1.5707963267948966 1.5927890256908564e-308
+atan0217 atan 2.8034285947515167 -1.3378049775753878e+308 -> 1.5707963267948966 -7.4749310756219562e-309
+atan0218 atan -1.4073509988974953 1.6776381785968355e+308 -> -1.5707963267948966 5.9607608646364569e-309
+atan0219 atan -2.7135551527592119 -1.281567445525738e+308 -> -1.5707963267948966 -7.8029447727565326e-309
+
+-- imaginary part = +/-1, real part tiny
+atan0300 atan -1e-150 -1.0 -> -0.78539816339744828 -173.04045556483339
+atan0301 atan 1e-155 1.0 -> 0.78539816339744828 178.79691829731851
+atan0302 atan 9.9999999999999999e-161 -1.0 -> 0.78539816339744828 -184.55338102980363
+atan0303 atan -1e-165 1.0 -> -0.78539816339744828 190.30984376228875
+atan0304 atan -9.9998886718268301e-321 -1.0 -> -0.78539816339744828 -368.76019403576692
+
+-- special values
+atan1000 atan -0.0 0.0 -> -0.0 0.0
+atan1001 atan nan 0.0 -> nan 0.0
+atan1002 atan -0.0 1.0 -> -0.0 inf divide-by-zero
+atan1003 atan -inf 0.0 -> -1.5707963267948966 0.0
+atan1004 atan -inf 2.2999999999999998 -> -1.5707963267948966 0.0
+atan1005 atan nan 2.2999999999999998 -> nan nan
+atan1006 atan -0.0 inf -> -1.5707963267948966 0.0
+atan1007 atan -2.2999999999999998 inf -> -1.5707963267948966 0.0
+atan1008 atan -inf inf -> -1.5707963267948966 0.0
+atan1009 atan nan inf -> nan 0.0
+atan1010 atan -0.0 nan -> nan nan
+atan1011 atan -2.2999999999999998 nan -> nan nan
+atan1012 atan -inf nan -> -1.5707963267948966 0.0 ignore-imag-sign
+atan1013 atan nan nan -> nan nan
+atan1014 atan 0.0 0.0 -> 0.0 0.0
+atan1015 atan 0.0 1.0 -> 0.0 inf divide-by-zero
+atan1016 atan inf 0.0 -> 1.5707963267948966 0.0
+atan1017 atan inf 2.2999999999999998 -> 1.5707963267948966 0.0
+atan1018 atan 0.0 inf -> 1.5707963267948966 0.0
+atan1019 atan 2.2999999999999998 inf -> 1.5707963267948966 0.0
+atan1020 atan inf inf -> 1.5707963267948966 0.0
+atan1021 atan 0.0 nan -> nan nan
+atan1022 atan 2.2999999999999998 nan -> nan nan
+atan1023 atan inf nan -> 1.5707963267948966 0.0 ignore-imag-sign
+atan1024 atan 0.0 -0.0 -> 0.0 -0.0
+atan1025 atan nan -0.0 -> nan -0.0
+atan1026 atan 0.0 -1.0 -> 0.0 -inf divide-by-zero
+atan1027 atan inf -0.0 -> 1.5707963267948966 -0.0
+atan1028 atan inf -2.2999999999999998 -> 1.5707963267948966 -0.0
+atan1029 atan nan -2.2999999999999998 -> nan nan
+atan1030 atan 0.0 -inf -> 1.5707963267948966 -0.0
+atan1031 atan 2.2999999999999998 -inf -> 1.5707963267948966 -0.0
+atan1032 atan inf -inf -> 1.5707963267948966 -0.0
+atan1033 atan nan -inf -> nan -0.0
+atan1034 atan -0.0 -0.0 -> -0.0 -0.0
+atan1035 atan -0.0 -1.0 -> -0.0 -inf divide-by-zero
+atan1036 atan -inf -0.0 -> -1.5707963267948966 -0.0
+atan1037 atan -inf -2.2999999999999998 -> -1.5707963267948966 -0.0
+atan1038 atan -0.0 -inf -> -1.5707963267948966 -0.0
+atan1039 atan -2.2999999999999998 -inf -> -1.5707963267948966 -0.0
+atan1040 atan -inf -inf -> -1.5707963267948966 -0.0
+
+
+---------------------------------------
+-- atanh: Inverse hyperbolic tangent --
+---------------------------------------
+
+-- zeros
+atanh0000 atanh 0.0 0.0 -> 0.0 0.0
+atanh0001 atanh 0.0 -0.0 -> 0.0 -0.0
+atanh0002 atanh -0.0 0.0 -> -0.0 0.0
+atanh0003 atanh -0.0 -0.0 -> -0.0 -0.0
+
+-- values along both sides of real axis
+atanh0010 atanh -9.8813129168249309e-324 0.0 -> -9.8813129168249309e-324 0.0
+atanh0011 atanh -9.8813129168249309e-324 -0.0 -> -9.8813129168249309e-324 -0.0
+atanh0012 atanh -1e-305 0.0 -> -1e-305 0.0
+atanh0013 atanh -1e-305 -0.0 -> -1e-305 -0.0
+atanh0014 atanh -1e-150 0.0 -> -1e-150 0.0
+atanh0015 atanh -1e-150 -0.0 -> -1e-150 -0.0
+atanh0016 atanh -9.9999999999999998e-17 0.0 -> -9.9999999999999998e-17 0.0
+atanh0017 atanh -9.9999999999999998e-17 -0.0 -> -9.9999999999999998e-17 -0.0
+atanh0018 atanh -0.001 0.0 -> -0.0010000003333335333 0.0
+atanh0019 atanh -0.001 -0.0 -> -0.0010000003333335333 -0.0
+atanh0020 atanh -0.57899999999999996 0.0 -> -0.6609570902866303 0.0
+atanh0021 atanh -0.57899999999999996 -0.0 -> -0.6609570902866303 -0.0
+atanh0022 atanh -0.99999999999999989 0.0 -> -18.714973875118524 0.0
+atanh0023 atanh -0.99999999999999989 -0.0 -> -18.714973875118524 -0.0
+atanh0024 atanh -1.0000000000000002 0.0 -> -18.36840028483855 1.5707963267948966
+atanh0025 atanh -1.0000000000000002 -0.0 -> -18.36840028483855 -1.5707963267948966
+atanh0026 atanh -1.0009999999999999 0.0 -> -3.8007011672919218 1.5707963267948966
+atanh0027 atanh -1.0009999999999999 -0.0 -> -3.8007011672919218 -1.5707963267948966
+atanh0028 atanh -2.0 0.0 -> -0.54930614433405489 1.5707963267948966
+atanh0029 atanh -2.0 -0.0 -> -0.54930614433405489 -1.5707963267948966
+atanh0030 atanh -23.0 0.0 -> -0.043505688494814884 1.5707963267948966
+atanh0031 atanh -23.0 -0.0 -> -0.043505688494814884 -1.5707963267948966
+atanh0032 atanh -10000000000000000.0 0.0 -> -9.9999999999999998e-17 1.5707963267948966
+atanh0033 atanh -10000000000000000.0 -0.0 -> -9.9999999999999998e-17 -1.5707963267948966
+atanh0034 atanh -9.9999999999999998e+149 0.0 -> -1e-150 1.5707963267948966
+atanh0035 atanh -9.9999999999999998e+149 -0.0 -> -1e-150 -1.5707963267948966
+atanh0036 atanh -1.0000000000000001e+299 0.0 -> -9.9999999999999999e-300 1.5707963267948966
+atanh0037 atanh -1.0000000000000001e+299 -0.0 -> -9.9999999999999999e-300 -1.5707963267948966
+atanh0038 atanh 9.8813129168249309e-324 0.0 -> 9.8813129168249309e-324 0.0
+atanh0039 atanh 9.8813129168249309e-324 -0.0 -> 9.8813129168249309e-324 -0.0
+atanh0040 atanh 1e-305 0.0 -> 1e-305 0.0
+atanh0041 atanh 1e-305 -0.0 -> 1e-305 -0.0
+atanh0042 atanh 1e-150 0.0 -> 1e-150 0.0
+atanh0043 atanh 1e-150 -0.0 -> 1e-150 -0.0
+atanh0044 atanh 9.9999999999999998e-17 0.0 -> 9.9999999999999998e-17 0.0
+atanh0045 atanh 9.9999999999999998e-17 -0.0 -> 9.9999999999999998e-17 -0.0
+atanh0046 atanh 0.001 0.0 -> 0.0010000003333335333 0.0
+atanh0047 atanh 0.001 -0.0 -> 0.0010000003333335333 -0.0
+atanh0048 atanh 0.57899999999999996 0.0 -> 0.6609570902866303 0.0
+atanh0049 atanh 0.57899999999999996 -0.0 -> 0.6609570902866303 -0.0
+atanh0050 atanh 0.99999999999999989 0.0 -> 18.714973875118524 0.0
+atanh0051 atanh 0.99999999999999989 -0.0 -> 18.714973875118524 -0.0
+atanh0052 atanh 1.0000000000000002 0.0 -> 18.36840028483855 1.5707963267948966
+atanh0053 atanh 1.0000000000000002 -0.0 -> 18.36840028483855 -1.5707963267948966
+atanh0054 atanh 1.0009999999999999 0.0 -> 3.8007011672919218 1.5707963267948966
+atanh0055 atanh 1.0009999999999999 -0.0 -> 3.8007011672919218 -1.5707963267948966
+atanh0056 atanh 2.0 0.0 -> 0.54930614433405489 1.5707963267948966
+atanh0057 atanh 2.0 -0.0 -> 0.54930614433405489 -1.5707963267948966
+atanh0058 atanh 23.0 0.0 -> 0.043505688494814884 1.5707963267948966
+atanh0059 atanh 23.0 -0.0 -> 0.043505688494814884 -1.5707963267948966
+atanh0060 atanh 10000000000000000.0 0.0 -> 9.9999999999999998e-17 1.5707963267948966
+atanh0061 atanh 10000000000000000.0 -0.0 -> 9.9999999999999998e-17 -1.5707963267948966
+atanh0062 atanh 9.9999999999999998e+149 0.0 -> 1e-150 1.5707963267948966
+atanh0063 atanh 9.9999999999999998e+149 -0.0 -> 1e-150 -1.5707963267948966
+atanh0064 atanh 1.0000000000000001e+299 0.0 -> 9.9999999999999999e-300 1.5707963267948966
+atanh0065 atanh 1.0000000000000001e+299 -0.0 -> 9.9999999999999999e-300 -1.5707963267948966
+
+-- random inputs
+atanh0100 atanh -0.54460925980633501 -0.54038050126721027 -> -0.41984265808446974 -0.60354153938352828
+atanh0101 atanh -1.6934614269829051 -0.48807386108113621 -> -0.58592769102243281 -1.3537837470975898
+atanh0102 atanh -1.3467293985501207 -0.47868354895395876 -> -0.69961624370709985 -1.1994450156570076
+atanh0103 atanh -5.6142232418984888 -544551613.39307702 -> -1.8932657550925744e-17 -1.5707963249585235
+atanh0104 atanh -0.011841460381263651 -3.259978899823385 -> -0.0010183936547405188 -1.2731614020743838
+atanh0105 atanh -0.0073345736950029532 0.35821949670922248 -> -0.0065004869024682466 0.34399359971920895
+atanh0106 atanh -13.866782244320014 0.9541129545860273 -> -0.071896852055058899 1.5658322704631409
+atanh0107 atanh -708.59964982780775 21.984802159266675 -> -0.0014098779074189741 1.5707525842838959
+atanh0108 atanh -30.916832076030602 1.3691897138829843 -> -0.032292682045743676 1.5693652094847115
+atanh0109 atanh -0.57461806339861754 0.29534797443913063 -> -0.56467464472482765 0.39615612824172625
+atanh0110 atanh 0.40089246737415685 -1.632285984300659 -> 0.1063832707890608 -1.0402821335326482
+atanh0111 atanh 2119.6167688262176 -1.5383653437377242e+17 -> 8.9565008518382049e-32 -1.5707963267948966
+atanh0112 atanh 756.86017850941641 -6.6064087133223817 -> 0.0013211481136820046 -1.5707847948702234
+atanh0113 atanh 4.0490617718041602 -2.5784456791040652e-12 -> 0.25218425538553618 -1.5707963267947291
+atanh0114 atanh 10.589254957173523 -0.13956391149624509 -> 0.094700890282197664 -1.5695407140217623
+atanh0115 atanh 1.0171187553160499 0.70766113465354019 -> 0.55260251975367791 0.96619711116641682
+atanh0116 atanh 0.031645502527750849 0.067319983726544394 -> 0.031513018344086742 0.067285437670549036
+atanh0117 atanh 0.13670177624994517 0.43240089361857947 -> 0.11538933151017253 0.41392008145336212
+atanh0118 atanh 0.64173899243596688 2.9008577686695256 -> 0.065680142424134405 1.2518535724053921
+atanh0119 atanh 0.19313813528025942 38.799619150741869 -> 0.00012820765917366644 1.5450292202823612
+
+-- values near infinity
+atanh0200 atanh 5.3242646831347954e+307 1.3740396080084153e+308 -> 2.4519253616695576e-309 1.5707963267948966
+atanh0201 atanh 1.158701641241358e+308 -6.5579268873375853e+307 -> 6.5365375267795098e-309 -1.5707963267948966
+atanh0202 atanh -1.3435325735762247e+308 9.8947369259601547e+307 -> -4.8256680906589956e-309 1.5707963267948966
+atanh0203 atanh -1.4359857522598942e+308 -9.4701204702391004e+307 -> -4.8531282262872645e-309 -1.5707963267948966
+atanh0204 atanh 0.0 5.6614181068098497e+307 -> 0.0 1.5707963267948966
+atanh0205 atanh -0.0 6.9813212721450139e+307 -> -0.0 1.5707963267948966
+atanh0206 atanh 0.0 -7.4970613060311453e+307 -> 0.0 -1.5707963267948966
+atanh0207 atanh -0.0 -1.5280601880314068e+308 -> -0.0 -1.5707963267948966
+atanh0208 atanh 8.2219472336000745e+307 0.0 -> 1.2162568933954813e-308 1.5707963267948966
+atanh0209 atanh 1.4811519617280899e+308 -0.0 -> 6.7515017083951325e-309 -1.5707963267948966
+atanh0210 atanh -1.2282016263598785e+308 0.0 -> -8.1419856360537615e-309 1.5707963267948966
+atanh0211 atanh -1.0616427760154426e+308 -0.0 -> -9.4193642399489563e-309 -1.5707963267948966
+atanh0212 atanh 1.2971536510180682e+308 5.2847948452333293 -> 7.7091869510998328e-309 1.5707963267948966
+atanh0213 atanh 1.1849860977411851e+308 -7.9781906447459949 -> 8.4389175696339014e-309 -1.5707963267948966
+atanh0214 atanh -1.4029969422586635e+308 0.93891986543663375 -> -7.127599283218073e-309 1.5707963267948966
+atanh0215 atanh -4.7508098912248211e+307 -8.2702421247039908 -> -2.1049042645278043e-308 -1.5707963267948966
+atanh0216 atanh 8.2680742115769998 8.1153898410918065e+307 -> 0.0 1.5707963267948966
+atanh0217 atanh 1.2575325146218885 -1.4746679147661649e+308 -> 0.0 -1.5707963267948966
+atanh0218 atanh -2.4618803682310899 1.3781522717005568e+308 -> -0.0 1.5707963267948966
+atanh0219 atanh -4.0952386694788112 -1.231083376353703e+308 -> -0.0 -1.5707963267948966
+
+-- values near 0
+atanh0220 atanh 3.8017563659811628e-314 2.6635484239074319e-312 -> 3.8017563659811628e-314 2.6635484239074319e-312
+atanh0221 atanh 1.7391110733611878e-321 -4.3547800672541419e-313 -> 1.7391110733611878e-321 -4.3547800672541419e-313
+atanh0222 atanh -5.9656816081325078e-317 9.9692253555416263e-313 -> -5.9656816081325078e-317 9.9692253555416263e-313
+atanh0223 atanh -6.5606671178400239e-313 -2.1680936406357335e-309 -> -6.5606671178400239e-313 -2.1680936406357335e-309
+atanh0224 atanh 0.0 2.5230944401820779e-319 -> 0.0 2.5230944401820779e-319
+atanh0225 atanh -0.0 5.6066569490064658e-320 -> -0.0 5.6066569490064658e-320
+atanh0226 atanh 0.0 -2.4222487249468377e-317 -> 0.0 -2.4222487249468377e-317
+atanh0227 atanh -0.0 -3.0861101089206037e-316 -> -0.0 -3.0861101089206037e-316
+atanh0228 atanh 3.1219222884393986e-310 0.0 -> 3.1219222884393986e-310 0.0
+atanh0229 atanh 9.8926337564976196e-309 -0.0 -> 9.8926337564976196e-309 -0.0
+atanh0230 atanh -1.5462535092918154e-312 0.0 -> -1.5462535092918154e-312 0.0
+atanh0231 atanh -9.8813129168249309e-324 -0.0 -> -9.8813129168249309e-324 -0.0
+
+-- real part = +/-1, imaginary part tiny
+atanh0300 atanh 1.0 1e-153 -> 176.49433320432448 0.78539816339744828
+atanh0301 atanh 1.0 9.9999999999999997e-155 -> 177.64562575082149 0.78539816339744828
+atanh0302 atanh -1.0 1e-161 -> -185.70467357630065 0.78539816339744828
+atanh0303 atanh 1.0 -1e-165 -> 190.30984376228875 -0.78539816339744828
+atanh0304 atanh -1.0 -9.8813129168249309e-324 -> -372.22003596069061 -0.78539816339744828
+
+-- special values
+atanh1000 atanh 0.0 0.0 -> 0.0 0.0
+atanh1001 atanh 0.0 nan -> 0.0 nan
+atanh1002 atanh 1.0 0.0 -> inf 0.0 divide-by-zero
+atanh1003 atanh 0.0 inf -> 0.0 1.5707963267948966
+atanh1004 atanh 2.3 inf -> 0.0 1.5707963267948966
+atanh1005 atanh 2.3 nan -> nan nan
+atanh1006 atanh inf 0.0 -> 0.0 1.5707963267948966
+atanh1007 atanh inf 2.3 -> 0.0 1.5707963267948966
+atanh1008 atanh inf inf -> 0.0 1.5707963267948966
+atanh1009 atanh inf nan -> 0.0 nan
+atanh1010 atanh nan 0.0 -> nan nan
+atanh1011 atanh nan 2.3 -> nan nan
+atanh1012 atanh nan inf -> 0.0 1.5707963267948966 ignore-real-sign
+atanh1013 atanh nan nan -> nan nan
+atanh1014 atanh 0.0 -0.0 -> 0.0 -0.0
+atanh1015 atanh 1.0 -0.0 -> inf -0.0 divide-by-zero
+atanh1016 atanh 0.0 -inf -> 0.0 -1.5707963267948966
+atanh1017 atanh 2.3 -inf -> 0.0 -1.5707963267948966
+atanh1018 atanh inf -0.0 -> 0.0 -1.5707963267948966
+atanh1019 atanh inf -2.3 -> 0.0 -1.5707963267948966
+atanh1020 atanh inf -inf -> 0.0 -1.5707963267948966
+atanh1021 atanh nan -0.0 -> nan nan
+atanh1022 atanh nan -2.3 -> nan nan
+atanh1023 atanh nan -inf -> 0.0 -1.5707963267948966 ignore-real-sign
+atanh1024 atanh -0.0 -0.0 -> -0.0 -0.0
+atanh1025 atanh -0.0 nan -> -0.0 nan
+atanh1026 atanh -1.0 -0.0 -> -inf -0.0 divide-by-zero
+atanh1027 atanh -0.0 -inf -> -0.0 -1.5707963267948966
+atanh1028 atanh -2.3 -inf -> -0.0 -1.5707963267948966
+atanh1029 atanh -2.3 nan -> nan nan
+atanh1030 atanh -inf -0.0 -> -0.0 -1.5707963267948966
+atanh1031 atanh -inf -2.3 -> -0.0 -1.5707963267948966
+atanh1032 atanh -inf -inf -> -0.0 -1.5707963267948966
+atanh1033 atanh -inf nan -> -0.0 nan
+atanh1034 atanh -0.0 0.0 -> -0.0 0.0
+atanh1035 atanh -1.0 0.0 -> -inf 0.0 divide-by-zero
+atanh1036 atanh -0.0 inf -> -0.0 1.5707963267948966
+atanh1037 atanh -2.3 inf -> -0.0 1.5707963267948966
+atanh1038 atanh -inf 0.0 -> -0.0 1.5707963267948966
+atanh1039 atanh -inf 2.3 -> -0.0 1.5707963267948966
+atanh1040 atanh -inf inf -> -0.0 1.5707963267948966
+
+
+----------------------------
+-- log: Natural logarithm --
+----------------------------
+
+log0000 log 1.0 0.0 -> 0.0 0.0
+log0001 log 1.0 -0.0 -> 0.0 -0.0
+log0002 log -1.0 0.0 -> 0.0 3.1415926535897931
+log0003 log -1.0 -0.0 -> 0.0 -3.1415926535897931
+-- values along both sides of real axis
+log0010 log -9.8813129168249309e-324 0.0 -> -743.74692474082133 3.1415926535897931
+log0011 log -9.8813129168249309e-324 -0.0 -> -743.74692474082133 -3.1415926535897931
+log0012 log -1e-305 0.0 -> -702.28845336318398 3.1415926535897931
+log0013 log -1e-305 -0.0 -> -702.28845336318398 -3.1415926535897931
+log0014 log -1e-150 0.0 -> -345.38776394910684 3.1415926535897931
+log0015 log -1e-150 -0.0 -> -345.38776394910684 -3.1415926535897931
+log0016 log -9.9999999999999998e-17 0.0 -> -36.841361487904734 3.1415926535897931
+log0017 log -9.9999999999999998e-17 -0.0 -> -36.841361487904734 -3.1415926535897931
+log0018 log -0.001 0.0 -> -6.9077552789821368 3.1415926535897931
+log0019 log -0.001 -0.0 -> -6.9077552789821368 -3.1415926535897931
+log0020 log -0.57899999999999996 0.0 -> -0.54645280140914188 3.1415926535897931
+log0021 log -0.57899999999999996 -0.0 -> -0.54645280140914188 -3.1415926535897931
+log0022 log -0.99999999999999989 0.0 -> -1.1102230246251565e-16 3.1415926535897931
+log0023 log -0.99999999999999989 -0.0 -> -1.1102230246251565e-16 -3.1415926535897931
+log0024 log -1.0000000000000002 0.0 -> 2.2204460492503128e-16 3.1415926535897931
+log0025 log -1.0000000000000002 -0.0 -> 2.2204460492503128e-16 -3.1415926535897931
+log0026 log -1.0009999999999999 0.0 -> 0.00099950033308342321 3.1415926535897931
+log0027 log -1.0009999999999999 -0.0 -> 0.00099950033308342321 -3.1415926535897931
+log0028 log -2.0 0.0 -> 0.69314718055994529 3.1415926535897931
+log0029 log -2.0 -0.0 -> 0.69314718055994529 -3.1415926535897931
+log0030 log -23.0 0.0 -> 3.1354942159291497 3.1415926535897931
+log0031 log -23.0 -0.0 -> 3.1354942159291497 -3.1415926535897931
+log0032 log -10000000000000000.0 0.0 -> 36.841361487904734 3.1415926535897931
+log0033 log -10000000000000000.0 -0.0 -> 36.841361487904734 -3.1415926535897931
+log0034 log -9.9999999999999998e+149 0.0 -> 345.38776394910684 3.1415926535897931
+log0035 log -9.9999999999999998e+149 -0.0 -> 345.38776394910684 -3.1415926535897931
+log0036 log -1.0000000000000001e+299 0.0 -> 688.47294280521965 3.1415926535897931
+log0037 log -1.0000000000000001e+299 -0.0 -> 688.47294280521965 -3.1415926535897931
+log0038 log 9.8813129168249309e-324 0.0 -> -743.74692474082133 0.0
+log0039 log 9.8813129168249309e-324 -0.0 -> -743.74692474082133 -0.0
+log0040 log 1e-305 0.0 -> -702.28845336318398 0.0
+log0041 log 1e-305 -0.0 -> -702.28845336318398 -0.0
+log0042 log 1e-150 0.0 -> -345.38776394910684 0.0
+log0043 log 1e-150 -0.0 -> -345.38776394910684 -0.0
+log0044 log 9.9999999999999998e-17 0.0 -> -36.841361487904734 0.0
+log0045 log 9.9999999999999998e-17 -0.0 -> -36.841361487904734 -0.0
+log0046 log 0.001 0.0 -> -6.9077552789821368 0.0
+log0047 log 0.001 -0.0 -> -6.9077552789821368 -0.0
+log0048 log 0.57899999999999996 0.0 -> -0.54645280140914188 0.0
+log0049 log 0.57899999999999996 -0.0 -> -0.54645280140914188 -0.0
+log0050 log 0.99999999999999989 0.0 -> -1.1102230246251565e-16 0.0
+log0051 log 0.99999999999999989 -0.0 -> -1.1102230246251565e-16 -0.0
+log0052 log 1.0000000000000002 0.0 -> 2.2204460492503128e-16 0.0
+log0053 log 1.0000000000000002 -0.0 -> 2.2204460492503128e-16 -0.0
+log0054 log 1.0009999999999999 0.0 -> 0.00099950033308342321 0.0
+log0055 log 1.0009999999999999 -0.0 -> 0.00099950033308342321 -0.0
+log0056 log 2.0 0.0 -> 0.69314718055994529 0.0
+log0057 log 2.0 -0.0 -> 0.69314718055994529 -0.0
+log0058 log 23.0 0.0 -> 3.1354942159291497 0.0
+log0059 log 23.0 -0.0 -> 3.1354942159291497 -0.0
+log0060 log 10000000000000000.0 0.0 -> 36.841361487904734 0.0
+log0061 log 10000000000000000.0 -0.0 -> 36.841361487904734 -0.0
+log0062 log 9.9999999999999998e+149 0.0 -> 345.38776394910684 0.0
+log0063 log 9.9999999999999998e+149 -0.0 -> 345.38776394910684 -0.0
+log0064 log 1.0000000000000001e+299 0.0 -> 688.47294280521965 0.0
+log0065 log 1.0000000000000001e+299 -0.0 -> 688.47294280521965 -0.0
+
+-- random inputs
+log0066 log -1.9830454945186191e-16 -2.0334448025673346 -> 0.70973130194329803 -1.5707963267948968
+log0067 log -0.96745853024741857 -0.84995816228299692 -> 0.25292811398722387 -2.4207570438536905
+log0068 log -0.1603644313948418 -0.2929942111041835 -> -1.0965857872427374 -2.0715870859971419
+log0069 log -0.15917913168438699 -0.25238799251132177 -> -1.2093477313249901 -2.1334784232033863
+log0070 log -0.68907818535078802 -3.0693105853476346 -> 1.1460398629184565 -1.7916403813913211
+log0071 log -17.268133447565589 6.8165120014604756 -> 2.9212694465974836 2.7656245081603164
+log0072 log -1.7153894479690328 26.434055372802636 -> 3.2767542953718003 1.6355986276341734
+log0073 log -8.0456794648936578e-06 0.19722758057570208 -> -1.6233969848296075 1.5708371206810101
+log0074 log -2.4306442691323173 0.6846919750700996 -> 0.92633592001969589 2.8670160576718331
+log0075 log -3.5488049250888194 0.45324040643185254 -> 1.2747008374256426 3.0145640007885111
+log0076 log 0.18418516851510189 -0.26062518836212617 -> -1.1421287121940344 -0.95558440841183434
+log0077 log 2.7124837795638399 -13.148769067133387 -> 2.5971659975706802 -1.3673583045209439
+log0078 log 3.6521275476169149e-13 -3.7820543023170673e-05 -> -10.182658136741569 -1.5707963171384316
+log0079 log 5.0877545813862239 -1.2834978326786852 -> 1.6576856213076328 -0.24711583497738485
+log0080 log 0.26477986808461512 -0.67659001194187429 -> -0.31944085207999973 -1.197773671987121
+log0081 log 0.0014754261398071962 5.3514691608205442 -> 1.6773711707153829 1.5705206219261802
+log0082 log 0.29667334462157885 0.00020056045042584795 -> -1.2151233667079588 0.00067603114168689204
+log0083 log 0.82104233671099425 3.9005387130133102 -> 1.3827918965299593 1.3633304701848363
+log0084 log 0.27268135358180667 124.42088110945804 -> 4.8236724223559229 1.5686047258789015
+log0085 log 0.0026286959168267485 0.47795808180573013 -> -0.73821712137809126 1.5652965360960087
+
+-- values near infinity
+log0100 log 1.0512025744003172e+308 7.2621669750664611e+307 -> 709.44123967814494 0.60455434048332968
+log0101 log 5.5344249034372126e+307 -1.2155859158431275e+308 -> 709.48562300345679 -1.143553056717973
+log0102 log -1.3155575403469408e+308 1.1610793541663864e+308 -> 709.75847809546428 2.41848796504974
+log0103 log -1.632366720973235e+308 -1.54299446211448e+308 -> 710.00545236515586 -2.3843326028455087
+log0104 log 0.0 5.9449276692327712e+307 -> 708.67616191258526 1.5707963267948966
+log0105 log -0.0 1.1201850459025692e+308 -> 709.30970253338171 1.5707963267948966
+log0106 log 0.0 -1.6214225933466528e+308 -> 709.6795125501086 -1.5707963267948966
+log0107 log -0.0 -1.7453269791591058e+308 -> 709.75315056087379 -1.5707963267948966
+log0108 log 1.440860577601428e+308 0.0 -> 709.56144920058262 0.0
+log0109 log 1.391515176148282e+308 -0.0 -> 709.52660185041327 -0.0
+log0110 log -1.201354401295296e+308 0.0 -> 709.37965823023956 3.1415926535897931
+log0111 log -1.6704337825976804e+308 -0.0 -> 709.70929198492399 -3.1415926535897931
+log0112 log 7.2276974655190223e+307 7.94879711369164 -> 708.87154406512104 1.0997689307850458e-307
+log0113 log 1.1207859593716076e+308 -6.1956200868221147 -> 709.31023883080104 -5.5279244310803286e-308
+log0114 log -4.6678933874471045e+307 9.947107893220382 -> 708.43433142431388 3.1415926535897931
+log0115 log -1.5108012453950142e+308 -5.3117197179375619 -> 709.60884877835008 -3.1415926535897931
+log0116 log 7.4903750871504435 1.5320703776626352e+308 -> 709.62282865085137 1.5707963267948966
+log0117 log 5.9760325525654778 -8.0149473997349123e+307 -> 708.97493177248396 -1.5707963267948966
+log0118 log -7.880194206386629 1.7861845814767441e+308 -> 709.77629046837137 1.5707963267948966
+log0119 log -9.886438993852865 -6.19235781080747e+307 -> 708.71693946977302 -1.5707963267948966
+
+-- values near 0
+log0120 log 2.2996867579227779e-308 6.7861840770939125e-312 -> -708.36343567717392 0.00029509166223339815
+log0121 log 6.9169190417774516e-323 -9.0414013188948118e-322 -> -739.22766796468386 -1.4944423210001669
+log0122 log -1.5378064962914011e-316 1.8243628389354635e-310 -> -713.20014803142965 1.5707971697228842
+log0123 log -2.3319898483706837e-321 -2.2358763941866371e-313 -> -719.9045008332522 -1.570796337224766
+log0124 log 0.0 3.872770101081121e-315 -> -723.96033425374401 1.5707963267948966
+log0125 log -0.0 9.6342800939043076e-322 -> -739.16707236281752 1.5707963267948966
+log0126 log 0.0 -2.266099393427834e-308 -> -708.37814861757965 -1.5707963267948966
+log0127 log -0.0 -2.1184695673766626e-315 -> -724.56361036731812 -1.5707963267948966
+log0128 log 1.1363509854348671e-322 0.0 -> -741.30457770545206 0.0
+log0129 log 3.5572726500569751e-322 -0.0 -> -740.16340580236522 -0.0
+log0130 log -2.3696071074040593e-310 0.0 -> -712.93865466421641 3.1415926535897931
+log0131 log -2.813283897266934e-317 -0.0 -> -728.88512203138862 -3.1415926535897931
+
+-- values near the unit circle
+log0200 log -0.59999999999999998 0.80000000000000004 -> 2.2204460492503132e-17 2.2142974355881808
+log0201 log 0.79999999999999993 0.60000000000000009 -> 6.1629758220391547e-33 0.64350110879328448
+
+-- special values
+log1000 log -0.0 0.0 -> -inf 3.1415926535897931 divide-by-zero
+log1001 log 0.0 0.0 -> -inf 0.0 divide-by-zero
+log1002 log 0.0 inf -> inf 1.5707963267948966
+log1003 log 2.3 inf -> inf 1.5707963267948966
+log1004 log -0.0 inf -> inf 1.5707963267948966
+log1005 log -2.3 inf -> inf 1.5707963267948966
+log1006 log 0.0 nan -> nan nan
+log1007 log 2.3 nan -> nan nan
+log1008 log -0.0 nan -> nan nan
+log1009 log -2.3 nan -> nan nan
+log1010 log -inf 0.0 -> inf 3.1415926535897931
+log1011 log -inf 2.3 -> inf 3.1415926535897931
+log1012 log inf 0.0 -> inf 0.0
+log1013 log inf 2.3 -> inf 0.0
+log1014 log -inf inf -> inf 2.3561944901923448
+log1015 log inf inf -> inf 0.78539816339744828
+log1016 log inf nan -> inf nan
+log1017 log -inf nan -> inf nan
+log1018 log nan 0.0 -> nan nan
+log1019 log nan 2.3 -> nan nan
+log1020 log nan inf -> inf nan
+log1021 log nan nan -> nan nan
+log1022 log -0.0 -0.0 -> -inf -3.1415926535897931 divide-by-zero
+log1023 log 0.0 -0.0 -> -inf -0.0 divide-by-zero
+log1024 log 0.0 -inf -> inf -1.5707963267948966
+log1025 log 2.3 -inf -> inf -1.5707963267948966
+log1026 log -0.0 -inf -> inf -1.5707963267948966
+log1027 log -2.3 -inf -> inf -1.5707963267948966
+log1028 log -inf -0.0 -> inf -3.1415926535897931
+log1029 log -inf -2.3 -> inf -3.1415926535897931
+log1030 log inf -0.0 -> inf -0.0
+log1031 log inf -2.3 -> inf -0.0
+log1032 log -inf -inf -> inf -2.3561944901923448
+log1033 log inf -inf -> inf -0.78539816339744828
+log1034 log nan -0.0 -> nan nan
+log1035 log nan -2.3 -> nan nan
+log1036 log nan -inf -> inf nan
+
+
+------------------------------
+-- log10: Logarithm base 10 --
+------------------------------
+
+logt0000 log10 1.0 0.0 -> 0.0 0.0
+logt0001 log10 1.0 -0.0 -> 0.0 -0.0
+logt0002 log10 -1.0 0.0 -> 0.0 1.3643763538418414
+logt0003 log10 -1.0 -0.0 -> 0.0 -1.3643763538418414
+-- values along both sides of real axis
+logt0010 log10 -9.8813129168249309e-324 0.0 -> -323.0051853474518 1.3643763538418414
+logt0011 log10 -9.8813129168249309e-324 -0.0 -> -323.0051853474518 -1.3643763538418414
+logt0012 log10 -1e-305 0.0 -> -305.0 1.3643763538418414
+logt0013 log10 -1e-305 -0.0 -> -305.0 -1.3643763538418414
+logt0014 log10 -1e-150 0.0 -> -150.0 1.3643763538418414
+logt0015 log10 -1e-150 -0.0 -> -150.0 -1.3643763538418414
+logt0016 log10 -9.9999999999999998e-17 0.0 -> -16.0 1.3643763538418414
+logt0017 log10 -9.9999999999999998e-17 -0.0 -> -16.0 -1.3643763538418414
+logt0018 log10 -0.001 0.0 -> -3.0 1.3643763538418414
+logt0019 log10 -0.001 -0.0 -> -3.0 -1.3643763538418414
+logt0020 log10 -0.57899999999999996 0.0 -> -0.23732143627256383 1.3643763538418414
+logt0021 log10 -0.57899999999999996 -0.0 -> -0.23732143627256383 -1.3643763538418414
+logt0022 log10 -0.99999999999999989 0.0 -> -4.821637332766436e-17 1.3643763538418414
+logt0023 log10 -0.99999999999999989 -0.0 -> -4.821637332766436e-17 -1.3643763538418414
+logt0024 log10 -1.0000000000000002 0.0 -> 9.6432746655328696e-17 1.3643763538418414
+logt0025 log10 -1.0000000000000002 -0.0 -> 9.6432746655328696e-17 -1.3643763538418414
+logt0026 log10 -1.0009999999999999 0.0 -> 0.0004340774793185929 1.3643763538418414
+logt0027 log10 -1.0009999999999999 -0.0 -> 0.0004340774793185929 -1.3643763538418414
+logt0028 log10 -2.0 0.0 -> 0.3010299956639812 1.3643763538418414
+logt0029 log10 -2.0 -0.0 -> 0.3010299956639812 -1.3643763538418414
+logt0030 log10 -23.0 0.0 -> 1.3617278360175928 1.3643763538418414
+logt0031 log10 -23.0 -0.0 -> 1.3617278360175928 -1.3643763538418414
+logt0032 log10 -10000000000000000.0 0.0 -> 16.0 1.3643763538418414
+logt0033 log10 -10000000000000000.0 -0.0 -> 16.0 -1.3643763538418414
+logt0034 log10 -9.9999999999999998e+149 0.0 -> 150.0 1.3643763538418414
+logt0035 log10 -9.9999999999999998e+149 -0.0 -> 150.0 -1.3643763538418414
+logt0036 log10 -1.0000000000000001e+299 0.0 -> 299.0 1.3643763538418414
+logt0037 log10 -1.0000000000000001e+299 -0.0 -> 299.0 -1.3643763538418414
+logt0038 log10 9.8813129168249309e-324 0.0 -> -323.0051853474518 0.0
+logt0039 log10 9.8813129168249309e-324 -0.0 -> -323.0051853474518 -0.0
+logt0040 log10 1e-305 0.0 -> -305.0 0.0
+logt0041 log10 1e-305 -0.0 -> -305.0 -0.0
+logt0042 log10 1e-150 0.0 -> -150.0 0.0
+logt0043 log10 1e-150 -0.0 -> -150.0 -0.0
+logt0044 log10 9.9999999999999998e-17 0.0 -> -16.0 0.0
+logt0045 log10 9.9999999999999998e-17 -0.0 -> -16.0 -0.0
+logt0046 log10 0.001 0.0 -> -3.0 0.0
+logt0047 log10 0.001 -0.0 -> -3.0 -0.0
+logt0048 log10 0.57899999999999996 0.0 -> -0.23732143627256383 0.0
+logt0049 log10 0.57899999999999996 -0.0 -> -0.23732143627256383 -0.0
+logt0050 log10 0.99999999999999989 0.0 -> -4.821637332766436e-17 0.0
+logt0051 log10 0.99999999999999989 -0.0 -> -4.821637332766436e-17 -0.0
+logt0052 log10 1.0000000000000002 0.0 -> 9.6432746655328696e-17 0.0
+logt0053 log10 1.0000000000000002 -0.0 -> 9.6432746655328696e-17 -0.0
+logt0054 log10 1.0009999999999999 0.0 -> 0.0004340774793185929 0.0
+logt0055 log10 1.0009999999999999 -0.0 -> 0.0004340774793185929 -0.0
+logt0056 log10 2.0 0.0 -> 0.3010299956639812 0.0
+logt0057 log10 2.0 -0.0 -> 0.3010299956639812 -0.0
+logt0058 log10 23.0 0.0 -> 1.3617278360175928 0.0
+logt0059 log10 23.0 -0.0 -> 1.3617278360175928 -0.0
+logt0060 log10 10000000000000000.0 0.0 -> 16.0 0.0
+logt0061 log10 10000000000000000.0 -0.0 -> 16.0 -0.0
+logt0062 log10 9.9999999999999998e+149 0.0 -> 150.0 0.0
+logt0063 log10 9.9999999999999998e+149 -0.0 -> 150.0 -0.0
+logt0064 log10 1.0000000000000001e+299 0.0 -> 299.0 0.0
+logt0065 log10 1.0000000000000001e+299 -0.0 -> 299.0 -0.0
+
+-- random inputs
+logt0066 log10 -1.9830454945186191e-16 -2.0334448025673346 -> 0.30823238806798503 -0.68218817692092071
+logt0067 log10 -0.96745853024741857 -0.84995816228299692 -> 0.10984528422284802 -1.051321426174086
+logt0068 log10 -0.1603644313948418 -0.2929942111041835 -> -0.47624115633305419 -0.89967884023059597
+logt0069 log10 -0.15917913168438699 -0.25238799251132177 -> -0.52521304641665956 -0.92655790645688119
+logt0070 log10 -0.68907818535078802 -3.0693105853476346 -> 0.4977187885066448 -0.77809953119328823
+logt0071 log10 -17.268133447565589 6.8165120014604756 -> 1.2686912008098534 1.2010954629104202
+logt0072 log10 -1.7153894479690328 26.434055372802636 -> 1.423076309032751 0.71033145859005309
+logt0073 log10 -8.0456794648936578e-06 0.19722758057570208 -> -0.70503235244987561 0.68220589348055516
+logt0074 log10 -2.4306442691323173 0.6846919750700996 -> 0.40230257845332595 1.2451292533748923
+logt0075 log10 -3.5488049250888194 0.45324040643185254 -> 0.55359553977141063 1.3092085108866405
+logt0076 log10 0.18418516851510189 -0.26062518836212617 -> -0.49602019732913638 -0.41500503556604301
+logt0077 log10 2.7124837795638399 -13.148769067133387 -> 1.1279348613317008 -0.59383616643803216
+logt0078 log10 3.6521275476169149e-13 -3.7820543023170673e-05 -> -4.4222722398941112 -0.68218817272717114
+logt0079 log10 5.0877545813862239 -1.2834978326786852 -> 0.71992371806426847 -0.10732104352159283
+logt0080 log10 0.26477986808461512 -0.67659001194187429 -> -0.13873139935281681 -0.52018649631300229
+logt0081 log10 0.0014754261398071962 5.3514691608205442 -> 0.72847304354528819 0.6820684398178033
+logt0082 log10 0.29667334462157885 0.00020056045042584795 -> -0.52772137299296806 0.00029359659442937261
+logt0083 log10 0.82104233671099425 3.9005387130133102 -> 0.60053889028349361 0.59208690021184018
+logt0084 log10 0.27268135358180667 124.42088110945804 -> 2.094894315538069 0.68123637673656989
+logt0085 log10 0.0026286959168267485 0.47795808180573013 -> -0.32060362226100814 0.67979964816877081
+
+-- values near infinity
+logt0100 log10 1.0512025744003172e+308 7.2621669750664611e+307 -> 308.10641562682065 0.26255461408256975
+logt0101 log10 5.5344249034372126e+307 -1.2155859158431275e+308 -> 308.12569106009209 -0.496638782296212
+logt0102 log10 -1.3155575403469408e+308 1.1610793541663864e+308 -> 308.24419052091019 1.0503359777705266
+logt0103 log10 -1.632366720973235e+308 -1.54299446211448e+308 -> 308.3514500834093 -1.0355024924378222
+logt0104 log10 0.0 5.9449276692327712e+307 -> 307.77414657501117 0.68218817692092071
+logt0105 log10 -0.0 1.1201850459025692e+308 -> 308.04928977068465 0.68218817692092071
+logt0106 log10 0.0 -1.6214225933466528e+308 -> 308.20989622030174 -0.68218817692092071
+logt0107 log10 -0.0 -1.7453269791591058e+308 -> 308.24187680203539 -0.68218817692092071
+logt0108 log10 1.440860577601428e+308 0.0 -> 308.15862195908755 0.0
+logt0109 log10 1.391515176148282e+308 -0.0 -> 308.14348794720007 -0.0
+logt0110 log10 -1.201354401295296e+308 0.0 -> 308.07967114380773 1.3643763538418414
+logt0111 log10 -1.6704337825976804e+308 -0.0 -> 308.22282926451624 -1.3643763538418414
+logt0112 log10 7.2276974655190223e+307 7.94879711369164 -> 307.85899996571993 4.7762357800858463e-308
+logt0113 log10 1.1207859593716076e+308 -6.1956200868221147 -> 308.04952268169455 -2.4007470767963597e-308
+logt0114 log10 -4.6678933874471045e+307 9.947107893220382 -> 307.66912092839902 1.3643763538418414
+logt0115 log10 -1.5108012453950142e+308 -5.3117197179375619 -> 308.1792073341565 -1.3643763538418414
+logt0116 log10 7.4903750871504435 1.5320703776626352e+308 -> 308.18527871564157 0.68218817692092071
+logt0117 log10 5.9760325525654778 -8.0149473997349123e+307 -> 307.90390067652424 -0.68218817692092071
+logt0118 log10 -7.880194206386629 1.7861845814767441e+308 -> 308.25192633617331 0.68218817692092071
+logt0119 log10 -9.886438993852865 -6.19235781080747e+307 -> 307.79185604308338 -0.68218817692092071
+
+-- values near 0
+logt0120 log10 2.2996867579227779e-308 6.7861840770939125e-312 -> -307.63833129662572 0.00012815668056362305
+logt0121 log10 6.9169190417774516e-323 -9.0414013188948118e-322 -> -321.04249706727148 -0.64902805353306059
+logt0122 log10 -1.5378064962914011e-316 1.8243628389354635e-310 -> -309.73888878263222 0.68218854299989429
+logt0123 log10 -2.3319898483706837e-321 -2.2358763941866371e-313 -> -312.65055220919641 -0.68218818145055538
+logt0124 log10 0.0 3.872770101081121e-315 -> -314.41197828323476 0.68218817692092071
+logt0125 log10 -0.0 9.6342800939043076e-322 -> -321.01618073175331 0.68218817692092071
+logt0126 log10 0.0 -2.266099393427834e-308 -> -307.64472104545649 -0.68218817692092071
+logt0127 log10 -0.0 -2.1184695673766626e-315 -> -314.67397777042407 -0.68218817692092071
+logt0128 log10 1.1363509854348671e-322 0.0 -> -321.94448750709819 0.0
+logt0129 log10 3.5572726500569751e-322 -0.0 -> -321.44888284668451 -0.0
+logt0130 log10 -2.3696071074040593e-310 0.0 -> -309.62532365619722 1.3643763538418414
+logt0131 log10 -2.813283897266934e-317 -0.0 -> -316.55078643961042 -1.3643763538418414
+
+-- values near the unit circle
+logt0200 log10 -0.59999999999999998 0.80000000000000004 -> 9.6432746655328709e-18 0.96165715756846815
+logt0201 log10 0.79999999999999993 0.60000000000000009 -> 2.6765463916147622e-33 0.2794689806475476
+
+-- special values
+logt1000 log10 -0.0 0.0 -> -inf 1.3643763538418414 divide-by-zero
+logt1001 log10 0.0 0.0 -> -inf 0.0 divide-by-zero
+logt1002 log10 0.0 inf -> inf 0.68218817692092071
+logt1003 log10 2.3 inf -> inf 0.68218817692092071
+logt1004 log10 -0.0 inf -> inf 0.68218817692092071
+logt1005 log10 -2.3 inf -> inf 0.68218817692092071
+logt1006 log10 0.0 nan -> nan nan
+logt1007 log10 2.3 nan -> nan nan
+logt1008 log10 -0.0 nan -> nan nan
+logt1009 log10 -2.3 nan -> nan nan
+logt1010 log10 -inf 0.0 -> inf 1.3643763538418414
+logt1011 log10 -inf 2.3 -> inf 1.3643763538418414
+logt1012 log10 inf 0.0 -> inf 0.0
+logt1013 log10 inf 2.3 -> inf 0.0
+logt1014 log10 -inf inf -> inf 1.0232822653813811
+logt1015 log10 inf inf -> inf 0.34109408846046035
+logt1016 log10 inf nan -> inf nan
+logt1017 log10 -inf nan -> inf nan
+logt1018 log10 nan 0.0 -> nan nan
+logt1019 log10 nan 2.3 -> nan nan
+logt1020 log10 nan inf -> inf nan
+logt1021 log10 nan nan -> nan nan
+logt1022 log10 -0.0 -0.0 -> -inf -1.3643763538418414 divide-by-zero
+logt1023 log10 0.0 -0.0 -> -inf -0.0 divide-by-zero
+logt1024 log10 0.0 -inf -> inf -0.68218817692092071
+logt1025 log10 2.3 -inf -> inf -0.68218817692092071
+logt1026 log10 -0.0 -inf -> inf -0.68218817692092071
+logt1027 log10 -2.3 -inf -> inf -0.68218817692092071
+logt1028 log10 -inf -0.0 -> inf -1.3643763538418414
+logt1029 log10 -inf -2.3 -> inf -1.3643763538418414
+logt1030 log10 inf -0.0 -> inf -0.0
+logt1031 log10 inf -2.3 -> inf -0.0
+logt1032 log10 -inf -inf -> inf -1.0232822653813811
+logt1033 log10 inf -inf -> inf -0.34109408846046035
+logt1034 log10 nan -0.0 -> nan nan
+logt1035 log10 nan -2.3 -> nan nan
+logt1036 log10 nan -inf -> inf nan
+
+
+-----------------------
+-- sqrt: Square root --
+-----------------------
+
+-- zeros
+sqrt0000 sqrt 0.0 0.0 -> 0.0 0.0
+sqrt0001 sqrt 0.0 -0.0 -> 0.0 -0.0
+sqrt0002 sqrt -0.0 0.0 -> 0.0 0.0
+sqrt0003 sqrt -0.0 -0.0 -> 0.0 -0.0
+
+-- values along both sides of real axis
+sqrt0010 sqrt -9.8813129168249309e-324 0.0 -> 0.0 3.1434555694052576e-162
+sqrt0011 sqrt -9.8813129168249309e-324 -0.0 -> 0.0 -3.1434555694052576e-162
+sqrt0012 sqrt -1e-305 0.0 -> 0.0 3.1622776601683791e-153
+sqrt0013 sqrt -1e-305 -0.0 -> 0.0 -3.1622776601683791e-153
+sqrt0014 sqrt -1e-150 0.0 -> 0.0 9.9999999999999996e-76
+sqrt0015 sqrt -1e-150 -0.0 -> 0.0 -9.9999999999999996e-76
+sqrt0016 sqrt -9.9999999999999998e-17 0.0 -> 0.0 1e-08
+sqrt0017 sqrt -9.9999999999999998e-17 -0.0 -> 0.0 -1e-08
+sqrt0018 sqrt -0.001 0.0 -> 0.0 0.031622776601683791
+sqrt0019 sqrt -0.001 -0.0 -> 0.0 -0.031622776601683791
+sqrt0020 sqrt -0.57899999999999996 0.0 -> 0.0 0.76092049518987193
+sqrt0021 sqrt -0.57899999999999996 -0.0 -> 0.0 -0.76092049518987193
+sqrt0022 sqrt -0.99999999999999989 0.0 -> 0.0 0.99999999999999989
+sqrt0023 sqrt -0.99999999999999989 -0.0 -> 0.0 -0.99999999999999989
+sqrt0024 sqrt -1.0000000000000002 0.0 -> 0.0 1.0
+sqrt0025 sqrt -1.0000000000000002 -0.0 -> 0.0 -1.0
+sqrt0026 sqrt -1.0009999999999999 0.0 -> 0.0 1.000499875062461
+sqrt0027 sqrt -1.0009999999999999 -0.0 -> 0.0 -1.000499875062461
+sqrt0028 sqrt -2.0 0.0 -> 0.0 1.4142135623730951
+sqrt0029 sqrt -2.0 -0.0 -> 0.0 -1.4142135623730951
+sqrt0030 sqrt -23.0 0.0 -> 0.0 4.7958315233127191
+sqrt0031 sqrt -23.0 -0.0 -> 0.0 -4.7958315233127191
+sqrt0032 sqrt -10000000000000000.0 0.0 -> 0.0 100000000.0
+sqrt0033 sqrt -10000000000000000.0 -0.0 -> 0.0 -100000000.0
+sqrt0034 sqrt -9.9999999999999998e+149 0.0 -> 0.0 9.9999999999999993e+74
+sqrt0035 sqrt -9.9999999999999998e+149 -0.0 -> 0.0 -9.9999999999999993e+74
+sqrt0036 sqrt -1.0000000000000001e+299 0.0 -> 0.0 3.1622776601683796e+149
+sqrt0037 sqrt -1.0000000000000001e+299 -0.0 -> 0.0 -3.1622776601683796e+149
+sqrt0038 sqrt 9.8813129168249309e-324 0.0 -> 3.1434555694052576e-162 0.0
+sqrt0039 sqrt 9.8813129168249309e-324 -0.0 -> 3.1434555694052576e-162 -0.0
+sqrt0040 sqrt 1e-305 0.0 -> 3.1622776601683791e-153 0.0
+sqrt0041 sqrt 1e-305 -0.0 -> 3.1622776601683791e-153 -0.0
+sqrt0042 sqrt 1e-150 0.0 -> 9.9999999999999996e-76 0.0
+sqrt0043 sqrt 1e-150 -0.0 -> 9.9999999999999996e-76 -0.0
+sqrt0044 sqrt 9.9999999999999998e-17 0.0 -> 1e-08 0.0
+sqrt0045 sqrt 9.9999999999999998e-17 -0.0 -> 1e-08 -0.0
+sqrt0046 sqrt 0.001 0.0 -> 0.031622776601683791 0.0
+sqrt0047 sqrt 0.001 -0.0 -> 0.031622776601683791 -0.0
+sqrt0048 sqrt 0.57899999999999996 0.0 -> 0.76092049518987193 0.0
+sqrt0049 sqrt 0.57899999999999996 -0.0 -> 0.76092049518987193 -0.0
+sqrt0050 sqrt 0.99999999999999989 0.0 -> 0.99999999999999989 0.0
+sqrt0051 sqrt 0.99999999999999989 -0.0 -> 0.99999999999999989 -0.0
+sqrt0052 sqrt 1.0000000000000002 0.0 -> 1.0 0.0
+sqrt0053 sqrt 1.0000000000000002 -0.0 -> 1.0 -0.0
+sqrt0054 sqrt 1.0009999999999999 0.0 -> 1.000499875062461 0.0
+sqrt0055 sqrt 1.0009999999999999 -0.0 -> 1.000499875062461 -0.0
+sqrt0056 sqrt 2.0 0.0 -> 1.4142135623730951 0.0
+sqrt0057 sqrt 2.0 -0.0 -> 1.4142135623730951 -0.0
+sqrt0058 sqrt 23.0 0.0 -> 4.7958315233127191 0.0
+sqrt0059 sqrt 23.0 -0.0 -> 4.7958315233127191 -0.0
+sqrt0060 sqrt 10000000000000000.0 0.0 -> 100000000.0 0.0
+sqrt0061 sqrt 10000000000000000.0 -0.0 -> 100000000.0 -0.0
+sqrt0062 sqrt 9.9999999999999998e+149 0.0 -> 9.9999999999999993e+74 0.0
+sqrt0063 sqrt 9.9999999999999998e+149 -0.0 -> 9.9999999999999993e+74 -0.0
+sqrt0064 sqrt 1.0000000000000001e+299 0.0 -> 3.1622776601683796e+149 0.0
+sqrt0065 sqrt 1.0000000000000001e+299 -0.0 -> 3.1622776601683796e+149 -0.0
+
+-- random inputs
+sqrt0100 sqrt -0.34252542541549913 -223039880.15076211 -> 10560.300180587592 -10560.300196805192
+sqrt0101 sqrt -0.88790791393018909 -5.3307751730827402 -> 1.5027154613689004 -1.7737140896343291
+sqrt0102 sqrt -113916.89291310767 -0.018143374626153858 -> 2.6877817875351178e-05 -337.51576691038952
+sqrt0103 sqrt -0.63187172386197121 -0.26293913366617694 -> 0.16205707495266153 -0.81125471918761971
+sqrt0104 sqrt -0.058185169308906215 -2.3548312990430991 -> 1.0717660342420072 -1.0985752598086966
+sqrt0105 sqrt -1.0580584765935896 0.14400319259151736 -> 0.069837489270111242 1.030987755262468
+sqrt0106 sqrt -1.1667595947504932 0.11159711473953678 -> 0.051598531319315251 1.0813981705111229
+sqrt0107 sqrt -0.5123728411449906 0.026175433648339085 -> 0.018278026262418718 0.71603556293597614
+sqrt0108 sqrt -3.7453400060067228 1.0946500314809635 -> 0.27990088541692498 1.9554243814742367
+sqrt0109 sqrt -0.0027736121575097673 1.0367943000839817 -> 0.71903560338719175 0.72096172651250545
+sqrt0110 sqrt 1501.2559699453188 -1.1997325207283589 -> 38.746047664730959 -0.015481998720355024
+sqrt0111 sqrt 1.4830075326850578 -0.64100878436755349 -> 1.244712815741096 -0.25749264258434584
+sqrt0112 sqrt 0.095395618499734602 -0.48226565701639595 -> 0.54175904053472879 -0.44509239434231551
+sqrt0113 sqrt 0.50109185681863277 -0.54054037379892561 -> 0.7868179858332387 -0.34349772344520979
+sqrt0114 sqrt 0.98779807595367897 -0.00019848758437225191 -> 0.99388031770665153 -9.9854872279921968e-05
+sqrt0115 sqrt 11.845472380792259 0.0010051104581506761 -> 3.4417252072345397 0.00014601840612346451
+sqrt0116 sqrt 2.3558249686735975 0.25605157371744403 -> 1.5371278477386647 0.083288964575761404
+sqrt0117 sqrt 0.77584894123159098 1.0496420627016076 -> 1.0200744386390885 0.51449287568756552
+sqrt0118 sqrt 1.8961715669604893 0.34940793467158854 -> 1.3827991781411615 0.12634080935066902
+sqrt0119 sqrt 0.96025378316565801 0.69573224860140515 -> 1.0358710342209998 0.33581991658093457
+
+-- values near 0
+sqrt0120 sqrt 7.3577938365086866e-313 8.1181408465112743e-319 -> 8.5777583531543516e-157 4.732087634251168e-163
+sqrt0121 sqrt 1.2406883874892108e-310 -5.1210133324269776e-312 -> 1.1140990057468052e-155 -2.2982756945349973e-157
+sqrt0122 sqrt -7.1145453001139502e-322 2.9561379244703735e-314 -> 1.2157585807480286e-157 1.2157586100077242e-157
+sqrt0123 sqrt -4.9963244206801218e-314 -8.4718424423690227e-319 -> 1.8950582312540437e-162 -2.2352459419578971e-157
+sqrt0124 sqrt 0.0 7.699553609385195e-318 -> 1.9620848107797476e-159 1.9620848107797476e-159
+sqrt0125 sqrt -0.0 3.3900826606499415e-309 -> 4.1170879639922327e-155 4.1170879639922327e-155
+sqrt0126 sqrt 0.0 -9.8907989772250828e-319 -> 7.032353438652342e-160 -7.032353438652342e-160
+sqrt0127 sqrt -0.0 -1.3722939367590908e-315 -> 2.6194407196566702e-158 -2.6194407196566702e-158
+sqrt0128 sqrt 7.9050503334599447e-323 0.0 -> 8.8910349979403099e-162 0.0
+sqrt0129 sqrt 1.8623241768349486e-309 -0.0 -> 4.3154654173506579e-155 -0.0
+sqrt0130 sqrt -2.665971134499887e-308 0.0 -> 0.0 1.6327801856036491e-154
+sqrt0131 sqrt -1.5477066694467245e-310 -0.0 -> 0.0 -1.2440685951533077e-155
+
+-- inputs whose absolute value overflows
+sqrt0140 sqrt 1.6999999999999999e+308 -1.6999999999999999e+308 -> 1.4325088230154573e+154 -5.9336458271212207e+153
+sqrt0141 sqrt -1.797e+308 -9.9999999999999999e+306 -> 3.7284476432057307e+152 -1.3410406899802901e+154
+
+-- special values
+sqrt1000 sqrt 0.0 0.0 -> 0.0 0.0
+sqrt1001 sqrt -0.0 0.0 -> 0.0 0.0
+sqrt1002 sqrt 0.0 inf -> inf inf
+sqrt1003 sqrt 2.3 inf -> inf inf
+sqrt1004 sqrt inf inf -> inf inf
+sqrt1005 sqrt -0.0 inf -> inf inf
+sqrt1006 sqrt -2.3 inf -> inf inf
+sqrt1007 sqrt -inf inf -> inf inf
+sqrt1008 sqrt nan inf -> inf inf
+sqrt1009 sqrt 0.0 nan -> nan nan
+sqrt1010 sqrt 2.3 nan -> nan nan
+sqrt1011 sqrt -0.0 nan -> nan nan
+sqrt1012 sqrt -2.3 nan -> nan nan
+sqrt1013 sqrt -inf 0.0 -> 0.0 inf
+sqrt1014 sqrt -inf 2.3 -> 0.0 inf
+sqrt1015 sqrt inf 0.0 -> inf 0.0
+sqrt1016 sqrt inf 2.3 -> inf 0.0
+sqrt1017 sqrt -inf nan -> nan inf ignore-imag-sign
+sqrt1018 sqrt inf nan -> inf nan
+sqrt1019 sqrt nan 0.0 -> nan nan
+sqrt1020 sqrt nan 2.3 -> nan nan
+sqrt1021 sqrt nan nan -> nan nan
+sqrt1022 sqrt 0.0 -0.0 -> 0.0 -0.0
+sqrt1023 sqrt -0.0 -0.0 -> 0.0 -0.0
+sqrt1024 sqrt 0.0 -inf -> inf -inf
+sqrt1025 sqrt 2.3 -inf -> inf -inf
+sqrt1026 sqrt inf -inf -> inf -inf
+sqrt1027 sqrt -0.0 -inf -> inf -inf
+sqrt1028 sqrt -2.3 -inf -> inf -inf
+sqrt1029 sqrt -inf -inf -> inf -inf
+sqrt1030 sqrt nan -inf -> inf -inf
+sqrt1031 sqrt -inf -0.0 -> 0.0 -inf
+sqrt1032 sqrt -inf -2.3 -> 0.0 -inf
+sqrt1033 sqrt inf -0.0 -> inf -0.0
+sqrt1034 sqrt inf -2.3 -> inf -0.0
+sqrt1035 sqrt nan -0.0 -> nan nan
+sqrt1036 sqrt nan -2.3 -> nan nan
+
+
+-- For exp, cosh, sinh, tanh we limit tests to arguments whose
+-- imaginary part is less than 10 in absolute value: most math
+-- libraries have poor accuracy for (real) sine and cosine for
+-- large arguments, and the accuracy of these complex functions
+-- suffer correspondingly.
+--
+-- Similarly, for cos, sin and tan we limit tests to arguments
+-- with relatively small real part.
+
+
+-------------------------------
+-- exp: Exponential function --
+-------------------------------
+
+-- zeros
+exp0000 exp 0.0 0.0 -> 1.0 0.0
+exp0001 exp 0.0 -0.0 -> 1.0 -0.0
+exp0002 exp -0.0 0.0 -> 1.0 0.0
+exp0003 exp -0.0 -0.0 -> 1.0 -0.0
+
+-- random inputs
+exp0004 exp -17.957359009564684 -1.108613895795274 -> 7.0869292576226611e-09 -1.4225929202377833e-08
+exp0005 exp -1.4456149663368642e-15 -0.75359817331772239 -> 0.72923148323917997 -0.68426708517419033
+exp0006 exp -0.76008654883512661 -0.46657235480105019 -> 0.41764393109928666 -0.21035108396792854
+exp0007 exp -5.7071614697735731 -2.3744161818115816e-11 -> 0.0033220890242068356 -7.8880219364953578e-14
+exp0008 exp -0.4653981327927097 -5.2236706667445587e-21 -> 0.62788507378216663 -3.2798648420026468e-21
+exp0009 exp -3.2444565242295518 1.1535625304243959 -> 0.015799936931457641 0.035644950380024749
+exp0010 exp -3.0651456337977727 0.87765086532391878 -> 0.029805595629855953 0.035882775180855669
+exp0011 exp -0.11080823753233926 0.96486386300873106 -> 0.50979112534376314 0.73575512419561562
+exp0012 exp -2.5629722598928648 0.019636235754708079 -> 0.077060452853917397 0.0015133717341137684
+exp0013 exp -3.3201709957983357e-10 1.2684017344487268 -> 0.29780699855434889 0.95462610007689186
+exp0014 exp 0.88767276057993272 -0.18953422986895557 -> 2.3859624049858095 -0.45771559132044426
+exp0015 exp 1.5738333486794742 -2.2576803075544328e-11 -> 4.8251091132458654 -1.0893553826776623e-10
+exp0016 exp 1.6408702341813795 -1.438879484380837 -> 0.6786733590689048 -5.1148284173168825
+exp0017 exp 1.820279424202033 -0.020812040370785722 -> 6.1722462896420902 -0.1284755888435051
+exp0018 exp 1.7273965735945873 -0.61140621328954947 -> 4.6067931898799976 -3.2294267694441308
+exp0019 exp 2.5606034306862995 0.098153136008435504 -> 12.881325889966629 1.2684184812864494
+exp0020 exp 10.280368619483029 3.4564622559748535 -> -27721.283321551502 -9028.9663215568835
+exp0021 exp 1.104007405129741e-155 0.21258803067317278 -> 0.97748813933531764 0.21099037290544478
+exp0022 exp 0.027364777809295172 0.00059226603500623363 -> 1.0277424518451876 0.0006086970181346579
+exp0023 exp 0.94356313429255245 3.418530463518592 -> -2.4712285695346194 -0.70242654900218349
+
+-- cases where exp(z) representable, exp(z.real) not
+exp0030 exp 710.0 0.78500000000000003 -> 1.5803016909637158e+308 1.5790437551806911e+308
+exp0031 exp 710.0 -0.78500000000000003 -> 1.5803016909637158e+308 -1.5790437551806911e+308
+
+-- values for which exp(x) is subnormal, or underflows to 0
+exp0040 exp -735.0 0.78500000000000003 -> 4.3976783136329355e-320 4.3942198541120468e-320
+exp0041 exp -735.0 -2.3559999999999999 -> -4.3952079854037293e-320 -4.396690182341253e-320
+exp0042 exp -745.0 0.0 -> 4.9406564584124654e-324 0.0
+exp0043 exp -745.0 0.7 -> 0.0 0.0
+exp0044 exp -745.0 2.1 -> -0.0 0.0
+exp0045 exp -745.0 3.7 -> -0.0 -0.0
+exp0046 exp -745.0 5.3 -> 0.0 -0.0
+
+-- values for which exp(z) overflows
+exp0050 exp 710.0 0.0 -> inf 0.0 overflow
+exp0051 exp 711.0 0.7 -> inf inf overflow
+exp0052 exp 710.0 1.5 -> 1.5802653829857376e+307 inf overflow
+exp0053 exp 710.0 1.6 -> -6.5231579995501372e+306 inf overflow
+exp0054 exp 710.0 2.8 -> -inf 7.4836177417448528e+307 overflow
+
+-- special values
+exp1000 exp 0.0 0.0 -> 1.0 0.0
+exp1001 exp -0.0 0.0 -> 1.0 0.0
+exp1002 exp 0.0 inf -> nan nan invalid
+exp1003 exp 2.3 inf -> nan nan invalid
+exp1004 exp -0.0 inf -> nan nan invalid
+exp1005 exp -2.3 inf -> nan nan invalid
+exp1006 exp 0.0 nan -> nan nan
+exp1007 exp 2.3 nan -> nan nan
+exp1008 exp -0.0 nan -> nan nan
+exp1009 exp -2.3 nan -> nan nan
+exp1010 exp -inf 0.0 -> 0.0 0.0
+exp1011 exp -inf 1.4 -> 0.0 0.0
+exp1012 exp -inf 2.8 -> -0.0 0.0
+exp1013 exp -inf 4.2 -> -0.0 -0.0
+exp1014 exp -inf 5.6 -> 0.0 -0.0
+exp1015 exp -inf 7.0 -> 0.0 0.0
+exp1016 exp inf 0.0 -> inf 0.0
+exp1017 exp inf 1.4 -> inf inf
+exp1018 exp inf 2.8 -> -inf inf
+exp1019 exp inf 4.2 -> -inf -inf
+exp1020 exp inf 5.6 -> inf -inf
+exp1021 exp inf 7.0 -> inf inf
+exp1022 exp -inf inf -> 0.0 0.0 ignore-real-sign ignore-imag-sign
+exp1023 exp inf inf -> inf nan invalid ignore-real-sign
+exp1024 exp -inf nan -> 0.0 0.0 ignore-real-sign ignore-imag-sign
+exp1025 exp inf nan -> inf nan ignore-real-sign
+exp1026 exp nan 0.0 -> nan 0.0
+exp1027 exp nan 2.3 -> nan nan
+exp1028 exp nan inf -> nan nan
+exp1029 exp nan nan -> nan nan
+exp1030 exp 0.0 -0.0 -> 1.0 -0.0
+exp1031 exp -0.0 -0.0 -> 1.0 -0.0
+exp1032 exp 0.0 -inf -> nan nan invalid
+exp1033 exp 2.3 -inf -> nan nan invalid
+exp1034 exp -0.0 -inf -> nan nan invalid
+exp1035 exp -2.3 -inf -> nan nan invalid
+exp1036 exp -inf -0.0 -> 0.0 -0.0
+exp1037 exp -inf -1.4 -> 0.0 -0.0
+exp1038 exp -inf -2.8 -> -0.0 -0.0
+exp1039 exp -inf -4.2 -> -0.0 0.0
+exp1040 exp -inf -5.6 -> 0.0 0.0
+exp1041 exp -inf -7.0 -> 0.0 -0.0
+exp1042 exp inf -0.0 -> inf -0.0
+exp1043 exp inf -1.4 -> inf -inf
+exp1044 exp inf -2.8 -> -inf -inf
+exp1045 exp inf -4.2 -> -inf inf
+exp1046 exp inf -5.6 -> inf inf
+exp1047 exp inf -7.0 -> inf -inf
+exp1048 exp -inf -inf -> 0.0 0.0 ignore-real-sign ignore-imag-sign
+exp1049 exp inf -inf -> inf nan invalid ignore-real-sign
+exp1050 exp nan -0.0 -> nan -0.0
+exp1051 exp nan -2.3 -> nan nan
+exp1052 exp nan -inf -> nan nan
+
+
+-----------------------------
+-- cosh: Hyperbolic Cosine --
+-----------------------------
+
+-- zeros
+cosh0000 cosh 0.0 0.0 -> 1.0 0.0
+cosh0001 cosh 0.0 -0.0 -> 1.0 -0.0
+cosh0002 cosh -0.0 0.0 -> 1.0 -0.0
+cosh0003 cosh -0.0 -0.0 -> 1.0 0.0
+
+-- random inputs
+cosh0004 cosh -0.85395264297414253 -8.8553756148671958 -> -1.1684340348021185 0.51842195359787435
+cosh0005 cosh -19.584904237211223 -0.066582627994906177 -> 159816812.23336992 10656776.050406246
+cosh0006 cosh -0.11072618401130772 -1.484820215073247 -> 0.086397164744949503 0.11054275637717284
+cosh0007 cosh -3.4764840250681752 -0.48440348288275276 -> 14.325931955190844 7.5242053548737955
+cosh0008 cosh -0.52047063604524602 -0.3603805382775585 -> 1.0653940354683802 0.19193293606252473
+cosh0009 cosh -1.39518962975995 0.0074738604700702906 -> 2.1417031027235969 -0.01415518712296308
+cosh0010 cosh -0.37107064757653541 0.14728085307856609 -> 1.0580601496776991 -0.055712531964568587
+cosh0011 cosh -5.8470200958739653 4.0021722388336292 -> -112.86220667618285 131.24734033545013
+cosh0012 cosh -0.1700261444851883 0.97167540135354513 -> 0.57208748253577946 -0.1410904820240203
+cosh0013 cosh -0.44042397902648783 1.0904791964139742 -> 0.50760322393058133 -0.40333966652010816
+cosh0014 cosh 0.052267552491867299 -3.8889011430644174 -> -0.73452303414639297 0.035540704833537134
+cosh0015 cosh 0.98000764177127453 -1.2548829247784097 -> 0.47220747341416142 -1.0879421432180316
+cosh0016 cosh 0.083594701222644008 -0.88847899930181284 -> 0.63279782419312613 -0.064954566816002285
+cosh0017 cosh 1.38173531783776 -0.43185040816732229 -> 1.9221663374671647 -0.78073830858849347
+cosh0018 cosh 0.57315681120148465 -0.22255760951027942 -> 1.1399733125173004 -0.1335512343605956
+cosh0019 cosh 1.8882512333062347 4.5024932182383797 -> -0.7041602065362691 -3.1573822131964615
+cosh0020 cosh 0.5618219206858317 0.92620452129575348 -> 0.69822380405378381 0.47309067471054522
+cosh0021 cosh 0.54361442847062591 0.64176483583018462 -> 0.92234462074193491 0.34167906495845501
+cosh0022 cosh 0.0014777403107920331 1.3682028122677661 -> 0.2012106963899549 0.001447518137863219
+cosh0023 cosh 2.218885944363501 2.0015727395883687 -> -1.94294321081968 4.1290269176083196
+
+-- large real part
+cosh0030 cosh 710.5 2.3519999999999999 -> -1.2967465239355998e+308 1.3076707908857333e+308
+cosh0031 cosh -710.5 0.69999999999999996 -> 1.4085466381392499e+308 -1.1864024666450239e+308
+
+-- special values
+cosh1000 cosh 0.0 0.0 -> 1.0 0.0
+cosh1001 cosh 0.0 inf -> nan 0.0 invalid ignore-imag-sign
+cosh1002 cosh 0.0 nan -> nan 0.0 ignore-imag-sign
+cosh1003 cosh 2.3 inf -> nan nan invalid
+cosh1004 cosh 2.3 nan -> nan nan
+cosh1005 cosh inf 0.0 -> inf 0.0
+cosh1006 cosh inf 1.4 -> inf inf
+cosh1007 cosh inf 2.8 -> -inf inf
+cosh1008 cosh inf 4.2 -> -inf -inf
+cosh1009 cosh inf 5.6 -> inf -inf
+cosh1010 cosh inf 7.0 -> inf inf
+cosh1011 cosh inf inf -> inf nan invalid ignore-real-sign
+cosh1012 cosh inf nan -> inf nan
+cosh1013 cosh nan 0.0 -> nan 0.0 ignore-imag-sign
+cosh1014 cosh nan 2.3 -> nan nan
+cosh1015 cosh nan inf -> nan nan
+cosh1016 cosh nan nan -> nan nan
+cosh1017 cosh 0.0 -0.0 -> 1.0 -0.0
+cosh1018 cosh 0.0 -inf -> nan 0.0 invalid ignore-imag-sign
+cosh1019 cosh 2.3 -inf -> nan nan invalid
+cosh1020 cosh inf -0.0 -> inf -0.0
+cosh1021 cosh inf -1.4 -> inf -inf
+cosh1022 cosh inf -2.8 -> -inf -inf
+cosh1023 cosh inf -4.2 -> -inf inf
+cosh1024 cosh inf -5.6 -> inf inf
+cosh1025 cosh inf -7.0 -> inf -inf
+cosh1026 cosh inf -inf -> inf nan invalid ignore-real-sign
+cosh1027 cosh nan -0.0 -> nan 0.0 ignore-imag-sign
+cosh1028 cosh nan -2.3 -> nan nan
+cosh1029 cosh nan -inf -> nan nan
+cosh1030 cosh -0.0 -0.0 -> 1.0 0.0
+cosh1031 cosh -0.0 -inf -> nan 0.0 invalid ignore-imag-sign
+cosh1032 cosh -0.0 nan -> nan 0.0 ignore-imag-sign
+cosh1033 cosh -2.3 -inf -> nan nan invalid
+cosh1034 cosh -2.3 nan -> nan nan
+cosh1035 cosh -inf -0.0 -> inf 0.0
+cosh1036 cosh -inf -1.4 -> inf inf
+cosh1037 cosh -inf -2.8 -> -inf inf
+cosh1038 cosh -inf -4.2 -> -inf -inf
+cosh1039 cosh -inf -5.6 -> inf -inf
+cosh1040 cosh -inf -7.0 -> inf inf
+cosh1041 cosh -inf -inf -> inf nan invalid ignore-real-sign
+cosh1042 cosh -inf nan -> inf nan
+cosh1043 cosh -0.0 0.0 -> 1.0 -0.0
+cosh1044 cosh -0.0 inf -> nan 0.0 invalid ignore-imag-sign
+cosh1045 cosh -2.3 inf -> nan nan invalid
+cosh1046 cosh -inf 0.0 -> inf -0.0
+cosh1047 cosh -inf 1.4 -> inf -inf
+cosh1048 cosh -inf 2.8 -> -inf -inf
+cosh1049 cosh -inf 4.2 -> -inf inf
+cosh1050 cosh -inf 5.6 -> inf inf
+cosh1051 cosh -inf 7.0 -> inf -inf
+cosh1052 cosh -inf inf -> inf nan invalid ignore-real-sign
+
+
+---------------------------
+-- sinh: Hyperbolic Sine --
+---------------------------
+
+-- zeros
+sinh0000 sinh 0.0 0.0 -> 0.0 0.0
+sinh0001 sinh 0.0 -0.0 -> 0.0 -0.0
+sinh0002 sinh -0.0 0.0 -> -0.0 0.0
+sinh0003 sinh -0.0 -0.0 -> -0.0 -0.0
+
+-- random inputs
+sinh0004 sinh -17.282588091462742 -0.38187948694103546 -> -14867386.857248396 -5970648.6553516639
+sinh0005 sinh -343.91971203143208 -5.0172868877771525e-22 -> -1.1518691776521735e+149 -5.7792581214689021e+127
+sinh0006 sinh -14.178122253300922 -1.9387157579351293 -> 258440.37909034826 -670452.58500946441
+sinh0007 sinh -1.0343810581686239 -1.0970235266369905 -> -0.56070858278092739 -1.4098883258046697
+sinh0008 sinh -0.066126561416368204 -0.070461584169961872 -> -0.066010558700938124 -0.070557276738637542
+sinh0009 sinh -0.37630149150308484 3.3621734692162173 -> 0.37591118119332617 -0.23447115926369383
+sinh0010 sinh -0.049941960978670055 0.40323767020414625 -> -0.045955482136329009 0.3928878494430646
+sinh0011 sinh -16.647852603903715 0.0026852219129082098 -> -8492566.5739382561 22804.480671133562
+sinh0012 sinh -1.476625314303694 0.89473773116683386 -> -1.2982943334382224 1.7966593367791204
+sinh0013 sinh -422.36429577556913 0.10366634502307912 -> -1.3400321008920044e+183 1.3941600948045599e+182
+sinh0014 sinh 0.09108340745641981 -0.40408227416070353 -> 0.083863724802237902 -0.39480716553935602
+sinh0015 sinh 2.036064132067386 -2.6831729961386239 -> -3.37621124363175 -1.723868330002817
+sinh0016 sinh 2.5616717223063317 -0.0078978498622717767 -> 6.4399415853815869 -0.051472264400722133
+sinh0017 sinh 0.336804011985188 -6.5654622971649337 -> 0.32962499307574578 -0.29449170159995197
+sinh0018 sinh 0.23774603755649693 -0.92467195799232049 -> 0.14449839490603389 -0.82109449053556793
+sinh0019 sinh 0.0011388273541465494 1.9676196882949855 -> -0.00044014605389634999 0.92229398407098806
+sinh0020 sinh 3.2443870105663759 0.8054287559616895 -> 8.8702890778527426 9.2610748597042196
+sinh0021 sinh 0.040628908857054738 0.098206391190944958 -> 0.04044426841671233 0.098129544739707392
+sinh0022 sinh 4.7252283918217696e-30 9.1198155642656697 -> -4.5071980561644404e-30 0.30025730701661713
+sinh0023 sinh 0.043713693678420068 0.22512549887532657 -> 0.042624198673416713 0.22344201231217961
+
+-- large real part
+sinh0030 sinh 710.5 -2.3999999999999999 -> -1.3579970564885919e+308 -1.24394470907798e+308
+sinh0031 sinh -710.5 0.80000000000000004 -> -1.2830671601735164e+308 1.3210954193997678e+308
+
+-- special values
+sinh1000 sinh 0.0 0.0 -> 0.0 0.0
+sinh1001 sinh 0.0 inf -> 0.0 nan invalid ignore-real-sign
+sinh1002 sinh 0.0 nan -> 0.0 nan ignore-real-sign
+sinh1003 sinh 2.3 inf -> nan nan invalid
+sinh1004 sinh 2.3 nan -> nan nan
+sinh1005 sinh inf 0.0 -> inf 0.0
+sinh1006 sinh inf 1.4 -> inf inf
+sinh1007 sinh inf 2.8 -> -inf inf
+sinh1008 sinh inf 4.2 -> -inf -inf
+sinh1009 sinh inf 5.6 -> inf -inf
+sinh1010 sinh inf 7.0 -> inf inf
+sinh1011 sinh inf inf -> inf nan invalid ignore-real-sign
+sinh1012 sinh inf nan -> inf nan ignore-real-sign
+sinh1013 sinh nan 0.0 -> nan 0.0
+sinh1014 sinh nan 2.3 -> nan nan
+sinh1015 sinh nan inf -> nan nan
+sinh1016 sinh nan nan -> nan nan
+sinh1017 sinh 0.0 -0.0 -> 0.0 -0.0
+sinh1018 sinh 0.0 -inf -> 0.0 nan invalid ignore-real-sign
+sinh1019 sinh 2.3 -inf -> nan nan invalid
+sinh1020 sinh inf -0.0 -> inf -0.0
+sinh1021 sinh inf -1.4 -> inf -inf
+sinh1022 sinh inf -2.8 -> -inf -inf
+sinh1023 sinh inf -4.2 -> -inf inf
+sinh1024 sinh inf -5.6 -> inf inf
+sinh1025 sinh inf -7.0 -> inf -inf
+sinh1026 sinh inf -inf -> inf nan invalid ignore-real-sign
+sinh1027 sinh nan -0.0 -> nan -0.0
+sinh1028 sinh nan -2.3 -> nan nan
+sinh1029 sinh nan -inf -> nan nan
+sinh1030 sinh -0.0 -0.0 -> -0.0 -0.0
+sinh1031 sinh -0.0 -inf -> 0.0 nan invalid ignore-real-sign
+sinh1032 sinh -0.0 nan -> 0.0 nan ignore-real-sign
+sinh1033 sinh -2.3 -inf -> nan nan invalid
+sinh1034 sinh -2.3 nan -> nan nan
+sinh1035 sinh -inf -0.0 -> -inf -0.0
+sinh1036 sinh -inf -1.4 -> -inf -inf
+sinh1037 sinh -inf -2.8 -> inf -inf
+sinh1038 sinh -inf -4.2 -> inf inf
+sinh1039 sinh -inf -5.6 -> -inf inf
+sinh1040 sinh -inf -7.0 -> -inf -inf
+sinh1041 sinh -inf -inf -> inf nan invalid ignore-real-sign
+sinh1042 sinh -inf nan -> inf nan ignore-real-sign
+sinh1043 sinh -0.0 0.0 -> -0.0 0.0
+sinh1044 sinh -0.0 inf -> 0.0 nan invalid ignore-real-sign
+sinh1045 sinh -2.3 inf -> nan nan invalid
+sinh1046 sinh -inf 0.0 -> -inf 0.0
+sinh1047 sinh -inf 1.4 -> -inf inf
+sinh1048 sinh -inf 2.8 -> inf inf
+sinh1049 sinh -inf 4.2 -> inf -inf
+sinh1050 sinh -inf 5.6 -> -inf -inf
+sinh1051 sinh -inf 7.0 -> -inf inf
+sinh1052 sinh -inf inf -> inf nan invalid ignore-real-sign
+
+
+------------------------------
+-- tanh: Hyperbolic Tangent --
+------------------------------
+
+-- zeros
+tanh0000 tanh 0.0 0.0 -> 0.0 0.0
+tanh0001 tanh 0.0 -0.0 -> 0.0 -0.0
+tanh0002 tanh -0.0 0.0 -> -0.0 0.0
+tanh0003 tanh -0.0 -0.0 -> -0.0 -0.0
+
+-- random inputs
+tanh0004 tanh -21.200500450664993 -1.6970729480342996 -> -1.0 1.9241352344849399e-19
+tanh0005 tanh -0.34158771504251928 -8.0848504951747131 -> -2.123711225855613 1.2827526782026006
+tanh0006 tanh -15.454144725193689 -0.23619582288265617 -> -0.99999999999993283 -3.4336684248260036e-14
+tanh0007 tanh -7.6103163119661952 -0.7802748320307008 -> -0.99999999497219438 -4.9064845343755437e-07
+tanh0008 tanh -0.15374717235792129 -0.6351086327306138 -> -0.23246081703561869 -0.71083467433910219
+tanh0009 tanh -0.49101115474392465 0.09723001264886301 -> -0.45844445715492133 0.077191158541805888
+tanh0010 tanh -0.10690612157664491 2.861612800856395 -> -0.11519761626257358 -0.28400488355647507
+tanh0011 tanh -0.91505774192066702 1.5431174597727007 -> -1.381109893068114 0.025160819663709356
+tanh0012 tanh -0.057433367093792223 0.35491159541246459 -> -0.065220499046696953 0.36921788332369498
+tanh0013 tanh -1.3540418621233514 0.18969415642242535 -> -0.88235642861151387 0.043764069984411721
+tanh0014 tanh 0.94864783961003529 -0.11333689578867717 -> 0.74348401861861368 -0.051271042543855221
+tanh0015 tanh 1.9591698133845488 -0.0029654444904578339 -> 0.9610270776968135 -0.00022664240049212933
+tanh0016 tanh 1.0949715796669197 -0.24706642853984456 -> 0.81636574501369386 -0.087767436914149954
+tanh0017 tanh 5770428.2113731047 -3.7160580339833165 -> 1.0 -0.0
+tanh0018 tanh 1.5576782321399629 -1.0357943787966468 -> 1.0403002384895388 -0.081126347894671463
+tanh0019 tanh 0.62378536230552961 2.3471393579560216 -> 0.85582499238960363 -0.53569473646842869
+tanh0020 tanh 17.400628602508025 9.3987059533841979 -> 0.99999999999999845 -8.0175867720530832e-17
+tanh0021 tanh 0.15026177509871896 0.50630349159505472 -> 0.19367536571827768 0.53849847858853661
+tanh0022 tanh 0.57433977530711167 1.0071604546265627 -> 1.0857848159262844 0.69139213955872214
+tanh0023 tanh 0.16291181500449456 0.006972810241567544 -> 0.16149335907551157 0.0067910772903467817
+
+-- large real part
+tanh0030 tanh 710 0.13 -> 1.0 0.0
+tanh0031 tanh -711 7.4000000000000004 -> -1.0 0.0
+tanh0032 tanh 1000 -2.3199999999999998 -> 1.0 0.0
+tanh0033 tanh -1.0000000000000001e+300 -9.6699999999999999 -> -1.0 -0.0
+
+--special values
+tanh1000 tanh 0.0 0.0 -> 0.0 0.0
+tanh1001 tanh 0.0 inf -> nan nan invalid
+tanh1002 tanh 2.3 inf -> nan nan invalid
+tanh1003 tanh 0.0 nan -> nan nan
+tanh1004 tanh 2.3 nan -> nan nan
+tanh1005 tanh inf 0.0 -> 1.0 0.0
+tanh1006 tanh inf 0.7 -> 1.0 0.0
+tanh1007 tanh inf 1.4 -> 1.0 0.0
+tanh1008 tanh inf 2.1 -> 1.0 -0.0
+tanh1009 tanh inf 2.8 -> 1.0 -0.0
+tanh1010 tanh inf 3.5 -> 1.0 0.0
+tanh1011 tanh inf inf -> 1.0 0.0 ignore-imag-sign
+tanh1012 tanh inf nan -> 1.0 0.0 ignore-imag-sign
+tanh1013 tanh nan 0.0 -> nan 0.0
+tanh1014 tanh nan 2.3 -> nan nan
+tanh1015 tanh nan inf -> nan nan
+tanh1016 tanh nan nan -> nan nan
+tanh1017 tanh 0.0 -0.0 -> 0.0 -0.0
+tanh1018 tanh 0.0 -inf -> nan nan invalid
+tanh1019 tanh 2.3 -inf -> nan nan invalid
+tanh1020 tanh inf -0.0 -> 1.0 -0.0
+tanh1021 tanh inf -0.7 -> 1.0 -0.0
+tanh1022 tanh inf -1.4 -> 1.0 -0.0
+tanh1023 tanh inf -2.1 -> 1.0 0.0
+tanh1024 tanh inf -2.8 -> 1.0 0.0
+tanh1025 tanh inf -3.5 -> 1.0 -0.0
+tanh1026 tanh inf -inf -> 1.0 0.0 ignore-imag-sign
+tanh1027 tanh nan -0.0 -> nan -0.0
+tanh1028 tanh nan -2.3 -> nan nan
+tanh1029 tanh nan -inf -> nan nan
+tanh1030 tanh -0.0 -0.0 -> -0.0 -0.0
+tanh1031 tanh -0.0 -inf -> nan nan invalid
+tanh1032 tanh -2.3 -inf -> nan nan invalid
+tanh1033 tanh -0.0 nan -> nan nan
+tanh1034 tanh -2.3 nan -> nan nan
+tanh1035 tanh -inf -0.0 -> -1.0 -0.0
+tanh1036 tanh -inf -0.7 -> -1.0 -0.0
+tanh1037 tanh -inf -1.4 -> -1.0 -0.0
+tanh1038 tanh -inf -2.1 -> -1.0 0.0
+tanh1039 tanh -inf -2.8 -> -1.0 0.0
+tanh1040 tanh -inf -3.5 -> -1.0 -0.0
+tanh1041 tanh -inf -inf -> -1.0 0.0 ignore-imag-sign
+tanh1042 tanh -inf nan -> -1.0 0.0 ignore-imag-sign
+tanh1043 tanh -0.0 0.0 -> -0.0 0.0
+tanh1044 tanh -0.0 inf -> nan nan invalid
+tanh1045 tanh -2.3 inf -> nan nan invalid
+tanh1046 tanh -inf 0.0 -> -1.0 0.0
+tanh1047 tanh -inf 0.7 -> -1.0 0.0
+tanh1048 tanh -inf 1.4 -> -1.0 0.0
+tanh1049 tanh -inf 2.1 -> -1.0 -0.0
+tanh1050 tanh -inf 2.8 -> -1.0 -0.0
+tanh1051 tanh -inf 3.5 -> -1.0 0.0
+tanh1052 tanh -inf inf -> -1.0 0.0 ignore-imag-sign
+
+
+-----------------
+-- cos: Cosine --
+-----------------
+
+-- zeros
+cos0000 cos 0.0 0.0 -> 1.0 -0.0
+cos0001 cos 0.0 -0.0 -> 1.0 0.0
+cos0002 cos -0.0 0.0 -> 1.0 0.0
+cos0003 cos -0.0 -0.0 -> 1.0 -0.0
+
+-- random inputs
+cos0004 cos -2.0689194692073034 -0.0016802181751734313 -> -0.47777827208561469 -0.0014760401501695971
+cos0005 cos -0.4209627318177977 -1.8238516774258027 -> 2.9010402201444108 -1.2329207042329617
+cos0006 cos -1.9402181630694557 -2.9751857392891217 -> -3.5465459297970985 -9.1119163586282248
+cos0007 cos -3.3118320290191616 -0.87871302909286142 -> -1.3911528636565498 0.16878141517391701
+cos0008 cos -4.9540404623376872 -0.57949232239026827 -> 0.28062445586552065 0.59467861308508008
+cos0009 cos -0.45374584316245026 1.3950283448373935 -> 1.9247665574290578 0.83004572204761107
+cos0010 cos -0.42578172040176843 1.2715881615413049 -> 1.7517161459489148 0.67863902697363332
+cos0011 cos -0.13862985354300136 0.43587635877670328 -> 1.0859880290361912 0.062157548146672272
+cos0012 cos -0.11073221308966584 9.9384082307326475e-15 -> 0.99387545040722947 1.0982543264065479e-15
+cos0013 cos -1.5027633662054623e-07 0.0069668060249955498 -> 1.0000242682912412 1.0469545565660995e-09
+cos0014 cos 4.9728645490503052 -0.00027479808860952822 -> 0.25754011731975501 -0.00026552849549083186
+cos0015 cos 7.81969303486719 -0.79621523445878783 -> 0.045734882501585063 0.88253139933082991
+cos0016 cos 0.13272421880766716 -0.74668445308718201 -> 1.2806012244432847 0.10825373267437005
+cos0017 cos 4.2396521985973274 -2.2178848380884881 -> -2.1165117057056855 -4.0416492444641401
+cos0018 cos 1.1622206624927296 -0.50400115461197081 -> 0.44884072613370379 0.4823469915034318
+cos0019 cos 1.628772864620884e-08 0.58205705428979282 -> 1.1742319995791435 -1.0024839481956604e-08
+cos0020 cos 2.6385212606111241 2.9886107100937296 -> -8.7209475927161417 -4.7748352107199796
+cos0021 cos 4.8048375263775256 0.0062248852898515658 -> 0.092318702015846243 0.0061983430422306142
+cos0022 cos 7.9914515433858515 0.71659966615501436 -> -0.17375439906936566 -0.77217043527294582
+cos0023 cos 0.45124351152540226 1.6992693993812158 -> 2.543477948972237 -1.1528193694875477
+
+-- special values
+cos1000 cos -0.0 0.0 -> 1.0 0.0
+cos1001 cos -inf 0.0 -> nan 0.0 invalid ignore-imag-sign
+cos1002 cos nan 0.0 -> nan 0.0 ignore-imag-sign
+cos1003 cos -inf 2.2999999999999998 -> nan nan invalid
+cos1004 cos nan 2.2999999999999998 -> nan nan
+cos1005 cos -0.0 inf -> inf 0.0
+cos1006 cos -1.3999999999999999 inf -> inf inf
+cos1007 cos -2.7999999999999998 inf -> -inf inf
+cos1008 cos -4.2000000000000002 inf -> -inf -inf
+cos1009 cos -5.5999999999999996 inf -> inf -inf
+cos1010 cos -7.0 inf -> inf inf
+cos1011 cos -inf inf -> inf nan invalid ignore-real-sign
+cos1012 cos nan inf -> inf nan
+cos1013 cos -0.0 nan -> nan 0.0 ignore-imag-sign
+cos1014 cos -2.2999999999999998 nan -> nan nan
+cos1015 cos -inf nan -> nan nan
+cos1016 cos nan nan -> nan nan
+cos1017 cos 0.0 0.0 -> 1.0 -0.0
+cos1018 cos inf 0.0 -> nan 0.0 invalid ignore-imag-sign
+cos1019 cos inf 2.2999999999999998 -> nan nan invalid
+cos1020 cos 0.0 inf -> inf -0.0
+cos1021 cos 1.3999999999999999 inf -> inf -inf
+cos1022 cos 2.7999999999999998 inf -> -inf -inf
+cos1023 cos 4.2000000000000002 inf -> -inf inf
+cos1024 cos 5.5999999999999996 inf -> inf inf
+cos1025 cos 7.0 inf -> inf -inf
+cos1026 cos inf inf -> inf nan invalid ignore-real-sign
+cos1027 cos 0.0 nan -> nan 0.0 ignore-imag-sign
+cos1028 cos 2.2999999999999998 nan -> nan nan
+cos1029 cos inf nan -> nan nan
+cos1030 cos 0.0 -0.0 -> 1.0 0.0
+cos1031 cos inf -0.0 -> nan 0.0 invalid ignore-imag-sign
+cos1032 cos nan -0.0 -> nan 0.0 ignore-imag-sign
+cos1033 cos inf -2.2999999999999998 -> nan nan invalid
+cos1034 cos nan -2.2999999999999998 -> nan nan
+cos1035 cos 0.0 -inf -> inf 0.0
+cos1036 cos 1.3999999999999999 -inf -> inf inf
+cos1037 cos 2.7999999999999998 -inf -> -inf inf
+cos1038 cos 4.2000000000000002 -inf -> -inf -inf
+cos1039 cos 5.5999999999999996 -inf -> inf -inf
+cos1040 cos 7.0 -inf -> inf inf
+cos1041 cos inf -inf -> inf nan invalid ignore-real-sign
+cos1042 cos nan -inf -> inf nan
+cos1043 cos -0.0 -0.0 -> 1.0 -0.0
+cos1044 cos -inf -0.0 -> nan 0.0 invalid ignore-imag-sign
+cos1045 cos -inf -2.2999999999999998 -> nan nan invalid
+cos1046 cos -0.0 -inf -> inf -0.0
+cos1047 cos -1.3999999999999999 -inf -> inf -inf
+cos1048 cos -2.7999999999999998 -inf -> -inf -inf
+cos1049 cos -4.2000000000000002 -inf -> -inf inf
+cos1050 cos -5.5999999999999996 -inf -> inf inf
+cos1051 cos -7.0 -inf -> inf -inf
+cos1052 cos -inf -inf -> inf nan invalid ignore-real-sign
+
+
+---------------
+-- sin: Sine --
+---------------
+
+-- zeros
+sin0000 sin 0.0 0.0 -> 0.0 0.0
+sin0001 sin 0.0 -0.0 -> 0.0 -0.0
+sin0002 sin -0.0 0.0 -> -0.0 0.0
+sin0003 sin -0.0 -0.0 -> -0.0 -0.0
+
+-- random inputs
+sin0004 sin -0.18691829163163759 -0.74388741985507034 -> -0.2396636733773444 -0.80023231101856751
+sin0005 sin -0.45127453702459158 -461.81339920716164 -> -7.9722299331077877e+199 -1.6450205811004628e+200
+sin0006 sin -0.47669228345768921 -2.7369936564987514 -> -3.557238022267124 -6.8308030771226615
+sin0007 sin -0.31024285525950857 -1.4869219939188296 -> -0.70972676047175209 -1.9985029635426839
+sin0008 sin -4.4194573407025608 -1.405999210989288 -> 2.0702480800802685 0.55362250792180601
+sin0009 sin -1.7810832046434898e-05 0.0016439555384379083 -> -1.7810856113185261e-05 0.0016439562786668375
+sin0010 sin -0.8200017874897666 0.61724876887771929 -> -0.8749078195948865 0.44835295550987758
+sin0011 sin -1.4536502806107114 0.63998575534150415 -> -1.2035709929437679 0.080012187489163708
+sin0012 sin -2.2653412155506079 0.13172760685583729 -> -0.77502093809190431 -0.084554426868229532
+sin0013 sin -0.02613983069491858 0.18404766597776073 -> -0.026580778863127943 0.18502525396735642
+sin0014 sin 1.5743065001054617 -0.53125574272642029 -> 1.1444596332092725 0.0019537598099352077
+sin0015 sin 7.3833101791283289e-20 -0.16453221324236217 -> 7.4834720674379429e-20 -0.16527555646466915
+sin0016 sin 0.34763834641254038 -2.8377416421089565 -> 2.918883541504663 -8.0002718053250224
+sin0017 sin 0.077105785180421563 -0.090056027316200674 -> 0.077341973814471304 -0.089909869380524587
+sin0018 sin 3.9063227798142329e-17 -0.05954098654295524 -> 3.9132490348956512e-17 -0.059576172859837351
+sin0019 sin 0.57333917932544598 8.7785221430594696e-06 -> 0.54244029338302935 7.3747869125301368e-06
+sin0020 sin 0.024861722816513169 0.33044620756118515 -> 0.026228801369651 0.3363889671570689
+sin0021 sin 1.4342727387492671 0.81361889790284347 -> 1.3370960060947923 0.12336137961387163
+sin0022 sin 1.1518087354403725 4.8597235966150558 -> 58.919141989603041 26.237003403758852
+sin0023 sin 0.00087773078406649192 34.792379211312095 -> 565548145569.38245 644329685822700.62
+
+-- special values
+sin1000 sin -0.0 0.0 -> -0.0 0.0
+sin1001 sin -inf 0.0 -> nan 0.0 invalid ignore-imag-sign
+sin1002 sin nan 0.0 -> nan 0.0 ignore-imag-sign
+sin1003 sin -inf 2.2999999999999998 -> nan nan invalid
+sin1004 sin nan 2.2999999999999998 -> nan nan
+sin1005 sin -0.0 inf -> -0.0 inf
+sin1006 sin -1.3999999999999999 inf -> -inf inf
+sin1007 sin -2.7999999999999998 inf -> -inf -inf
+sin1008 sin -4.2000000000000002 inf -> inf -inf
+sin1009 sin -5.5999999999999996 inf -> inf inf
+sin1010 sin -7.0 inf -> -inf inf
+sin1011 sin -inf inf -> nan inf invalid ignore-imag-sign
+sin1012 sin nan inf -> nan inf ignore-imag-sign
+sin1013 sin -0.0 nan -> -0.0 nan
+sin1014 sin -2.2999999999999998 nan -> nan nan
+sin1015 sin -inf nan -> nan nan
+sin1016 sin nan nan -> nan nan
+sin1017 sin 0.0 0.0 -> 0.0 0.0
+sin1018 sin inf 0.0 -> nan 0.0 invalid ignore-imag-sign
+sin1019 sin inf 2.2999999999999998 -> nan nan invalid
+sin1020 sin 0.0 inf -> 0.0 inf
+sin1021 sin 1.3999999999999999 inf -> inf inf
+sin1022 sin 2.7999999999999998 inf -> inf -inf
+sin1023 sin 4.2000000000000002 inf -> -inf -inf
+sin1024 sin 5.5999999999999996 inf -> -inf inf
+sin1025 sin 7.0 inf -> inf inf
+sin1026 sin inf inf -> nan inf invalid ignore-imag-sign
+sin1027 sin 0.0 nan -> 0.0 nan
+sin1028 sin 2.2999999999999998 nan -> nan nan
+sin1029 sin inf nan -> nan nan
+sin1030 sin 0.0 -0.0 -> 0.0 -0.0
+sin1031 sin inf -0.0 -> nan 0.0 invalid ignore-imag-sign
+sin1032 sin nan -0.0 -> nan 0.0 ignore-imag-sign
+sin1033 sin inf -2.2999999999999998 -> nan nan invalid
+sin1034 sin nan -2.2999999999999998 -> nan nan
+sin1035 sin 0.0 -inf -> 0.0 -inf
+sin1036 sin 1.3999999999999999 -inf -> inf -inf
+sin1037 sin 2.7999999999999998 -inf -> inf inf
+sin1038 sin 4.2000000000000002 -inf -> -inf inf
+sin1039 sin 5.5999999999999996 -inf -> -inf -inf
+sin1040 sin 7.0 -inf -> inf -inf
+sin1041 sin inf -inf -> nan inf invalid ignore-imag-sign
+sin1042 sin nan -inf -> nan inf ignore-imag-sign
+sin1043 sin -0.0 -0.0 -> -0.0 -0.0
+sin1044 sin -inf -0.0 -> nan 0.0 invalid ignore-imag-sign
+sin1045 sin -inf -2.2999999999999998 -> nan nan invalid
+sin1046 sin -0.0 -inf -> -0.0 -inf
+sin1047 sin -1.3999999999999999 -inf -> -inf -inf
+sin1048 sin -2.7999999999999998 -inf -> -inf inf
+sin1049 sin -4.2000000000000002 -inf -> inf inf
+sin1050 sin -5.5999999999999996 -inf -> inf -inf
+sin1051 sin -7.0 -inf -> -inf -inf
+sin1052 sin -inf -inf -> nan inf invalid ignore-imag-sign
+
+
+------------------
+-- tan: Tangent --
+------------------
+
+-- zeros
+tan0000 tan 0.0 0.0 -> 0.0 0.0
+tan0001 tan 0.0 -0.0 -> 0.0 -0.0
+tan0002 tan -0.0 0.0 -> -0.0 0.0
+tan0003 tan -0.0 -0.0 -> -0.0 -0.0
+
+-- random inputs
+tan0004 tan -0.56378561833861074 -1.7110276237187664e+73 -> -0.0 -1.0
+tan0005 tan -3.5451633993471915e-12 -2.855471863564059 -> -4.6622441304889575e-14 -0.99340273843093951
+tan0006 tan -2.502442719638696 -0.26742234390504221 -> 0.66735215252994995 -0.39078997935420956
+tan0007 tan -0.87639597720371365 -55.586225523280206 -> -1.0285264565948176e-48 -1.0
+tan0008 tan -0.015783869596427243 -520.05944436039272 -> -0.0 -1.0
+tan0009 tan -0.84643549990725164 2.0749097935396343 -> -0.031412661676959573 1.0033548479526764
+tan0010 tan -0.43613792248559646 8.1082741629458059 -> -1.3879848444644593e-07 0.99999988344224011
+tan0011 tan -1.0820906367833114 0.28571868992480248 -> -1.3622485737936536 0.99089269377971245
+tan0012 tan -1.1477859580220084 1.9021637002708041 -> -0.034348450042071196 1.0293954097901687
+tan0013 tan -0.12465543176953409 3.0606851016344815e-05 -> -0.12530514290387343 3.1087420769945479e-05
+tan0014 tan 3.7582848717525343 -692787020.44038939 -> 0.0 -1.0
+tan0015 tan 2.2321967655142176e-06 -10.090069423008169 -> 1.5369846120622643e-14 -0.99999999655723759
+tan0016 tan 0.88371172390245012 -1.1635053630132823 -> 0.19705017118625889 -1.0196452280843129
+tan0017 tan 2.1347414231849267 -1.9311339960416831 -> -0.038663576915982524 -1.0174399993980778
+tan0018 tan 5.9027945255899974 -2.1574195684607135e-183 -> -0.39986591539281496 -2.5023753167976915e-183
+tan0019 tan 0.44811489490805362 683216075670.07556 -> 0.0 1.0
+tan0020 tan 4.1459766396068325 12.523017205605756 -> 2.4022514758988068e-11 1.0000000000112499
+tan0021 tan 1.7809617968443272 1.5052381702853379 -> -0.044066222118946903 1.0932684517702778
+tan0022 tan 1.1615313900880577 1.7956298728647107 -> 0.041793186826390362 1.0375339546034792
+tan0023 tan 0.067014779477908945 5.8517361577457097 -> 2.2088639754800034e-06 0.9999836182420061
+
+-- special values
+tan1000 tan -0.0 0.0 -> -0.0 0.0
+tan1001 tan -inf 0.0 -> nan nan invalid
+tan1002 tan -inf 2.2999999999999998 -> nan nan invalid
+tan1003 tan nan 0.0 -> nan nan
+tan1004 tan nan 2.2999999999999998 -> nan nan
+tan1005 tan -0.0 inf -> -0.0 1.0
+tan1006 tan -0.69999999999999996 inf -> -0.0 1.0
+tan1007 tan -1.3999999999999999 inf -> -0.0 1.0
+tan1008 tan -2.1000000000000001 inf -> 0.0 1.0
+tan1009 tan -2.7999999999999998 inf -> 0.0 1.0
+tan1010 tan -3.5 inf -> -0.0 1.0
+tan1011 tan -inf inf -> -0.0 1.0 ignore-real-sign
+tan1012 tan nan inf -> -0.0 1.0 ignore-real-sign
+tan1013 tan -0.0 nan -> -0.0 nan
+tan1014 tan -2.2999999999999998 nan -> nan nan
+tan1015 tan -inf nan -> nan nan
+tan1016 tan nan nan -> nan nan
+tan1017 tan 0.0 0.0 -> 0.0 0.0
+tan1018 tan inf 0.0 -> nan nan invalid
+tan1019 tan inf 2.2999999999999998 -> nan nan invalid
+tan1020 tan 0.0 inf -> 0.0 1.0
+tan1021 tan 0.69999999999999996 inf -> 0.0 1.0
+tan1022 tan 1.3999999999999999 inf -> 0.0 1.0
+tan1023 tan 2.1000000000000001 inf -> -0.0 1.0
+tan1024 tan 2.7999999999999998 inf -> -0.0 1.0
+tan1025 tan 3.5 inf -> 0.0 1.0
+tan1026 tan inf inf -> -0.0 1.0 ignore-real-sign
+tan1027 tan 0.0 nan -> 0.0 nan
+tan1028 tan 2.2999999999999998 nan -> nan nan
+tan1029 tan inf nan -> nan nan
+tan1030 tan 0.0 -0.0 -> 0.0 -0.0
+tan1031 tan inf -0.0 -> nan nan invalid
+tan1032 tan inf -2.2999999999999998 -> nan nan invalid
+tan1033 tan nan -0.0 -> nan nan
+tan1034 tan nan -2.2999999999999998 -> nan nan
+tan1035 tan 0.0 -inf -> 0.0 -1.0
+tan1036 tan 0.69999999999999996 -inf -> 0.0 -1.0
+tan1037 tan 1.3999999999999999 -inf -> 0.0 -1.0
+tan1038 tan 2.1000000000000001 -inf -> -0.0 -1.0
+tan1039 tan 2.7999999999999998 -inf -> -0.0 -1.0
+tan1040 tan 3.5 -inf -> 0.0 -1.0
+tan1041 tan inf -inf -> -0.0 -1.0 ignore-real-sign
+tan1042 tan nan -inf -> -0.0 -1.0 ignore-real-sign
+tan1043 tan -0.0 -0.0 -> -0.0 -0.0
+tan1044 tan -inf -0.0 -> nan nan invalid
+tan1045 tan -inf -2.2999999999999998 -> nan nan invalid
+tan1046 tan -0.0 -inf -> -0.0 -1.0
+tan1047 tan -0.69999999999999996 -inf -> -0.0 -1.0
+tan1048 tan -1.3999999999999999 -inf -> -0.0 -1.0
+tan1049 tan -2.1000000000000001 -inf -> 0.0 -1.0
+tan1050 tan -2.7999999999999998 -inf -> 0.0 -1.0
+tan1051 tan -3.5 -inf -> -0.0 -1.0
+tan1052 tan -inf -inf -> -0.0 -1.0 ignore-real-sign
+
+
+------------------------------------------------------------------------
+-- rect: Conversion from polar coordinates to rectangular coordinates --
+------------------------------------------------------------------------
+--
+-- For cmath.rect, we can use the same testcase syntax as for the
+-- complex -> complex functions above, but here the input arguments
+-- should be interpreted as a pair of floating-point numbers rather
+-- than the real and imaginary parts of a complex number.
+--
+-- Here are the 'spirit of C99' rules for rect. First, the short
+-- version:
+--
+-- rect(x, t) = exp(log(x)+it) for positive-signed x
+-- rect(x, t) = -exp(log(-x)+it) for negative-signed x
+-- rect(nan, t) = exp(nan + it), except that in rect(nan, +-0) the
+-- sign of the imaginary part is unspecified.
+--
+-- and now the long version:
+--
+-- rect(x, -t) = conj(rect(x, t)) for all x and t
+-- rect(-x, t) = -rect(x, t) for all x and t
+-- rect(+0, +0) returns +0 + i0
+-- rect(+0, inf) returns +- 0 +- i0, where the signs of the real and
+-- imaginary parts are unspecified.
+-- rect(x, inf) returns NaN + i NaN and raises the "invalid"
+-- floating-point exception, for finite nonzero x.
+-- rect(inf, inf) returns +-inf + i NaN and raises the "invalid"
+-- floating-point exception (where the sign of the real part of the
+-- result is unspecified).
+-- rect(inf, +0) returns inf+i0
+-- rect(inf, x) returns inf*cis(x), for finite nonzero x
+-- rect(inf, NaN) returns +-inf+i NaN, where the sign of the real part
+-- of the result is unspecified.
+-- rect(NaN, x) returns NaN + i NaN for all nonzero numbers (including
+-- infinities) x
+-- rect(NaN, 0) returns NaN +- i0, where the sign of the imaginary
+-- part is unspecified
+-- rect(NaN, NaN) returns NaN + i NaN
+-- rect(x, NaN) returns NaN + i NaN for finite nonzero x
+-- rect(+0, NaN) return +-0 +- i0, where the signs of the real and
+-- imaginary parts are unspecified.
+
+-- special values
+rect1000 rect 0.0 0.0 -> 0.0 0.0
+rect1001 rect 0.0 inf -> 0.0 0.0 ignore-real-sign ignore-imag-sign
+rect1002 rect 2.3 inf -> nan nan invalid
+rect1003 rect inf inf -> inf nan invalid ignore-real-sign
+rect1004 rect inf 0.0 -> inf 0.0
+rect1005 rect inf 1.4 -> inf inf
+rect1006 rect inf 2.8 -> -inf inf
+rect1007 rect inf 4.2 -> -inf -inf
+rect1008 rect inf 5.6 -> inf -inf
+rect1009 rect inf 7.0 -> inf inf
+rect1010 rect nan 0.0 -> nan 0.0 ignore-imag-sign
+rect1011 rect nan 2.3 -> nan nan
+rect1012 rect nan inf -> nan nan
+rect1013 rect nan nan -> nan nan
+rect1014 rect inf nan -> inf nan ignore-real-sign
+rect1015 rect 2.3 nan -> nan nan
+rect1016 rect 0.0 nan -> 0.0 0.0 ignore-real-sign ignore-imag-sign
+rect1017 rect 0.0 -0.0 -> 0.0 -0.0
+rect1018 rect 0.0 -inf -> 0.0 0.0 ignore-real-sign ignore-imag-sign
+rect1019 rect 2.3 -inf -> nan nan invalid
+rect1020 rect inf -inf -> inf nan invalid ignore-real-sign
+rect1021 rect inf -0.0 -> inf -0.0
+rect1022 rect inf -1.4 -> inf -inf
+rect1023 rect inf -2.8 -> -inf -inf
+rect1024 rect inf -4.2 -> -inf inf
+rect1025 rect inf -5.6 -> inf inf
+rect1026 rect inf -7.0 -> inf -inf
+rect1027 rect nan -0.0 -> nan 0.0 ignore-imag-sign
+rect1028 rect nan -2.3 -> nan nan
+rect1029 rect nan -inf -> nan nan
+rect1030 rect -0.0 0.0 -> -0.0 -0.0
+rect1031 rect -0.0 inf -> 0.0 0.0 ignore-real-sign ignore-imag-sign
+rect1032 rect -2.3 inf -> nan nan invalid
+rect1033 rect -inf inf -> -inf nan invalid ignore-real-sign
+rect1034 rect -inf 0.0 -> -inf -0.0
+rect1035 rect -inf 1.4 -> -inf -inf
+rect1036 rect -inf 2.8 -> inf -inf
+rect1037 rect -inf 4.2 -> inf inf
+rect1038 rect -inf 5.6 -> -inf inf
+rect1039 rect -inf 7.0 -> -inf -inf
+rect1040 rect -inf nan -> inf nan ignore-real-sign
+rect1041 rect -2.3 nan -> nan nan
+rect1042 rect -0.0 nan -> 0.0 0.0 ignore-real-sign ignore-imag-sign
+rect1043 rect -0.0 -0.0 -> -0.0 0.0
+rect1044 rect -0.0 -inf -> 0.0 0.0 ignore-real-sign ignore-imag-sign
+rect1045 rect -2.3 -inf -> nan nan invalid
+rect1046 rect -inf -inf -> -inf nan invalid ignore-real-sign
+rect1047 rect -inf -0.0 -> -inf 0.0
+rect1048 rect -inf -1.4 -> -inf inf
+rect1049 rect -inf -2.8 -> inf inf
+rect1050 rect -inf -4.2 -> inf -inf
+rect1051 rect -inf -5.6 -> -inf -inf
+rect1052 rect -inf -7.0 -> -inf inf
+
+-------------------------------------------------------------------------
+-- polar: Conversion from rectangular coordinates to polar coordinates --
+-------------------------------------------------------------------------
+--
+-- For cmath.polar, we can use the same testcase syntax as for the
+-- complex -> complex functions above, but here the output arguments
+-- should be interpreted as a pair of floating-point numbers rather
+-- than the real and imaginary parts of a complex number.
+--
+-- Annex G of the C99 standard describes fully both the real and
+-- imaginary parts of polar (as cabs and carg, respectively, which in turn
+-- are defined in terms of the functions hypot and atan2).
+
+-- overflow
+polar0100 polar 1.4e308 1.4e308 -> inf 0.78539816339744828 overflow
+
+-- special values
+polar1000 polar 0.0 0.0 -> 0.0 0.0
+polar1001 polar 0.0 -0.0 -> 0.0 -0.0
+polar1002 polar -0.0 0.0 -> 0.0 3.1415926535897931
+polar1003 polar -0.0 -0.0 -> 0.0 -3.1415926535897931
+polar1004 polar inf 0.0 -> inf 0.0
+polar1005 polar inf 2.3 -> inf 0.0
+polar1006 polar inf inf -> inf 0.78539816339744828
+polar1007 polar 2.3 inf -> inf 1.5707963267948966
+polar1008 polar 0.0 inf -> inf 1.5707963267948966
+polar1009 polar -0.0 inf -> inf 1.5707963267948966
+polar1010 polar -2.3 inf -> inf 1.5707963267948966
+polar1011 polar -inf inf -> inf 2.3561944901923448
+polar1012 polar -inf 2.3 -> inf 3.1415926535897931
+polar1013 polar -inf 0.0 -> inf 3.1415926535897931
+polar1014 polar -inf -0.0 -> inf -3.1415926535897931
+polar1015 polar -inf -2.3 -> inf -3.1415926535897931
+polar1016 polar -inf -inf -> inf -2.3561944901923448
+polar1017 polar -2.3 -inf -> inf -1.5707963267948966
+polar1018 polar -0.0 -inf -> inf -1.5707963267948966
+polar1019 polar 0.0 -inf -> inf -1.5707963267948966
+polar1020 polar 2.3 -inf -> inf -1.5707963267948966
+polar1021 polar inf -inf -> inf -0.78539816339744828
+polar1022 polar inf -2.3 -> inf -0.0
+polar1023 polar inf -0.0 -> inf -0.0
+polar1024 polar nan -inf -> inf nan
+polar1025 polar nan -2.3 -> nan nan
+polar1026 polar nan -0.0 -> nan nan
+polar1027 polar nan 0.0 -> nan nan
+polar1028 polar nan 2.3 -> nan nan
+polar1029 polar nan inf -> inf nan
+polar1030 polar nan nan -> nan nan
+polar1031 polar inf nan -> inf nan
+polar1032 polar 2.3 nan -> nan nan
+polar1033 polar 0.0 nan -> nan nan
+polar1034 polar -0.0 nan -> nan nan
+polar1035 polar -2.3 nan -> nan nan
+polar1036 polar -inf nan -> inf nan
diff --git a/Lib/test/ieee754.txt b/Lib/test/ieee754.txt
new file mode 100644
index 0000000..5a41c8f
--- /dev/null
+++ b/Lib/test/ieee754.txt
@@ -0,0 +1,183 @@
+======================================
+Python IEEE 754 floating point support
+======================================
+
+>>> from sys import float_info as FI
+>>> from math import *
+>>> PI = pi
+>>> E = e
+
+You must never compare two floats with == because you are not going to get
+what you expect. We treat two floats as equal if the difference between them
+is small than epsilon.
+>>> EPS = 1E-15
+>>> def equal(x, y):
+... """Almost equal helper for floats"""
+... return abs(x - y) < EPS
+
+
+NaNs and INFs
+=============
+
+In Python 2.6 and newer NaNs (not a number) and infinity can be constructed
+from the strings 'inf' and 'nan'.
+
+>>> INF = float('inf')
+>>> NINF = float('-inf')
+>>> NAN = float('nan')
+
+>>> INF
+inf
+>>> NINF
+-inf
+>>> NAN
+nan
+
+The math module's ``isnan`` and ``isinf`` functions can be used to detect INF
+and NAN:
+>>> isinf(INF), isinf(NINF), isnan(NAN)
+(True, True, True)
+>>> INF == -NINF
+True
+
+Infinity
+--------
+
+Ambiguous operations like ``0 * inf`` or ``inf - inf`` result in NaN.
+>>> INF * 0
+nan
+>>> INF - INF
+nan
+>>> INF / INF
+nan
+
+However unambigous operations with inf return inf:
+>>> INF * INF
+inf
+>>> 1.5 * INF
+inf
+>>> 0.5 * INF
+inf
+>>> INF / 1000
+inf
+
+Not a Number
+------------
+
+NaNs are never equal to another number, even itself
+>>> NAN == NAN
+False
+>>> NAN < 0
+False
+>>> NAN >= 0
+False
+
+All operations involving a NaN return a NaN except for the power of *0* and *1*.
+>>> 1 + NAN
+nan
+>>> 1 * NAN
+nan
+>>> 0 * NAN
+nan
+>>> 1 ** NAN
+1.0
+>>> 0 ** NAN
+0.0
+>>> (1.0 + FI.epsilon) * NAN
+nan
+
+Misc Functions
+==============
+
+The power of 1 raised to x is always 1.0, even for special values like 0,
+infinity and NaN.
+
+>>> pow(1, 0)
+1.0
+>>> pow(1, INF)
+1.0
+>>> pow(1, -INF)
+1.0
+>>> pow(1, NAN)
+1.0
+
+The power of 0 raised to x is defined as 0, if x is positive. Negative
+values are a domain error or zero division error and NaN result in a
+silent NaN.
+
+>>> pow(0, 0)
+1.0
+>>> pow(0, INF)
+0.0
+>>> pow(0, -INF)
+Traceback (most recent call last):
+...
+ValueError: math domain error
+>>> 0 ** -1
+Traceback (most recent call last):
+...
+ZeroDivisionError: 0.0 cannot be raised to a negative power
+>>> pow(0, NAN)
+nan
+
+
+Trigonometric Functions
+=======================
+
+>>> sin(INF)
+Traceback (most recent call last):
+...
+ValueError: math domain error
+>>> sin(NINF)
+Traceback (most recent call last):
+...
+ValueError: math domain error
+>>> sin(NAN)
+nan
+>>> cos(INF)
+Traceback (most recent call last):
+...
+ValueError: math domain error
+>>> cos(NINF)
+Traceback (most recent call last):
+...
+ValueError: math domain error
+>>> cos(NAN)
+nan
+>>> tan(INF)
+Traceback (most recent call last):
+...
+ValueError: math domain error
+>>> tan(NINF)
+Traceback (most recent call last):
+...
+ValueError: math domain error
+>>> tan(NAN)
+nan
+
+Neither pi nor tan are exact, but you can assume that tan(pi/2) is a large value
+and tan(pi) is a very small value:
+>>> tan(PI/2) > 1E10
+True
+>>> -tan(-PI/2) > 1E10
+True
+>>> tan(PI) < 1E-15
+True
+
+>>> asin(NAN), acos(NAN), atan(NAN)
+(nan, nan, nan)
+>>> asin(INF), asin(NINF)
+Traceback (most recent call last):
+...
+ValueError: math domain error
+>>> acos(INF), acos(NINF)
+Traceback (most recent call last):
+...
+ValueError: math domain error
+>>> equal(atan(INF), PI/2), equal(atan(NINF), -PI/2)
+(True, True)
+
+
+Hyberbolic Functions
+====================
+
diff --git a/Lib/test/test_cmath.py b/Lib/test/test_cmath.py
index 7c5f4a5..ca4945d 100755
--- a/Lib/test/test_cmath.py
+++ b/Lib/test/test_cmath.py
@@ -1,6 +1,81 @@
from test.test_support import run_unittest
+from test.test_math import parse_testfile, test_file
import unittest
+import os, sys
import cmath, math
+from cmath import phase, polar, rect, pi
+
+INF = float('inf')
+NAN = float('nan')
+
+complex_zeros = [complex(x, y) for x in [0.0, -0.0] for y in [0.0, -0.0]]
+complex_infinities = [complex(x, y) for x, y in [
+ (INF, 0.0), # 1st quadrant
+ (INF, 2.3),
+ (INF, INF),
+ (2.3, INF),
+ (0.0, INF),
+ (-0.0, INF), # 2nd quadrant
+ (-2.3, INF),
+ (-INF, INF),
+ (-INF, 2.3),
+ (-INF, 0.0),
+ (-INF, -0.0), # 3rd quadrant
+ (-INF, -2.3),
+ (-INF, -INF),
+ (-2.3, -INF),
+ (-0.0, -INF),
+ (0.0, -INF), # 4th quadrant
+ (2.3, -INF),
+ (INF, -INF),
+ (INF, -2.3),
+ (INF, -0.0)
+ ]]
+complex_nans = [complex(x, y) for x, y in [
+ (NAN, -INF),
+ (NAN, -2.3),
+ (NAN, -0.0),
+ (NAN, 0.0),
+ (NAN, 2.3),
+ (NAN, INF),
+ (-INF, NAN),
+ (-2.3, NAN),
+ (-0.0, NAN),
+ (0.0, NAN),
+ (2.3, NAN),
+ (INF, NAN)
+ ]]
+
+def almostEqualF(a, b, rel_err=2e-15, abs_err = 5e-323):
+ """Determine whether floating-point values a and b are equal to within
+ a (small) rounding error. The default values for rel_err and
+ abs_err are chosen to be suitable for platforms where a float is
+ represented by an IEEE 754 double. They allow an error of between
+ 9 and 19 ulps."""
+
+ # special values testing
+ if math.isnan(a):
+ return math.isnan(b)
+ if math.isinf(a):
+ return a == b
+
+ # if both a and b are zero, check whether they have the same sign
+ # (in theory there are examples where it would be legitimate for a
+ # and b to have opposite signs; in practice these hardly ever
+ # occur).
+ if not a and not b:
+ return math.copysign(1., a) == math.copysign(1., b)
+
+ # if a-b overflows, or b is infinite, return False. Again, in
+ # theory there are examples where a is within a few ulps of the
+ # max representable float, and then b could legitimately be
+ # infinite. In practice these examples are rare.
+ try:
+ absolute_error = abs(b-a)
+ except OverflowError:
+ return False
+ else:
+ return absolute_error <= max(abs_err, rel_err * abs(a))
class CMathTests(unittest.TestCase):
# list of all functions in cmath
@@ -12,25 +87,51 @@ class CMathTests(unittest.TestCase):
test_functions.append(lambda x : cmath.log(x, 1729. + 0j))
test_functions.append(lambda x : cmath.log(14.-27j, x))
- def cAssertAlmostEqual(self, a, b, rel_eps = 1e-10, abs_eps = 1e-100):
- """Check that two complex numbers are almost equal."""
- # the two complex numbers are considered almost equal if
- # either the relative error is <= rel_eps or the absolute error
- # is tiny, <= abs_eps.
- if a == b == 0:
- return
- absolute_error = abs(a-b)
- relative_error = absolute_error/max(abs(a), abs(b))
- if relative_error > rel_eps and absolute_error > abs_eps:
- self.fail("%s and %s are not almost equal" % (a, b))
+ def setUp(self):
+ self.test_values = open(test_file)
+
+ def tearDown(self):
+ self.test_values.close()
+
+ def rAssertAlmostEqual(self, a, b, rel_err = 2e-15, abs_err = 5e-323):
+ """Check that two floating-point numbers are almost equal."""
+
+ # special values testing
+ if math.isnan(a):
+ if math.isnan(b):
+ return
+ self.fail("%s should be nan" % repr(b))
+
+ if math.isinf(a):
+ if a == b:
+ return
+ self.fail("finite result where infinity excpected: "
+ "expected %s, got %s" % (repr(a), repr(b)))
+
+ if not a and not b:
+ if math.atan2(a, -1.) != math.atan2(b, -1.):
+ self.fail("zero has wrong sign: expected %s, got %s" %
+ (repr(a), repr(b)))
+
+ # test passes if either the absolute error or the relative
+ # error is sufficiently small. The defaults amount to an
+ # error of between 9 ulps and 19 ulps on an IEEE-754 compliant
+ # machine.
+
+ try:
+ absolute_error = abs(b-a)
+ except OverflowError:
+ pass
+ else:
+ if absolute_error <= max(abs_err, rel_err * abs(a)):
+ return
+ self.fail("%s and %s are not sufficiently close" % (repr(a), repr(b)))
def test_constants(self):
e_expected = 2.71828182845904523536
pi_expected = 3.14159265358979323846
- self.assertAlmostEqual(cmath.pi, pi_expected, places=9,
- msg="cmath.pi is %s; should be %s" % (cmath.pi, pi_expected))
- self.assertAlmostEqual(cmath.e, e_expected, places=9,
- msg="cmath.e is %s; should be %s" % (cmath.e, e_expected))
+ self.assertAlmostEqual(cmath.pi, pi_expected)
+ self.assertAlmostEqual(cmath.e, e_expected)
def test_user_object(self):
# Test automatic calling of __complex__ and __float__ by cmath
@@ -109,13 +210,13 @@ class CMathTests(unittest.TestCase):
for f in self.test_functions:
# usual usage
- self.cAssertAlmostEqual(f(MyComplex(cx_arg)), f(cx_arg))
- self.cAssertAlmostEqual(f(MyComplexOS(cx_arg)), f(cx_arg))
+ self.assertEqual(f(MyComplex(cx_arg)), f(cx_arg))
+ self.assertEqual(f(MyComplexOS(cx_arg)), f(cx_arg))
# other combinations of __float__ and __complex__
- self.cAssertAlmostEqual(f(FloatAndComplex()), f(cx_arg))
- self.cAssertAlmostEqual(f(FloatAndComplexOS()), f(cx_arg))
- self.cAssertAlmostEqual(f(JustFloat()), f(flt_arg))
- self.cAssertAlmostEqual(f(JustFloatOS()), f(flt_arg))
+ self.assertEqual(f(FloatAndComplex()), f(cx_arg))
+ self.assertEqual(f(FloatAndComplexOS()), f(cx_arg))
+ self.assertEqual(f(JustFloat()), f(flt_arg))
+ self.assertEqual(f(JustFloatOS()), f(flt_arg))
# TypeError should be raised for classes not providing
# either __complex__ or __float__, even if they provide
# __int__, __long__ or __index__. An old-style class
@@ -138,7 +239,7 @@ class CMathTests(unittest.TestCase):
# functions, by virtue of providing a __float__ method
for f in self.test_functions:
for arg in [2, 2.]:
- self.cAssertAlmostEqual(f(arg), f(arg.__float__()))
+ self.assertEqual(f(arg), f(arg.__float__()))
# but strings should give a TypeError
for f in self.test_functions:
@@ -182,12 +283,201 @@ class CMathTests(unittest.TestCase):
float_fn = getattr(math, fn)
complex_fn = getattr(cmath, fn)
for v in values:
- self.cAssertAlmostEqual(float_fn(v), complex_fn(v))
+ z = complex_fn(v)
+ self.rAssertAlmostEqual(float_fn(v), z.real)
+ self.assertEqual(0., z.imag)
# test two-argument version of log with various bases
for base in [0.5, 2., 10.]:
for v in positive:
- self.cAssertAlmostEqual(cmath.log(v, base), math.log(v, base))
+ z = cmath.log(v, base)
+ self.rAssertAlmostEqual(math.log(v, base), z.real)
+ self.assertEqual(0., z.imag)
+
+ def test_specific_values(self):
+ if not float.__getformat__("double").startswith("IEEE"):
+ return
+
+ def rect_complex(z):
+ """Wrapped version of rect that accepts a complex number instead of
+ two float arguments."""
+ return cmath.rect(z.real, z.imag)
+
+ def polar_complex(z):
+ """Wrapped version of polar that returns a complex number instead of
+ two floats."""
+ return complex(*polar(z))
+
+ for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
+ arg = complex(ar, ai)
+ expected = complex(er, ei)
+ if fn == 'rect':
+ function = rect_complex
+ elif fn == 'polar':
+ function = polar_complex
+ else:
+ function = getattr(cmath, fn)
+ if 'divide-by-zero' in flags or 'invalid' in flags:
+ try:
+ actual = function(arg)
+ except ValueError:
+ continue
+ else:
+ test_str = "%s: %s(complex(%r, %r))" % (id, fn, ar, ai)
+ self.fail('ValueError not raised in test %s' % test_str)
+
+ if 'overflow' in flags:
+ try:
+ actual = function(arg)
+ except OverflowError:
+ continue
+ else:
+ test_str = "%s: %s(complex(%r, %r))" % (id, fn, ar, ai)
+ self.fail('OverflowError not raised in test %s' % test_str)
+
+ actual = function(arg)
+
+ if 'ignore-real-sign' in flags:
+ actual = complex(abs(actual.real), actual.imag)
+ expected = complex(abs(expected.real), expected.imag)
+ if 'ignore-imag-sign' in flags:
+ actual = complex(actual.real, abs(actual.imag))
+ expected = complex(expected.real, abs(expected.imag))
+
+ # for the real part of the log function, we allow an
+ # absolute error of up to 2e-15.
+ if fn in ('log', 'log10'):
+ real_abs_err = 2e-15
+ else:
+ real_abs_err = 5e-323
+
+ if not (almostEqualF(expected.real, actual.real,
+ abs_err = real_abs_err) and
+ almostEqualF(expected.imag, actual.imag)):
+ error_message = (
+ "%s: %s(complex(%r, %r))\n" % (id, fn, ar, ai) +
+ "Expected: complex(%r, %r)\n" %
+ (expected.real, expected.imag) +
+ "Received: complex(%r, %r)\n" %
+ (actual.real, actual.imag) +
+ "Received value insufficiently close to expected value.")
+ self.fail(error_message)
+
+ def assertCISEqual(self, a, b):
+ eps = 1E-7
+ if abs(a[0] - b[0]) > eps or abs(a[1] - b[1]) > eps:
+ self.fail((a ,b))
+
+ def test_polar(self):
+ self.assertCISEqual(polar(0), (0., 0.))
+ self.assertCISEqual(polar(1.), (1., 0.))
+ self.assertCISEqual(polar(-1.), (1., pi))
+ self.assertCISEqual(polar(1j), (1., pi/2))
+ self.assertCISEqual(polar(-1j), (1., -pi/2))
+
+ def test_phase(self):
+ self.assertAlmostEqual(phase(0), 0.)
+ self.assertAlmostEqual(phase(1.), 0.)
+ self.assertAlmostEqual(phase(-1.), pi)
+ self.assertAlmostEqual(phase(-1.+1E-300j), pi)
+ self.assertAlmostEqual(phase(-1.-1E-300j), -pi)
+ self.assertAlmostEqual(phase(1j), pi/2)
+ self.assertAlmostEqual(phase(-1j), -pi/2)
+
+ # zeros
+ self.assertEqual(phase(complex(0.0, 0.0)), 0.0)
+ self.assertEqual(phase(complex(0.0, -0.0)), -0.0)
+ self.assertEqual(phase(complex(-0.0, 0.0)), pi)
+ self.assertEqual(phase(complex(-0.0, -0.0)), -pi)
+
+ # infinities
+ self.assertAlmostEqual(phase(complex(-INF, -0.0)), -pi)
+ self.assertAlmostEqual(phase(complex(-INF, -2.3)), -pi)
+ self.assertAlmostEqual(phase(complex(-INF, -INF)), -0.75*pi)
+ self.assertAlmostEqual(phase(complex(-2.3, -INF)), -pi/2)
+ self.assertAlmostEqual(phase(complex(-0.0, -INF)), -pi/2)
+ self.assertAlmostEqual(phase(complex(0.0, -INF)), -pi/2)
+ self.assertAlmostEqual(phase(complex(2.3, -INF)), -pi/2)
+ self.assertAlmostEqual(phase(complex(INF, -INF)), -pi/4)
+ self.assertEqual(phase(complex(INF, -2.3)), -0.0)
+ self.assertEqual(phase(complex(INF, -0.0)), -0.0)
+ self.assertEqual(phase(complex(INF, 0.0)), 0.0)
+ self.assertEqual(phase(complex(INF, 2.3)), 0.0)
+ self.assertAlmostEqual(phase(complex(INF, INF)), pi/4)
+ self.assertAlmostEqual(phase(complex(2.3, INF)), pi/2)
+ self.assertAlmostEqual(phase(complex(0.0, INF)), pi/2)
+ self.assertAlmostEqual(phase(complex(-0.0, INF)), pi/2)
+ self.assertAlmostEqual(phase(complex(-2.3, INF)), pi/2)
+ self.assertAlmostEqual(phase(complex(-INF, INF)), 0.75*pi)
+ self.assertAlmostEqual(phase(complex(-INF, 2.3)), pi)
+ self.assertAlmostEqual(phase(complex(-INF, 0.0)), pi)
+
+ # real or imaginary part NaN
+ for z in complex_nans:
+ self.assert_(math.isnan(phase(z)))
+
+ def test_abs(self):
+ # zeros
+ for z in complex_zeros:
+ self.assertEqual(abs(z), 0.0)
+
+ # infinities
+ for z in complex_infinities:
+ self.assertEqual(abs(z), INF)
+
+ # real or imaginary part NaN
+ self.assertEqual(abs(complex(NAN, -INF)), INF)
+ self.assert_(math.isnan(abs(complex(NAN, -2.3))))
+ self.assert_(math.isnan(abs(complex(NAN, -0.0))))
+ self.assert_(math.isnan(abs(complex(NAN, 0.0))))
+ self.assert_(math.isnan(abs(complex(NAN, 2.3))))
+ self.assertEqual(abs(complex(NAN, INF)), INF)
+ self.assertEqual(abs(complex(-INF, NAN)), INF)
+ self.assert_(math.isnan(abs(complex(-2.3, NAN))))
+ self.assert_(math.isnan(abs(complex(-0.0, NAN))))
+ self.assert_(math.isnan(abs(complex(0.0, NAN))))
+ self.assert_(math.isnan(abs(complex(2.3, NAN))))
+ self.assertEqual(abs(complex(INF, NAN)), INF)
+ self.assert_(math.isnan(abs(complex(NAN, NAN))))
+
+ # result overflows
+ if float.__getformat__("double").startswith("IEEE"):
+ self.assertRaises(OverflowError, abs, complex(1.4e308, 1.4e308))
+
+ def assertCEqual(self, a, b):
+ eps = 1E-7
+ if abs(a.real - b[0]) > eps or abs(a.imag - b[1]) > eps:
+ self.fail((a ,b))
+
+ def test_rect(self):
+ self.assertCEqual(rect(0, 0), (0, 0))
+ self.assertCEqual(rect(1, 0), (1., 0))
+ self.assertCEqual(rect(1, -pi), (-1., 0))
+ self.assertCEqual(rect(1, pi/2), (0, 1.))
+ self.assertCEqual(rect(1, -pi/2), (0, -1.))
+
+ def test_isnan(self):
+ self.failIf(cmath.isnan(1))
+ self.failIf(cmath.isnan(1j))
+ self.failIf(cmath.isnan(INF))
+ self.assert_(cmath.isnan(NAN))
+ self.assert_(cmath.isnan(complex(NAN, 0)))
+ self.assert_(cmath.isnan(complex(0, NAN)))
+ self.assert_(cmath.isnan(complex(NAN, NAN)))
+ self.assert_(cmath.isnan(complex(NAN, INF)))
+ self.assert_(cmath.isnan(complex(INF, NAN)))
+
+ def test_isinf(self):
+ self.failIf(cmath.isinf(1))
+ self.failIf(cmath.isinf(1j))
+ self.failIf(cmath.isinf(NAN))
+ self.assert_(cmath.isinf(INF))
+ self.assert_(cmath.isinf(complex(INF, 0)))
+ self.assert_(cmath.isinf(complex(0, INF)))
+ self.assert_(cmath.isinf(complex(INF, INF)))
+ self.assert_(cmath.isinf(complex(NAN, INF)))
+ self.assert_(cmath.isinf(complex(INF, NAN)))
+
def test_main():
run_unittest(CMathTests)
diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py
index b9ad8c5..e89d723 100644
--- a/Lib/test/test_float.py
+++ b/Lib/test/test_float.py
@@ -2,12 +2,12 @@
import unittest, struct
import os
from test import test_support
+import math
+from math import isinf, isnan
+import operator
-def isinf(x):
- return x * 0.5 == x
-
-def isnan(x):
- return x != x
+INF = float("inf")
+NAN = float("nan")
class FormatFunctionsTestCase(unittest.TestCase):
@@ -239,6 +239,17 @@ class InfNanTest(unittest.TestCase):
self.assertEqual(str(1e300 * 1e300 * 0), "nan")
self.assertEqual(str(-1e300 * 1e300 * 0), "nan")
+ def notest_float_nan(self):
+ self.assert_(NAN.is_nan())
+ self.failIf(INF.is_nan())
+ self.failIf((0.).is_nan())
+
+ def notest_float_inf(self):
+ self.assert_(INF.is_inf())
+ self.failIf(NAN.is_inf())
+ self.failIf((0.).is_inf())
+
+
def test_main():
test_support.run_unittest(
FormatFunctionsTestCase,
diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py
index aa44253..b8c23db 100644
--- a/Lib/test/test_math.py
+++ b/Lib/test/test_math.py
@@ -4,9 +4,45 @@
from test.test_support import run_unittest, verbose
import unittest
import math
+import os
+import sys
-seps='1e-05'
-eps = eval(seps)
+eps = 1E-05
+NAN = float('nan')
+INF = float('inf')
+NINF = float('-inf')
+
+# locate file with test values
+if __name__ == '__main__':
+ file = sys.argv[0]
+else:
+ file = __file__
+test_dir = os.path.dirname(file) or os.curdir
+test_file = os.path.join(test_dir, 'cmath_testcases.txt')
+
+def parse_testfile(fname):
+ """Parse a file with test values
+
+ Empty lines or lines starting with -- are ignored
+ yields id, fn, arg_real, arg_imag, exp_real, exp_imag
+ """
+ with open(fname) as fp:
+ for line in fp:
+ # skip comment lines and blank lines
+ if line.startswith('--') or not line.strip():
+ continue
+
+ lhs, rhs = line.split('->')
+ id, fn, arg_real, arg_imag = lhs.split()
+ rhs_pieces = rhs.split()
+ exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1]
+ flags = rhs_pieces[2:]
+
+ yield (id, fn,
+ float(arg_real), float(arg_imag),
+ float(exp_real), float(exp_imag),
+ flags
+ )
class MathTests(unittest.TestCase):
@@ -28,18 +64,57 @@ class MathTests(unittest.TestCase):
self.ftest('acos(-1)', math.acos(-1), math.pi)
self.ftest('acos(0)', math.acos(0), math.pi/2)
self.ftest('acos(1)', math.acos(1), 0)
+ self.assertRaises(ValueError, math.acos, INF)
+ self.assertRaises(ValueError, math.acos, NINF)
+ self.assert_(math.isnan(math.acos(NAN)))
+
+ def testAcosh(self):
+ self.assertRaises(TypeError, math.acosh)
+ self.ftest('acosh(1)', math.acosh(1), 0)
+ self.ftest('acosh(2)', math.acosh(2), 1.3169578969248168)
+ self.assertRaises(ValueError, math.acosh, 0)
+ self.assertRaises(ValueError, math.acosh, -1)
+ self.assertEquals(math.acosh(INF), INF)
+ self.assertRaises(ValueError, math.acosh, NINF)
+ self.assert_(math.isnan(math.acosh(NAN)))
def testAsin(self):
self.assertRaises(TypeError, math.asin)
self.ftest('asin(-1)', math.asin(-1), -math.pi/2)
self.ftest('asin(0)', math.asin(0), 0)
self.ftest('asin(1)', math.asin(1), math.pi/2)
+ self.assertRaises(ValueError, math.asin, INF)
+ self.assertRaises(ValueError, math.asin, NINF)
+ self.assert_(math.isnan(math.asin(NAN)))
+
+ def testAsinh(self):
+ self.assertRaises(TypeError, math.asinh)
+ self.ftest('asinh(0)', math.asinh(0), 0)
+ self.ftest('asinh(1)', math.asinh(1), 0.88137358701954305)
+ self.ftest('asinh(-1)', math.asinh(-1), -0.88137358701954305)
+ self.assertEquals(math.asinh(INF), INF)
+ self.assertEquals(math.asinh(NINF), NINF)
+ self.assert_(math.isnan(math.asinh(NAN)))
def testAtan(self):
self.assertRaises(TypeError, math.atan)
self.ftest('atan(-1)', math.atan(-1), -math.pi/4)
self.ftest('atan(0)', math.atan(0), 0)
self.ftest('atan(1)', math.atan(1), math.pi/4)
+ self.ftest('atan(inf)', math.atan(INF), math.pi/2)
+ self.ftest('atan(-inf)', math.atan(-INF), -math.pi/2)
+ self.assert_(math.isnan(math.atan(NAN)))
+
+ def testAtanh(self):
+ self.assertRaises(TypeError, math.atan)
+ self.ftest('atanh(0)', math.atanh(0), 0)
+ self.ftest('atanh(0.5)', math.atanh(0.5), 0.54930614433405489)
+ self.ftest('atanh(-0.5)', math.atanh(-0.5), -0.54930614433405489)
+ self.assertRaises(ValueError, math.atanh, 1)
+ self.assertRaises(ValueError, math.atanh, -1)
+ self.assertRaises(ValueError, math.atanh, INF)
+ self.assertRaises(ValueError, math.atanh, NINF)
+ self.assert_(math.isnan(math.atanh(NAN)))
def testAtan2(self):
self.assertRaises(TypeError, math.atan2)
@@ -58,6 +133,9 @@ class MathTests(unittest.TestCase):
self.ftest('ceil(-0.5)', math.ceil(-0.5), 0)
self.ftest('ceil(-1.0)', math.ceil(-1.0), -1)
self.ftest('ceil(-1.5)', math.ceil(-1.5), -1)
+ #self.assertEquals(math.ceil(INF), INF)
+ #self.assertEquals(math.ceil(NINF), NINF)
+ #self.assert_(math.isnan(math.ceil(NAN)))
class TestCeil:
def __ceil__(self):
@@ -72,17 +150,55 @@ class MathTests(unittest.TestCase):
self.assertRaises(TypeError, math.ceil, t)
self.assertRaises(TypeError, math.ceil, t, 0)
+ if float.__getformat__("double").startswith("IEEE"):
+ def testCopysign(self):
+ self.assertRaises(TypeError, math.copysign)
+ # copysign should let us distinguish signs of zeros
+ self.assertEquals(copysign(1., 0.), 1.)
+ self.assertEquals(copysign(1., -0.), -1.)
+ self.assertEquals(copysign(INF, 0.), INF)
+ self.assertEquals(copysign(INF, -0.), NINF)
+ self.assertEquals(copysign(NINF, 0.), INF)
+ self.assertEquals(copysign(NINF, -0.), NINF)
+ # and of infinities
+ self.assertEquals(copysign(1., INF), 1.)
+ self.assertEquals(copysign(1., NINF), -1.)
+ self.assertEquals(copysign(INF, INF), INF)
+ self.assertEquals(copysign(INF, NINF), NINF)
+ self.assertEquals(copysign(NINF, INF), INF)
+ self.assertEquals(copysign(NINF, NINF), NINF)
+ self.assert_(math.isnan(copysign(NAN, 1.)))
+ self.assert_(math.isnan(copysign(NAN, INF)))
+ self.assert_(math.isnan(copysign(NAN, NINF)))
+ self.assert_(math.isnan(copysign(NAN, NAN)))
+ # copysign(INF, NAN) may be INF or it may be NINF, since
+ # we don't know whether the sign bit of NAN is set on any
+ # given platform.
+ self.assert_(math.isinf(copysign(INF, NAN)))
+ # similarly, copysign(2., NAN) could be 2. or -2.
+ self.assertEquals(abs(copysign(2., NAN)), 2.)
+
def testCos(self):
self.assertRaises(TypeError, math.cos)
self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0)
self.ftest('cos(0)', math.cos(0), 1)
self.ftest('cos(pi/2)', math.cos(math.pi/2), 0)
self.ftest('cos(pi)', math.cos(math.pi), -1)
+ try:
+ self.assert_(math.isnan(math.cos(INF)))
+ self.assert_(math.isnan(math.cos(NINF)))
+ except ValueError:
+ self.assertRaises(ValueError, math.cos, INF)
+ self.assertRaises(ValueError, math.cos, NINF)
+ self.assert_(math.isnan(math.cos(NAN)))
def testCosh(self):
self.assertRaises(TypeError, math.cosh)
self.ftest('cosh(0)', math.cosh(0), 1)
self.ftest('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
+ self.assertEquals(math.cosh(INF), INF)
+ self.assertEquals(math.cosh(NINF), INF)
+ self.assert_(math.isnan(math.cosh(NAN)))
def testDegrees(self):
self.assertRaises(TypeError, math.degrees)
@@ -95,6 +211,9 @@ class MathTests(unittest.TestCase):
self.ftest('exp(-1)', math.exp(-1), 1/math.e)
self.ftest('exp(0)', math.exp(0), 1)
self.ftest('exp(1)', math.exp(1), math.e)
+ self.assertEquals(math.exp(INF), INF)
+ self.assertEquals(math.exp(NINF), 0.)
+ self.assert_(math.isnan(math.exp(NAN)))
def testFabs(self):
self.assertRaises(TypeError, math.fabs)
@@ -115,6 +234,9 @@ class MathTests(unittest.TestCase):
# This fails on some platforms - so check it here
self.ftest('floor(1.23e167)', math.floor(1.23e167), 1.23e167)
self.ftest('floor(-1.23e167)', math.floor(-1.23e167), -1.23e167)
+ #self.assertEquals(math.ceil(INF), INF)
+ #self.assertEquals(math.ceil(NINF), NINF)
+ #self.assert_(math.isnan(math.floor(NAN)))
class TestFloor:
def __floor__(self):
@@ -137,6 +259,19 @@ class MathTests(unittest.TestCase):
self.ftest('fmod(-10,1)', math.fmod(-10,1), 0)
self.ftest('fmod(-10,0.5)', math.fmod(-10,0.5), 0)
self.ftest('fmod(-10,1.5)', math.fmod(-10,1.5), -1)
+ self.assert_(math.isnan(math.fmod(NAN, 1.)))
+ self.assert_(math.isnan(math.fmod(1., NAN)))
+ self.assert_(math.isnan(math.fmod(NAN, NAN)))
+ self.assertRaises(ValueError, math.fmod, 1., 0.)
+ self.assertRaises(ValueError, math.fmod, INF, 1.)
+ self.assertRaises(ValueError, math.fmod, NINF, 1.)
+ self.assertRaises(ValueError, math.fmod, INF, 0.)
+ self.assertEquals(math.fmod(3.0, INF), 3.0)
+ self.assertEquals(math.fmod(-3.0, INF), -3.0)
+ self.assertEquals(math.fmod(3.0, NINF), 3.0)
+ self.assertEquals(math.fmod(-3.0, NINF), -3.0)
+ self.assertEquals(math.fmod(0.0, 3.0), 0.0)
+ self.assertEquals(math.fmod(0.0, NINF), 0.0)
def testFrexp(self):
self.assertRaises(TypeError, math.frexp)
@@ -152,10 +287,20 @@ class MathTests(unittest.TestCase):
testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
+ self.assertEquals(math.frexp(INF)[0], INF)
+ self.assertEquals(math.frexp(NINF)[0], NINF)
+ self.assert_(math.isnan(math.frexp(NAN)[0]))
+
def testHypot(self):
self.assertRaises(TypeError, math.hypot)
self.ftest('hypot(0,0)', math.hypot(0,0), 0)
self.ftest('hypot(3,4)', math.hypot(3,4), 5)
+ self.assertEqual(math.hypot(NAN, INF), INF)
+ self.assertEqual(math.hypot(INF, NAN), INF)
+ self.assertEqual(math.hypot(NAN, NINF), INF)
+ self.assertEqual(math.hypot(NINF, NAN), INF)
+ self.assert_(math.isnan(math.hypot(1.0, NAN)))
+ self.assert_(math.isnan(math.hypot(NAN, -2.0)))
def testLdexp(self):
self.assertRaises(TypeError, math.ldexp)
@@ -163,6 +308,13 @@ class MathTests(unittest.TestCase):
self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
+ self.assertRaises(OverflowError, math.ldexp, 1., 1000000)
+ self.assertRaises(OverflowError, math.ldexp, -1., 1000000)
+ self.assertEquals(math.ldexp(1., -1000000), 0.)
+ self.assertEquals(math.ldexp(-1., -1000000), -0.)
+ self.assertEquals(math.ldexp(INF, 30), INF)
+ self.assertEquals(math.ldexp(NINF, -213), NINF)
+ self.assert_(math.isnan(math.ldexp(NAN, 0)))
def testLog(self):
self.assertRaises(TypeError, math.log)
@@ -172,12 +324,31 @@ class MathTests(unittest.TestCase):
self.ftest('log(32,2)', math.log(32,2), 5)
self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
+ self.assertEquals(math.log(INF), INF)
+ self.assertRaises(ValueError, math.log, NINF)
+ self.assert_(math.isnan(math.log(NAN)))
+
+ def testLog1p(self):
+ self.assertRaises(TypeError, math.log1p)
+ self.ftest('log1p(1/e -1)', math.log1p(1/math.e-1), -1)
+ self.ftest('log1p(0)', math.log1p(0), 0)
+ self.ftest('log1p(e-1)', math.log1p(math.e-1), 1)
+ self.ftest('log1p(1)', math.log1p(1), math.log(2))
+ self.assertEquals(math.log1p(INF), INF)
+ self.assertRaises(ValueError, math.log1p, NINF)
+ self.assert_(math.isnan(math.log1p(NAN)))
+ n= 2**90
+ self.assertAlmostEquals(math.log1p(n), 62.383246250395075)
+ self.assertAlmostEquals(math.log1p(n), math.log1p(float(n)))
def testLog10(self):
self.assertRaises(TypeError, math.log10)
self.ftest('log10(0.1)', math.log10(0.1), -1)
self.ftest('log10(1)', math.log10(1), 0)
self.ftest('log10(10)', math.log10(10), 1)
+ self.assertEquals(math.log(INF), INF)
+ self.assertRaises(ValueError, math.log10, NINF)
+ self.assert_(math.isnan(math.log10(NAN)))
def testModf(self):
self.assertRaises(TypeError, math.modf)
@@ -191,12 +362,35 @@ class MathTests(unittest.TestCase):
testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
+ self.assertEquals(math.modf(INF), (0.0, INF))
+ self.assertEquals(math.modf(NINF), (-0.0, NINF))
+
+ modf_nan = math.modf(NAN)
+ self.assert_(math.isnan(modf_nan[0]))
+ self.assert_(math.isnan(modf_nan[1]))
+
def testPow(self):
self.assertRaises(TypeError, math.pow)
self.ftest('pow(0,1)', math.pow(0,1), 0)
self.ftest('pow(1,0)', math.pow(1,0), 1)
self.ftest('pow(2,1)', math.pow(2,1), 2)
self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
+ self.assertEqual(math.pow(INF, 1), INF)
+ self.assertEqual(math.pow(NINF, 1), NINF)
+ self.assertEqual((math.pow(1, INF)), 1.)
+ self.assertEqual((math.pow(1, NINF)), 1.)
+ self.assert_(math.isnan(math.pow(NAN, 1)))
+ self.assert_(math.isnan(math.pow(2, NAN)))
+ self.assert_(math.isnan(math.pow(0, NAN)))
+ self.assertEqual(math.pow(1, NAN), 1)
+ self.assertEqual(1**NAN, 1)
+ self.assertEqual(1**INF, 1)
+ self.assertEqual(1**NINF, 1)
+ self.assertEqual(1**0, 1)
+ self.assertEqual(1.**NAN, 1)
+ self.assertEqual(1.**INF, 1)
+ self.assertEqual(1.**NINF, 1)
+ self.assertEqual(1.**0, 1)
def testRadians(self):
self.assertRaises(TypeError, math.radians)
@@ -209,29 +403,52 @@ class MathTests(unittest.TestCase):
self.ftest('sin(0)', math.sin(0), 0)
self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
+ try:
+ self.assert_(math.isnan(math.sin(INF)))
+ self.assert_(math.isnan(math.sin(NINF)))
+ except ValueError:
+ self.assertRaises(ValueError, math.sin, INF)
+ self.assertRaises(ValueError, math.sin, NINF)
+ self.assert_(math.isnan(math.sin(NAN)))
def testSinh(self):
self.assertRaises(TypeError, math.sinh)
self.ftest('sinh(0)', math.sinh(0), 0)
self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
+ self.assertEquals(math.sinh(INF), INF)
+ self.assertEquals(math.sinh(-INF), -INF)
+ self.assert_(math.isnan(math.sinh(NAN)))
def testSqrt(self):
self.assertRaises(TypeError, math.sqrt)
self.ftest('sqrt(0)', math.sqrt(0), 0)
self.ftest('sqrt(1)', math.sqrt(1), 1)
self.ftest('sqrt(4)', math.sqrt(4), 2)
+ self.assertEquals(math.sqrt(INF), INF)
+ self.assertRaises(ValueError, math.sqrt, NINF)
+ self.assert_(math.isnan(math.sqrt(NAN)))
def testTan(self):
self.assertRaises(TypeError, math.tan)
self.ftest('tan(0)', math.tan(0), 0)
self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
+ try:
+ self.assert_(math.isnan(math.tan(INF)))
+ self.assert_(math.isnan(math.tan(NINF)))
+ except:
+ self.assertRaises(ValueError, math.tan, INF)
+ self.assertRaises(ValueError, math.tan, NINF)
+ self.assert_(math.isnan(math.tan(NAN)))
def testTanh(self):
self.assertRaises(TypeError, math.tanh)
self.ftest('tanh(0)', math.tanh(0), 0)
self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
+ self.ftest('tanh(inf)', math.tanh(INF), 1)
+ self.ftest('tanh(-inf)', math.tanh(NINF), -1)
+ self.assert_(math.isnan(math.tanh(NAN)))
def test_trunc(self):
self.assertEqual(math.trunc(1), 1)
@@ -326,9 +543,27 @@ class MathTests(unittest.TestCase):
else:
self.fail("sqrt(-1) didn't raise ValueError")
+ def test_testfile(self):
+ if not float.__getformat__("double").startswith("IEEE"):
+ return
+ for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
+ # Skip if either the input or result is complex, or if
+ # flags is nonempty
+ if ai != 0. or ei != 0. or flags:
+ continue
+ if fn in ['rect', 'polar']:
+ # no real versions of rect, polar
+ continue
+ func = getattr(math, fn)
+ result = func(ar)
+ self.ftest("%s:%s(%r)" % (id, fn, ar), result, er)
def test_main():
- run_unittest(MathTests)
+ from doctest import DocFileSuite
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(MathTests))
+ suite.addTest(DocFileSuite("ieee754.txt"))
+ run_unittest(suite)
if __name__ == '__main__':
test_main()
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 2a77354..d9627e0 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -276,6 +276,7 @@ PYTHON_OBJS= \
Python/peephole.o \
Python/pyarena.o \
Python/pyfpe.o \
+ Python/pymath.o \
Python/pystate.o \
Python/pythonrun.o \
Python/structmember.o \
@@ -622,6 +623,7 @@ PYTHON_HEADERS= \
Include/pydebug.h \
Include/pyerrors.h \
Include/pyfpe.h \
+ Include/pymath.h \
Include/pygetopt.h \
Include/pymem.h \
Include/pyport.h \
diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c
index ec48ce8..8e3c31e 100644
--- a/Modules/cmathmodule.c
+++ b/Modules/cmathmodule.c
@@ -3,31 +3,172 @@
/* much code borrowed from mathmodule.c */
#include "Python.h"
+/* we need DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_MANT_DIG and FLT_RADIX from
+ float.h. We assume that FLT_RADIX is either 2 or 16. */
+#include <float.h>
-#ifndef M_PI
-#define M_PI (3.141592653589793239)
+#if (FLT_RADIX != 2 && FLT_RADIX != 16)
+#error "Modules/cmathmodule.c expects FLT_RADIX to be 2 or 16"
#endif
-/* First, the C functions that do the real work */
+#ifndef M_LN2
+#define M_LN2 (0.6931471805599453094) /* natural log of 2 */
+#endif
+
+#ifndef M_LN10
+#define M_LN10 (2.302585092994045684) /* natural log of 10 */
+#endif
-/* constants */
-static Py_complex c_one = {1., 0.};
-static Py_complex c_half = {0.5, 0.};
-static Py_complex c_i = {0., 1.};
-static Py_complex c_halfi = {0., 0.5};
+/*
+ CM_LARGE_DOUBLE is used to avoid spurious overflow in the sqrt, log,
+ inverse trig and inverse hyperbolic trig functions. Its log is used in the
+ evaluation of exp, cos, cosh, sin, sinh, tan, and tanh to avoid unecessary
+ overflow.
+ */
+
+#define CM_LARGE_DOUBLE (DBL_MAX/4.)
+#define CM_SQRT_LARGE_DOUBLE (sqrt(CM_LARGE_DOUBLE))
+#define CM_LOG_LARGE_DOUBLE (log(CM_LARGE_DOUBLE))
+#define CM_SQRT_DBL_MIN (sqrt(DBL_MIN))
+
+/*
+ CM_SCALE_UP is an odd integer chosen such that multiplication by
+ 2**CM_SCALE_UP is sufficient to turn a subnormal into a normal.
+ CM_SCALE_DOWN is (-(CM_SCALE_UP+1)/2). These scalings are used to compute
+ square roots accurately when the real and imaginary parts of the argument
+ are subnormal.
+*/
+
+#if FLT_RADIX==2
+#define CM_SCALE_UP (2*(DBL_MANT_DIG/2) + 1)
+#elif FLT_RADIX==16
+#define CM_SCALE_UP (4*DBL_MANT_DIG+1)
+#endif
+#define CM_SCALE_DOWN (-(CM_SCALE_UP+1)/2)
/* forward declarations */
-static Py_complex c_log(Py_complex);
-static Py_complex c_prodi(Py_complex);
+static Py_complex c_asinh(Py_complex);
+static Py_complex c_atanh(Py_complex);
+static Py_complex c_cosh(Py_complex);
+static Py_complex c_sinh(Py_complex);
static Py_complex c_sqrt(Py_complex);
+static Py_complex c_tanh(Py_complex);
static PyObject * math_error(void);
+/* Code to deal with special values (infinities, NaNs, etc.). */
+
+/* special_type takes a double and returns an integer code indicating
+ the type of the double as follows:
+*/
+
+enum special_types {
+ ST_NINF, /* 0, negative infinity */
+ ST_NEG, /* 1, negative finite number (nonzero) */
+ ST_NZERO, /* 2, -0. */
+ ST_PZERO, /* 3, +0. */
+ ST_POS, /* 4, positive finite number (nonzero) */
+ ST_PINF, /* 5, positive infinity */
+ ST_NAN, /* 6, Not a Number */
+};
+
+static enum special_types
+special_type(double d)
+{
+ if (Py_IS_FINITE(d)) {
+ if (d != 0) {
+ if (copysign(1., d) == 1.)
+ return ST_POS;
+ else
+ return ST_NEG;
+ }
+ else {
+ if (copysign(1., d) == 1.)
+ return ST_PZERO;
+ else
+ return ST_NZERO;
+ }
+ }
+ if (Py_IS_NAN(d))
+ return ST_NAN;
+ if (copysign(1., d) == 1.)
+ return ST_PINF;
+ else
+ return ST_NINF;
+}
+
+#define SPECIAL_VALUE(z, table) \
+ if (!Py_IS_FINITE((z).real) || !Py_IS_FINITE((z).imag)) { \
+ errno = 0; \
+ return table[special_type((z).real)] \
+ [special_type((z).imag)]; \
+ }
+
+#define P Py_MATH_PI
+#define P14 0.25*Py_MATH_PI
+#define P12 0.5*Py_MATH_PI
+#define P34 0.75*Py_MATH_PI
+#ifdef MS_WINDOWS
+/* On Windows HUGE_VAL is an extern variable and not a constant. Since the
+ special value arrays need a constant we have to roll our own infinity
+ and nan. */
+# define INF (DBL_MAX*DBL_MAX)
+# define N (INF*0.)
+#else
+# define INF Py_HUGE_VAL
+# define N Py_NAN
+#endif /* MS_WINDOWS */
+#define U -9.5426319407711027e33 /* unlikely value, used as placeholder */
+
+/* First, the C functions that do the real work. Each of the c_*
+ functions computes and returns the C99 Annex G recommended result
+ and also sets errno as follows: errno = 0 if no floating-point
+ exception is associated with the result; errno = EDOM if C99 Annex
+ G recommends raising divide-by-zero or invalid for this result; and
+ errno = ERANGE where the overflow floating-point signal should be
+ raised.
+*/
+
+static Py_complex acos_special_values[7][7] = {
+ {{P34,INF},{P,INF}, {P,INF}, {P,-INF}, {P,-INF}, {P34,-INF},{N,INF}},
+ {{P12,INF},{U,U}, {U,U}, {U,U}, {U,U}, {P12,-INF},{N,N}},
+ {{P12,INF},{U,U}, {P12,0.},{P12,-0.},{U,U}, {P12,-INF},{P12,N}},
+ {{P12,INF},{U,U}, {P12,0.},{P12,-0.},{U,U}, {P12,-INF},{P12,N}},
+ {{P12,INF},{U,U}, {U,U}, {U,U}, {U,U}, {P12,-INF},{N,N}},
+ {{P14,INF},{0.,INF},{0.,INF},{0.,-INF},{0.,-INF},{P14,-INF},{N,INF}},
+ {{N,INF}, {N,N}, {N,N}, {N,N}, {N,N}, {N,-INF}, {N,N}}
+};
static Py_complex
-c_acos(Py_complex x)
+c_acos(Py_complex z)
{
- return c_neg(c_prodi(c_log(c_sum(x,c_prod(c_i,
- c_sqrt(c_diff(c_one,c_prod(x,x))))))));
+ Py_complex s1, s2, r;
+
+ SPECIAL_VALUE(z, acos_special_values);
+
+ if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) {
+ /* avoid unnecessary overflow for large arguments */
+ r.real = atan2(fabs(z.imag), z.real);
+ /* split into cases to make sure that the branch cut has the
+ correct continuity on systems with unsigned zeros */
+ if (z.real < 0.) {
+ r.imag = -copysign(log(hypot(z.real/2., z.imag/2.)) +
+ M_LN2*2., z.imag);
+ } else {
+ r.imag = copysign(log(hypot(z.real/2., z.imag/2.)) +
+ M_LN2*2., -z.imag);
+ }
+ } else {
+ s1.real = 1.-z.real;
+ s1.imag = -z.imag;
+ s1 = c_sqrt(s1);
+ s2.real = 1.+z.real;
+ s2.imag = z.imag;
+ s2 = c_sqrt(s2);
+ r.real = 2.*atan2(s1.real, s2.real);
+ r.imag = asinh(s2.real*s1.imag - s2.imag*s1.real);
+ }
+ errno = 0;
+ return r;
}
PyDoc_STRVAR(c_acos_doc,
@@ -36,14 +177,39 @@ PyDoc_STRVAR(c_acos_doc,
"Return the arc cosine of x.");
+static Py_complex acosh_special_values[7][7] = {
+ {{INF,-P34},{INF,-P}, {INF,-P}, {INF,P}, {INF,P}, {INF,P34},{INF,N}},
+ {{INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {INF,P12},{N,N}},
+ {{INF,-P12},{U,U}, {0.,-P12},{0.,P12},{U,U}, {INF,P12},{N,N}},
+ {{INF,-P12},{U,U}, {0.,-P12},{0.,P12},{U,U}, {INF,P12},{N,N}},
+ {{INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {INF,P12},{N,N}},
+ {{INF,-P14},{INF,-0.},{INF,-0.},{INF,0.},{INF,0.},{INF,P14},{INF,N}},
+ {{INF,N}, {N,N}, {N,N}, {N,N}, {N,N}, {INF,N}, {N,N}}
+};
+
static Py_complex
-c_acosh(Py_complex x)
+c_acosh(Py_complex z)
{
- Py_complex z;
- z = c_sqrt(c_half);
- z = c_log(c_prod(z, c_sum(c_sqrt(c_sum(x,c_one)),
- c_sqrt(c_diff(x,c_one)))));
- return c_sum(z, z);
+ Py_complex s1, s2, r;
+
+ SPECIAL_VALUE(z, acosh_special_values);
+
+ if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) {
+ /* avoid unnecessary overflow for large arguments */
+ r.real = log(hypot(z.real/2., z.imag/2.)) + M_LN2*2.;
+ r.imag = atan2(z.imag, z.real);
+ } else {
+ s1.real = z.real - 1.;
+ s1.imag = z.imag;
+ s1 = c_sqrt(s1);
+ s2.real = z.real + 1.;
+ s2.imag = z.imag;
+ s2 = c_sqrt(s2);
+ r.real = asinh(s1.real*s2.real + s1.imag*s2.imag);
+ r.imag = 2.*atan2(s1.imag, s2.real);
+ }
+ errno = 0;
+ return r;
}
PyDoc_STRVAR(c_acosh_doc,
@@ -53,14 +219,16 @@ PyDoc_STRVAR(c_acosh_doc,
static Py_complex
-c_asin(Py_complex x)
+c_asin(Py_complex z)
{
- /* -i * log[(sqrt(1-x**2) + i*x] */
- const Py_complex squared = c_prod(x, x);
- const Py_complex sqrt_1_minus_x_sq = c_sqrt(c_diff(c_one, squared));
- return c_neg(c_prodi(c_log(
- c_sum(sqrt_1_minus_x_sq, c_prodi(x))
- ) ) );
+ /* asin(z) = -i asinh(iz) */
+ Py_complex s, r;
+ s.real = -z.imag;
+ s.imag = z.real;
+ s = c_asinh(s);
+ r.real = s.imag;
+ r.imag = -s.real;
+ return r;
}
PyDoc_STRVAR(c_asin_doc,
@@ -69,14 +237,44 @@ PyDoc_STRVAR(c_asin_doc,
"Return the arc sine of x.");
+static Py_complex asinh_special_values[7][7] = {
+ {{-INF,-P14},{-INF,-0.},{-INF,-0.},{-INF,0.},{-INF,0.},{-INF,P14},{-INF,N}},
+ {{-INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {-INF,P12},{N,N}},
+ {{-INF,-P12},{U,U}, {-0.,-0.}, {-0.,0.}, {U,U}, {-INF,P12},{N,N}},
+ {{INF,-P12}, {U,U}, {0.,-0.}, {0.,0.}, {U,U}, {INF,P12}, {N,N}},
+ {{INF,-P12}, {U,U}, {U,U}, {U,U}, {U,U}, {INF,P12}, {N,N}},
+ {{INF,-P14}, {INF,-0.}, {INF,-0.}, {INF,0.}, {INF,0.}, {INF,P14}, {INF,N}},
+ {{INF,N}, {N,N}, {N,-0.}, {N,0.}, {N,N}, {INF,N}, {N,N}}
+};
+
static Py_complex
-c_asinh(Py_complex x)
+c_asinh(Py_complex z)
{
- Py_complex z;
- z = c_sqrt(c_half);
- z = c_log(c_prod(z, c_sum(c_sqrt(c_sum(x, c_i)),
- c_sqrt(c_diff(x, c_i)))));
- return c_sum(z, z);
+ Py_complex s1, s2, r;
+
+ SPECIAL_VALUE(z, asinh_special_values);
+
+ if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) {
+ if (z.imag >= 0.) {
+ r.real = copysign(log(hypot(z.real/2., z.imag/2.)) +
+ M_LN2*2., z.real);
+ } else {
+ r.real = -copysign(log(hypot(z.real/2., z.imag/2.)) +
+ M_LN2*2., -z.real);
+ }
+ r.imag = atan2(z.imag, fabs(z.real));
+ } else {
+ s1.real = 1.+z.imag;
+ s1.imag = -z.real;
+ s1 = c_sqrt(s1);
+ s2.real = 1.-z.imag;
+ s2.imag = z.real;
+ s2 = c_sqrt(s2);
+ r.real = asinh(s1.real*s2.imag-s2.real*s1.imag);
+ r.imag = atan2(z.imag, s1.real*s2.real-s1.imag*s2.imag);
+ }
+ errno = 0;
+ return r;
}
PyDoc_STRVAR(c_asinh_doc,
@@ -86,9 +284,37 @@ PyDoc_STRVAR(c_asinh_doc,
static Py_complex
-c_atan(Py_complex x)
+c_atan(Py_complex z)
{
- return c_prod(c_halfi,c_log(c_quot(c_sum(c_i,x),c_diff(c_i,x))));
+ /* atan(z) = -i atanh(iz) */
+ Py_complex s, r;
+ s.real = -z.imag;
+ s.imag = z.real;
+ s = c_atanh(s);
+ r.real = s.imag;
+ r.imag = -s.real;
+ return r;
+}
+
+/* Windows screws up atan2 for inf and nan */
+static double
+c_atan2(Py_complex z)
+{
+ if (Py_IS_NAN(z.real) || Py_IS_NAN(z.imag))
+ return Py_NAN;
+ if (Py_IS_INFINITY(z.imag)) {
+ if (Py_IS_INFINITY(z.real)) {
+ if (copysign(1., z.real) == 1.)
+ /* atan2(+-inf, +inf) == +-pi/4 */
+ return copysign(0.25*Py_MATH_PI, z.imag);
+ else
+ /* atan2(+-inf, -inf) == +-pi*3/4 */
+ return copysign(0.75*Py_MATH_PI, z.imag);
+ }
+ /* atan2(+-inf, x) == +-pi/2 for finite x */
+ return copysign(0.5*Py_MATH_PI, z.imag);
+ }
+ return atan2(z.imag, z.real);
}
PyDoc_STRVAR(c_atan_doc,
@@ -97,10 +323,61 @@ PyDoc_STRVAR(c_atan_doc,
"Return the arc tangent of x.");
+static Py_complex atanh_special_values[7][7] = {
+ {{-0.,-P12},{-0.,-P12},{-0.,-P12},{-0.,P12},{-0.,P12},{-0.,P12},{-0.,N}},
+ {{-0.,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {-0.,P12},{N,N}},
+ {{-0.,-P12},{U,U}, {-0.,-0.}, {-0.,0.}, {U,U}, {-0.,P12},{-0.,N}},
+ {{0.,-P12}, {U,U}, {0.,-0.}, {0.,0.}, {U,U}, {0.,P12}, {0.,N}},
+ {{0.,-P12}, {U,U}, {U,U}, {U,U}, {U,U}, {0.,P12}, {N,N}},
+ {{0.,-P12}, {0.,-P12}, {0.,-P12}, {0.,P12}, {0.,P12}, {0.,P12}, {0.,N}},
+ {{0.,-P12}, {N,N}, {N,N}, {N,N}, {N,N}, {0.,P12}, {N,N}}
+};
+
static Py_complex
-c_atanh(Py_complex x)
+c_atanh(Py_complex z)
{
- return c_prod(c_half,c_log(c_quot(c_sum(c_one,x),c_diff(c_one,x))));
+ Py_complex r;
+ double ay, h;
+
+ SPECIAL_VALUE(z, atanh_special_values);
+
+ /* Reduce to case where z.real >= 0., using atanh(z) = -atanh(-z). */
+ if (z.real < 0.) {
+ return c_neg(c_atanh(c_neg(z)));
+ }
+
+ ay = fabs(z.imag);
+ if (z.real > CM_SQRT_LARGE_DOUBLE || ay > CM_SQRT_LARGE_DOUBLE) {
+ /*
+ if abs(z) is large then we use the approximation
+ atanh(z) ~ 1/z +/- i*pi/2 (+/- depending on the sign
+ of z.imag)
+ */
+ h = hypot(z.real/2., z.imag/2.); /* safe from overflow */
+ r.real = z.real/4./h/h;
+ /* the two negations in the next line cancel each other out
+ except when working with unsigned zeros: they're there to
+ ensure that the branch cut has the correct continuity on
+ systems that don't support signed zeros */
+ r.imag = -copysign(Py_MATH_PI/2., -z.imag);
+ errno = 0;
+ } else if (z.real == 1. && ay < CM_SQRT_DBL_MIN) {
+ /* C99 standard says: atanh(1+/-0.) should be inf +/- 0i */
+ if (ay == 0.) {
+ r.real = INF;
+ r.imag = z.imag;
+ errno = EDOM;
+ } else {
+ r.real = -log(sqrt(ay)/sqrt(hypot(ay, 2.)));
+ r.imag = copysign(atan2(2., -ay)/2, z.imag);
+ errno = 0;
+ }
+ } else {
+ r.real = log1p(4.*z.real/((1-z.real)*(1-z.real) + ay*ay))/4.;
+ r.imag = -atan2(-2.*z.imag, (1-z.real)*(1+z.real) - ay*ay)/2.;
+ errno = 0;
+ }
+ return r;
}
PyDoc_STRVAR(c_atanh_doc,
@@ -110,11 +387,13 @@ PyDoc_STRVAR(c_atanh_doc,
static Py_complex
-c_cos(Py_complex x)
+c_cos(Py_complex z)
{
+ /* cos(z) = cosh(iz) */
Py_complex r;
- r.real = cos(x.real)*cosh(x.imag);
- r.imag = -sin(x.real)*sinh(x.imag);
+ r.real = -z.imag;
+ r.imag = z.real;
+ r = c_cosh(r);
return r;
}
@@ -124,12 +403,64 @@ PyDoc_STRVAR(c_cos_doc,
"Return the cosine of x.");
+/* cosh(infinity + i*y) needs to be dealt with specially */
+static Py_complex cosh_special_values[7][7] = {
+ {{INF,N},{U,U},{INF,0.}, {INF,-0.},{U,U},{INF,N},{INF,N}},
+ {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
+ {{N,0.}, {U,U},{1.,0.}, {1.,-0.}, {U,U},{N,0.}, {N,0.}},
+ {{N,0.}, {U,U},{1.,-0.}, {1.,0.}, {U,U},{N,0.}, {N,0.}},
+ {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
+ {{INF,N},{U,U},{INF,-0.},{INF,0.}, {U,U},{INF,N},{INF,N}},
+ {{N,N}, {N,N},{N,0.}, {N,0.}, {N,N},{N,N}, {N,N}}
+};
+
static Py_complex
-c_cosh(Py_complex x)
+c_cosh(Py_complex z)
{
Py_complex r;
- r.real = cos(x.imag)*cosh(x.real);
- r.imag = sin(x.imag)*sinh(x.real);
+ double x_minus_one;
+
+ /* special treatment for cosh(+/-inf + iy) if y is not a NaN */
+ if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
+ if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) &&
+ (z.imag != 0.)) {
+ if (z.real > 0) {
+ r.real = copysign(INF, cos(z.imag));
+ r.imag = copysign(INF, sin(z.imag));
+ }
+ else {
+ r.real = copysign(INF, cos(z.imag));
+ r.imag = -copysign(INF, sin(z.imag));
+ }
+ }
+ else {
+ r = cosh_special_values[special_type(z.real)]
+ [special_type(z.imag)];
+ }
+ /* need to set errno = EDOM if y is +/- infinity and x is not
+ a NaN */
+ if (Py_IS_INFINITY(z.imag) && !Py_IS_NAN(z.real))
+ errno = EDOM;
+ else
+ errno = 0;
+ return r;
+ }
+
+ if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) {
+ /* deal correctly with cases where cosh(z.real) overflows but
+ cosh(z) does not. */
+ x_minus_one = z.real - copysign(1., z.real);
+ r.real = cos(z.imag) * cosh(x_minus_one) * Py_MATH_E;
+ r.imag = sin(z.imag) * sinh(x_minus_one) * Py_MATH_E;
+ } else {
+ r.real = cos(z.imag) * cosh(z.real);
+ r.imag = sin(z.imag) * sinh(z.real);
+ }
+ /* detect overflow, and set errno accordingly */
+ if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag))
+ errno = ERANGE;
+ else
+ errno = 0;
return r;
}
@@ -139,13 +470,65 @@ PyDoc_STRVAR(c_cosh_doc,
"Return the hyperbolic cosine of x.");
+/* exp(infinity + i*y) and exp(-infinity + i*y) need special treatment for
+ finite y */
+static Py_complex exp_special_values[7][7] = {
+ {{0.,0.},{U,U},{0.,-0.}, {0.,0.}, {U,U},{0.,0.},{0.,0.}},
+ {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
+ {{N,N}, {U,U},{1.,-0.}, {1.,0.}, {U,U},{N,N}, {N,N}},
+ {{N,N}, {U,U},{1.,-0.}, {1.,0.}, {U,U},{N,N}, {N,N}},
+ {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
+ {{INF,N},{U,U},{INF,-0.},{INF,0.},{U,U},{INF,N},{INF,N}},
+ {{N,N}, {N,N},{N,-0.}, {N,0.}, {N,N},{N,N}, {N,N}}
+};
+
static Py_complex
-c_exp(Py_complex x)
+c_exp(Py_complex z)
{
Py_complex r;
- double l = exp(x.real);
- r.real = l*cos(x.imag);
- r.imag = l*sin(x.imag);
+ double l;
+
+ if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
+ if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag)
+ && (z.imag != 0.)) {
+ if (z.real > 0) {
+ r.real = copysign(INF, cos(z.imag));
+ r.imag = copysign(INF, sin(z.imag));
+ }
+ else {
+ r.real = copysign(0., cos(z.imag));
+ r.imag = copysign(0., sin(z.imag));
+ }
+ }
+ else {
+ r = exp_special_values[special_type(z.real)]
+ [special_type(z.imag)];
+ }
+ /* need to set errno = EDOM if y is +/- infinity and x is not
+ a NaN and not -infinity */
+ if (Py_IS_INFINITY(z.imag) &&
+ (Py_IS_FINITE(z.real) ||
+ (Py_IS_INFINITY(z.real) && z.real > 0)))
+ errno = EDOM;
+ else
+ errno = 0;
+ return r;
+ }
+
+ if (z.real > CM_LOG_LARGE_DOUBLE) {
+ l = exp(z.real-1.);
+ r.real = l*cos(z.imag)*Py_MATH_E;
+ r.imag = l*sin(z.imag)*Py_MATH_E;
+ } else {
+ l = exp(z.real);
+ r.real = l*cos(z.imag);
+ r.imag = l*sin(z.imag);
+ }
+ /* detect overflow, and set errno accordingly */
+ if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag))
+ errno = ERANGE;
+ else
+ errno = 0;
return r;
}
@@ -155,24 +538,97 @@ PyDoc_STRVAR(c_exp_doc,
"Return the exponential value e**x.");
+static Py_complex log_special_values[7][7] = {
+ {{INF,-P34},{INF,-P}, {INF,-P}, {INF,P}, {INF,P}, {INF,P34}, {INF,N}},
+ {{INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {INF,P12}, {N,N}},
+ {{INF,-P12},{U,U}, {-INF,-P}, {-INF,P}, {U,U}, {INF,P12}, {N,N}},
+ {{INF,-P12},{U,U}, {-INF,-0.},{-INF,0.},{U,U}, {INF,P12}, {N,N}},
+ {{INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {INF,P12}, {N,N}},
+ {{INF,-P14},{INF,-0.},{INF,-0.}, {INF,0.}, {INF,0.},{INF,P14}, {INF,N}},
+ {{INF,N}, {N,N}, {N,N}, {N,N}, {N,N}, {INF,N}, {N,N}}
+};
+
static Py_complex
-c_log(Py_complex x)
+c_log(Py_complex z)
{
+ /*
+ The usual formula for the real part is log(hypot(z.real, z.imag)).
+ There are four situations where this formula is potentially
+ problematic:
+
+ (1) the absolute value of z is subnormal. Then hypot is subnormal,
+ so has fewer than the usual number of bits of accuracy, hence may
+ have large relative error. This then gives a large absolute error
+ in the log. This can be solved by rescaling z by a suitable power
+ of 2.
+
+ (2) the absolute value of z is greater than DBL_MAX (e.g. when both
+ z.real and z.imag are within a factor of 1/sqrt(2) of DBL_MAX)
+ Again, rescaling solves this.
+
+ (3) the absolute value of z is close to 1. In this case it's
+ difficult to achieve good accuracy, at least in part because a
+ change of 1ulp in the real or imaginary part of z can result in a
+ change of billions of ulps in the correctly rounded answer.
+
+ (4) z = 0. The simplest thing to do here is to call the
+ floating-point log with an argument of 0, and let its behaviour
+ (returning -infinity, signaling a floating-point exception, setting
+ errno, or whatever) determine that of c_log. So the usual formula
+ is fine here.
+
+ */
+
Py_complex r;
- double l = hypot(x.real,x.imag);
- r.imag = atan2(x.imag, x.real);
- r.real = log(l);
+ double ax, ay, am, an, h;
+
+ SPECIAL_VALUE(z, log_special_values);
+
+ ax = fabs(z.real);
+ ay = fabs(z.imag);
+
+ if (ax > CM_LARGE_DOUBLE || ay > CM_LARGE_DOUBLE) {
+ r.real = log(hypot(ax/2., ay/2.)) + M_LN2;
+ } else if (ax < DBL_MIN && ay < DBL_MIN) {
+ if (ax > 0. || ay > 0.) {
+ /* catch cases where hypot(ax, ay) is subnormal */
+ r.real = log(hypot(ldexp(ax, DBL_MANT_DIG),
+ ldexp(ay, DBL_MANT_DIG))) - DBL_MANT_DIG*M_LN2;
+ }
+ else {
+ /* log(+/-0. +/- 0i) */
+ r.real = -INF;
+ r.imag = atan2(z.imag, z.real);
+ errno = EDOM;
+ return r;
+ }
+ } else {
+ h = hypot(ax, ay);
+ if (0.71 <= h && h <= 1.73) {
+ am = ax > ay ? ax : ay; /* max(ax, ay) */
+ an = ax > ay ? ay : ax; /* min(ax, ay) */
+ r.real = log1p((am-1)*(am+1)+an*an)/2.;
+ } else {
+ r.real = log(h);
+ }
+ }
+ r.imag = atan2(z.imag, z.real);
+ errno = 0;
return r;
}
static Py_complex
-c_log10(Py_complex x)
+c_log10(Py_complex z)
{
Py_complex r;
- double l = hypot(x.real,x.imag);
- r.imag = atan2(x.imag, x.real)/log(10.);
- r.real = log10(l);
+ int errno_save;
+
+ r = c_log(z);
+ errno_save = errno; /* just in case the divisions affect errno */
+ r.real = r.real / M_LN10;
+ r.imag = r.imag / M_LN10;
+ errno = errno_save;
return r;
}
@@ -182,23 +638,16 @@ PyDoc_STRVAR(c_log10_doc,
"Return the base-10 logarithm of x.");
-/* internal function not available from Python */
-static Py_complex
-c_prodi(Py_complex x)
-{
- Py_complex r;
- r.real = -x.imag;
- r.imag = x.real;
- return r;
-}
-
-
static Py_complex
-c_sin(Py_complex x)
+c_sin(Py_complex z)
{
- Py_complex r;
- r.real = sin(x.real) * cosh(x.imag);
- r.imag = cos(x.real) * sinh(x.imag);
+ /* sin(z) = -i sin(iz) */
+ Py_complex s, r;
+ s.real = -z.imag;
+ s.imag = z.real;
+ s = c_sinh(s);
+ r.real = s.imag;
+ r.imag = -s.real;
return r;
}
@@ -208,12 +657,63 @@ PyDoc_STRVAR(c_sin_doc,
"Return the sine of x.");
+/* sinh(infinity + i*y) needs to be dealt with specially */
+static Py_complex sinh_special_values[7][7] = {
+ {{INF,N},{U,U},{-INF,-0.},{-INF,0.},{U,U},{INF,N},{INF,N}},
+ {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
+ {{0.,N}, {U,U},{-0.,-0.}, {-0.,0.}, {U,U},{0.,N}, {0.,N}},
+ {{0.,N}, {U,U},{0.,-0.}, {0.,0.}, {U,U},{0.,N}, {0.,N}},
+ {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
+ {{INF,N},{U,U},{INF,-0.}, {INF,0.}, {U,U},{INF,N},{INF,N}},
+ {{N,N}, {N,N},{N,-0.}, {N,0.}, {N,N},{N,N}, {N,N}}
+};
+
static Py_complex
-c_sinh(Py_complex x)
+c_sinh(Py_complex z)
{
Py_complex r;
- r.real = cos(x.imag) * sinh(x.real);
- r.imag = sin(x.imag) * cosh(x.real);
+ double x_minus_one;
+
+ /* special treatment for sinh(+/-inf + iy) if y is finite and
+ nonzero */
+ if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
+ if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag)
+ && (z.imag != 0.)) {
+ if (z.real > 0) {
+ r.real = copysign(INF, cos(z.imag));
+ r.imag = copysign(INF, sin(z.imag));
+ }
+ else {
+ r.real = -copysign(INF, cos(z.imag));
+ r.imag = copysign(INF, sin(z.imag));
+ }
+ }
+ else {
+ r = sinh_special_values[special_type(z.real)]
+ [special_type(z.imag)];
+ }
+ /* need to set errno = EDOM if y is +/- infinity and x is not
+ a NaN */
+ if (Py_IS_INFINITY(z.imag) && !Py_IS_NAN(z.real))
+ errno = EDOM;
+ else
+ errno = 0;
+ return r;
+ }
+
+ if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) {
+ x_minus_one = z.real - copysign(1., z.real);
+ r.real = cos(z.imag) * sinh(x_minus_one) * Py_MATH_E;
+ r.imag = sin(z.imag) * cosh(x_minus_one) * Py_MATH_E;
+ } else {
+ r.real = cos(z.imag) * sinh(z.real);
+ r.imag = sin(z.imag) * cosh(z.real);
+ }
+ /* detect overflow, and set errno accordingly */
+ if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag))
+ errno = ERANGE;
+ else
+ errno = 0;
return r;
}
@@ -223,29 +723,80 @@ PyDoc_STRVAR(c_sinh_doc,
"Return the hyperbolic sine of x.");
+static Py_complex sqrt_special_values[7][7] = {
+ {{INF,-INF},{0.,-INF},{0.,-INF},{0.,INF},{0.,INF},{INF,INF},{N,INF}},
+ {{INF,-INF},{U,U}, {U,U}, {U,U}, {U,U}, {INF,INF},{N,N}},
+ {{INF,-INF},{U,U}, {0.,-0.}, {0.,0.}, {U,U}, {INF,INF},{N,N}},
+ {{INF,-INF},{U,U}, {0.,-0.}, {0.,0.}, {U,U}, {INF,INF},{N,N}},
+ {{INF,-INF},{U,U}, {U,U}, {U,U}, {U,U}, {INF,INF},{N,N}},
+ {{INF,-INF},{INF,-0.},{INF,-0.},{INF,0.},{INF,0.},{INF,INF},{INF,N}},
+ {{INF,-INF},{N,N}, {N,N}, {N,N}, {N,N}, {INF,INF},{N,N}}
+};
+
static Py_complex
-c_sqrt(Py_complex x)
+c_sqrt(Py_complex z)
{
+ /*
+ Method: use symmetries to reduce to the case when x = z.real and y
+ = z.imag are nonnegative. Then the real part of the result is
+ given by
+
+ s = sqrt((x + hypot(x, y))/2)
+
+ and the imaginary part is
+
+ d = (y/2)/s
+
+ If either x or y is very large then there's a risk of overflow in
+ computation of the expression x + hypot(x, y). We can avoid this
+ by rewriting the formula for s as:
+
+ s = 2*sqrt(x/8 + hypot(x/8, y/8))
+
+ This costs us two extra multiplications/divisions, but avoids the
+ overhead of checking for x and y large.
+
+ If both x and y are subnormal then hypot(x, y) may also be
+ subnormal, so will lack full precision. We solve this by rescaling
+ x and y by a sufficiently large power of 2 to ensure that x and y
+ are normal.
+ */
+
+
Py_complex r;
double s,d;
- if (x.real == 0. && x.imag == 0.)
- r = x;
- else {
- s = sqrt(0.5*(fabs(x.real) + hypot(x.real,x.imag)));
- d = 0.5*x.imag/s;
- if (x.real > 0.) {
- r.real = s;
- r.imag = d;
- }
- else if (x.imag >= 0.) {
- r.real = d;
- r.imag = s;
- }
- else {
- r.real = -d;
- r.imag = -s;
- }
+ double ax, ay;
+
+ SPECIAL_VALUE(z, sqrt_special_values);
+
+ if (z.real == 0. && z.imag == 0.) {
+ r.real = 0.;
+ r.imag = z.imag;
+ return r;
+ }
+
+ ax = fabs(z.real);
+ ay = fabs(z.imag);
+
+ if (ax < DBL_MIN && ay < DBL_MIN && (ax > 0. || ay > 0.)) {
+ /* here we catch cases where hypot(ax, ay) is subnormal */
+ ax = ldexp(ax, CM_SCALE_UP);
+ s = ldexp(sqrt(ax + hypot(ax, ldexp(ay, CM_SCALE_UP))),
+ CM_SCALE_DOWN);
+ } else {
+ ax /= 8.;
+ s = 2.*sqrt(ax + hypot(ax, ay/8.));
+ }
+ d = ay/(2.*s);
+
+ if (z.real >= 0.) {
+ r.real = s;
+ r.imag = copysign(d, z.imag);
+ } else {
+ r.real = d;
+ r.imag = copysign(s, z.imag);
}
+ errno = 0;
return r;
}
@@ -256,23 +807,15 @@ PyDoc_STRVAR(c_sqrt_doc,
static Py_complex
-c_tan(Py_complex x)
+c_tan(Py_complex z)
{
- Py_complex r;
- double sr,cr,shi,chi;
- double rs,is,rc,ic;
- double d;
- sr = sin(x.real);
- cr = cos(x.real);
- shi = sinh(x.imag);
- chi = cosh(x.imag);
- rs = sr * chi;
- is = cr * shi;
- rc = cr * chi;
- ic = -sr * shi;
- d = rc*rc + ic * ic;
- r.real = (rs*rc + is*ic) / d;
- r.imag = (is*rc - rs*ic) / d;
+ /* tan(z) = -i tanh(iz) */
+ Py_complex s, r;
+ s.real = -z.imag;
+ s.imag = z.real;
+ s = c_tanh(s);
+ r.real = s.imag;
+ r.imag = -s.real;
return r;
}
@@ -282,24 +825,78 @@ PyDoc_STRVAR(c_tan_doc,
"Return the tangent of x.");
+/* tanh(infinity + i*y) needs to be dealt with specially */
+static Py_complex tanh_special_values[7][7] = {
+ {{-1.,0.},{U,U},{-1.,-0.},{-1.,0.},{U,U},{-1.,0.},{-1.,0.}},
+ {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
+ {{N,N}, {U,U},{-0.,-0.},{-0.,0.},{U,U},{N,N}, {N,N}},
+ {{N,N}, {U,U},{0.,-0.}, {0.,0.}, {U,U},{N,N}, {N,N}},
+ {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
+ {{1.,0.}, {U,U},{1.,-0.}, {1.,0.}, {U,U},{1.,0.}, {1.,0.}},
+ {{N,N}, {N,N},{N,-0.}, {N,0.}, {N,N},{N,N}, {N,N}}
+};
+
static Py_complex
-c_tanh(Py_complex x)
+c_tanh(Py_complex z)
{
+ /* Formula:
+
+ tanh(x+iy) = (tanh(x)(1+tan(y)^2) + i tan(y)(1-tanh(x))^2) /
+ (1+tan(y)^2 tanh(x)^2)
+
+ To avoid excessive roundoff error, 1-tanh(x)^2 is better computed
+ as 1/cosh(x)^2. When abs(x) is large, we approximate 1-tanh(x)^2
+ by 4 exp(-2*x) instead, to avoid possible overflow in the
+ computation of cosh(x).
+
+ */
+
Py_complex r;
- double si,ci,shr,chr;
- double rs,is,rc,ic;
- double d;
- si = sin(x.imag);
- ci = cos(x.imag);
- shr = sinh(x.real);
- chr = cosh(x.real);
- rs = ci * shr;
- is = si * chr;
- rc = ci * chr;
- ic = si * shr;
- d = rc*rc + ic*ic;
- r.real = (rs*rc + is*ic) / d;
- r.imag = (is*rc - rs*ic) / d;
+ double tx, ty, cx, txty, denom;
+
+ /* special treatment for tanh(+/-inf + iy) if y is finite and
+ nonzero */
+ if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
+ if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag)
+ && (z.imag != 0.)) {
+ if (z.real > 0) {
+ r.real = 1.0;
+ r.imag = copysign(0.,
+ 2.*sin(z.imag)*cos(z.imag));
+ }
+ else {
+ r.real = -1.0;
+ r.imag = copysign(0.,
+ 2.*sin(z.imag)*cos(z.imag));
+ }
+ }
+ else {
+ r = tanh_special_values[special_type(z.real)]
+ [special_type(z.imag)];
+ }
+ /* need to set errno = EDOM if z.imag is +/-infinity and
+ z.real is finite */
+ if (Py_IS_INFINITY(z.imag) && Py_IS_FINITE(z.real))
+ errno = EDOM;
+ else
+ errno = 0;
+ return r;
+ }
+
+ /* danger of overflow in 2.*z.imag !*/
+ if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) {
+ r.real = copysign(1., z.real);
+ r.imag = 4.*sin(z.imag)*cos(z.imag)*exp(-2.*fabs(z.real));
+ } else {
+ tx = tanh(z.real);
+ ty = tan(z.imag);
+ cx = 1./cosh(z.real);
+ txty = tx*ty;
+ denom = 1. + txty*txty;
+ r.real = tx*(1.+ty*ty)/denom;
+ r.imag = ((ty/denom)*cx)*cx;
+ }
+ errno = 0;
return r;
}
@@ -308,6 +905,7 @@ PyDoc_STRVAR(c_tanh_doc,
"\n"
"Return the hyperbolic tangent of x.");
+
static PyObject *
cmath_log(PyObject *self, PyObject *args)
{
@@ -325,7 +923,6 @@ cmath_log(PyObject *self, PyObject *args)
PyFPE_END_PROTECT(x)
if (errno != 0)
return math_error();
- Py_ADJUST_ERANGE2(x.real, x.imag);
return PyComplex_FromCComplex(x);
}
@@ -351,18 +948,24 @@ math_error(void)
static PyObject *
math_1(PyObject *args, Py_complex (*func)(Py_complex))
{
- Py_complex x;
+ Py_complex x,r ;
if (!PyArg_ParseTuple(args, "D", &x))
return NULL;
errno = 0;
- PyFPE_START_PROTECT("complex function", return 0)
- x = (*func)(x);
- PyFPE_END_PROTECT(x)
- Py_ADJUST_ERANGE2(x.real, x.imag);
- if (errno != 0)
- return math_error();
- else
- return PyComplex_FromCComplex(x);
+ PyFPE_START_PROTECT("complex function", return 0);
+ r = (*func)(x);
+ PyFPE_END_PROTECT(r);
+ if (errno == EDOM) {
+ PyErr_SetString(PyExc_ValueError, "math domain error");
+ return NULL;
+ }
+ else if (errno == ERANGE) {
+ PyErr_SetString(PyExc_OverflowError, "math range error");
+ return NULL;
+ }
+ else {
+ return PyComplex_FromCComplex(r);
+ }
}
#define FUNC1(stubname, func) \
@@ -386,6 +989,151 @@ FUNC1(cmath_sqrt, c_sqrt)
FUNC1(cmath_tan, c_tan)
FUNC1(cmath_tanh, c_tanh)
+static PyObject *
+cmath_phase(PyObject *self, PyObject *args)
+{
+ Py_complex z;
+ double phi;
+ if (!PyArg_ParseTuple(args, "D:phase", &z))
+ return NULL;
+ errno = 0;
+ PyFPE_START_PROTECT("arg function", return 0)
+ phi = c_atan2(z);
+ PyFPE_END_PROTECT(r)
+ if (errno != 0)
+ return math_error();
+ else
+ return PyFloat_FromDouble(phi);
+}
+
+PyDoc_STRVAR(cmath_phase_doc,
+"phase(z) -> float\n\n\
+Return argument, also known as the phase angle, of a complex.");
+
+static PyObject *
+cmath_polar(PyObject *self, PyObject *args)
+{
+ Py_complex z;
+ double r, phi;
+ if (!PyArg_ParseTuple(args, "D:polar", &z))
+ return NULL;
+ PyFPE_START_PROTECT("polar function", return 0)
+ phi = c_atan2(z); /* should not cause any exception */
+ r = c_abs(z); /* sets errno to ERANGE on overflow; otherwise 0 */
+ PyFPE_END_PROTECT(r)
+ if (errno != 0)
+ return math_error();
+ else
+ return Py_BuildValue("dd", r, phi);
+}
+
+PyDoc_STRVAR(cmath_polar_doc,
+"polar(z) -> r: float, phi: float\n\n\
+Convert a complex from rectangular coordinates to polar coordinates. r is\n\
+the distance from 0 and phi the phase angle.");
+
+/*
+ rect() isn't covered by the C99 standard, but it's not too hard to
+ figure out 'spirit of C99' rules for special value handing:
+
+ rect(x, t) should behave like exp(log(x) + it) for positive-signed x
+ rect(x, t) should behave like -exp(log(-x) + it) for negative-signed x
+ rect(nan, t) should behave like exp(nan + it), except that rect(nan, 0)
+ gives nan +- i0 with the sign of the imaginary part unspecified.
+
+*/
+
+static Py_complex rect_special_values[7][7] = {
+ {{INF,N},{U,U},{-INF,0.},{-INF,-0.},{U,U},{INF,N},{INF,N}},
+ {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
+ {{0.,0.},{U,U},{-0.,0.}, {-0.,-0.}, {U,U},{0.,0.},{0.,0.}},
+ {{0.,0.},{U,U},{0.,-0.}, {0.,0.}, {U,U},{0.,0.},{0.,0.}},
+ {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
+ {{INF,N},{U,U},{INF,-0.},{INF,0.}, {U,U},{INF,N},{INF,N}},
+ {{N,N}, {N,N},{N,0.}, {N,0.}, {N,N},{N,N}, {N,N}}
+};
+
+static PyObject *
+cmath_rect(PyObject *self, PyObject *args)
+{
+ Py_complex z;
+ double r, phi;
+ if (!PyArg_ParseTuple(args, "dd:rect", &r, &phi))
+ return NULL;
+ errno = 0;
+ PyFPE_START_PROTECT("rect function", return 0)
+
+ /* deal with special values */
+ if (!Py_IS_FINITE(r) || !Py_IS_FINITE(phi)) {
+ /* if r is +/-infinity and phi is finite but nonzero then
+ result is (+-INF +-INF i), but we need to compute cos(phi)
+ and sin(phi) to figure out the signs. */
+ if (Py_IS_INFINITY(r) && (Py_IS_FINITE(phi)
+ && (phi != 0.))) {
+ if (r > 0) {
+ z.real = copysign(INF, cos(phi));
+ z.imag = copysign(INF, sin(phi));
+ }
+ else {
+ z.real = -copysign(INF, cos(phi));
+ z.imag = -copysign(INF, sin(phi));
+ }
+ }
+ else {
+ z = rect_special_values[special_type(r)]
+ [special_type(phi)];
+ }
+ /* need to set errno = EDOM if r is a nonzero number and phi
+ is infinite */
+ if (r != 0. && !Py_IS_NAN(r) && Py_IS_INFINITY(phi))
+ errno = EDOM;
+ else
+ errno = 0;
+ }
+ else {
+ z.real = r * cos(phi);
+ z.imag = r * sin(phi);
+ errno = 0;
+ }
+
+ PyFPE_END_PROTECT(z)
+ if (errno != 0)
+ return math_error();
+ else
+ return PyComplex_FromCComplex(z);
+}
+
+PyDoc_STRVAR(cmath_rect_doc,
+"rect(r, phi) -> z: complex\n\n\
+Convert from polar coordinates to rectangular coordinates.");
+
+static PyObject *
+cmath_isnan(PyObject *self, PyObject *args)
+{
+ Py_complex z;
+ if (!PyArg_ParseTuple(args, "D:isnan", &z))
+ return NULL;
+ return PyBool_FromLong(Py_IS_NAN(z.real) || Py_IS_NAN(z.imag));
+}
+
+PyDoc_STRVAR(cmath_isnan_doc,
+"isnan(z) -> bool\n\
+Checks if the real or imaginary part of z not a number (NaN)");
+
+static PyObject *
+cmath_isinf(PyObject *self, PyObject *args)
+{
+ Py_complex z;
+ if (!PyArg_ParseTuple(args, "D:isnan", &z))
+ return NULL;
+ return PyBool_FromLong(Py_IS_INFINITY(z.real) ||
+ Py_IS_INFINITY(z.imag));
+}
+
+PyDoc_STRVAR(cmath_isinf_doc,
+"isinf(z) -> bool\n\
+Checks if the real or imaginary part of z is infinite.");
+
PyDoc_STRVAR(module_doc,
"This module is always available. It provides access to mathematical\n"
@@ -401,8 +1149,13 @@ static PyMethodDef cmath_methods[] = {
{"cos", cmath_cos, METH_VARARGS, c_cos_doc},
{"cosh", cmath_cosh, METH_VARARGS, c_cosh_doc},
{"exp", cmath_exp, METH_VARARGS, c_exp_doc},
+ {"isinf", cmath_isinf, METH_VARARGS, cmath_isinf_doc},
+ {"isnan", cmath_isnan, METH_VARARGS, cmath_isnan_doc},
{"log", cmath_log, METH_VARARGS, cmath_log_doc},
{"log10", cmath_log10, METH_VARARGS, c_log10_doc},
+ {"phase", cmath_phase, METH_VARARGS, cmath_phase_doc},
+ {"polar", cmath_polar, METH_VARARGS, cmath_polar_doc},
+ {"rect", cmath_rect, METH_VARARGS, cmath_rect_doc},
{"sin", cmath_sin, METH_VARARGS, c_sin_doc},
{"sinh", cmath_sinh, METH_VARARGS, c_sinh_doc},
{"sqrt", cmath_sqrt, METH_VARARGS, c_sqrt_doc},
@@ -421,6 +1174,6 @@ initcmath(void)
return;
PyModule_AddObject(m, "pi",
- PyFloat_FromDouble(atan(1.0) * 4.0));
- PyModule_AddObject(m, "e", PyFloat_FromDouble(exp(1.0)));
+ PyFloat_FromDouble(Py_MATH_PI));
+ PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E));
}
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index cf2bf64..8c48316 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -1,17 +1,60 @@
/* Math module -- standard C math library functions, pi and e */
+/* Here are some comments from Tim Peters, extracted from the
+ discussion attached to http://bugs.python.org/issue1640. They
+ describe the general aims of the math module with respect to
+ special values, IEEE-754 floating-point exceptions, and Python
+ exceptions.
+
+These are the "spirit of 754" rules:
+
+1. If the mathematical result is a real number, but of magnitude too
+large to approximate by a machine float, overflow is signaled and the
+result is an infinity (with the appropriate sign).
+
+2. If the mathematical result is a real number, but of magnitude too
+small to approximate by a machine float, underflow is signaled and the
+result is a zero (with the appropriate sign).
+
+3. At a singularity (a value x such that the limit of f(y) as y
+approaches x exists and is an infinity), "divide by zero" is signaled
+and the result is an infinity (with the appropriate sign). This is
+complicated a little by that the left-side and right-side limits may
+not be the same; e.g., 1/x approaches +inf or -inf as x approaches 0
+from the positive or negative directions. In that specific case, the
+sign of the zero determines the result of 1/0.
+
+4. At a point where a function has no defined result in the extended
+reals (i.e., the reals plus an infinity or two), invalid operation is
+signaled and a NaN is returned.
+
+And these are what Python has historically /tried/ to do (but not
+always successfully, as platform libm behavior varies a lot):
+
+For #1, raise OverflowError.
+
+For #2, return a zero (with the appropriate sign if that happens by
+accident ;-)).
+
+For #3 and #4, raise ValueError. It may have made sense to raise
+Python's ZeroDivisionError in #3, but historically that's only been
+raised for division by zero and mod by zero.
+
+*/
+
+/*
+ In general, on an IEEE-754 platform the aim is to follow the C99
+ standard, including Annex 'F', whenever possible. Where the
+ standard recommends raising the 'divide-by-zero' or 'invalid'
+ floating-point exceptions, Python should raise a ValueError. Where
+ the standard recommends raising 'overflow', Python should raise an
+ OverflowError. In all other circumstances a value should be
+ returned.
+ */
+
#include "Python.h"
#include "longintrepr.h" /* just for SHIFT */
-#ifndef _MSC_VER
-#ifndef __STDC__
-extern double fmod (double, double);
-extern double frexp (double, int *);
-extern double ldexp (double, int);
-extern double modf (double, double *);
-#endif /* __STDC__ */
-#endif /* _MSC_VER */
-
#ifdef _OSF_SOURCE
/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */
extern double copysign(double, double);
@@ -52,41 +95,111 @@ is_error(double x)
return result;
}
+/*
+ math_1 is used to wrap a libm function f that takes a double
+ arguments and returns a double.
+
+ The error reporting follows these rules, which are designed to do
+ the right thing on C89/C99 platforms and IEEE 754/non IEEE 754
+ platforms.
+
+ - a NaN result from non-NaN inputs causes ValueError to be raised
+ - an infinite result from finite inputs causes OverflowError to be
+ raised if can_overflow is 1, or raises ValueError if can_overflow
+ is 0.
+ - if the result is finite and errno == EDOM then ValueError is
+ raised
+ - if the result is finite and nonzero and errno == ERANGE then
+ OverflowError is raised
+
+ The last rule is used to catch overflow on platforms which follow
+ C89 but for which HUGE_VAL is not an infinity.
+
+ For the majority of one-argument functions these rules are enough
+ to ensure that Python's functions behave as specified in 'Annex F'
+ of the C99 standard, with the 'invalid' and 'divide-by-zero'
+ floating-point exceptions mapping to Python's ValueError and the
+ 'overflow' floating-point exception mapping to OverflowError.
+ math_1 only works for functions that don't have singularities *and*
+ the possibility of overflow; fortunately, that covers everything we
+ care about right now.
+*/
+
static PyObject *
math_1_to_whatever(PyObject *arg, double (*func) (double),
- PyObject *(*from_double_func) (double))
+ PyObject *(*from_double_func) (double),
+ int can_overflow)
{
- double x = PyFloat_AsDouble(arg);
+ double x, r;
+ x = PyFloat_AsDouble(arg);
if (x == -1.0 && PyErr_Occurred())
return NULL;
errno = 0;
- PyFPE_START_PROTECT("in math_1", return 0)
- x = (*func)(x);
- PyFPE_END_PROTECT(x)
- Py_SET_ERRNO_ON_MATH_ERROR(x);
- if (errno && is_error(x))
+ PyFPE_START_PROTECT("in math_1", return 0);
+ r = (*func)(x);
+ PyFPE_END_PROTECT(r);
+ if (Py_IS_NAN(r)) {
+ if (!Py_IS_NAN(x))
+ errno = EDOM;
+ else
+ errno = 0;
+ }
+ else if (Py_IS_INFINITY(r)) {
+ if (Py_IS_FINITE(x))
+ errno = can_overflow ? ERANGE : EDOM;
+ else
+ errno = 0;
+ }
+ if (errno && is_error(r))
return NULL;
else
- return (*from_double_func)(x);
+ return (*from_double_func)(r);
}
+/*
+ math_2 is used to wrap a libm function f that takes two double
+ arguments and returns a double.
+
+ The error reporting follows these rules, which are designed to do
+ the right thing on C89/C99 platforms and IEEE 754/non IEEE 754
+ platforms.
+
+ - a NaN result from non-NaN inputs causes ValueError to be raised
+ - an infinite result from finite inputs causes OverflowError to be
+ raised.
+ - if the result is finite and errno == EDOM then ValueError is
+ raised
+ - if the result is finite and nonzero and errno == ERANGE then
+ OverflowError is raised
+
+ The last rule is used to catch overflow on platforms which follow
+ C89 but for which HUGE_VAL is not an infinity.
+
+ For most two-argument functions (copysign, fmod, hypot, atan2)
+ these rules are enough to ensure that Python's functions behave as
+ specified in 'Annex F' of the C99 standard, with the 'invalid' and
+ 'divide-by-zero' floating-point exceptions mapping to Python's
+ ValueError and the 'overflow' floating-point exception mapping to
+ OverflowError.
+*/
+
static PyObject *
-math_1(PyObject *arg, double (*func) (double))
+math_1(PyObject *arg, double (*func) (double), int can_overflow)
{
- return math_1_to_whatever(arg, func, PyFloat_FromDouble);
+ return math_1_to_whatever(arg, func, PyFloat_FromDouble, can_overflow);
}
static PyObject *
-math_1_to_int(PyObject *arg, double (*func) (double))
+math_1_to_int(PyObject *arg, double (*func) (double), int can_overflow)
{
- return math_1_to_whatever(arg, func, PyLong_FromDouble);
+ return math_1_to_whatever(arg, func, PyLong_FromDouble, can_overflow);
}
static PyObject *
math_2(PyObject *args, double (*func) (double, double), char *funcname)
{
PyObject *ox, *oy;
- double x, y;
+ double x, y, r;
if (! PyArg_UnpackTuple(args, funcname, 2, 2, &ox, &oy))
return NULL;
x = PyFloat_AsDouble(ox);
@@ -94,19 +207,30 @@ math_2(PyObject *args, double (*func) (double, double), char *funcname)
if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
return NULL;
errno = 0;
- PyFPE_START_PROTECT("in math_2", return 0)
- x = (*func)(x, y);
- PyFPE_END_PROTECT(x)
- Py_SET_ERRNO_ON_MATH_ERROR(x);
- if (errno && is_error(x))
+ PyFPE_START_PROTECT("in math_2", return 0);
+ r = (*func)(x, y);
+ PyFPE_END_PROTECT(r);
+ if (Py_IS_NAN(r)) {
+ if (!Py_IS_NAN(x) && !Py_IS_NAN(y))
+ errno = EDOM;
+ else
+ errno = 0;
+ }
+ else if (Py_IS_INFINITY(r)) {
+ if (Py_IS_FINITE(x) && Py_IS_FINITE(y))
+ errno = ERANGE;
+ else
+ errno = 0;
+ }
+ if (errno && is_error(r))
return NULL;
else
- return PyFloat_FromDouble(x);
+ return PyFloat_FromDouble(r);
}
-#define FUNC1(funcname, func, docstring) \
+#define FUNC1(funcname, func, can_overflow, docstring) \
static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
- return math_1(args, func); \
+ return math_1(args, func, can_overflow); \
}\
PyDoc_STRVAR(math_##funcname##_doc, docstring);
@@ -116,15 +240,21 @@ math_2(PyObject *args, double (*func) (double, double), char *funcname)
}\
PyDoc_STRVAR(math_##funcname##_doc, docstring);
-FUNC1(acos, acos,
+FUNC1(acos, acos, 0,
"acos(x)\n\nReturn the arc cosine (measured in radians) of x.")
-FUNC1(asin, asin,
+FUNC1(acosh, acosh, 0,
+ "acosh(x)\n\nReturn the hyperbolic arc cosine (measured in radians) of x.")
+FUNC1(asin, asin, 0,
"asin(x)\n\nReturn the arc sine (measured in radians) of x.")
-FUNC1(atan, atan,
+FUNC1(asinh, asinh, 0,
+ "asinh(x)\n\nReturn the hyperbolic arc sine (measured in radians) of x.")
+FUNC1(atan, atan, 0,
"atan(x)\n\nReturn the arc tangent (measured in radians) of x.")
FUNC2(atan2, atan2,
"atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n"
"Unlike atan(y/x), the signs of both x and y are considered.")
+FUNC1(atanh, atanh, 0,
+ "atanh(x)\n\nReturn the hyperbolic arc tangent (measured in radians) of x.")
static PyObject * math_ceil(PyObject *self, PyObject *number) {
static PyObject *ceil_str = NULL;
@@ -138,7 +268,7 @@ static PyObject * math_ceil(PyObject *self, PyObject *number) {
method = _PyType_Lookup(Py_TYPE(number), ceil_str);
if (method == NULL)
- return math_1_to_int(number, ceil);
+ return math_1_to_int(number, ceil, 0);
else
return PyObject_CallFunction(method, "O", number);
}
@@ -147,23 +277,15 @@ PyDoc_STRVAR(math_ceil_doc,
"ceil(x)\n\nReturn the ceiling of x as an int.\n"
"This is the smallest integral value >= x.");
-FUNC1(cos, cos,
+FUNC2(copysign, copysign,
+ "copysign(x,y)\n\nReturn x with the sign of y.")
+FUNC1(cos, cos, 0,
"cos(x)\n\nReturn the cosine of x (measured in radians).")
-FUNC1(cosh, cosh,
+FUNC1(cosh, cosh, 1,
"cosh(x)\n\nReturn the hyperbolic cosine of x.")
-
-#ifdef MS_WINDOWS
-# define copysign _copysign
-# define HAVE_COPYSIGN 1
-#endif
-#ifdef HAVE_COPYSIGN
-FUNC2(copysign, copysign,
- "copysign(x,y)\n\nReturn x with the sign of y.");
-#endif
-
-FUNC1(exp, exp,
+FUNC1(exp, exp, 1,
"exp(x)\n\nReturn e raised to the power of x.")
-FUNC1(fabs, fabs,
+FUNC1(fabs, fabs, 0,
"fabs(x)\n\nReturn the absolute value of the float x.")
static PyObject * math_floor(PyObject *self, PyObject *number) {
@@ -178,7 +300,7 @@ static PyObject * math_floor(PyObject *self, PyObject *number) {
method = _PyType_Lookup(Py_TYPE(number), floor_str);
if (method == NULL)
- return math_1_to_int(number, floor);
+ return math_1_to_int(number, floor, 0);
else
return PyObject_CallFunction(method, "O", number);
}
@@ -187,22 +309,18 @@ PyDoc_STRVAR(math_floor_doc,
"floor(x)\n\nReturn the floor of x as an int.\n"
"This is the largest integral value <= x.");
-FUNC2(fmod, fmod,
- "fmod(x,y)\n\nReturn fmod(x, y), according to platform C."
- " x % y may differ.")
-FUNC2(hypot, hypot,
- "hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).")
-FUNC2(pow, pow,
- "pow(x,y)\n\nReturn x**y (x to the power of y).")
-FUNC1(sin, sin,
+FUNC1(log1p, log1p, 1,
+ "log1p(x)\n\nReturn the natural logarithm of 1+x (base e).\n\
+ The result is computed in a way which is accurate for x near zero.")
+FUNC1(sin, sin, 0,
"sin(x)\n\nReturn the sine of x (measured in radians).")
-FUNC1(sinh, sinh,
+FUNC1(sinh, sinh, 1,
"sinh(x)\n\nReturn the hyperbolic sine of x.")
-FUNC1(sqrt, sqrt,
+FUNC1(sqrt, sqrt, 0,
"sqrt(x)\n\nReturn the square root of x.")
-FUNC1(tan, tan,
+FUNC1(tan, tan, 0,
"tan(x)\n\nReturn the tangent of x (measured in radians).")
-FUNC1(tanh, tanh,
+FUNC1(tanh, tanh, 0,
"tanh(x)\n\nReturn the hyperbolic tangent of x.")
static PyObject *
@@ -244,13 +362,17 @@ math_frexp(PyObject *self, PyObject *arg)
double x = PyFloat_AsDouble(arg);
if (x == -1.0 && PyErr_Occurred())
return NULL;
- errno = 0;
- x = frexp(x, &i);
- Py_SET_ERRNO_ON_MATH_ERROR(x);
- if (errno && is_error(x))
- return NULL;
- else
- return Py_BuildValue("(di)", x, i);
+ /* deal with special cases directly, to sidestep platform
+ differences */
+ if (Py_IS_NAN(x) || Py_IS_INFINITY(x) || !x) {
+ i = 0;
+ }
+ else {
+ PyFPE_START_PROTECT("in math_frexp", return 0);
+ x = frexp(x, &i);
+ PyFPE_END_PROTECT(x);
+ }
+ return Py_BuildValue("(di)", x, i);
}
PyDoc_STRVAR(math_frexp_doc,
@@ -263,19 +385,24 @@ PyDoc_STRVAR(math_frexp_doc,
static PyObject *
math_ldexp(PyObject *self, PyObject *args)
{
- double x;
+ double x, r;
int exp;
if (! PyArg_ParseTuple(args, "di:ldexp", &x, &exp))
return NULL;
errno = 0;
- PyFPE_START_PROTECT("ldexp", return 0)
- x = ldexp(x, exp);
- PyFPE_END_PROTECT(x)
- Py_SET_ERRNO_ON_MATH_ERROR(x);
- if (errno && is_error(x))
+ PyFPE_START_PROTECT("in math_ldexp", return 0)
+ r = ldexp(x, exp);
+ PyFPE_END_PROTECT(r)
+ if (Py_IS_FINITE(x) && Py_IS_INFINITY(r))
+ errno = ERANGE;
+ /* Windows MSVC8 sets errno = EDOM on ldexp(NaN, i);
+ we unset it to avoid raising a ValueError here. */
+ if (errno == EDOM)
+ errno = 0;
+ if (errno && is_error(r))
return NULL;
else
- return PyFloat_FromDouble(x);
+ return PyFloat_FromDouble(r);
}
PyDoc_STRVAR(math_ldexp_doc,
@@ -288,12 +415,10 @@ math_modf(PyObject *self, PyObject *arg)
if (x == -1.0 && PyErr_Occurred())
return NULL;
errno = 0;
+ PyFPE_START_PROTECT("in math_modf", return 0);
x = modf(x, &y);
- Py_SET_ERRNO_ON_MATH_ERROR(x);
- if (errno && is_error(x))
- return NULL;
- else
- return Py_BuildValue("(dd)", x, y);
+ PyFPE_END_PROTECT(x);
+ return Py_BuildValue("(dd)", x, y);
}
PyDoc_STRVAR(math_modf_doc,
@@ -332,7 +457,7 @@ loghelper(PyObject* arg, double (*func)(double), char *funcname)
}
/* Else let libm handle it by itself. */
- return math_1(arg, func);
+ return math_1(arg, func, 0);
}
static PyObject *
@@ -375,6 +500,141 @@ math_log10(PyObject *self, PyObject *arg)
PyDoc_STRVAR(math_log10_doc,
"log10(x) -> the base 10 logarithm of x.");
+static PyObject *
+math_fmod(PyObject *self, PyObject *args)
+{
+ PyObject *ox, *oy;
+ double r, x, y;
+ if (! PyArg_UnpackTuple(args, "fmod", 2, 2, &ox, &oy))
+ return NULL;
+ x = PyFloat_AsDouble(ox);
+ y = PyFloat_AsDouble(oy);
+ if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
+ return NULL;
+ /* fmod(x, +/-Inf) returns x for finite x. */
+ if (Py_IS_INFINITY(y) && Py_IS_FINITE(x))
+ return PyFloat_FromDouble(x);
+ errno = 0;
+ PyFPE_START_PROTECT("in math_fmod", return 0);
+ r = fmod(x, y);
+ PyFPE_END_PROTECT(r);
+ if (Py_IS_NAN(r)) {
+ if (!Py_IS_NAN(x) && !Py_IS_NAN(y))
+ errno = EDOM;
+ else
+ errno = 0;
+ }
+ if (errno && is_error(r))
+ return NULL;
+ else
+ return PyFloat_FromDouble(r);
+}
+
+PyDoc_STRVAR(math_fmod_doc,
+"fmod(x,y)\n\nReturn fmod(x, y), according to platform C."
+" x % y may differ.");
+
+static PyObject *
+math_hypot(PyObject *self, PyObject *args)
+{
+ PyObject *ox, *oy;
+ double r, x, y;
+ if (! PyArg_UnpackTuple(args, "hypot", 2, 2, &ox, &oy))
+ return NULL;
+ x = PyFloat_AsDouble(ox);
+ y = PyFloat_AsDouble(oy);
+ if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
+ return NULL;
+ /* hypot(x, +/-Inf) returns Inf, even if x is a NaN. */
+ if (Py_IS_INFINITY(x))
+ return PyFloat_FromDouble(fabs(x));
+ if (Py_IS_INFINITY(y))
+ return PyFloat_FromDouble(fabs(y));
+ errno = 0;
+ PyFPE_START_PROTECT("in math_hypot", return 0);
+ r = hypot(x, y);
+ PyFPE_END_PROTECT(r);
+ if (Py_IS_NAN(r)) {
+ if (!Py_IS_NAN(x) && !Py_IS_NAN(y))
+ errno = EDOM;
+ else
+ errno = 0;
+ }
+ else if (Py_IS_INFINITY(r)) {
+ if (Py_IS_FINITE(x) && Py_IS_FINITE(y))
+ errno = ERANGE;
+ else
+ errno = 0;
+ }
+ if (errno && is_error(r))
+ return NULL;
+ else
+ return PyFloat_FromDouble(r);
+}
+
+PyDoc_STRVAR(math_hypot_doc,
+"hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).");
+
+/* pow can't use math_2, but needs its own wrapper: the problem is
+ that an infinite result can arise either as a result of overflow
+ (in which case OverflowError should be raised) or as a result of
+ e.g. 0.**-5. (for which ValueError needs to be raised.)
+*/
+
+static PyObject *
+math_pow(PyObject *self, PyObject *args)
+{
+ PyObject *ox, *oy;
+ double r, x, y;
+
+ if (! PyArg_UnpackTuple(args, "pow", 2, 2, &ox, &oy))
+ return NULL;
+ x = PyFloat_AsDouble(ox);
+ y = PyFloat_AsDouble(oy);
+ if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
+ return NULL;
+ /* 1**x and x**0 return 1., even if x is a NaN or infinity. */
+ if (x == 1.0 || y == 0.0)
+ return PyFloat_FromDouble(1.);
+ errno = 0;
+ PyFPE_START_PROTECT("in math_pow", return 0);
+ r = pow(x, y);
+ PyFPE_END_PROTECT(r);
+ if (Py_IS_NAN(r)) {
+ if (!Py_IS_NAN(x) && !Py_IS_NAN(y))
+ errno = EDOM;
+ else
+ errno = 0;
+ }
+ /* an infinite result arises either from:
+
+ (A) (+/-0.)**negative,
+ (B) overflow of x**y with both x and y finite (and x nonzero)
+ (C) (+/-inf)**positive, or
+ (D) x**inf with |x| > 1, or x**-inf with |x| < 1.
+
+ In case (A) we want ValueError to be raised. In case (B)
+ OverflowError should be raised. In cases (C) and (D) the infinite
+ result should be returned.
+ */
+ else if (Py_IS_INFINITY(r)) {
+ if (x == 0.)
+ errno = EDOM;
+ else if (Py_IS_FINITE(x) && Py_IS_FINITE(y))
+ errno = ERANGE;
+ else
+ errno = 0;
+ }
+
+ if (errno && is_error(r))
+ return NULL;
+ else
+ return PyFloat_FromDouble(r);
+}
+
+PyDoc_STRVAR(math_pow_doc,
+"pow(x,y)\n\nReturn x**y (x to the power of y).");
+
static const double degToRad = Py_MATH_PI / 180.0;
static const double radToDeg = 180.0 / Py_MATH_PI;
@@ -428,16 +688,16 @@ PyDoc_STRVAR(math_isinf_doc,
"isinf(x) -> bool\n\
Checks if float x is infinite (positive or negative)");
-
static PyMethodDef math_methods[] = {
{"acos", math_acos, METH_O, math_acos_doc},
+ {"acosh", math_acosh, METH_O, math_acosh_doc},
{"asin", math_asin, METH_O, math_asin_doc},
+ {"asinh", math_asinh, METH_O, math_asinh_doc},
{"atan", math_atan, METH_O, math_atan_doc},
{"atan2", math_atan2, METH_VARARGS, math_atan2_doc},
+ {"atanh", math_atanh, METH_O, math_atanh_doc},
{"ceil", math_ceil, METH_O, math_ceil_doc},
-#ifdef HAVE_COPYSIGN
{"copysign", math_copysign, METH_VARARGS, math_copysign_doc},
-#endif
{"cos", math_cos, METH_O, math_cos_doc},
{"cosh", math_cosh, METH_O, math_cosh_doc},
{"degrees", math_degrees, METH_O, math_degrees_doc},
@@ -451,6 +711,7 @@ static PyMethodDef math_methods[] = {
{"isnan", math_isnan, METH_O, math_isnan_doc},
{"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc},
{"log", math_log, METH_VARARGS, math_log_doc},
+ {"log1p", math_log1p, METH_O, math_log1p_doc},
{"log10", math_log10, METH_O, math_log10_doc},
{"modf", math_modf, METH_O, math_modf_doc},
{"pow", math_pow, METH_VARARGS, math_pow_doc},
@@ -472,27 +733,15 @@ PyDoc_STRVAR(module_doc,
PyMODINIT_FUNC
initmath(void)
{
- PyObject *m, *d, *v;
+ PyObject *m;
m = Py_InitModule3("math", math_methods, module_doc);
if (m == NULL)
goto finally;
- d = PyModule_GetDict(m);
- if (d == NULL)
- goto finally;
-
- if (!(v = PyFloat_FromDouble(Py_MATH_PI)))
- goto finally;
- if (PyDict_SetItemString(d, "pi", v) < 0)
- goto finally;
- Py_DECREF(v);
- if (!(v = PyFloat_FromDouble(Py_MATH_E)))
- goto finally;
- if (PyDict_SetItemString(d, "e", v) < 0)
- goto finally;
- Py_DECREF(v);
+ PyModule_AddObject(m, "pi", PyFloat_FromDouble(Py_MATH_PI));
+ PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E));
- finally:
+ finally:
return;
}
diff --git a/Objects/complexobject.c b/Objects/complexobject.c
index 90b970e..acd5a4a 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -187,6 +187,38 @@ c_powi(Py_complex x, long n)
}
+double
+c_abs(Py_complex z)
+{
+ /* sets errno = ERANGE on overflow; otherwise errno = 0 */
+ double result;
+
+ if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
+ /* C99 rules: if either the real or the imaginary part is an
+ infinity, return infinity, even if the other part is a
+ NaN. */
+ if (Py_IS_INFINITY(z.real)) {
+ result = fabs(z.real);
+ errno = 0;
+ return result;
+ }
+ if (Py_IS_INFINITY(z.imag)) {
+ result = fabs(z.imag);
+ errno = 0;
+ return result;
+ }
+ /* either the real or imaginary part is a NaN,
+ and neither is infinite. Result should be NaN. */
+ return Py_NAN;
+ }
+ result = hypot(z.real, z.imag);
+ if (!Py_IS_FINITE(result))
+ errno = ERANGE;
+ else
+ errno = 0;
+ return result;
+}
+
static PyObject *
complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
{
@@ -321,8 +353,7 @@ complex_to_buf(char *buf, int bufsz, PyComplexObject *v, int precision)
if (!Py_IS_FINITE(v->cval.imag)) {
if (Py_IS_NAN(v->cval.imag))
strncpy(buf, "nan*j", 6);
- /* else if (copysign(1, v->cval.imag) == 1) */
- else if (v->cval.imag > 0)
+ else if (copysign(1, v->cval.imag) == 1)
strncpy(buf, "inf*j", 6);
else
strncpy(buf, "-inf*j", 7);
@@ -578,9 +609,16 @@ static PyObject *
complex_abs(PyComplexObject *v)
{
double result;
+
PyFPE_START_PROTECT("complex_abs", return 0)
- result = hypot(v->cval.real,v->cval.imag);
+ result = c_abs(v->cval);
PyFPE_END_PROTECT(result)
+
+ if (errno == ERANGE) {
+ PyErr_SetString(PyExc_OverflowError,
+ "absolute value too large");
+ return NULL;
+ }
return PyFloat_FromDouble(result);
}
@@ -658,9 +696,29 @@ complex_getnewargs(PyComplexObject *v)
return Py_BuildValue("(D)", &v->cval);
}
+#if 0
+static PyObject *
+complex_is_finite(PyObject *self)
+{
+ Py_complex c;
+ c = ((PyComplexObject *)self)->cval;
+ return PyBool_FromLong((long)(Py_IS_FINITE(c.real) &&
+ Py_IS_FINITE(c.imag)));
+}
+
+PyDoc_STRVAR(complex_is_finite_doc,
+"complex.is_finite() -> bool\n"
+"\n"
+"Returns True if the real and the imaginary part is finite.");
+#endif
+
static PyMethodDef complex_methods[] = {
{"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS,
complex_conjugate_doc},
+#if 0
+ {"is_finite", (PyCFunction)complex_is_finite, METH_NOARGS,
+ complex_is_finite_doc},
+#endif
{"__getnewargs__", (PyCFunction)complex_getnewargs, METH_NOARGS},
{NULL, NULL} /* sentinel */
};
diff --git a/Objects/doubledigits.c b/Objects/doubledigits.c
deleted file mode 100644
index 1f1c91c..0000000
--- a/Objects/doubledigits.c
+++ /dev/null
@@ -1,601 +0,0 @@
-/* Free-format floating point printer
- *
- * Based on "Floating-Point Printer Sample Code", by Robert G. Burger,
- * http://www.cs.indiana.edu/~burger/fp/index.html
- */
-
-#include "Python.h"
-
-#if defined(__alpha) || defined(__i386) || defined(_M_IX86) || defined(_M_X64) || defined(_M_IA64)
-#define LITTLE_ENDIAN_IEEE_DOUBLE
-#elif !(defined(__ppc__) || defined(sparc) || defined(__sgi) || defined(_IBMR2) || defined(hpux))
-#error unknown machine type
-#endif
-
-#if defined(_M_IX86)
-#define UNSIGNED64 unsigned __int64
-#elif defined(__alpha)
-#define UNSIGNED64 unsigned long
-#else
-#define UNSIGNED64 unsigned long long
-#endif
-
-#ifndef U32
-#define U32 unsigned int
-#endif
-
-/* exponent stored + 1024, hidden bit to left of decimal point */
-#define bias 1023
-#define bitstoright 52
-#define m1mask 0xf
-#define hidden_bit 0x100000
-#ifdef LITTLE_ENDIAN_IEEE_DOUBLE
-struct dblflt {
- unsigned int m4: 16;
- unsigned int m3: 16;
- unsigned int m2: 16;
- unsigned int m1: 4;
- unsigned int e: 11;
- unsigned int s: 1;
-};
-#else
-/* Big Endian IEEE Double Floats */
-struct dblflt {
- unsigned int s: 1;
- unsigned int e: 11;
- unsigned int m1: 4;
- unsigned int m2: 16;
- unsigned int m3: 16;
- unsigned int m4: 16;
-};
-#endif
-#define float_radix 2.147483648e9
-
-
-typedef UNSIGNED64 Bigit;
-#define BIGSIZE 24
-#define MIN_E -1074
-#define MAX_FIVE 325
-#define B_P1 ((Bigit)1 << 52)
-
-typedef struct {
- int l;
- Bigit d[BIGSIZE];
-} Bignum;
-
-static Bignum R, S, MP, MM, five[MAX_FIVE];
-static Bignum S2, S3, S4, S5, S6, S7, S8, S9;
-static int ruf, k, s_n, use_mp, qr_shift, sl, slr;
-
-static void mul10(Bignum *x);
-static void big_short_mul(Bignum *x, Bigit y, Bignum *z);
-/*
-static void print_big(Bignum *x);
-*/
-static int estimate(int n);
-static void one_shift_left(int y, Bignum *z);
-static void short_shift_left(Bigit x, int y, Bignum *z);
-static void big_shift_left(Bignum *x, int y, Bignum *z);
-static int big_comp(Bignum *x, Bignum *y);
-static int sub_big(Bignum *x, Bignum *y, Bignum *z);
-static void add_big(Bignum *x, Bignum *y, Bignum *z);
-static int add_cmp(void);
-static int qr(void);
-
-/*static int _PyFloat_Digits(char *buf, double v, int *signum);*/
-/*static void _PyFloat_DigitsInit(void);*/
-
-#define ADD(x, y, z, k) {\
- Bigit x_add, z_add;\
- x_add = (x);\
- if ((k))\
- z_add = x_add + (y) + 1, (k) = (z_add <= x_add);\
- else\
- z_add = x_add + (y), (k) = (z_add < x_add);\
- (z) = z_add;\
-}
-
-#define SUB(x, y, z, b) {\
- Bigit x_sub, y_sub;\
- x_sub = (x); y_sub = (y);\
- if ((b))\
- (z) = x_sub - y_sub - 1, b = (y_sub >= x_sub);\
- else\
- (z) = x_sub - y_sub, b = (y_sub > x_sub);\
-}
-
-#define MUL(x, y, z, k) {\
- Bigit x_mul, low, high;\
- x_mul = (x);\
- low = (x_mul & 0xffffffff) * (y) + (k);\
- high = (x_mul >> 32) * (y) + (low >> 32);\
- (k) = high >> 32;\
- (z) = (low & 0xffffffff) | (high << 32);\
-}
-
-#define SLL(x, y, z, k) {\
- Bigit x_sll = (x);\
- (z) = (x_sll << (y)) | (k);\
- (k) = x_sll >> (64 - (y));\
-}
-
-static void
-mul10(Bignum *x)
-{
- int i, l;
- Bigit *p, k;
-
- l = x->l;
- for (i = l, p = &x->d[0], k = 0; i >= 0; i--)
- MUL(*p, 10, *p++, k);
- if (k != 0)
- *p = k, x->l = l+1;
-}
-
-static void
-big_short_mul(Bignum *x, Bigit y, Bignum *z)
-{
- int i, xl, zl;
- Bigit *xp, *zp, k;
- U32 high, low;
-
- xl = x->l;
- xp = &x->d[0];
- zl = xl;
- zp = &z->d[0];
- high = y >> 32;
- low = y & 0xffffffff;
- for (i = xl, k = 0; i >= 0; i--, xp++, zp++) {
- Bigit xlow, xhigh, z0, t, c, z1;
- xlow = *xp & 0xffffffff;
- xhigh = *xp >> 32;
- z0 = (xlow * low) + k; /* Cout is (z0 < k) */
- t = xhigh * low;
- z1 = (xlow * high) + t;
- c = (z1 < t);
- t = z0 >> 32;
- z1 += t;
- c += (z1 < t);
- *zp = (z1 << 32) | (z0 & 0xffffffff);
- k = (xhigh * high) + (c << 32) + (z1 >> 32) + (z0 < k);
- }
- if (k != 0)
- *zp = k, zl++;
- z->l = zl;
-}
-
-/*
-static void
-print_big(Bignum *x)
-{
- int i;
- Bigit *p;
-
- printf("#x");
- i = x->l;
- p = &x->d[i];
- for (p = &x->d[i]; i >= 0; i--) {
- Bigit b = *p--;
- printf("%08x%08x", (int)(b >> 32), (int)(b & 0xffffffff));
- }
-}
-*/
-
-static int
-estimate(int n)
-{
- if (n < 0)
- return (int)(n*0.3010299956639812);
- else
- return 1+(int)(n*0.3010299956639811);
-}
-
-static void
-one_shift_left(int y, Bignum *z)
-{
- int n, m, i;
- Bigit *zp;
-
- n = y / 64;
- m = y % 64;
- zp = &z->d[0];
- for (i = n; i > 0; i--) *zp++ = 0;
- *zp = (Bigit)1 << m;
- z->l = n;
-}
-
-static void
-short_shift_left(Bigit x, int y, Bignum *z)
-{
- int n, m, i, zl;
- Bigit *zp;
-
- n = y / 64;
- m = y % 64;
- zl = n;
- zp = &(z->d[0]);
- for (i = n; i > 0; i--) *zp++ = 0;
- if (m == 0)
- *zp = x;
- else {
- Bigit high = x >> (64 - m);
- *zp = x << m;
- if (high != 0)
- *++zp = high, zl++;
- }
- z->l = zl;
-}
-
-static void
-big_shift_left(Bignum *x, int y, Bignum *z)
-{
- int n, m, i, xl, zl;
- Bigit *xp, *zp, k;
-
- n = y / 64;
- m = y % 64;
- xl = x->l;
- xp = &(x->d[0]);
- zl = xl + n;
- zp = &(z->d[0]);
- for (i = n; i > 0; i--) *zp++ = 0;
- if (m == 0)
- for (i = xl; i >= 0; i--) *zp++ = *xp++;
- else {
- for (i = xl, k = 0; i >= 0; i--)
- SLL(*xp++, m, *zp++, k);
- if (k != 0)
- *zp = k, zl++;
- }
- z->l = zl;
-}
-
-
-static int
-big_comp(Bignum *x, Bignum *y)
-{
- int i, xl, yl;
- Bigit *xp, *yp;
-
- xl = x->l;
- yl = y->l;
- if (xl > yl) return 1;
- if (xl < yl) return -1;
- xp = &x->d[xl];
- yp = &y->d[xl];
- for (i = xl; i >= 0; i--, xp--, yp--) {
- Bigit a = *xp;
- Bigit b = *yp;
-
- if (a > b) return 1;
- else if (a < b) return -1;
- }
- return 0;
-}
-
-static int
-sub_big(Bignum *x, Bignum *y, Bignum *z)
-{
- int xl, yl, zl, b, i;
- Bigit *xp, *yp, *zp;
-
- xl = x->l;
- yl = y->l;
- if (yl > xl) return 1;
- xp = &x->d[0];
- yp = &y->d[0];
- zp = &z->d[0];
-
- for (i = yl, b = 0; i >= 0; i--)
- SUB(*xp++, *yp++, *zp++, b);
- for (i = xl-yl; b && i > 0; i--) {
- Bigit x_sub;
- x_sub = *xp++;
- *zp++ = x_sub - 1;
- b = (x_sub == 0);
- }
- for (; i > 0; i--) *zp++ = *xp++;
- if (b) return 1;
- zl = xl;
- while (*--zp == 0) zl--;
- z->l = zl;
- return 0;
-}
-
-static void
-add_big(Bignum *x, Bignum *y, Bignum *z)
-{
- int xl, yl, k, i;
- Bigit *xp, *yp, *zp;
-
- xl = x->l;
- yl = y->l;
- if (yl > xl) {
- int tl;
- Bignum *tn;
- tl = xl; xl = yl; yl = tl;
- tn = x; x = y; y = tn;
- }
-
- xp = &x->d[0];
- yp = &y->d[0];
- zp = &z->d[0];
-
- for (i = yl, k = 0; i >= 0; i--)
- ADD(*xp++, *yp++, *zp++, k);
- for (i = xl-yl; k && i > 0; i--) {
- Bigit z_add;
- z_add = *xp++ + 1;
- k = (z_add == 0);
- *zp++ = z_add;
- }
- for (; i > 0; i--) *zp++ = *xp++;
- if (k)
- *zp = 1, z->l = xl+1;
- else
- z->l = xl;
-}
-
-static int
-add_cmp()
-{
- int rl, ml, sl, suml;
- static Bignum sum;
-
- rl = R.l;
- ml = (use_mp ? MP.l : MM.l);
- sl = S.l;
-
- suml = rl >= ml ? rl : ml;
- if ((sl > suml+1) || ((sl == suml+1) && (S.d[sl] > 1))) return -1;
- if (sl < suml) return 1;
-
- add_big(&R, (use_mp ? &MP : &MM), &sum);
- return big_comp(&sum, &S);
-}
-
-static int
-qr()
-{
- if (big_comp(&R, &S5) < 0)
- if (big_comp(&R, &S2) < 0)
- if (big_comp(&R, &S) < 0)
- return 0;
- else {
- sub_big(&R, &S, &R);
- return 1;
- }
- else if (big_comp(&R, &S3) < 0) {
- sub_big(&R, &S2, &R);
- return 2;
- }
- else if (big_comp(&R, &S4) < 0) {
- sub_big(&R, &S3, &R);
- return 3;
- }
- else {
- sub_big(&R, &S4, &R);
- return 4;
- }
- else if (big_comp(&R, &S7) < 0)
- if (big_comp(&R, &S6) < 0) {
- sub_big(&R, &S5, &R);
- return 5;
- }
- else {
- sub_big(&R, &S6, &R);
- return 6;
- }
- else if (big_comp(&R, &S9) < 0)
- if (big_comp(&R, &S8) < 0) {
- sub_big(&R, &S7, &R);
- return 7;
- }
- else {
- sub_big(&R, &S8, &R);
- return 8;
- }
- else {
- sub_big(&R, &S9, &R);
- return 9;
- }
-}
-
-#define OUTDIG(d) { *buf++ = (d) + '0'; *buf = 0; return k; }
-
-int
-_PyFloat_Digits(char *buf, double v, int *signum)
-{
- struct dblflt *x;
- int sign, e, f_n, m_n, i, d, tc1, tc2;
- Bigit f;
-
- /* decompose float into sign, mantissa & exponent */
- x = (struct dblflt *)&v;
- sign = x->s;
- e = x->e;
- f = (Bigit)(x->m1 << 16 | x->m2) << 32 | (U32)(x->m3 << 16 | x->m4);
- if (e != 0) {
- e = e - bias - bitstoright;
- f |= (Bigit)hidden_bit << 32;
- }
- else if (f != 0)
- /* denormalized */
- e = 1 - bias - bitstoright;
-
- *signum = sign;
- if (f == 0) {
- *buf++ = '0';
- *buf = 0;
- return 0;
- }
-
- ruf = !(f & 1); /* ruf = (even? f) */
-
- /* Compute the scaling factor estimate, k */
- if (e > MIN_E)
- k = estimate(e+52);
- else {
- int n;
- Bigit y;
-
- for (n = e+52, y = (Bigit)1 << 52; f < y; n--) y >>= 1;
- k = estimate(n);
- }
-
- if (e >= 0)
- if (f != B_P1)
- use_mp = 0, f_n = e+1, s_n = 1, m_n = e;
- else
- use_mp = 1, f_n = e+2, s_n = 2, m_n = e;
- else
- if ((e == MIN_E) || (f != B_P1))
- use_mp = 0, f_n = 1, s_n = 1-e, m_n = 0;
- else
- use_mp = 1, f_n = 2, s_n = 2-e, m_n = 0;
-
- /* Scale it! */
- if (k == 0) {
- short_shift_left(f, f_n, &R);
- one_shift_left(s_n, &S);
- one_shift_left(m_n, &MM);
- if (use_mp) one_shift_left(m_n+1, &MP);
- qr_shift = 1;
- }
- else if (k > 0) {
- s_n += k;
- if (m_n >= s_n)
- f_n -= s_n, m_n -= s_n, s_n = 0;
- else
- f_n -= m_n, s_n -= m_n, m_n = 0;
- short_shift_left(f, f_n, &R);
- big_shift_left(&five[k-1], s_n, &S);
- one_shift_left(m_n, &MM);
- if (use_mp) one_shift_left(m_n+1, &MP);
- qr_shift = 0;
- }
- else {
- Bignum *power = &five[-k-1];
-
- s_n += k;
- big_short_mul(power, f, &S);
- big_shift_left(&S, f_n, &R);
- one_shift_left(s_n, &S);
- big_shift_left(power, m_n, &MM);
- if (use_mp) big_shift_left(power, m_n+1, &MP);
- qr_shift = 1;
- }
-
- /* fixup */
- if (add_cmp() <= -ruf) {
- k--;
- mul10(&R);
- mul10(&MM);
- if (use_mp) mul10(&MP);
- }
-
- /*
- printf("\nk = %d\n", k);
- printf("R = "); print_big(&R);
- printf("\nS = "); print_big(&S);
- printf("\nM- = "); print_big(&MM);
- if (use_mp) printf("\nM+ = "), print_big(&MP);
- putchar('\n');
- fflush(0);
- */
-
- if (qr_shift) {
- sl = s_n / 64;
- slr = s_n % 64;
- }
- else {
- big_shift_left(&S, 1, &S2);
- add_big(&S2, &S, &S3);
- big_shift_left(&S2, 1, &S4);
- add_big(&S4, &S, &S5);
- add_big(&S4, &S2, &S6);
- add_big(&S4, &S3, &S7);
- big_shift_left(&S4, 1, &S8);
- add_big(&S8, &S, &S9);
- }
-
-again:
- if (qr_shift) { /* Take advantage of the fact that S = (ash 1 s_n) */
- if (R.l < sl)
- d = 0;
- else if (R.l == sl) {
- Bigit *p;
-
- p = &R.d[sl];
- d = *p >> slr;
- *p &= ((Bigit)1 << slr) - 1;
- for (i = sl; (i > 0) && (*p == 0); i--) p--;
- R.l = i;
- }
- else {
- Bigit *p;
-
- p = &R.d[sl+1];
- d = *p << (64 - slr) | *(p-1) >> slr;
- p--;
- *p &= ((Bigit)1 << slr) - 1;
- for (i = sl; (i > 0) && (*p == 0); i--) p--;
- R.l = i;
- }
- }
- else /* We need to do quotient-remainder */
- d = qr();
-
- tc1 = big_comp(&R, &MM) < ruf;
- tc2 = add_cmp() > -ruf;
- if (!tc1)
- if (!tc2) {
- mul10(&R);
- mul10(&MM);
- if (use_mp) mul10(&MP);
- *buf++ = d + '0';
- goto again;
- }
- else
- OUTDIG(d+1)
- else
- if (!tc2)
- OUTDIG(d)
- else {
- big_shift_left(&R, 1, &MM);
- if (big_comp(&MM, &S) == -1)
- OUTDIG(d)
- else
- OUTDIG(d+1)
- }
-}
-
-void
-_PyFloat_DigitsInit()
-{
- int n, i, l;
- Bignum *b;
- Bigit *xp, *zp, k;
-
- five[0].l = l = 0;
- five[0].d[0] = 5;
- for (n = MAX_FIVE-1, b = &five[0]; n > 0; n--) {
- xp = &b->d[0];
- b++;
- zp = &b->d[0];
- for (i = l, k = 0; i >= 0; i--)
- MUL(*xp++, 5, *zp++, k);
- if (k != 0)
- *zp = k, l++;
- b->l = l;
- }
-
- /*
- for (n = 1, b = &five[0]; n <= MAX_FIVE; n++) {
- big_shift_left(b++, n, &R);
- print_big(&R);
- putchar('\n');
- }
- fflush(0);
- */
-}
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 745dfc3..a748abb 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -16,10 +16,6 @@
#include <ieeefp.h>
#endif
-#if !defined(__STDC__)
-extern double fmod(double, double);
-extern double pow(double, double);
-#endif
#ifdef _OSF_SOURCE
/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */
@@ -224,11 +220,11 @@ PyFloat_FromString(PyObject *v)
p++;
}
if (PyOS_strnicmp(p, "inf", 4) == 0) {
- return PyFloat_FromDouble(sign * Py_HUGE_VAL);
+ Py_RETURN_INF(sign);
}
#ifdef Py_NAN
if(PyOS_strnicmp(p, "nan", 4) == 0) {
- return PyFloat_FromDouble(Py_NAN);
+ Py_RETURN_NAN;
}
#endif
PyOS_snprintf(buffer, sizeof(buffer),
@@ -378,110 +374,6 @@ format_float(char *buf, size_t buflen, PyFloatObject *v, int precision)
format_double(buf, buflen, PyFloat_AS_DOUBLE(v), precision);
}
-#ifdef Py_BROKEN_REPR
-/* The following function is based on Tcl_PrintDouble,
- * from tclUtil.c.
- */
-
-#define is_infinite(d) ( (d) > DBL_MAX || (d) < -DBL_MAX )
-#define is_nan(d) ((d) != (d))
-
-static void
-format_double_repr(char *dst, double value)
-{
- char *p, c;
- int exp;
- int signum;
- char buffer[30];
-
- /*
- * Handle NaN.
- */
-
- if (is_nan(value)) {
- strcpy(dst, "nan");
- return;
- }
-
- /*
- * Handle infinities.
- */
-
- if (is_infinite(value)) {
- if (value < 0) {
- strcpy(dst, "-inf");
- } else {
- strcpy(dst, "inf");
- }
- return;
- }
-
- /*
- * Ordinary (normal and denormal) values.
- */
-
- exp = _PyFloat_Digits(buffer, value, &signum)+1;
- if (signum) {
- *dst++ = '-';
- }
- p = buffer;
- if (exp < -3 || exp > 17) {
- /*
- * E format for numbers < 1e-3 or >= 1e17.
- */
-
- *dst++ = *p++;
- c = *p;
- if (c != '\0') {
- *dst++ = '.';
- while (c != '\0') {
- *dst++ = c;
- c = *++p;
- }
- }
- sprintf(dst, "e%+d", exp-1);
- } else {
- /*
- * F format for others.
- */
-
- if (exp <= 0) {
- *dst++ = '0';
- }
- c = *p;
- while (exp-- > 0) {
- if (c != '\0') {
- *dst++ = c;
- c = *++p;
- } else {
- *dst++ = '0';
- }
- }
- *dst++ = '.';
- if (c == '\0') {
- *dst++ = '0';
- } else {
- while (++exp < 0) {
- *dst++ = '0';
- }
- while (c != '\0') {
- *dst++ = c;
- c = *++p;
- }
- }
- *dst++ = '\0';
- }
-}
-
-static void
-format_float_repr(char *buf, PyFloatObject *v)
-{
- assert(PyFloat_Check(v));
- format_double_repr(buf, PyFloat_AS_DOUBLE(v));
-}
-
-#endif /* Py_BROKEN_REPR */
-
/* Macro and helper that convert PyObject obj to a C double and store
the value in dbl. If conversion to double raises an exception, obj is
set to NULL, and the function invoking this macro returns NULL. If
@@ -534,13 +426,8 @@ convert_to_double(PyObject **v, double *dbl)
static PyObject *
float_repr(PyFloatObject *v)
{
-#ifdef Py_BROKEN_REPR
- char buf[30];
- format_float_repr(buf, v);
-#else
char buf[100];
format_float(buf, sizeof(buf), v, PREC_REPR);
-#endif
return PyUnicode_FromString(buf);
}
@@ -804,10 +691,13 @@ float_div(PyObject *v, PyObject *w)
double a,b;
CONVERT_TO_DOUBLE(v, a);
CONVERT_TO_DOUBLE(w, b);
+#ifdef Py_NAN
if (b == 0.0) {
- PyErr_SetString(PyExc_ZeroDivisionError, "float division");
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "float division");
return NULL;
}
+#endif
PyFPE_START_PROTECT("divide", return 0)
a = a / b;
PyFPE_END_PROTECT(a)
@@ -819,12 +709,15 @@ float_rem(PyObject *v, PyObject *w)
{
double vx, wx;
double mod;
- CONVERT_TO_DOUBLE(v, vx);
- CONVERT_TO_DOUBLE(w, wx);
+ CONVERT_TO_DOUBLE(v, vx);
+ CONVERT_TO_DOUBLE(w, wx);
+#ifdef Py_NAN
if (wx == 0.0) {
- PyErr_SetString(PyExc_ZeroDivisionError, "float modulo");
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "float modulo");
return NULL;
}
+#endif
PyFPE_START_PROTECT("modulo", return 0)
mod = fmod(vx, wx);
/* note: checking mod*wx < 0 is incorrect -- underflows to
@@ -928,6 +821,9 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
}
return PyFloat_FromDouble(0.0);
}
+ if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */
+ return PyFloat_FromDouble(1.0);
+ }
if (iv < 0.0) {
/* Whether this is an error is a mess, and bumps into libm
* bugs so we have to figure it out ourselves.
@@ -995,6 +891,57 @@ float_bool(PyFloatObject *v)
}
static PyObject *
+float_is_integer(PyObject *v)
+{
+ double x = PyFloat_AsDouble(v);
+ PyObject *o;
+
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+ if (!Py_IS_FINITE(x))
+ Py_RETURN_FALSE;
+ PyFPE_START_PROTECT("is_integer", return NULL)
+ o = (floor(x) == x) ? Py_True : Py_False;
+ PyFPE_END_PROTECT(x)
+ if (errno != 0) {
+ PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :
+ PyExc_ValueError);
+ return NULL;
+ }
+ Py_INCREF(o);
+ return o;
+}
+
+#if 0
+static PyObject *
+float_is_inf(PyObject *v)
+{
+ double x = PyFloat_AsDouble(v);
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+ return PyBool_FromLong((long)Py_IS_INFINITY(x));
+}
+
+static PyObject *
+float_is_nan(PyObject *v)
+{
+ double x = PyFloat_AsDouble(v);
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+ return PyBool_FromLong((long)Py_IS_NAN(x));
+}
+
+static PyObject *
+float_is_finite(PyObject *v)
+{
+ double x = PyFloat_AsDouble(v);
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+ return PyBool_FromLong((long)Py_IS_FINITE(x));
+}
+#endif
+
+static PyObject *
float_trunc(PyObject *v)
{
double x = PyFloat_AsDouble(v);
@@ -1368,7 +1315,7 @@ PyDoc_STRVAR(float__format__doc,
static PyMethodDef float_methods[] = {
- {"conjugate", (PyCFunction)float_float, METH_NOARGS,
+ {"conjugate", (PyCFunction)float_float, METH_NOARGS,
"Returns self, the complex conjugate of any float."},
{"__trunc__", (PyCFunction)float_trunc, METH_NOARGS,
"Returns the Integral closest to x between 0 and x."},
@@ -1377,6 +1324,16 @@ static PyMethodDef float_methods[] = {
"When an argument is passed, works like built-in round(x, ndigits)."},
{"as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS,
float_as_integer_ratio_doc},
+ {"is_integer", (PyCFunction)float_is_integer, METH_NOARGS,
+ "Returns True if the float is an integer."},
+#if 0
+ {"is_inf", (PyCFunction)float_is_inf, METH_NOARGS,
+ "Returns True if the float is positive or negative infinite."},
+ {"is_finite", (PyCFunction)float_is_finite, METH_NOARGS,
+ "Returns True if the float is finite, neither infinite nor NaN."},
+ {"is_nan", (PyCFunction)float_is_nan, METH_NOARGS,
+ "Returns True if the float is not a number (NaN)."},
+#endif
{"__getnewargs__", (PyCFunction)float_getnewargs, METH_NOARGS},
{"__getformat__", (PyCFunction)float_getformat,
METH_O|METH_CLASS, float_getformat_doc},
@@ -1534,10 +1491,6 @@ _PyFloat_Init(void)
double_format = detected_double_format;
float_format = detected_float_format;
-#ifdef Py_BROKEN_REPR
- /* Initialize floating point repr */
- _PyFloat_DigitsInit();
-#endif
/* Init float info */
if (FloatInfoType.tp_name == 0)
PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc);
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 44b040c..d88a13e 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -3611,9 +3611,21 @@ long_round(PyObject *self, PyObject *args)
#undef UNDEF_NDIGITS
}
+#if 0
+static PyObject *
+long_is_finite(PyObject *v)
+{
+ Py_RETURN_TRUE;
+}
+#endif
+
static PyMethodDef long_methods[] = {
{"conjugate", (PyCFunction)long_long, METH_NOARGS,
"Returns self, the complex conjugate of any int."},
+#if 0
+ {"is_finite", (PyCFunction)long_is_finite, METH_NOARGS,
+ "Returns always True."},
+#endif
{"__trunc__", (PyCFunction)long_long, METH_NOARGS,
"Truncating an Integral returns itself."},
{"__floor__", (PyCFunction)long_long, METH_NOARGS,
diff --git a/PC/VC6/pythoncore.dsp b/PC/VC6/pythoncore.dsp
index de8860f..969e9df 100644
--- a/PC/VC6/pythoncore.dsp
+++ b/PC/VC6/pythoncore.dsp
@@ -587,6 +587,10 @@ SOURCE=..\..\Python\pyfpe.c
# End Source File
# Begin Source File
+SOURCE=..\..\Python\pymath.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Python\pystate.c
# End Source File
# Begin Source File
diff --git a/PC/VS7.1/pythoncore.vcproj b/PC/VS7.1/pythoncore.vcproj
index 304b119..cc46faf 100644
--- a/PC/VS7.1/pythoncore.vcproj
+++ b/PC/VS7.1/pythoncore.vcproj
@@ -698,6 +698,9 @@
RelativePath="..\..\Python\pyfpe.c">
</File>
<File
+ RelativePath="..\..\Python\pymath.c">
+ </File>
+ <File
RelativePath="..\..\Python\pystate.c">
</File>
<File
diff --git a/PC/VS8.0/pythoncore.vcproj b/PC/VS8.0/pythoncore.vcproj
index b63ed88..6bc4715 100644
--- a/PC/VS8.0/pythoncore.vcproj
+++ b/PC/VS8.0/pythoncore.vcproj
@@ -1707,6 +1707,10 @@
>
</File>
<File
+ RelativePath="..\..\Python\pymath.c"
+ >
+ </File>
+ <File
RelativePath="..\..\Python\pystate.c"
>
</File>
diff --git a/PC/pyconfig.h b/PC/pyconfig.h
index 4291192..e38e823 100644
--- a/PC/pyconfig.h
+++ b/PC/pyconfig.h
@@ -207,12 +207,13 @@ typedef _W64 int ssize_t;
#endif /* MS_WIN32 && !MS_WIN64 */
typedef int pid_t;
-#define hypot _hypot
#include <float.h>
#define Py_IS_NAN _isnan
#define Py_IS_INFINITY(X) (!_finite(X) && !_isnan(X))
#define Py_IS_FINITE(X) _finite(X)
+#define copysign _copysign
+#define hypot _hypot
#endif /* _MSC_VER */
@@ -392,7 +393,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
/* Fairly standard from here! */
/* Define to 1 if you have the `copysign' function. */
-/* #define HAVE_COPYSIGN 1*/
+#define HAVE_COPYSIGN 1
/* Define to 1 if you have the `isinf' function. */
#define HAVE_ISINF 1
diff --git a/PCbuild/pythoncore.vcproj b/PCbuild/pythoncore.vcproj
index 1f69bca..c93bc71 100644
--- a/PCbuild/pythoncore.vcproj
+++ b/PCbuild/pythoncore.vcproj
@@ -871,6 +871,10 @@
>
</File>
<File
+ RelativePath="..\Include\pymath.h"
+ >
+ </File>
+ <File
RelativePath="..\Include\pymem.h"
>
</File>
@@ -1707,6 +1711,10 @@
>
</File>
<File
+ RelativePath="..\Python\pymath.c"
+ >
+ </File>
+ <File
RelativePath="..\Python\pystate.c"
>
</File>
diff --git a/Python/hypot.c b/Python/hypot.c
deleted file mode 100644
index a18ce16..0000000
--- a/Python/hypot.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* hypot() replacement */
-
-#include "Python.h"
-
-#ifndef HAVE_HYPOT
-double hypot(double x, double y)
-{
- double yx;
-
- x = fabs(x);
- y = fabs(y);
- if (x < y) {
- double temp = x;
- x = y;
- y = temp;
- }
- if (x == 0.)
- return 0.;
- else {
- yx = y/x;
- return x*sqrt(1.+yx*yx);
- }
-}
-#endif /* HAVE_HYPOT */
-
diff --git a/Python/pymath.c b/Python/pymath.c
new file mode 100644
index 0000000..7c00106
--- /dev/null
+++ b/Python/pymath.c
@@ -0,0 +1,232 @@
+#include "Python.h"
+
+#ifndef HAVE_HYPOT
+double hypot(double x, double y)
+{
+ double yx;
+
+ x = fabs(x);
+ y = fabs(y);
+ if (x < y) {
+ double temp = x;
+ x = y;
+ y = temp;
+ }
+ if (x == 0.)
+ return 0.;
+ else {
+ yx = y/x;
+ return x*sqrt(1.+yx*yx);
+ }
+}
+#endif /* HAVE_HYPOT */
+
+#ifndef HAVE_COPYSIGN
+static double
+copysign(double x, double y)
+{
+ /* use atan2 to distinguish -0. from 0. */
+ if (y > 0. || (y == 0. && atan2(y, -1.) > 0.)) {
+ return fabs(x);
+ } else {
+ return -fabs(x);
+ }
+}
+#endif /* HAVE_COPYSIGN */
+
+#ifndef HAVE_LOG1P
+double
+log1p(double x)
+{
+ /* For x small, we use the following approach. Let y be the nearest
+ float to 1+x, then
+
+ 1+x = y * (1 - (y-1-x)/y)
+
+ so log(1+x) = log(y) + log(1-(y-1-x)/y). Since (y-1-x)/y is tiny,
+ the second term is well approximated by (y-1-x)/y. If abs(x) >=
+ DBL_EPSILON/2 or the rounding-mode is some form of round-to-nearest
+ then y-1-x will be exactly representable, and is computed exactly
+ by (y-1)-x.
+
+ If abs(x) < DBL_EPSILON/2 and the rounding mode is not known to be
+ round-to-nearest then this method is slightly dangerous: 1+x could
+ be rounded up to 1+DBL_EPSILON instead of down to 1, and in that
+ case y-1-x will not be exactly representable any more and the
+ result can be off by many ulps. But this is easily fixed: for a
+ floating-point number |x| < DBL_EPSILON/2., the closest
+ floating-point number to log(1+x) is exactly x.
+ */
+
+ double y;
+ if (fabs(x) < DBL_EPSILON/2.) {
+ return x;
+ } else if (-0.5 <= x && x <= 1.) {
+ /* WARNING: it's possible than an overeager compiler
+ will incorrectly optimize the following two lines
+ to the equivalent of "return log(1.+x)". If this
+ happens, then results from log1p will be inaccurate
+ for small x. */
+ y = 1.+x;
+ return log(y)-((y-1.)-x)/y;
+ } else {
+ /* NaNs and infinities should end up here */
+ return log(1.+x);
+ }
+}
+#endif /* HAVE_LOG1P */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+static const double ln2 = 6.93147180559945286227E-01;
+static const double two_pow_m28 = 3.7252902984619141E-09; /* 2**-28 */
+static const double two_pow_p28 = 268435456.0; /* 2**28 */
+static const double zero = 0.0;
+
+/* asinh(x)
+ * Method :
+ * Based on
+ * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
+ * we have
+ * asinh(x) := x if 1+x*x=1,
+ * := sign(x)*(log(x)+ln2)) for large |x|, else
+ * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
+ * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))
+ */
+
+#ifndef HAVE_ASINH
+double
+asinh(double x)
+{
+ double w;
+ double absx = fabs(x);
+
+ if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) {
+ return x+x;
+ }
+ if (absx < two_pow_m28) { /* |x| < 2**-28 */
+ return x; /* return x inexact except 0 */
+ }
+ if (absx > two_pow_p28) { /* |x| > 2**28 */
+ w = log(absx)+ln2;
+ }
+ else if (absx > 2.0) { /* 2 < |x| < 2**28 */
+ w = log(2.0*absx + 1.0 / (sqrt(x*x + 1.0) + absx));
+ }
+ else { /* 2**-28 <= |x| < 2= */
+ double t = x*x;
+ w = log1p(absx + t / (1.0 + sqrt(1.0 + t)));
+ }
+ return copysign(w, x);
+
+}
+#endif /* HAVE_ASINH */
+
+/* acosh(x)
+ * Method :
+ * Based on
+ * acosh(x) = log [ x + sqrt(x*x-1) ]
+ * we have
+ * acosh(x) := log(x)+ln2, if x is large; else
+ * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
+ * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
+ *
+ * Special cases:
+ * acosh(x) is NaN with signal if x<1.
+ * acosh(NaN) is NaN without signal.
+ */
+
+#ifndef HAVE_ACOSH
+double
+acosh(double x)
+{
+ if (Py_IS_NAN(x)) {
+ return x+x;
+ }
+ if (x < 1.) { /* x < 1; return a signaling NaN */
+ errno = EDOM;
+#ifdef Py_NAN
+ return Py_NAN;
+#else
+ return (x-x)/(x-x);
+#endif
+ }
+ else if (x >= two_pow_p28) { /* x > 2**28 */
+ if (Py_IS_INFINITY(x)) {
+ return x+x;
+ } else {
+ return log(x)+ln2; /* acosh(huge)=log(2x) */
+ }
+ }
+ else if (x == 1.) {
+ return 0.0; /* acosh(1) = 0 */
+ }
+ else if (x > 2.) { /* 2 < x < 2**28 */
+ double t = x*x;
+ return log(2.0*x - 1.0 / (x + sqrt(t - 1.0)));
+ }
+ else { /* 1 < x <= 2 */
+ double t = x - 1.0;
+ return log1p(t + sqrt(2.0*t + t*t));
+ }
+}
+#endif /* HAVE_ACOSH */
+
+/* atanh(x)
+ * Method :
+ * 1.Reduced x to positive by atanh(-x) = -atanh(x)
+ * 2.For x>=0.5
+ * 1 2x x
+ * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
+ * 2 1 - x 1 - x
+ *
+ * For x<0.5
+ * atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
+ *
+ * Special cases:
+ * atanh(x) is NaN if |x| >= 1 with signal;
+ * atanh(NaN) is that NaN with no signal;
+ *
+ */
+
+#ifndef HAVE_ATANH
+double
+atanh(double x)
+{
+ double absx;
+ double t;
+
+ if (Py_IS_NAN(x)) {
+ return x+x;
+ }
+ absx = fabs(x);
+ if (absx >= 1.) { /* |x| >= 1 */
+ errno = EDOM;
+#ifdef Py_NAN
+ return Py_NAN;
+#else
+ return x/zero;
+#endif
+ }
+ if (absx < two_pow_m28) { /* |x| < 2**-28 */
+ return x;
+ }
+ if (absx < 0.5) { /* |x| < 0.5 */
+ t = absx+absx;
+ t = 0.5 * log1p(t + t*absx / (1.0 - absx));
+ }
+ else { /* 0.5 <= |x| <= 1.0 */
+ t = 0.5 * log1p((absx + absx) / (1.0 - absx));
+ }
+ return copysign(t, x);
+}
+#endif /* HAVE_ATANH */
diff --git a/configure b/configure
index 0e9e7bb..86d4c46 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 62003 .
+# From configure.in Revision: 62146 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for python 3.0.
#