summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorChristian Heimes <christian@cheimes.de>2008-04-20 21:01:16 (GMT)
committerChristian Heimes <christian@cheimes.de>2008-04-20 21:01:16 (GMT)
commita342c013fc97df2110c420af2cd66b7e8489b9af (patch)
tree8e95e3309129066e84c3aa83bdbc7aaf087fbf62 /Modules
parent58f9e4f34793a14050648c9f620e96189908a3e9 (diff)
downloadcpython-a342c013fc97df2110c420af2cd66b7e8489b9af.zip
cpython-a342c013fc97df2110c420af2cd66b7e8489b9af.tar.gz
cpython-a342c013fc97df2110c420af2cd66b7e8489b9af.tar.bz2
Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r62386 | christian.heimes | 2008-04-19 04:23:57 +0200 (Sat, 19 Apr 2008) | 2 lines Added kill, terminate and send_signal to subprocess.Popen The bits and pieces for the Windows side were already in place. The POSIX side is trivial (as usual) and uses os.kill(). ........ r62387 | georg.brandl | 2008-04-19 10:23:59 +0200 (Sat, 19 Apr 2008) | 2 lines Fix-up docs for revision 62386. ........ r62389 | georg.brandl | 2008-04-19 18:57:43 +0200 (Sat, 19 Apr 2008) | 2 lines #2369: clarify that copyfile() doesn't take a target directory. ........ r62390 | georg.brandl | 2008-04-19 18:58:28 +0200 (Sat, 19 Apr 2008) | 2 lines #2634: clarify meaning of env parameter to spawn/exec*e. ........ r62391 | georg.brandl | 2008-04-19 18:58:49 +0200 (Sat, 19 Apr 2008) | 2 lines #2633: clarify meaning of env parameter. ........ r62392 | georg.brandl | 2008-04-19 18:59:16 +0200 (Sat, 19 Apr 2008) | 2 lines #2631: clarify IMPORT_NAME semantics. ........ r62393 | georg.brandl | 2008-04-19 19:00:14 +0200 (Sat, 19 Apr 2008) | 2 lines :func: et al. should *not* include the parens. ........ r62396 | mark.dickinson | 2008-04-19 20:51:48 +0200 (Sat, 19 Apr 2008) | 5 lines Additional tests for math.pow, and extra special-case handling code in math.pow, in the hope of making all tests pass on the alpha Tru64 buildbot. ........ r62400 | mark.dickinson | 2008-04-19 21:41:52 +0200 (Sat, 19 Apr 2008) | 3 lines Additional special-case handling for math.pow. Windows/VS2008 doesn't like (-1)**(+-inf). ........ r62401 | benjamin.peterson | 2008-04-19 21:47:34 +0200 (Sat, 19 Apr 2008) | 2 lines Complete documentation for errors argument of io's open and TextIOWrapper ........ r62402 | mark.dickinson | 2008-04-19 22:31:16 +0200 (Sat, 19 Apr 2008) | 2 lines Document updates to math and cmath modules. ........ r62407 | georg.brandl | 2008-04-19 23:28:38 +0200 (Sat, 19 Apr 2008) | 2 lines Update template for newest Sphinx. ........ r62409 | mark.dickinson | 2008-04-19 23:35:35 +0200 (Sat, 19 Apr 2008) | 5 lines Correct documentation for math.pow; 0**nan is nan, not 0. (But nan**0 and 1**nan are 1.) Also fix minor typo: 'quite NaN' -> 'quiet NaN' ........ r62410 | mark.dickinson | 2008-04-19 23:49:22 +0200 (Sat, 19 Apr 2008) | 4 lines Move asinh documentation to the proper place. Remove meaningless 'in radians' from inverse hyperbolic functions. ........ r62412 | mark.dickinson | 2008-04-20 03:22:30 +0200 (Sun, 20 Apr 2008) | 5 lines Report additional diagnostic information in test_math, to help track down debian-alpha buildbot failure. ........ r62413 | mark.dickinson | 2008-04-20 03:39:24 +0200 (Sun, 20 Apr 2008) | 3 lines FreeBSD doesn't follow C99 for modf(inf); so add explicit special-value handling to math.modf code. ........ r62414 | mark.dickinson | 2008-04-20 06:13:13 +0200 (Sun, 20 Apr 2008) | 5 lines Yet more explicit special case handling to make math.pow behave on alpha Tru64. All IEEE 754 special values are now handled directly; only the finite**finite case is handled by libm. ........ r62418 | mark.dickinson | 2008-04-20 18:13:17 +0200 (Sun, 20 Apr 2008) | 7 lines Issue 2662: Initialize special value tables dynamically (i.e. when cmath module is loaded) instead of statically. This fixes compile-time problems on platforms where HUGE_VAL is an extern variable rather than a constant. Thanks Hirokazu Yamamoto for the patch. ........ r62419 | andrew.kuchling | 2008-04-20 18:54:02 +0200 (Sun, 20 Apr 2008) | 1 line Move description of math module changes; various edits to description of cmath changes ........
Diffstat (limited to 'Modules')
-rw-r--r--Modules/cmathmodule.c237
-rw-r--r--Modules/mathmodule.c95
2 files changed, 193 insertions, 139 deletions
diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c
index 8e3c31e..347f88d 100644
--- a/Modules/cmathmodule.c
+++ b/Modules/cmathmodule.c
@@ -107,16 +107,8 @@ special_type(double d)
#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 INF Py_HUGE_VAL
+#define N Py_NAN
#define U -9.5426319407711027e33 /* unlikely value, used as placeholder */
/* First, the C functions that do the real work. Each of the c_*
@@ -128,15 +120,7 @@ special_type(double d)
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 acos_special_values[7][7];
static Py_complex
c_acos(Py_complex z)
@@ -177,15 +161,7 @@ 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 acosh_special_values[7][7];
static Py_complex
c_acosh(Py_complex z)
@@ -237,15 +213,7 @@ 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 asinh_special_values[7][7];
static Py_complex
c_asinh(Py_complex z)
@@ -323,15 +291,7 @@ 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 atanh_special_values[7][7];
static Py_complex
c_atanh(Py_complex z)
@@ -404,15 +364,7 @@ PyDoc_STRVAR(c_cos_doc,
/* 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 cosh_special_values[7][7];
static Py_complex
c_cosh(Py_complex z)
@@ -472,15 +424,7 @@ PyDoc_STRVAR(c_cosh_doc,
/* 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 exp_special_values[7][7];
static Py_complex
c_exp(Py_complex z)
@@ -538,15 +482,7 @@ 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 log_special_values[7][7];
static Py_complex
c_log(Py_complex z)
@@ -658,15 +594,7 @@ PyDoc_STRVAR(c_sin_doc,
/* 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 sinh_special_values[7][7];
static Py_complex
c_sinh(Py_complex z)
@@ -723,15 +651,7 @@ 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 sqrt_special_values[7][7];
static Py_complex
c_sqrt(Py_complex z)
@@ -826,15 +746,7 @@ PyDoc_STRVAR(c_tan_doc,
/* 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 tanh_special_values[7][7];
static Py_complex
c_tanh(Py_complex z)
@@ -1043,15 +955,7 @@ the distance from 0 and phi the phase angle.");
*/
-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 Py_complex rect_special_values[7][7];
static PyObject *
cmath_rect(PyObject *self, PyObject *args)
@@ -1176,4 +1080,119 @@ initcmath(void)
PyModule_AddObject(m, "pi",
PyFloat_FromDouble(Py_MATH_PI));
PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E));
+
+ /* initialize special value tables */
+
+#define INIT_SPECIAL_VALUES(NAME, BODY) { Py_complex* p = (Py_complex*)NAME; BODY }
+#define C(REAL, IMAG) p->real = REAL; p->imag = IMAG; ++p;
+
+ INIT_SPECIAL_VALUES(acos_special_values, {
+ C(P34,INF) C(P,INF) C(P,INF) C(P,-INF) C(P,-INF) C(P34,-INF) C(N,INF)
+ C(P12,INF) C(U,U) C(U,U) C(U,U) C(U,U) C(P12,-INF) C(N,N)
+ C(P12,INF) C(U,U) C(P12,0.) C(P12,-0.) C(U,U) C(P12,-INF) C(P12,N)
+ C(P12,INF) C(U,U) C(P12,0.) C(P12,-0.) C(U,U) C(P12,-INF) C(P12,N)
+ C(P12,INF) C(U,U) C(U,U) C(U,U) C(U,U) C(P12,-INF) C(N,N)
+ C(P14,INF) C(0.,INF) C(0.,INF) C(0.,-INF) C(0.,-INF) C(P14,-INF) C(N,INF)
+ C(N,INF) C(N,N) C(N,N) C(N,N) C(N,N) C(N,-INF) C(N,N)
+ })
+
+ INIT_SPECIAL_VALUES(acosh_special_values, {
+ C(INF,-P34) C(INF,-P) C(INF,-P) C(INF,P) C(INF,P) C(INF,P34) C(INF,N)
+ C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N)
+ C(INF,-P12) C(U,U) C(0.,-P12) C(0.,P12) C(U,U) C(INF,P12) C(N,N)
+ C(INF,-P12) C(U,U) C(0.,-P12) C(0.,P12) C(U,U) C(INF,P12) C(N,N)
+ C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N)
+ C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N)
+ C(INF,N) C(N,N) C(N,N) C(N,N) C(N,N) C(INF,N) C(N,N)
+ })
+
+ INIT_SPECIAL_VALUES(asinh_special_values, {
+ C(-INF,-P14) C(-INF,-0.) C(-INF,-0.) C(-INF,0.) C(-INF,0.) C(-INF,P14) C(-INF,N)
+ C(-INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(-INF,P12) C(N,N)
+ C(-INF,-P12) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(-INF,P12) C(N,N)
+ C(INF,-P12) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(INF,P12) C(N,N)
+ C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N)
+ C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N)
+ C(INF,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(INF,N) C(N,N)
+ })
+
+ INIT_SPECIAL_VALUES(atanh_special_values, {
+ C(-0.,-P12) C(-0.,-P12) C(-0.,-P12) C(-0.,P12) C(-0.,P12) C(-0.,P12) C(-0.,N)
+ C(-0.,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(-0.,P12) C(N,N)
+ C(-0.,-P12) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(-0.,P12) C(-0.,N)
+ C(0.,-P12) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,P12) C(0.,N)
+ C(0.,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(0.,P12) C(N,N)
+ C(0.,-P12) C(0.,-P12) C(0.,-P12) C(0.,P12) C(0.,P12) C(0.,P12) C(0.,N)
+ C(0.,-P12) C(N,N) C(N,N) C(N,N) C(N,N) C(0.,P12) C(N,N)
+ })
+
+ INIT_SPECIAL_VALUES(cosh_special_values, {
+ C(INF,N) C(U,U) C(INF,0.) C(INF,-0.) C(U,U) C(INF,N) C(INF,N)
+ C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
+ C(N,0.) C(U,U) C(1.,0.) C(1.,-0.) C(U,U) C(N,0.) C(N,0.)
+ C(N,0.) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(N,0.) C(N,0.)
+ C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
+ C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N)
+ C(N,N) C(N,N) C(N,0.) C(N,0.) C(N,N) C(N,N) C(N,N)
+ })
+
+ INIT_SPECIAL_VALUES(exp_special_values, {
+ C(0.,0.) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,0.) C(0.,0.)
+ C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
+ C(N,N) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(N,N) C(N,N)
+ C(N,N) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(N,N) C(N,N)
+ C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
+ C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N)
+ C(N,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(N,N) C(N,N)
+ })
+
+ INIT_SPECIAL_VALUES(log_special_values, {
+ C(INF,-P34) C(INF,-P) C(INF,-P) C(INF,P) C(INF,P) C(INF,P34) C(INF,N)
+ C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N)
+ C(INF,-P12) C(U,U) C(-INF,-P) C(-INF,P) C(U,U) C(INF,P12) C(N,N)
+ C(INF,-P12) C(U,U) C(-INF,-0.) C(-INF,0.) C(U,U) C(INF,P12) C(N,N)
+ C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N)
+ C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N)
+ C(INF,N) C(N,N) C(N,N) C(N,N) C(N,N) C(INF,N) C(N,N)
+ })
+
+ INIT_SPECIAL_VALUES(sinh_special_values, {
+ C(INF,N) C(U,U) C(-INF,-0.) C(-INF,0.) C(U,U) C(INF,N) C(INF,N)
+ C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
+ C(0.,N) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(0.,N) C(0.,N)
+ C(0.,N) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,N) C(0.,N)
+ C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
+ C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N)
+ C(N,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(N,N) C(N,N)
+ })
+
+ INIT_SPECIAL_VALUES(sqrt_special_values, {
+ C(INF,-INF) C(0.,-INF) C(0.,-INF) C(0.,INF) C(0.,INF) C(INF,INF) C(N,INF)
+ C(INF,-INF) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,INF) C(N,N)
+ C(INF,-INF) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(INF,INF) C(N,N)
+ C(INF,-INF) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(INF,INF) C(N,N)
+ C(INF,-INF) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,INF) C(N,N)
+ C(INF,-INF) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,INF) C(INF,N)
+ C(INF,-INF) C(N,N) C(N,N) C(N,N) C(N,N) C(INF,INF) C(N,N)
+ })
+
+ INIT_SPECIAL_VALUES(tanh_special_values, {
+ C(-1.,0.) C(U,U) C(-1.,-0.) C(-1.,0.) C(U,U) C(-1.,0.) C(-1.,0.)
+ C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
+ C(N,N) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(N,N) C(N,N)
+ C(N,N) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(N,N) C(N,N)
+ C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
+ C(1.,0.) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(1.,0.) C(1.,0.)
+ C(N,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(N,N) C(N,N)
+ })
+
+ INIT_SPECIAL_VALUES(rect_special_values, {
+ C(INF,N) C(U,U) C(-INF,0.) C(-INF,-0.) C(U,U) C(INF,N) C(INF,N)
+ C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
+ C(0.,0.) C(U,U) C(-0.,0.) C(-0.,-0.) C(U,U) C(0.,0.) C(0.,0.)
+ C(0.,0.) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,0.) C(0.,0.)
+ C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N)
+ C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N)
+ C(N,N) C(N,N) C(N,0.) C(N,0.) C(N,N) C(N,N) C(N,N)
+ })
}
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index 8c48316..19ed1b1 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -414,6 +414,15 @@ math_modf(PyObject *self, PyObject *arg)
double y, x = PyFloat_AsDouble(arg);
if (x == -1.0 && PyErr_Occurred())
return NULL;
+ /* some platforms don't do the right thing for NaNs and
+ infinities, so we take care of special cases directly. */
+ if (!Py_IS_FINITE(x)) {
+ if (Py_IS_INFINITY(x))
+ return Py_BuildValue("(dd)", copysign(0., x), x);
+ else if (Py_IS_NAN(x))
+ return Py_BuildValue("(dd)", x, x);
+ }
+
errno = 0;
PyFPE_START_PROTECT("in math_modf", return 0);
x = modf(x, &y);
@@ -586,6 +595,7 @@ math_pow(PyObject *self, PyObject *args)
{
PyObject *ox, *oy;
double r, x, y;
+ int odd_y;
if (! PyArg_UnpackTuple(args, "pow", 2, 2, &ox, &oy))
return NULL;
@@ -593,37 +603,62 @@ math_pow(PyObject *self, PyObject *args)
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;
+ /* deal directly with IEEE specials, to cope with problems on various
+ platforms whose semantics don't exactly match C99 */
+ if (!Py_IS_FINITE(x) || !Py_IS_FINITE(y)) {
+ errno = 0;
+ if (Py_IS_NAN(x))
+ r = y == 0. ? 1. : x; /* NaN**0 = 1 */
+ else if (Py_IS_NAN(y))
+ r = x == 1. ? 1. : y; /* 1**NaN = 1 */
+ else if (Py_IS_INFINITY(x)) {
+ odd_y = Py_IS_FINITE(y) && fmod(fabs(y), 2.0) == 1.0;
+ if (y > 0.)
+ r = odd_y ? x : fabs(x);
+ else if (y == 0.)
+ r = 1.;
+ else /* y < 0. */
+ r = odd_y ? copysign(0., x) : 0.;
+ }
+ else if (Py_IS_INFINITY(y)) {
+ if (fabs(x) == 1.0)
+ r = 1.;
+ else if (y > 0. && fabs(x) > 1.0)
+ r = y;
+ else if (y < 0. && fabs(x) < 1.0) {
+ r = -y; /* result is +inf */
+ if (x == 0.) /* 0**-inf: divide-by-zero */
+ errno = EDOM;
+ }
+ else
+ r = 0.;
+ }
+ }
+ else {
+ /* let libm handle finite**finite */
+ errno = 0;
+ PyFPE_START_PROTECT("in math_pow", return 0);
+ r = pow(x, y);
+ PyFPE_END_PROTECT(r);
+ /* a NaN result should arise only from (-ve)**(finite
+ non-integer); in this case we want to raise ValueError. */
+ if (!Py_IS_FINITE(r)) {
+ if (Py_IS_NAN(r)) {
+ errno = EDOM;
+ }
+ /*
+ an infinite result here arises either from:
+ (A) (+/-0.)**negative (-> divide-by-zero)
+ (B) overflow of x**y with x and y finite
+ */
+ else if (Py_IS_INFINITY(r)) {
+ if (x == 0.)
+ errno = EDOM;
+ else
+ errno = ERANGE;
+ }
+ }
}
if (errno && is_error(r))