Kaydet (Commit) e57950fb authored tarafından Christian Heimes's avatar Christian Heimes

Merged revisions 62420-62421,62423-62424 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r62420 | mark.dickinson | 2008-04-20 20:30:05 +0200 (Sun, 20 Apr 2008) | 3 lines

  Even more fixes for alpha Tru64, this time for
  the phase and polar methods.
........
  r62421 | mark.dickinson | 2008-04-20 22:38:48 +0200 (Sun, 20 Apr 2008) | 2 lines

  Add test for tanh(-0.) == -0. on IEEE 754 systems
........
  r62423 | amaury.forgeotdarc | 2008-04-20 23:02:21 +0200 (Sun, 20 Apr 2008) | 3 lines

  Correct an apparent refleak in test_pkgutil: zipimport._zip_directory_cache contains
  info for all processed zip files, even when they are no longer used.
........
  r62424 | mark.dickinson | 2008-04-20 23:39:04 +0200 (Sun, 20 Apr 2008) | 4 lines

  math.atan2 is misbehaving on Windows;  this patch
  should fix the problem in the same way that
  the cmath.phase problems were fixed.
........
üst 1a3239e9
......@@ -124,6 +124,59 @@ class MathTests(unittest.TestCase):
self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
# math.atan2(0, x)
self.ftest('atan2(0., -inf)', math.atan2(0., NINF), math.pi)
self.ftest('atan2(0., -2.3)', math.atan2(0., -2.3), math.pi)
self.ftest('atan2(0., -0.)', math.atan2(0., -0.), math.pi)
self.assertEqual(math.atan2(0., 0.), 0.)
self.assertEqual(math.atan2(0., 2.3), 0.)
self.assertEqual(math.atan2(0., INF), 0.)
self.assert_(math.isnan(math.atan2(0., NAN)))
# math.atan2(-0, x)
self.ftest('atan2(-0., -inf)', math.atan2(-0., NINF), -math.pi)
self.ftest('atan2(-0., -2.3)', math.atan2(-0., -2.3), -math.pi)
self.ftest('atan2(-0., -0.)', math.atan2(-0., -0.), -math.pi)
self.assertEqual(math.atan2(-0., 0.), -0.)
self.assertEqual(math.atan2(-0., 2.3), -0.)
self.assertEqual(math.atan2(-0., INF), -0.)
self.assert_(math.isnan(math.atan2(-0., NAN)))
# math.atan2(INF, x)
self.ftest('atan2(inf, -inf)', math.atan2(INF, NINF), math.pi*3/4)
self.ftest('atan2(inf, -2.3)', math.atan2(INF, -2.3), math.pi/2)
self.ftest('atan2(inf, -0.)', math.atan2(INF, -0.0), math.pi/2)
self.ftest('atan2(inf, 0.)', math.atan2(INF, 0.0), math.pi/2)
self.ftest('atan2(inf, 2.3)', math.atan2(INF, 2.3), math.pi/2)
self.ftest('atan2(inf, inf)', math.atan2(INF, INF), math.pi/4)
self.assert_(math.isnan(math.atan2(INF, NAN)))
# math.atan2(NINF, x)
self.ftest('atan2(-inf, -inf)', math.atan2(NINF, NINF), -math.pi*3/4)
self.ftest('atan2(-inf, -2.3)', math.atan2(NINF, -2.3), -math.pi/2)
self.ftest('atan2(-inf, -0.)', math.atan2(NINF, -0.0), -math.pi/2)
self.ftest('atan2(-inf, 0.)', math.atan2(NINF, 0.0), -math.pi/2)
self.ftest('atan2(-inf, 2.3)', math.atan2(NINF, 2.3), -math.pi/2)
self.ftest('atan2(-inf, inf)', math.atan2(NINF, INF), -math.pi/4)
self.assert_(math.isnan(math.atan2(NINF, NAN)))
# math.atan2(+finite, x)
self.ftest('atan2(2.3, -inf)', math.atan2(2.3, NINF), math.pi)
self.ftest('atan2(2.3, -0.)', math.atan2(2.3, -0.), math.pi/2)
self.ftest('atan2(2.3, 0.)', math.atan2(2.3, 0.), math.pi/2)
self.assertEqual(math.atan2(2.3, INF), 0.)
self.assert_(math.isnan(math.atan2(2.3, NAN)))
# math.atan2(-finite, x)
self.ftest('atan2(-2.3, -inf)', math.atan2(-2.3, NINF), -math.pi)
self.ftest('atan2(-2.3, -0.)', math.atan2(-2.3, -0.), -math.pi/2)
self.ftest('atan2(-2.3, 0.)', math.atan2(-2.3, 0.), -math.pi/2)
self.assertEqual(math.atan2(-2.3, INF), -0.)
self.assert_(math.isnan(math.atan2(-2.3, NAN)))
# math.atan2(NAN, x)
self.assert_(math.isnan(math.atan2(NAN, NINF)))
self.assert_(math.isnan(math.atan2(NAN, -2.3)))
self.assert_(math.isnan(math.atan2(NAN, -0.)))
self.assert_(math.isnan(math.atan2(NAN, 0.)))
self.assert_(math.isnan(math.atan2(NAN, 2.3)))
self.assert_(math.isnan(math.atan2(NAN, INF)))
self.assert_(math.isnan(math.atan2(NAN, NAN)))
def testCeil(self):
self.assertRaises(TypeError, math.ceil)
self.assertEquals(int, type(math.ceil(0.5)))
......@@ -575,6 +628,11 @@ class MathTests(unittest.TestCase):
self.ftest('tanh(inf)', math.tanh(INF), 1)
self.ftest('tanh(-inf)', math.tanh(NINF), -1)
self.assert_(math.isnan(math.tanh(NAN)))
# check that tanh(-0.) == -0. on IEEE 754 systems
if float.__getformat__("double").startswith("IEEE"):
self.assertEqual(math.tanh(-0.), -0.)
self.assertEqual(math.copysign(1., math.tanh(-0.)),
math.copysign(1., -0.))
def test_trunc(self):
self.assertEqual(math.trunc(1), 1)
......
......@@ -122,6 +122,9 @@ class PkgutilPEP302Tests(unittest.TestCase):
def test_main():
run_unittest(PkgutilTests, PkgutilPEP302Tests)
# this is necessary if test is run repeated (like when finding leaks)
import zipimport
zipimport._zip_directory_cache.clear()
if __name__ == '__main__':
test_main()
......@@ -264,7 +264,8 @@ c_atan(Py_complex z)
return r;
}
/* Windows screws up atan2 for inf and nan */
/* Windows screws up atan2 for inf and nan, and alpha Tru64 5.1 doesn't follow
C99 for atan2(0., 0.). */
static double
c_atan2(Py_complex z)
{
......@@ -282,6 +283,14 @@ c_atan2(Py_complex z)
/* atan2(+-inf, x) == +-pi/2 for finite x */
return copysign(0.5*Py_MATH_PI, z.imag);
}
if (Py_IS_INFINITY(z.real) || z.imag == 0.) {
if (copysign(1., z.real) == 1.)
/* atan2(+-y, +inf) = atan2(+-0, +x) = +-0. */
return copysign(0., z.imag);
else
/* atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. */
return copysign(Py_MATH_PI, z.imag);
}
return atan2(z.imag, z.real);
}
......
......@@ -95,6 +95,42 @@ is_error(double x)
return result;
}
/*
wrapper for atan2 that deals directly with special cases before
delegating to the platform libm for the remaining cases. This
is necessary to get consistent behaviour across platforms.
Windows, FreeBSD and alpha Tru64 are amongst platforms that don't
always follow C99.
*/
static double
m_atan2(double y, double x)
{
if (Py_IS_NAN(x) || Py_IS_NAN(y))
return Py_NAN;
if (Py_IS_INFINITY(y)) {
if (Py_IS_INFINITY(x)) {
if (copysign(1., x) == 1.)
/* atan2(+-inf, +inf) == +-pi/4 */
return copysign(0.25*Py_MATH_PI, y);
else
/* atan2(+-inf, -inf) == +-pi*3/4 */
return copysign(0.75*Py_MATH_PI, y);
}
/* atan2(+-inf, x) == +-pi/2 for finite x */
return copysign(0.5*Py_MATH_PI, y);
}
if (Py_IS_INFINITY(x) || y == 0.) {
if (copysign(1., x) == 1.)
/* atan2(+-y, +inf) = atan2(+-0, +x) = +-0. */
return copysign(0., y);
else
/* atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. */
return copysign(Py_MATH_PI, y);
}
return atan2(y, x);
}
/*
math_1 is used to wrap a libm function f that takes a double
arguments and returns a double.
......@@ -250,7 +286,7 @@ 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,
FUNC2(atan2, m_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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment