mirror of
https://github.com/python/cpython.git
synced 2025-07-17 08:15:19 +00:00

svn+ssh://pythondev@svn.python.org/python/trunk ........ r63542 | mark.dickinson | 2008-05-22 20:35:30 -0500 (Thu, 22 May 2008) | 5 lines Issue #2819: Add math.sum, a function that sums a sequence of floats efficiently but with no intermediate loss of precision. Based on Raymond Hettinger's ASPN recipe. Thanks Jean Brouwers for the patch. ........ r63543 | mark.dickinson | 2008-05-22 21:36:48 -0500 (Thu, 22 May 2008) | 2 lines Add tests for math.sum (Issue #2819) ........ r63544 | mark.dickinson | 2008-05-22 22:30:01 -0500 (Thu, 22 May 2008) | 2 lines Better error reporting in test_math.py ........ r63546 | raymond.hettinger | 2008-05-22 23:32:43 -0500 (Thu, 22 May 2008) | 1 line Tweak the comments and formatting. ........ r63553 | mark.dickinson | 2008-05-23 07:07:36 -0500 (Fri, 23 May 2008) | 3 lines Skip math.sum tests on non IEEE 754 platforms, and on IEEE 754 platforms that exhibit the problem described in issue #2937. ........ r63563 | martin.v.loewis | 2008-05-23 10:18:28 -0500 (Fri, 23 May 2008) | 3 lines Issue #1390: Raise ValueError in toxml when an invalid comment would otherwise be produced. ........ r63564 | raymond.hettinger | 2008-05-23 12:21:44 -0500 (Fri, 23 May 2008) | 1 line Issue 2909: show how to name unpacked fields. ........ r63567 | raymond.hettinger | 2008-05-23 12:34:34 -0500 (Fri, 23 May 2008) | 1 line Fix typo ........ r63569 | martin.v.loewis | 2008-05-23 14:33:13 -0500 (Fri, 23 May 2008) | 3 lines Mention that the leaking of variables from list comprehensions is fixed in 3.0. ........ r63576 | martin.v.loewis | 2008-05-24 04:36:45 -0500 (Sat, 24 May 2008) | 3 lines Don't try to get the window size if it was never set before. Fixes the test failure on Solaris. ........
932 lines
40 KiB
Python
932 lines
40 KiB
Python
# Python test set -- math module
|
|
# XXXX Should not do tests around zero only
|
|
|
|
from test.support import run_unittest, verbose
|
|
import unittest
|
|
import math
|
|
import os
|
|
import sys
|
|
|
|
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):
|
|
|
|
def ftest(self, name, value, expected):
|
|
if abs(value-expected) > eps:
|
|
# Use %r instead of %f so the error message
|
|
# displays full precision. Otherwise discrepancies
|
|
# in the last few bits will lead to very confusing
|
|
# error messages
|
|
self.fail('%s returned %r, expected %r' %
|
|
(name, value, expected))
|
|
|
|
def testConstants(self):
|
|
self.ftest('pi', math.pi, 3.1415926)
|
|
self.ftest('e', math.e, 2.7182818)
|
|
|
|
def testAcos(self):
|
|
self.assertRaises(TypeError, math.acos)
|
|
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(NINF), -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)
|
|
self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
|
|
self.ftest('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
|
|
self.ftest('atan2(0, 1)', math.atan2(0, 1), 0)
|
|
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)))
|
|
self.ftest('ceil(0.5)', math.ceil(0.5), 1)
|
|
self.ftest('ceil(1.0)', math.ceil(1.0), 1)
|
|
self.ftest('ceil(1.5)', math.ceil(1.5), 2)
|
|
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):
|
|
return 42
|
|
class TestNoCeil:
|
|
pass
|
|
self.ftest('ceil(TestCeil())', math.ceil(TestCeil()), 42)
|
|
self.assertRaises(TypeError, math.ceil, TestNoCeil())
|
|
|
|
t = TestNoCeil()
|
|
t.__ceil__ = lambda *args: args
|
|
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)
|
|
self.ftest('degrees(pi)', math.degrees(math.pi), 180.0)
|
|
self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
|
|
self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
|
|
|
|
def testExp(self):
|
|
self.assertRaises(TypeError, math.exp)
|
|
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)
|
|
self.ftest('fabs(-1)', math.fabs(-1), 1)
|
|
self.ftest('fabs(0)', math.fabs(0), 0)
|
|
self.ftest('fabs(1)', math.fabs(1), 1)
|
|
|
|
def testFloor(self):
|
|
self.assertRaises(TypeError, math.floor)
|
|
self.assertEquals(int, type(math.floor(0.5)))
|
|
self.ftest('floor(0.5)', math.floor(0.5), 0)
|
|
self.ftest('floor(1.0)', math.floor(1.0), 1)
|
|
self.ftest('floor(1.5)', math.floor(1.5), 1)
|
|
self.ftest('floor(-0.5)', math.floor(-0.5), -1)
|
|
self.ftest('floor(-1.0)', math.floor(-1.0), -1)
|
|
self.ftest('floor(-1.5)', math.floor(-1.5), -2)
|
|
# pow() relies on floor() to check for integers
|
|
# 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):
|
|
return 42
|
|
class TestNoFloor:
|
|
pass
|
|
self.ftest('floor(TestFloor())', math.floor(TestFloor()), 42)
|
|
self.assertRaises(TypeError, math.floor, TestNoFloor())
|
|
|
|
t = TestNoFloor()
|
|
t.__floor__ = lambda *args: args
|
|
self.assertRaises(TypeError, math.floor, t)
|
|
self.assertRaises(TypeError, math.floor, t, 0)
|
|
|
|
def testFmod(self):
|
|
self.assertRaises(TypeError, math.fmod)
|
|
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.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)
|
|
|
|
def testfrexp(name, result, expected):
|
|
(mant, exp), (emant, eexp) = result, expected
|
|
if abs(mant-emant) > eps or exp != eexp:
|
|
self.fail('%s returned %r, expected %r'%\
|
|
(name, result, expected))
|
|
|
|
testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
|
|
testfrexp('frexp(0)', math.frexp(0), (0, 0))
|
|
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)
|
|
self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
|
|
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)))
|
|
|
|
# large second argument
|
|
for n in [10**5, 10**10, 10**20, 10**40]:
|
|
self.assertEquals(math.ldexp(INF, -n), INF)
|
|
self.assertEquals(math.ldexp(NINF, -n), NINF)
|
|
self.assertEquals(math.ldexp(1., -n), 0.)
|
|
self.assertEquals(math.ldexp(-1., -n), -0.)
|
|
self.assertEquals(math.ldexp(0., -n), 0.)
|
|
self.assertEquals(math.ldexp(-0., -n), -0.)
|
|
self.assert_(math.isnan(math.ldexp(NAN, -n)))
|
|
|
|
self.assertRaises(OverflowError, math.ldexp, 1., n)
|
|
self.assertRaises(OverflowError, math.ldexp, -1., n)
|
|
self.assertEquals(math.ldexp(0., n), 0.)
|
|
self.assertEquals(math.ldexp(-0., n), -0.)
|
|
self.assertEquals(math.ldexp(INF, n), INF)
|
|
self.assertEquals(math.ldexp(NINF, n), NINF)
|
|
self.assert_(math.isnan(math.ldexp(NAN, n)))
|
|
|
|
def testLog(self):
|
|
self.assertRaises(TypeError, math.log)
|
|
self.ftest('log(1/e)', math.log(1/math.e), -1)
|
|
self.ftest('log(1)', math.log(1), 0)
|
|
self.ftest('log(e)', math.log(math.e), 1)
|
|
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)
|
|
|
|
def testmodf(name, result, expected):
|
|
(v1, v2), (e1, e2) = result, expected
|
|
if abs(v1-e1) > eps or abs(v2-e2):
|
|
self.fail('%s returned %r, expected %r'%\
|
|
(name, result, expected))
|
|
|
|
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)
|
|
|
|
# pow(0., x)
|
|
self.assertEqual(math.pow(0., INF), 0.)
|
|
self.assertEqual(math.pow(0., 3.), 0.)
|
|
self.assertEqual(math.pow(0., 2.3), 0.)
|
|
self.assertEqual(math.pow(0., 2.), 0.)
|
|
self.assertEqual(math.pow(0., 0.), 1.)
|
|
self.assertEqual(math.pow(0., -0.), 1.)
|
|
self.assertRaises(ValueError, math.pow, 0., -2.)
|
|
self.assertRaises(ValueError, math.pow, 0., -2.3)
|
|
self.assertRaises(ValueError, math.pow, 0., -3.)
|
|
self.assertRaises(ValueError, math.pow, 0., NINF)
|
|
self.assert_(math.isnan(math.pow(0., NAN)))
|
|
|
|
# pow(INF, x)
|
|
self.assertEqual(math.pow(INF, INF), INF)
|
|
self.assertEqual(math.pow(INF, 3.), INF)
|
|
self.assertEqual(math.pow(INF, 2.3), INF)
|
|
self.assertEqual(math.pow(INF, 2.), INF)
|
|
self.assertEqual(math.pow(INF, 0.), 1.)
|
|
self.assertEqual(math.pow(INF, -0.), 1.)
|
|
self.assertEqual(math.pow(INF, -2.), 0.)
|
|
self.assertEqual(math.pow(INF, -2.3), 0.)
|
|
self.assertEqual(math.pow(INF, -3.), 0.)
|
|
self.assertEqual(math.pow(INF, NINF), 0.)
|
|
self.assert_(math.isnan(math.pow(INF, NAN)))
|
|
|
|
# pow(-0., x)
|
|
self.assertEqual(math.pow(-0., INF), 0.)
|
|
self.assertEqual(math.pow(-0., 3.), -0.)
|
|
self.assertEqual(math.pow(-0., 2.3), 0.)
|
|
self.assertEqual(math.pow(-0., 2.), 0.)
|
|
self.assertEqual(math.pow(-0., 0.), 1.)
|
|
self.assertEqual(math.pow(-0., -0.), 1.)
|
|
self.assertRaises(ValueError, math.pow, -0., -2.)
|
|
self.assertRaises(ValueError, math.pow, -0., -2.3)
|
|
self.assertRaises(ValueError, math.pow, -0., -3.)
|
|
self.assertRaises(ValueError, math.pow, -0., NINF)
|
|
self.assert_(math.isnan(math.pow(-0., NAN)))
|
|
|
|
# pow(NINF, x)
|
|
self.assertEqual(math.pow(NINF, INF), INF)
|
|
self.assertEqual(math.pow(NINF, 3.), NINF)
|
|
self.assertEqual(math.pow(NINF, 2.3), INF)
|
|
self.assertEqual(math.pow(NINF, 2.), INF)
|
|
self.assertEqual(math.pow(NINF, 0.), 1.)
|
|
self.assertEqual(math.pow(NINF, -0.), 1.)
|
|
self.assertEqual(math.pow(NINF, -2.), 0.)
|
|
self.assertEqual(math.pow(NINF, -2.3), 0.)
|
|
self.assertEqual(math.pow(NINF, -3.), -0.)
|
|
self.assertEqual(math.pow(NINF, NINF), 0.)
|
|
self.assert_(math.isnan(math.pow(NINF, NAN)))
|
|
|
|
# pow(-1, x)
|
|
self.assertEqual(math.pow(-1., INF), 1.)
|
|
self.assertEqual(math.pow(-1., 3.), -1.)
|
|
self.assertRaises(ValueError, math.pow, -1., 2.3)
|
|
self.assertEqual(math.pow(-1., 2.), 1.)
|
|
self.assertEqual(math.pow(-1., 0.), 1.)
|
|
self.assertEqual(math.pow(-1., -0.), 1.)
|
|
self.assertEqual(math.pow(-1., -2.), 1.)
|
|
self.assertRaises(ValueError, math.pow, -1., -2.3)
|
|
self.assertEqual(math.pow(-1., -3.), -1.)
|
|
self.assertEqual(math.pow(-1., NINF), 1.)
|
|
self.assert_(math.isnan(math.pow(-1., NAN)))
|
|
|
|
# pow(1, x)
|
|
self.assertEqual(math.pow(1., INF), 1.)
|
|
self.assertEqual(math.pow(1., 3.), 1.)
|
|
self.assertEqual(math.pow(1., 2.3), 1.)
|
|
self.assertEqual(math.pow(1., 2.), 1.)
|
|
self.assertEqual(math.pow(1., 0.), 1.)
|
|
self.assertEqual(math.pow(1., -0.), 1.)
|
|
self.assertEqual(math.pow(1., -2.), 1.)
|
|
self.assertEqual(math.pow(1., -2.3), 1.)
|
|
self.assertEqual(math.pow(1., -3.), 1.)
|
|
self.assertEqual(math.pow(1., NINF), 1.)
|
|
self.assertEqual(math.pow(1., NAN), 1.)
|
|
|
|
# pow(x, 0) should be 1 for any x
|
|
self.assertEqual(math.pow(2.3, 0.), 1.)
|
|
self.assertEqual(math.pow(-2.3, 0.), 1.)
|
|
self.assertEqual(math.pow(NAN, 0.), 1.)
|
|
self.assertEqual(math.pow(2.3, -0.), 1.)
|
|
self.assertEqual(math.pow(-2.3, -0.), 1.)
|
|
self.assertEqual(math.pow(NAN, -0.), 1.)
|
|
|
|
# pow(x, y) is invalid if x is negative and y is not integral
|
|
self.assertRaises(ValueError, math.pow, -1., 2.3)
|
|
self.assertRaises(ValueError, math.pow, -15., -3.1)
|
|
|
|
# pow(x, NINF)
|
|
self.assertEqual(math.pow(1.9, NINF), 0.)
|
|
self.assertEqual(math.pow(1.1, NINF), 0.)
|
|
self.assertEqual(math.pow(0.9, NINF), INF)
|
|
self.assertEqual(math.pow(0.1, NINF), INF)
|
|
self.assertEqual(math.pow(-0.1, NINF), INF)
|
|
self.assertEqual(math.pow(-0.9, NINF), INF)
|
|
self.assertEqual(math.pow(-1.1, NINF), 0.)
|
|
self.assertEqual(math.pow(-1.9, NINF), 0.)
|
|
|
|
# pow(x, INF)
|
|
self.assertEqual(math.pow(1.9, INF), INF)
|
|
self.assertEqual(math.pow(1.1, INF), INF)
|
|
self.assertEqual(math.pow(0.9, INF), 0.)
|
|
self.assertEqual(math.pow(0.1, INF), 0.)
|
|
self.assertEqual(math.pow(-0.1, INF), 0.)
|
|
self.assertEqual(math.pow(-0.9, INF), 0.)
|
|
self.assertEqual(math.pow(-1.1, INF), INF)
|
|
self.assertEqual(math.pow(-1.9, INF), INF)
|
|
|
|
# pow(x, y) should work for x negative, y an integer
|
|
self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
|
|
self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
|
|
self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
|
|
self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
|
|
self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
|
|
self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
|
|
self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
|
|
self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
|
|
self.assertRaises(ValueError, math.pow, -2.0, -0.5)
|
|
self.assertRaises(ValueError, math.pow, -2.0, 0.5)
|
|
|
|
# the following tests have been commented out since they don't
|
|
# really belong here: the implementation of ** for floats is
|
|
# independent of the implemention of math.pow
|
|
#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)
|
|
self.ftest('radians(180)', math.radians(180), math.pi)
|
|
self.ftest('radians(90)', math.radians(90), math.pi/2)
|
|
self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
|
|
|
|
def testSin(self):
|
|
self.assertRaises(TypeError, math.sin)
|
|
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(NINF), NINF)
|
|
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 testSum(self):
|
|
# math.sum relies on exact rounding for correct operation.
|
|
# There's a known problem with IA32 floating-point that causes
|
|
# inexact rounding in some situations, and will cause the
|
|
# math.sum tests below to fail; see issue #2937. On non IEEE
|
|
# 754 platforms, and on IEEE 754 platforms that exhibit the
|
|
# problem described in issue #2937, we simply skip the whole
|
|
# test.
|
|
|
|
if not float.__getformat__("double").startswith("IEEE"):
|
|
return
|
|
|
|
# on IEEE 754 compliant machines, both of the expressions
|
|
# below should round to 10000000000000002.0.
|
|
if 1e16+2.999 != 1e16+2.9999:
|
|
return
|
|
|
|
# Python version of math.sum algorithm, for comparison
|
|
def msum(iterable):
|
|
"""Full precision sum of values in iterable. Returns the value of
|
|
the sum, rounded to the nearest representable floating-point number
|
|
using the round-half-to-even rule.
|
|
|
|
"""
|
|
# Stage 1: accumulate partials
|
|
partials = []
|
|
for x in iterable:
|
|
i = 0
|
|
for y in partials:
|
|
if abs(x) < abs(y):
|
|
x, y = y, x
|
|
hi = x + y
|
|
lo = y - (hi - x)
|
|
if lo:
|
|
partials[i] = lo
|
|
i += 1
|
|
x = hi
|
|
partials[i:] = [x] if x else []
|
|
|
|
# Stage 2: sum partials
|
|
if not partials:
|
|
return 0.0
|
|
|
|
# sum from the top, stopping as soon as the sum is inexact.
|
|
total = partials.pop()
|
|
while partials:
|
|
x = partials.pop()
|
|
old_total, total = total, total + x
|
|
error = x - (total - old_total)
|
|
if error != 0.0:
|
|
# adjust for correct rounding if necessary
|
|
if partials and (partials[-1] > 0.0) == (error > 0.0) and \
|
|
total + 2*error - total == 2*error:
|
|
total += 2*error
|
|
break
|
|
return total
|
|
|
|
from sys import float_info
|
|
maxfloat = float_info.max
|
|
twopow = 2.**(float_info.max_exp - 1)
|
|
|
|
test_values = [
|
|
([], 0.0),
|
|
([0.0], 0.0),
|
|
([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
|
|
([1e308, 1e308, -1e308], OverflowError),
|
|
([-1e308, 1e308, 1e308], 1e308),
|
|
([1e308, -1e308, 1e308], 1e308),
|
|
([2.0**1023, 2.0**1023, -2.0**1000], OverflowError),
|
|
([twopow, twopow, twopow, twopow, -twopow, -twopow, -twopow],
|
|
OverflowError),
|
|
([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
|
|
([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
|
|
([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
|
|
|
|
([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
|
|
([2.0**1023-2.0**970, -1.0, 2.0**1023], OverflowError),
|
|
([maxfloat, maxfloat*2.**-54], maxfloat),
|
|
([maxfloat, maxfloat*2.**-53], OverflowError),
|
|
([1./n for n in range(1, 1001)], 7.4854708605503451),
|
|
([(-1.)**n/n for n in range(1, 1001)], -0.69264743055982025),
|
|
([1.7**(i+1)-1.7**i for i in range(1000)] + [-1.7**1000], -1.0),
|
|
([INF, -INF, NAN], ValueError),
|
|
([NAN, INF, -INF], ValueError),
|
|
([INF, NAN, INF], ValueError),
|
|
|
|
([INF, INF], OverflowError),
|
|
([INF, -INF], ValueError),
|
|
([-INF, 1e308, 1e308, -INF], OverflowError),
|
|
([2.0**1023-2.0**970, 0.0, 2.0**1023], OverflowError),
|
|
([2.0**1023-2.0**970, 1.0, 2.0**1023], OverflowError),
|
|
([2.0**1023, 2.0**1023], OverflowError),
|
|
([2.0**1023, 2.0**1023, -1.0], OverflowError),
|
|
([twopow, twopow, twopow, twopow, -twopow, -twopow],
|
|
OverflowError),
|
|
([twopow, twopow, twopow, twopow, -twopow, twopow], OverflowError),
|
|
([-twopow, -twopow, -twopow, -twopow], OverflowError),
|
|
|
|
([2.**1023, 2.**1023, -2.**971], OverflowError),
|
|
([2.**1023, 2.**1023, -2.**970], OverflowError),
|
|
([-2.**970, 2.**1023, 2.**1023, -2.**-1074], OverflowError),
|
|
([ 2.**1023, 2.**1023, -2.**970, 2.**-1074], OverflowError),
|
|
([-2.**1023, 2.**971, -2.**1023], -maxfloat),
|
|
([-2.**1023, -2.**1023, 2.**970], OverflowError),
|
|
([-2.**1023, -2.**1023, 2.**970, 2.**-1074], OverflowError),
|
|
([-2.**-1074, -2.**1023, -2.**1023, 2.**970], OverflowError),
|
|
([2.**930, -2.**980, 2.**1023, 2.**1023, twopow, -twopow],
|
|
OverflowError),
|
|
([2.**1023, 2.**1023, -1e307], OverflowError),
|
|
([1e16, 1., 1e-16], 10000000000000002.0),
|
|
([1e16-2., 1.-2.**53, -(1e16-2.), -(1.-2.**53)], 0.0),
|
|
]
|
|
|
|
for i, (vals, s) in enumerate(test_values):
|
|
if isinstance(s, type) and issubclass(s, Exception):
|
|
try:
|
|
m = math.sum(vals)
|
|
except s:
|
|
pass
|
|
else:
|
|
self.fail("test %d failed: got %r, expected %r "
|
|
"for math.sum(%.100r)" %
|
|
(i, m, s.__name__, vals))
|
|
else:
|
|
try:
|
|
self.assertEqual(math.sum(vals), s)
|
|
except OverflowError:
|
|
self.fail("test %d failed: got OverflowError, expected %r "
|
|
"for math.sum(%.100r)" % (i, s, vals))
|
|
except ValueError:
|
|
self.fail("test %d failed: got ValueError, expected %r "
|
|
"for math.sum(%.100r)" % (i, s, vals))
|
|
|
|
# compare with output of msum above, but only when
|
|
# result isn't an IEEE special or an exception
|
|
if not math.isinf(s) and not math.isnan(s):
|
|
self.assertEqual(msum(vals), s)
|
|
|
|
from random import random, gauss, shuffle
|
|
for j in range(1000):
|
|
vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
|
|
s = 0
|
|
for i in range(200):
|
|
v = gauss(0, random()) ** 7 - s
|
|
s += v
|
|
vals.append(v)
|
|
shuffle(vals)
|
|
|
|
s = msum(vals)
|
|
self.assertEqual(msum(vals), math.sum(vals))
|
|
|
|
|
|
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)))
|
|
# 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)
|
|
self.assertEqual(math.trunc(-1), -1)
|
|
self.assertEqual(type(math.trunc(1)), int)
|
|
self.assertEqual(type(math.trunc(1.5)), int)
|
|
self.assertEqual(math.trunc(1.5), 1)
|
|
self.assertEqual(math.trunc(-1.5), -1)
|
|
self.assertEqual(math.trunc(1.999999), 1)
|
|
self.assertEqual(math.trunc(-1.999999), -1)
|
|
self.assertEqual(math.trunc(-0.999999), -0)
|
|
self.assertEqual(math.trunc(-100.999), -100)
|
|
|
|
class TestTrunc(object):
|
|
def __trunc__(self):
|
|
return 23
|
|
|
|
class TestNoTrunc(object):
|
|
pass
|
|
|
|
self.assertEqual(math.trunc(TestTrunc()), 23)
|
|
|
|
self.assertRaises(TypeError, math.trunc)
|
|
self.assertRaises(TypeError, math.trunc, 1, 2)
|
|
self.assertRaises(TypeError, math.trunc, TestNoTrunc())
|
|
|
|
# XXX Doesn't work because the method is looked up on
|
|
# the type only.
|
|
#t = TestNoTrunc()
|
|
#t.__trunc__ = lambda *args: args
|
|
#self.assertEquals((), math.trunc(t))
|
|
#self.assertRaises(TypeError, math.trunc, t, 0)
|
|
|
|
def testCopysign(self):
|
|
self.assertEqual(math.copysign(1, 42), 1.0)
|
|
self.assertEqual(math.copysign(0., 42), 0.0)
|
|
self.assertEqual(math.copysign(1., -42), -1.0)
|
|
self.assertEqual(math.copysign(3, 0.), 3.0)
|
|
self.assertEqual(math.copysign(4., -0.), -4.0)
|
|
|
|
def testIsnan(self):
|
|
self.assert_(math.isnan(float("nan")))
|
|
self.assert_(math.isnan(float("inf")* 0.))
|
|
self.failIf(math.isnan(float("inf")))
|
|
self.failIf(math.isnan(0.))
|
|
self.failIf(math.isnan(1.))
|
|
|
|
def testIsinf(self):
|
|
self.assert_(math.isinf(float("inf")))
|
|
self.assert_(math.isinf(float("-inf")))
|
|
self.assert_(math.isinf(1E400))
|
|
self.assert_(math.isinf(-1E400))
|
|
self.failIf(math.isinf(float("nan")))
|
|
self.failIf(math.isinf(0.))
|
|
self.failIf(math.isinf(1.))
|
|
|
|
# RED_FLAG 16-Oct-2000 Tim
|
|
# While 2.0 is more consistent about exceptions than previous releases, it
|
|
# still fails this part of the test on some platforms. For now, we only
|
|
# *run* test_exceptions() in verbose mode, so that this isn't normally
|
|
# tested.
|
|
|
|
if verbose:
|
|
def test_exceptions(self):
|
|
try:
|
|
x = math.exp(-1000000000)
|
|
except:
|
|
# mathmodule.c is failing to weed out underflows from libm, or
|
|
# we've got an fp format with huge dynamic range
|
|
self.fail("underflowing exp() should not have raised "
|
|
"an exception")
|
|
if x != 0:
|
|
self.fail("underflowing exp() should have returned 0")
|
|
|
|
# If this fails, probably using a strict IEEE-754 conforming libm, and x
|
|
# is +Inf afterwards. But Python wants overflows detected by default.
|
|
try:
|
|
x = math.exp(1000000000)
|
|
except OverflowError:
|
|
pass
|
|
else:
|
|
self.fail("overflowing exp() didn't trigger OverflowError")
|
|
|
|
# If this fails, it could be a puzzle. One odd possibility is that
|
|
# mathmodule.c's macros are getting confused while comparing
|
|
# Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
|
|
# as a result (and so raising OverflowError instead).
|
|
try:
|
|
x = math.sqrt(-1.0)
|
|
except ValueError:
|
|
pass
|
|
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)
|
|
try:
|
|
result = func(ar)
|
|
except ValueError as exc:
|
|
message = (("Unexpected ValueError: %s\n " +
|
|
"in test %s:%s(%r)\n") % (exc.args[0], id, fn, ar))
|
|
self.fail(message)
|
|
except OverflowError:
|
|
message = ("Unexpected OverflowError in " +
|
|
"test %s:%s(%r)\n" % (id, fn, ar))
|
|
self.fail(message)
|
|
self.ftest("%s:%s(%r)" % (id, fn, ar), result, er)
|
|
|
|
def test_main():
|
|
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()
|