Home | History | Annotate | Download | only in test
      1 # Python test set -- math module
      2 # XXXX Should not do tests around zero only
      3 
      4 from test.test_support import run_unittest, verbose
      5 import unittest
      6 import math
      7 import os
      8 import sys
      9 import random
     10 import struct
     11 
     12 eps = 1E-05
     13 NAN = float('nan')
     14 INF = float('inf')
     15 NINF = float('-inf')
     16 
     17 # decorator for skipping tests on non-IEEE 754 platforms
     18 requires_IEEE_754 = unittest.skipUnless(
     19     float.__getformat__("double").startswith("IEEE"),
     20     "test requires IEEE 754 doubles")
     21 
     22 # detect evidence of double-rounding: fsum is not always correctly
     23 # rounded on machines that suffer from double rounding.
     24 x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer
     25 HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4)
     26 
     27 # locate file with test values
     28 if __name__ == '__main__':
     29     file = sys.argv[0]
     30 else:
     31     file = __file__
     32 test_dir = os.path.dirname(file) or os.curdir
     33 math_testcases = os.path.join(test_dir, 'math_testcases.txt')
     34 test_file = os.path.join(test_dir, 'cmath_testcases.txt')
     35 
     36 def to_ulps(x):
     37     """Convert a non-NaN float x to an integer, in such a way that
     38     adjacent floats are converted to adjacent integers.  Then
     39     abs(ulps(x) - ulps(y)) gives the difference in ulps between two
     40     floats.
     41 
     42     The results from this function will only make sense on platforms
     43     where C doubles are represented in IEEE 754 binary64 format.
     44 
     45     """
     46     n = struct.unpack('<q', struct.pack('<d', x))[0]
     47     if n < 0:
     48         n = ~(n+2**63)
     49     return n
     50 
     51 def ulps_check(expected, got, ulps=20):
     52     """Given non-NaN floats `expected` and `got`,
     53     check that they're equal to within the given number of ulps.
     54 
     55     Returns None on success and an error message on failure."""
     56 
     57     ulps_error = to_ulps(got) - to_ulps(expected)
     58     if abs(ulps_error) <= ulps:
     59         return None
     60     return "error = {} ulps; permitted error = {} ulps".format(ulps_error,
     61                                                                ulps)
     62 
     63 def acc_check(expected, got, rel_err=2e-15, abs_err = 5e-323):
     64     """Determine whether non-NaN floats a and b are equal to within a
     65     (small) rounding error.  The default values for rel_err and
     66     abs_err are chosen to be suitable for platforms where a float is
     67     represented by an IEEE 754 double.  They allow an error of between
     68     9 and 19 ulps."""
     69 
     70     # need to special case infinities, since inf - inf gives nan
     71     if math.isinf(expected) and got == expected:
     72         return None
     73 
     74     error = got - expected
     75 
     76     permitted_error = max(abs_err, rel_err * abs(expected))
     77     if abs(error) < permitted_error:
     78         return None
     79     return "error = {}; permitted error = {}".format(error,
     80                                                      permitted_error)
     81 
     82 def parse_mtestfile(fname):
     83     """Parse a file with test values
     84 
     85     -- starts a comment
     86     blank lines, or lines containing only a comment, are ignored
     87     other lines are expected to have the form
     88       id fn arg -> expected [flag]*
     89 
     90     """
     91     with open(fname) as fp:
     92         for line in fp:
     93             # strip comments, and skip blank lines
     94             if '--' in line:
     95                 line = line[:line.index('--')]
     96             if not line.strip():
     97                 continue
     98 
     99             lhs, rhs = line.split('->')
    100             id, fn, arg = lhs.split()
    101             rhs_pieces = rhs.split()
    102             exp = rhs_pieces[0]
    103             flags = rhs_pieces[1:]
    104 
    105             yield (id, fn, float(arg), float(exp), flags)
    106 
    107 def parse_testfile(fname):
    108     """Parse a file with test values
    109 
    110     Empty lines or lines starting with -- are ignored
    111     yields id, fn, arg_real, arg_imag, exp_real, exp_imag
    112     """
    113     with open(fname) as fp:
    114         for line in fp:
    115             # skip comment lines and blank lines
    116             if line.startswith('--') or not line.strip():
    117                 continue
    118 
    119             lhs, rhs = line.split('->')
    120             id, fn, arg_real, arg_imag = lhs.split()
    121             rhs_pieces = rhs.split()
    122             exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1]
    123             flags = rhs_pieces[2:]
    124 
    125             yield (id, fn,
    126                    float(arg_real), float(arg_imag),
    127                    float(exp_real), float(exp_imag),
    128                    flags
    129                   )
    130 
    131 class MathTests(unittest.TestCase):
    132 
    133     def ftest(self, name, value, expected):
    134         if abs(value-expected) > eps:
    135             # Use %r instead of %f so the error message
    136             # displays full precision. Otherwise discrepancies
    137             # in the last few bits will lead to very confusing
    138             # error messages
    139             self.fail('%s returned %r, expected %r' %
    140                       (name, value, expected))
    141 
    142     def testConstants(self):
    143         self.ftest('pi', math.pi, 3.1415926)
    144         self.ftest('e', math.e, 2.7182818)
    145 
    146     def testAcos(self):
    147         self.assertRaises(TypeError, math.acos)
    148         self.ftest('acos(-1)', math.acos(-1), math.pi)
    149         self.ftest('acos(0)', math.acos(0), math.pi/2)
    150         self.ftest('acos(1)', math.acos(1), 0)
    151         self.assertRaises(ValueError, math.acos, INF)
    152         self.assertRaises(ValueError, math.acos, NINF)
    153         self.assertTrue(math.isnan(math.acos(NAN)))
    154 
    155     def testAcosh(self):
    156         self.assertRaises(TypeError, math.acosh)
    157         self.ftest('acosh(1)', math.acosh(1), 0)
    158         self.ftest('acosh(2)', math.acosh(2), 1.3169578969248168)
    159         self.assertRaises(ValueError, math.acosh, 0)
    160         self.assertRaises(ValueError, math.acosh, -1)
    161         self.assertEqual(math.acosh(INF), INF)
    162         self.assertRaises(ValueError, math.acosh, NINF)
    163         self.assertTrue(math.isnan(math.acosh(NAN)))
    164 
    165     def testAsin(self):
    166         self.assertRaises(TypeError, math.asin)
    167         self.ftest('asin(-1)', math.asin(-1), -math.pi/2)
    168         self.ftest('asin(0)', math.asin(0), 0)
    169         self.ftest('asin(1)', math.asin(1), math.pi/2)
    170         self.assertRaises(ValueError, math.asin, INF)
    171         self.assertRaises(ValueError, math.asin, NINF)
    172         self.assertTrue(math.isnan(math.asin(NAN)))
    173 
    174     def testAsinh(self):
    175         self.assertRaises(TypeError, math.asinh)
    176         self.ftest('asinh(0)', math.asinh(0), 0)
    177         self.ftest('asinh(1)', math.asinh(1), 0.88137358701954305)
    178         self.ftest('asinh(-1)', math.asinh(-1), -0.88137358701954305)
    179         self.assertEqual(math.asinh(INF), INF)
    180         self.assertEqual(math.asinh(NINF), NINF)
    181         self.assertTrue(math.isnan(math.asinh(NAN)))
    182 
    183     def testAtan(self):
    184         self.assertRaises(TypeError, math.atan)
    185         self.ftest('atan(-1)', math.atan(-1), -math.pi/4)
    186         self.ftest('atan(0)', math.atan(0), 0)
    187         self.ftest('atan(1)', math.atan(1), math.pi/4)
    188         self.ftest('atan(inf)', math.atan(INF), math.pi/2)
    189         self.ftest('atan(-inf)', math.atan(NINF), -math.pi/2)
    190         self.assertTrue(math.isnan(math.atan(NAN)))
    191 
    192     def testAtanh(self):
    193         self.assertRaises(TypeError, math.atan)
    194         self.ftest('atanh(0)', math.atanh(0), 0)
    195         self.ftest('atanh(0.5)', math.atanh(0.5), 0.54930614433405489)
    196         self.ftest('atanh(-0.5)', math.atanh(-0.5), -0.54930614433405489)
    197         self.assertRaises(ValueError, math.atanh, 1)
    198         self.assertRaises(ValueError, math.atanh, -1)
    199         self.assertRaises(ValueError, math.atanh, INF)
    200         self.assertRaises(ValueError, math.atanh, NINF)
    201         self.assertTrue(math.isnan(math.atanh(NAN)))
    202 
    203     def testAtan2(self):
    204         self.assertRaises(TypeError, math.atan2)
    205         self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
    206         self.ftest('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
    207         self.ftest('atan2(0, 1)', math.atan2(0, 1), 0)
    208         self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
    209         self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
    210 
    211         # math.atan2(0, x)
    212         self.ftest('atan2(0., -inf)', math.atan2(0., NINF), math.pi)
    213         self.ftest('atan2(0., -2.3)', math.atan2(0., -2.3), math.pi)
    214         self.ftest('atan2(0., -0.)', math.atan2(0., -0.), math.pi)
    215         self.assertEqual(math.atan2(0., 0.), 0.)
    216         self.assertEqual(math.atan2(0., 2.3), 0.)
    217         self.assertEqual(math.atan2(0., INF), 0.)
    218         self.assertTrue(math.isnan(math.atan2(0., NAN)))
    219         # math.atan2(-0, x)
    220         self.ftest('atan2(-0., -inf)', math.atan2(-0., NINF), -math.pi)
    221         self.ftest('atan2(-0., -2.3)', math.atan2(-0., -2.3), -math.pi)
    222         self.ftest('atan2(-0., -0.)', math.atan2(-0., -0.), -math.pi)
    223         self.assertEqual(math.atan2(-0., 0.), -0.)
    224         self.assertEqual(math.atan2(-0., 2.3), -0.)
    225         self.assertEqual(math.atan2(-0., INF), -0.)
    226         self.assertTrue(math.isnan(math.atan2(-0., NAN)))
    227         # math.atan2(INF, x)
    228         self.ftest('atan2(inf, -inf)', math.atan2(INF, NINF), math.pi*3/4)
    229         self.ftest('atan2(inf, -2.3)', math.atan2(INF, -2.3), math.pi/2)
    230         self.ftest('atan2(inf, -0.)', math.atan2(INF, -0.0), math.pi/2)
    231         self.ftest('atan2(inf, 0.)', math.atan2(INF, 0.0), math.pi/2)
    232         self.ftest('atan2(inf, 2.3)', math.atan2(INF, 2.3), math.pi/2)
    233         self.ftest('atan2(inf, inf)', math.atan2(INF, INF), math.pi/4)
    234         self.assertTrue(math.isnan(math.atan2(INF, NAN)))
    235         # math.atan2(NINF, x)
    236         self.ftest('atan2(-inf, -inf)', math.atan2(NINF, NINF), -math.pi*3/4)
    237         self.ftest('atan2(-inf, -2.3)', math.atan2(NINF, -2.3), -math.pi/2)
    238         self.ftest('atan2(-inf, -0.)', math.atan2(NINF, -0.0), -math.pi/2)
    239         self.ftest('atan2(-inf, 0.)', math.atan2(NINF, 0.0), -math.pi/2)
    240         self.ftest('atan2(-inf, 2.3)', math.atan2(NINF, 2.3), -math.pi/2)
    241         self.ftest('atan2(-inf, inf)', math.atan2(NINF, INF), -math.pi/4)
    242         self.assertTrue(math.isnan(math.atan2(NINF, NAN)))
    243         # math.atan2(+finite, x)
    244         self.ftest('atan2(2.3, -inf)', math.atan2(2.3, NINF), math.pi)
    245         self.ftest('atan2(2.3, -0.)', math.atan2(2.3, -0.), math.pi/2)
    246         self.ftest('atan2(2.3, 0.)', math.atan2(2.3, 0.), math.pi/2)
    247         self.assertEqual(math.atan2(2.3, INF), 0.)
    248         self.assertTrue(math.isnan(math.atan2(2.3, NAN)))
    249         # math.atan2(-finite, x)
    250         self.ftest('atan2(-2.3, -inf)', math.atan2(-2.3, NINF), -math.pi)
    251         self.ftest('atan2(-2.3, -0.)', math.atan2(-2.3, -0.), -math.pi/2)
    252         self.ftest('atan2(-2.3, 0.)', math.atan2(-2.3, 0.), -math.pi/2)
    253         self.assertEqual(math.atan2(-2.3, INF), -0.)
    254         self.assertTrue(math.isnan(math.atan2(-2.3, NAN)))
    255         # math.atan2(NAN, x)
    256         self.assertTrue(math.isnan(math.atan2(NAN, NINF)))
    257         self.assertTrue(math.isnan(math.atan2(NAN, -2.3)))
    258         self.assertTrue(math.isnan(math.atan2(NAN, -0.)))
    259         self.assertTrue(math.isnan(math.atan2(NAN, 0.)))
    260         self.assertTrue(math.isnan(math.atan2(NAN, 2.3)))
    261         self.assertTrue(math.isnan(math.atan2(NAN, INF)))
    262         self.assertTrue(math.isnan(math.atan2(NAN, NAN)))
    263 
    264     def testCeil(self):
    265         self.assertRaises(TypeError, math.ceil)
    266         # These types will be int in py3k.
    267         self.assertEqual(float, type(math.ceil(1)))
    268         self.assertEqual(float, type(math.ceil(1L)))
    269         self.assertEqual(float, type(math.ceil(1.0)))
    270         self.ftest('ceil(0.5)', math.ceil(0.5), 1)
    271         self.ftest('ceil(1.0)', math.ceil(1.0), 1)
    272         self.ftest('ceil(1.5)', math.ceil(1.5), 2)
    273         self.ftest('ceil(-0.5)', math.ceil(-0.5), 0)
    274         self.ftest('ceil(-1.0)', math.ceil(-1.0), -1)
    275         self.ftest('ceil(-1.5)', math.ceil(-1.5), -1)
    276         self.assertEqual(math.ceil(INF), INF)
    277         self.assertEqual(math.ceil(NINF), NINF)
    278         self.assertTrue(math.isnan(math.ceil(NAN)))
    279 
    280         class TestCeil(object):
    281             def __float__(self):
    282                 return 41.3
    283         class TestNoCeil(object):
    284             pass
    285         self.ftest('ceil(TestCeil())', math.ceil(TestCeil()), 42)
    286         self.assertRaises(TypeError, math.ceil, TestNoCeil())
    287 
    288         t = TestNoCeil()
    289         t.__ceil__ = lambda *args: args
    290         self.assertRaises(TypeError, math.ceil, t)
    291         self.assertRaises(TypeError, math.ceil, t, 0)
    292 
    293     @requires_IEEE_754
    294     def testCopysign(self):
    295         self.assertEqual(math.copysign(1, 42), 1.0)
    296         self.assertEqual(math.copysign(0., 42), 0.0)
    297         self.assertEqual(math.copysign(1., -42), -1.0)
    298         self.assertEqual(math.copysign(3, 0.), 3.0)
    299         self.assertEqual(math.copysign(4., -0.), -4.0)
    300 
    301         self.assertRaises(TypeError, math.copysign)
    302         # copysign should let us distinguish signs of zeros
    303         self.assertEqual(math.copysign(1., 0.), 1.)
    304         self.assertEqual(math.copysign(1., -0.), -1.)
    305         self.assertEqual(math.copysign(INF, 0.), INF)
    306         self.assertEqual(math.copysign(INF, -0.), NINF)
    307         self.assertEqual(math.copysign(NINF, 0.), INF)
    308         self.assertEqual(math.copysign(NINF, -0.), NINF)
    309         # and of infinities
    310         self.assertEqual(math.copysign(1., INF), 1.)
    311         self.assertEqual(math.copysign(1., NINF), -1.)
    312         self.assertEqual(math.copysign(INF, INF), INF)
    313         self.assertEqual(math.copysign(INF, NINF), NINF)
    314         self.assertEqual(math.copysign(NINF, INF), INF)
    315         self.assertEqual(math.copysign(NINF, NINF), NINF)
    316         self.assertTrue(math.isnan(math.copysign(NAN, 1.)))
    317         self.assertTrue(math.isnan(math.copysign(NAN, INF)))
    318         self.assertTrue(math.isnan(math.copysign(NAN, NINF)))
    319         self.assertTrue(math.isnan(math.copysign(NAN, NAN)))
    320         # copysign(INF, NAN) may be INF or it may be NINF, since
    321         # we don't know whether the sign bit of NAN is set on any
    322         # given platform.
    323         self.assertTrue(math.isinf(math.copysign(INF, NAN)))
    324         # similarly, copysign(2., NAN) could be 2. or -2.
    325         self.assertEqual(abs(math.copysign(2., NAN)), 2.)
    326 
    327     def testCos(self):
    328         self.assertRaises(TypeError, math.cos)
    329         self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0)
    330         self.ftest('cos(0)', math.cos(0), 1)
    331         self.ftest('cos(pi/2)', math.cos(math.pi/2), 0)
    332         self.ftest('cos(pi)', math.cos(math.pi), -1)
    333         try:
    334             self.assertTrue(math.isnan(math.cos(INF)))
    335             self.assertTrue(math.isnan(math.cos(NINF)))
    336         except ValueError:
    337             self.assertRaises(ValueError, math.cos, INF)
    338             self.assertRaises(ValueError, math.cos, NINF)
    339         self.assertTrue(math.isnan(math.cos(NAN)))
    340 
    341     def testCosh(self):
    342         self.assertRaises(TypeError, math.cosh)
    343         self.ftest('cosh(0)', math.cosh(0), 1)
    344         self.ftest('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
    345         self.assertEqual(math.cosh(INF), INF)
    346         self.assertEqual(math.cosh(NINF), INF)
    347         self.assertTrue(math.isnan(math.cosh(NAN)))
    348 
    349     def testDegrees(self):
    350         self.assertRaises(TypeError, math.degrees)
    351         self.ftest('degrees(pi)', math.degrees(math.pi), 180.0)
    352         self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
    353         self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
    354 
    355     def testExp(self):
    356         self.assertRaises(TypeError, math.exp)
    357         self.ftest('exp(-1)', math.exp(-1), 1/math.e)
    358         self.ftest('exp(0)', math.exp(0), 1)
    359         self.ftest('exp(1)', math.exp(1), math.e)
    360         self.assertEqual(math.exp(INF), INF)
    361         self.assertEqual(math.exp(NINF), 0.)
    362         self.assertTrue(math.isnan(math.exp(NAN)))
    363 
    364     def testFabs(self):
    365         self.assertRaises(TypeError, math.fabs)
    366         self.ftest('fabs(-1)', math.fabs(-1), 1)
    367         self.ftest('fabs(0)', math.fabs(0), 0)
    368         self.ftest('fabs(1)', math.fabs(1), 1)
    369 
    370     def testFactorial(self):
    371         def fact(n):
    372             result = 1
    373             for i in range(1, int(n)+1):
    374                 result *= i
    375             return result
    376         values = range(10) + [50, 100, 500]
    377         random.shuffle(values)
    378         for x in values:
    379             for cast in (int, long, float):
    380                 self.assertEqual(math.factorial(cast(x)), fact(x), (x, fact(x), math.factorial(x)))
    381         self.assertRaises(ValueError, math.factorial, -1)
    382         self.assertRaises(ValueError, math.factorial, math.pi)
    383 
    384     def testFloor(self):
    385         self.assertRaises(TypeError, math.floor)
    386         # These types will be int in py3k.
    387         self.assertEqual(float, type(math.floor(1)))
    388         self.assertEqual(float, type(math.floor(1L)))
    389         self.assertEqual(float, type(math.floor(1.0)))
    390         self.ftest('floor(0.5)', math.floor(0.5), 0)
    391         self.ftest('floor(1.0)', math.floor(1.0), 1)
    392         self.ftest('floor(1.5)', math.floor(1.5), 1)
    393         self.ftest('floor(-0.5)', math.floor(-0.5), -1)
    394         self.ftest('floor(-1.0)', math.floor(-1.0), -1)
    395         self.ftest('floor(-1.5)', math.floor(-1.5), -2)
    396         # pow() relies on floor() to check for integers
    397         # This fails on some platforms - so check it here
    398         self.ftest('floor(1.23e167)', math.floor(1.23e167), 1.23e167)
    399         self.ftest('floor(-1.23e167)', math.floor(-1.23e167), -1.23e167)
    400         self.assertEqual(math.ceil(INF), INF)
    401         self.assertEqual(math.ceil(NINF), NINF)
    402         self.assertTrue(math.isnan(math.floor(NAN)))
    403 
    404         class TestFloor(object):
    405             def __float__(self):
    406                 return 42.3
    407         class TestNoFloor(object):
    408             pass
    409         self.ftest('floor(TestFloor())', math.floor(TestFloor()), 42)
    410         self.assertRaises(TypeError, math.floor, TestNoFloor())
    411 
    412         t = TestNoFloor()
    413         t.__floor__ = lambda *args: args
    414         self.assertRaises(TypeError, math.floor, t)
    415         self.assertRaises(TypeError, math.floor, t, 0)
    416 
    417     def testFmod(self):
    418         self.assertRaises(TypeError, math.fmod)
    419         self.ftest('fmod(10,1)', math.fmod(10,1), 0)
    420         self.ftest('fmod(10,0.5)', math.fmod(10,0.5), 0)
    421         self.ftest('fmod(10,1.5)', math.fmod(10,1.5), 1)
    422         self.ftest('fmod(-10,1)', math.fmod(-10,1), 0)
    423         self.ftest('fmod(-10,0.5)', math.fmod(-10,0.5), 0)
    424         self.ftest('fmod(-10,1.5)', math.fmod(-10,1.5), -1)
    425         self.assertTrue(math.isnan(math.fmod(NAN, 1.)))
    426         self.assertTrue(math.isnan(math.fmod(1., NAN)))
    427         self.assertTrue(math.isnan(math.fmod(NAN, NAN)))
    428         self.assertRaises(ValueError, math.fmod, 1., 0.)
    429         self.assertRaises(ValueError, math.fmod, INF, 1.)
    430         self.assertRaises(ValueError, math.fmod, NINF, 1.)
    431         self.assertRaises(ValueError, math.fmod, INF, 0.)
    432         self.assertEqual(math.fmod(3.0, INF), 3.0)
    433         self.assertEqual(math.fmod(-3.0, INF), -3.0)
    434         self.assertEqual(math.fmod(3.0, NINF), 3.0)
    435         self.assertEqual(math.fmod(-3.0, NINF), -3.0)
    436         self.assertEqual(math.fmod(0.0, 3.0), 0.0)
    437         self.assertEqual(math.fmod(0.0, NINF), 0.0)
    438 
    439     def testFrexp(self):
    440         self.assertRaises(TypeError, math.frexp)
    441 
    442         def testfrexp(name, result, expected):
    443             (mant, exp), (emant, eexp) = result, expected
    444             if abs(mant-emant) > eps or exp != eexp:
    445                 self.fail('%s returned %r, expected %r'%\
    446                           (name, (mant, exp), (emant,eexp)))
    447 
    448         testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
    449         testfrexp('frexp(0)', math.frexp(0), (0, 0))
    450         testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
    451         testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
    452 
    453         self.assertEqual(math.frexp(INF)[0], INF)
    454         self.assertEqual(math.frexp(NINF)[0], NINF)
    455         self.assertTrue(math.isnan(math.frexp(NAN)[0]))
    456 
    457     @requires_IEEE_754
    458     @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
    459                          "fsum is not exact on machines with double rounding")
    460     def testFsum(self):
    461         # math.fsum relies on exact rounding for correct operation.
    462         # There's a known problem with IA32 floating-point that causes
    463         # inexact rounding in some situations, and will cause the
    464         # math.fsum tests below to fail; see issue #2937.  On non IEEE
    465         # 754 platforms, and on IEEE 754 platforms that exhibit the
    466         # problem described in issue #2937, we simply skip the whole
    467         # test.
    468 
    469         # Python version of math.fsum, for comparison.  Uses a
    470         # different algorithm based on frexp, ldexp and integer
    471         # arithmetic.
    472         from sys import float_info
    473         mant_dig = float_info.mant_dig
    474         etiny = float_info.min_exp - mant_dig
    475 
    476         def msum(iterable):
    477             """Full precision summation.  Compute sum(iterable) without any
    478             intermediate accumulation of error.  Based on the 'lsum' function
    479             at http://code.activestate.com/recipes/393090/
    480 
    481             """
    482             tmant, texp = 0, 0
    483             for x in iterable:
    484                 mant, exp = math.frexp(x)
    485                 mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig
    486                 if texp > exp:
    487                     tmant <<= texp-exp
    488                     texp = exp
    489                 else:
    490                     mant <<= exp-texp
    491                 tmant += mant
    492             # Round tmant * 2**texp to a float.  The original recipe
    493             # used float(str(tmant)) * 2.0**texp for this, but that's
    494             # a little unsafe because str -> float conversion can't be
    495             # relied upon to do correct rounding on all platforms.
    496             tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp)
    497             if tail > 0:
    498                 h = 1 << (tail-1)
    499                 tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1)
    500                 texp += tail
    501             return math.ldexp(tmant, texp)
    502 
    503         test_values = [
    504             ([], 0.0),
    505             ([0.0], 0.0),
    506             ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
    507             ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
    508             ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
    509             ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
    510             ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
    511             ([1./n for n in range(1, 1001)],
    512              float.fromhex('0x1.df11f45f4e61ap+2')),
    513             ([(-1.)**n/n for n in range(1, 1001)],
    514              float.fromhex('-0x1.62a2af1bd3624p-1')),
    515             ([1.7**(i+1)-1.7**i for i in range(1000)] + [-1.7**1000], -1.0),
    516             ([1e16, 1., 1e-16], 10000000000000002.0),
    517             ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
    518             # exercise code for resizing partials array
    519             ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] +
    520              [-2.**1022],
    521              float.fromhex('0x1.5555555555555p+970')),
    522             ]
    523 
    524         for i, (vals, expected) in enumerate(test_values):
    525             try:
    526                 actual = math.fsum(vals)
    527             except OverflowError:
    528                 self.fail("test %d failed: got OverflowError, expected %r "
    529                           "for math.fsum(%.100r)" % (i, expected, vals))
    530             except ValueError:
    531                 self.fail("test %d failed: got ValueError, expected %r "
    532                           "for math.fsum(%.100r)" % (i, expected, vals))
    533             self.assertEqual(actual, expected)
    534 
    535         from random import random, gauss, shuffle
    536         for j in xrange(1000):
    537             vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
    538             s = 0
    539             for i in xrange(200):
    540                 v = gauss(0, random()) ** 7 - s
    541                 s += v
    542                 vals.append(v)
    543             shuffle(vals)
    544 
    545             s = msum(vals)
    546             self.assertEqual(msum(vals), math.fsum(vals))
    547 
    548     def testHypot(self):
    549         self.assertRaises(TypeError, math.hypot)
    550         self.ftest('hypot(0,0)', math.hypot(0,0), 0)
    551         self.ftest('hypot(3,4)', math.hypot(3,4), 5)
    552         self.assertEqual(math.hypot(NAN, INF), INF)
    553         self.assertEqual(math.hypot(INF, NAN), INF)
    554         self.assertEqual(math.hypot(NAN, NINF), INF)
    555         self.assertEqual(math.hypot(NINF, NAN), INF)
    556         self.assertTrue(math.isnan(math.hypot(1.0, NAN)))
    557         self.assertTrue(math.isnan(math.hypot(NAN, -2.0)))
    558 
    559     def testLdexp(self):
    560         self.assertRaises(TypeError, math.ldexp)
    561         self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
    562         self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
    563         self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
    564         self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
    565         self.assertRaises(OverflowError, math.ldexp, 1., 1000000)
    566         self.assertRaises(OverflowError, math.ldexp, -1., 1000000)
    567         self.assertEqual(math.ldexp(1., -1000000), 0.)
    568         self.assertEqual(math.ldexp(-1., -1000000), -0.)
    569         self.assertEqual(math.ldexp(INF, 30), INF)
    570         self.assertEqual(math.ldexp(NINF, -213), NINF)
    571         self.assertTrue(math.isnan(math.ldexp(NAN, 0)))
    572 
    573         # large second argument
    574         for n in [10**5, 10L**5, 10**10, 10L**10, 10**20, 10**40]:
    575             self.assertEqual(math.ldexp(INF, -n), INF)
    576             self.assertEqual(math.ldexp(NINF, -n), NINF)
    577             self.assertEqual(math.ldexp(1., -n), 0.)
    578             self.assertEqual(math.ldexp(-1., -n), -0.)
    579             self.assertEqual(math.ldexp(0., -n), 0.)
    580             self.assertEqual(math.ldexp(-0., -n), -0.)
    581             self.assertTrue(math.isnan(math.ldexp(NAN, -n)))
    582 
    583             self.assertRaises(OverflowError, math.ldexp, 1., n)
    584             self.assertRaises(OverflowError, math.ldexp, -1., n)
    585             self.assertEqual(math.ldexp(0., n), 0.)
    586             self.assertEqual(math.ldexp(-0., n), -0.)
    587             self.assertEqual(math.ldexp(INF, n), INF)
    588             self.assertEqual(math.ldexp(NINF, n), NINF)
    589             self.assertTrue(math.isnan(math.ldexp(NAN, n)))
    590 
    591     def testLog(self):
    592         self.assertRaises(TypeError, math.log)
    593         self.ftest('log(1/e)', math.log(1/math.e), -1)
    594         self.ftest('log(1)', math.log(1), 0)
    595         self.ftest('log(e)', math.log(math.e), 1)
    596         self.ftest('log(32,2)', math.log(32,2), 5)
    597         self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
    598         self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
    599         self.assertEqual(math.log(INF), INF)
    600         self.assertRaises(ValueError, math.log, NINF)
    601         self.assertTrue(math.isnan(math.log(NAN)))
    602         # Log values should match for int and long (issue #18739).
    603         for n in range(1, 1000):
    604             self.assertEqual(math.log(n), math.log(long(n)))
    605 
    606     def testLog1p(self):
    607         self.assertRaises(TypeError, math.log1p)
    608         self.ftest('log1p(1/e -1)', math.log1p(1/math.e-1), -1)
    609         self.ftest('log1p(0)', math.log1p(0), 0)
    610         self.ftest('log1p(e-1)', math.log1p(math.e-1), 1)
    611         self.ftest('log1p(1)', math.log1p(1), math.log(2))
    612         self.assertEqual(math.log1p(INF), INF)
    613         self.assertRaises(ValueError, math.log1p, NINF)
    614         self.assertTrue(math.isnan(math.log1p(NAN)))
    615         n= 2**90
    616         self.assertAlmostEqual(math.log1p(n), 62.383246250395075)
    617         self.assertAlmostEqual(math.log1p(n), math.log1p(float(n)))
    618 
    619     def testLog10(self):
    620         self.assertRaises(TypeError, math.log10)
    621         self.ftest('log10(0.1)', math.log10(0.1), -1)
    622         self.ftest('log10(1)', math.log10(1), 0)
    623         self.ftest('log10(10)', math.log10(10), 1)
    624         self.assertEqual(math.log(INF), INF)
    625         self.assertRaises(ValueError, math.log10, NINF)
    626         self.assertTrue(math.isnan(math.log10(NAN)))
    627         # Log values should match for int and long (issue #18739).
    628         for n in range(1, 1000):
    629             self.assertEqual(math.log10(n), math.log10(long(n)))
    630 
    631     def testModf(self):
    632         self.assertRaises(TypeError, math.modf)
    633 
    634         def testmodf(name, result, expected):
    635             (v1, v2), (e1, e2) = result, expected
    636             if abs(v1-e1) > eps or abs(v2-e2):
    637                 self.fail('%s returned %r, expected %r'%\
    638                           (name, (v1,v2), (e1,e2)))
    639 
    640         testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
    641         testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
    642 
    643         self.assertEqual(math.modf(INF), (0.0, INF))
    644         self.assertEqual(math.modf(NINF), (-0.0, NINF))
    645 
    646         modf_nan = math.modf(NAN)
    647         self.assertTrue(math.isnan(modf_nan[0]))
    648         self.assertTrue(math.isnan(modf_nan[1]))
    649 
    650     def testPow(self):
    651         self.assertRaises(TypeError, math.pow)
    652         self.ftest('pow(0,1)', math.pow(0,1), 0)
    653         self.ftest('pow(1,0)', math.pow(1,0), 1)
    654         self.ftest('pow(2,1)', math.pow(2,1), 2)
    655         self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
    656         self.assertEqual(math.pow(INF, 1), INF)
    657         self.assertEqual(math.pow(NINF, 1), NINF)
    658         self.assertEqual((math.pow(1, INF)), 1.)
    659         self.assertEqual((math.pow(1, NINF)), 1.)
    660         self.assertTrue(math.isnan(math.pow(NAN, 1)))
    661         self.assertTrue(math.isnan(math.pow(2, NAN)))
    662         self.assertTrue(math.isnan(math.pow(0, NAN)))
    663         self.assertEqual(math.pow(1, NAN), 1)
    664 
    665         # pow(0., x)
    666         self.assertEqual(math.pow(0., INF), 0.)
    667         self.assertEqual(math.pow(0., 3.), 0.)
    668         self.assertEqual(math.pow(0., 2.3), 0.)
    669         self.assertEqual(math.pow(0., 2.), 0.)
    670         self.assertEqual(math.pow(0., 0.), 1.)
    671         self.assertEqual(math.pow(0., -0.), 1.)
    672         self.assertRaises(ValueError, math.pow, 0., -2.)
    673         self.assertRaises(ValueError, math.pow, 0., -2.3)
    674         self.assertRaises(ValueError, math.pow, 0., -3.)
    675         self.assertRaises(ValueError, math.pow, 0., NINF)
    676         self.assertTrue(math.isnan(math.pow(0., NAN)))
    677 
    678         # pow(INF, x)
    679         self.assertEqual(math.pow(INF, INF), INF)
    680         self.assertEqual(math.pow(INF, 3.), INF)
    681         self.assertEqual(math.pow(INF, 2.3), INF)
    682         self.assertEqual(math.pow(INF, 2.), INF)
    683         self.assertEqual(math.pow(INF, 0.), 1.)
    684         self.assertEqual(math.pow(INF, -0.), 1.)
    685         self.assertEqual(math.pow(INF, -2.), 0.)
    686         self.assertEqual(math.pow(INF, -2.3), 0.)
    687         self.assertEqual(math.pow(INF, -3.), 0.)
    688         self.assertEqual(math.pow(INF, NINF), 0.)
    689         self.assertTrue(math.isnan(math.pow(INF, NAN)))
    690 
    691         # pow(-0., x)
    692         self.assertEqual(math.pow(-0., INF), 0.)
    693         self.assertEqual(math.pow(-0., 3.), -0.)
    694         self.assertEqual(math.pow(-0., 2.3), 0.)
    695         self.assertEqual(math.pow(-0., 2.), 0.)
    696         self.assertEqual(math.pow(-0., 0.), 1.)
    697         self.assertEqual(math.pow(-0., -0.), 1.)
    698         self.assertRaises(ValueError, math.pow, -0., -2.)
    699         self.assertRaises(ValueError, math.pow, -0., -2.3)
    700         self.assertRaises(ValueError, math.pow, -0., -3.)
    701         self.assertRaises(ValueError, math.pow, -0., NINF)
    702         self.assertTrue(math.isnan(math.pow(-0., NAN)))
    703 
    704         # pow(NINF, x)
    705         self.assertEqual(math.pow(NINF, INF), INF)
    706         self.assertEqual(math.pow(NINF, 3.), NINF)
    707         self.assertEqual(math.pow(NINF, 2.3), INF)
    708         self.assertEqual(math.pow(NINF, 2.), INF)
    709         self.assertEqual(math.pow(NINF, 0.), 1.)
    710         self.assertEqual(math.pow(NINF, -0.), 1.)
    711         self.assertEqual(math.pow(NINF, -2.), 0.)
    712         self.assertEqual(math.pow(NINF, -2.3), 0.)
    713         self.assertEqual(math.pow(NINF, -3.), -0.)
    714         self.assertEqual(math.pow(NINF, NINF), 0.)
    715         self.assertTrue(math.isnan(math.pow(NINF, NAN)))
    716 
    717         # pow(-1, x)
    718         self.assertEqual(math.pow(-1., INF), 1.)
    719         self.assertEqual(math.pow(-1., 3.), -1.)
    720         self.assertRaises(ValueError, math.pow, -1., 2.3)
    721         self.assertEqual(math.pow(-1., 2.), 1.)
    722         self.assertEqual(math.pow(-1., 0.), 1.)
    723         self.assertEqual(math.pow(-1., -0.), 1.)
    724         self.assertEqual(math.pow(-1., -2.), 1.)
    725         self.assertRaises(ValueError, math.pow, -1., -2.3)
    726         self.assertEqual(math.pow(-1., -3.), -1.)
    727         self.assertEqual(math.pow(-1., NINF), 1.)
    728         self.assertTrue(math.isnan(math.pow(-1., NAN)))
    729 
    730         # pow(1, x)
    731         self.assertEqual(math.pow(1., INF), 1.)
    732         self.assertEqual(math.pow(1., 3.), 1.)
    733         self.assertEqual(math.pow(1., 2.3), 1.)
    734         self.assertEqual(math.pow(1., 2.), 1.)
    735         self.assertEqual(math.pow(1., 0.), 1.)
    736         self.assertEqual(math.pow(1., -0.), 1.)
    737         self.assertEqual(math.pow(1., -2.), 1.)
    738         self.assertEqual(math.pow(1., -2.3), 1.)
    739         self.assertEqual(math.pow(1., -3.), 1.)
    740         self.assertEqual(math.pow(1., NINF), 1.)
    741         self.assertEqual(math.pow(1., NAN), 1.)
    742 
    743         # pow(x, 0) should be 1 for any x
    744         self.assertEqual(math.pow(2.3, 0.), 1.)
    745         self.assertEqual(math.pow(-2.3, 0.), 1.)
    746         self.assertEqual(math.pow(NAN, 0.), 1.)
    747         self.assertEqual(math.pow(2.3, -0.), 1.)
    748         self.assertEqual(math.pow(-2.3, -0.), 1.)
    749         self.assertEqual(math.pow(NAN, -0.), 1.)
    750 
    751         # pow(x, y) is invalid if x is negative and y is not integral
    752         self.assertRaises(ValueError, math.pow, -1., 2.3)
    753         self.assertRaises(ValueError, math.pow, -15., -3.1)
    754 
    755         # pow(x, NINF)
    756         self.assertEqual(math.pow(1.9, NINF), 0.)
    757         self.assertEqual(math.pow(1.1, NINF), 0.)
    758         self.assertEqual(math.pow(0.9, NINF), INF)
    759         self.assertEqual(math.pow(0.1, NINF), INF)
    760         self.assertEqual(math.pow(-0.1, NINF), INF)
    761         self.assertEqual(math.pow(-0.9, NINF), INF)
    762         self.assertEqual(math.pow(-1.1, NINF), 0.)
    763         self.assertEqual(math.pow(-1.9, NINF), 0.)
    764 
    765         # pow(x, INF)
    766         self.assertEqual(math.pow(1.9, INF), INF)
    767         self.assertEqual(math.pow(1.1, INF), INF)
    768         self.assertEqual(math.pow(0.9, INF), 0.)
    769         self.assertEqual(math.pow(0.1, INF), 0.)
    770         self.assertEqual(math.pow(-0.1, INF), 0.)
    771         self.assertEqual(math.pow(-0.9, INF), 0.)
    772         self.assertEqual(math.pow(-1.1, INF), INF)
    773         self.assertEqual(math.pow(-1.9, INF), INF)
    774 
    775         # pow(x, y) should work for x negative, y an integer
    776         self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
    777         self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
    778         self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
    779         self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
    780         self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
    781         self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
    782         self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
    783         self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
    784         self.assertRaises(ValueError, math.pow, -2.0, -0.5)
    785         self.assertRaises(ValueError, math.pow, -2.0, 0.5)
    786 
    787         # the following tests have been commented out since they don't
    788         # really belong here:  the implementation of ** for floats is
    789         # independent of the implementation of math.pow
    790         #self.assertEqual(1**NAN, 1)
    791         #self.assertEqual(1**INF, 1)
    792         #self.assertEqual(1**NINF, 1)
    793         #self.assertEqual(1**0, 1)
    794         #self.assertEqual(1.**NAN, 1)
    795         #self.assertEqual(1.**INF, 1)
    796         #self.assertEqual(1.**NINF, 1)
    797         #self.assertEqual(1.**0, 1)
    798 
    799     def testRadians(self):
    800         self.assertRaises(TypeError, math.radians)
    801         self.ftest('radians(180)', math.radians(180), math.pi)
    802         self.ftest('radians(90)', math.radians(90), math.pi/2)
    803         self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
    804 
    805     def testSin(self):
    806         self.assertRaises(TypeError, math.sin)
    807         self.ftest('sin(0)', math.sin(0), 0)
    808         self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
    809         self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
    810         try:
    811             self.assertTrue(math.isnan(math.sin(INF)))
    812             self.assertTrue(math.isnan(math.sin(NINF)))
    813         except ValueError:
    814             self.assertRaises(ValueError, math.sin, INF)
    815             self.assertRaises(ValueError, math.sin, NINF)
    816         self.assertTrue(math.isnan(math.sin(NAN)))
    817 
    818     def testSinh(self):
    819         self.assertRaises(TypeError, math.sinh)
    820         self.ftest('sinh(0)', math.sinh(0), 0)
    821         self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
    822         self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
    823         self.assertEqual(math.sinh(INF), INF)
    824         self.assertEqual(math.sinh(NINF), NINF)
    825         self.assertTrue(math.isnan(math.sinh(NAN)))
    826 
    827     def testSqrt(self):
    828         self.assertRaises(TypeError, math.sqrt)
    829         self.ftest('sqrt(0)', math.sqrt(0), 0)
    830         self.ftest('sqrt(1)', math.sqrt(1), 1)
    831         self.ftest('sqrt(4)', math.sqrt(4), 2)
    832         self.assertEqual(math.sqrt(INF), INF)
    833         self.assertRaises(ValueError, math.sqrt, NINF)
    834         self.assertTrue(math.isnan(math.sqrt(NAN)))
    835 
    836     def testTan(self):
    837         self.assertRaises(TypeError, math.tan)
    838         self.ftest('tan(0)', math.tan(0), 0)
    839         self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
    840         self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
    841         try:
    842             self.assertTrue(math.isnan(math.tan(INF)))
    843             self.assertTrue(math.isnan(math.tan(NINF)))
    844         except:
    845             self.assertRaises(ValueError, math.tan, INF)
    846             self.assertRaises(ValueError, math.tan, NINF)
    847         self.assertTrue(math.isnan(math.tan(NAN)))
    848 
    849     def testTanh(self):
    850         self.assertRaises(TypeError, math.tanh)
    851         self.ftest('tanh(0)', math.tanh(0), 0)
    852         self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
    853         self.ftest('tanh(inf)', math.tanh(INF), 1)
    854         self.ftest('tanh(-inf)', math.tanh(NINF), -1)
    855         self.assertTrue(math.isnan(math.tanh(NAN)))
    856         # check that tanh(-0.) == -0. on IEEE 754 systems
    857         if float.__getformat__("double").startswith("IEEE"):
    858             self.assertEqual(math.tanh(-0.), -0.)
    859             self.assertEqual(math.copysign(1., math.tanh(-0.)),
    860                              math.copysign(1., -0.))
    861 
    862     def test_trunc(self):
    863         self.assertEqual(math.trunc(1), 1)
    864         self.assertEqual(math.trunc(-1), -1)
    865         self.assertEqual(type(math.trunc(1)), int)
    866         self.assertEqual(type(math.trunc(1.5)), int)
    867         self.assertEqual(math.trunc(1.5), 1)
    868         self.assertEqual(math.trunc(-1.5), -1)
    869         self.assertEqual(math.trunc(1.999999), 1)
    870         self.assertEqual(math.trunc(-1.999999), -1)
    871         self.assertEqual(math.trunc(-0.999999), -0)
    872         self.assertEqual(math.trunc(-100.999), -100)
    873 
    874         class TestTrunc(object):
    875             def __trunc__(self):
    876                 return 23
    877 
    878         class TestNoTrunc(object):
    879             pass
    880 
    881         self.assertEqual(math.trunc(TestTrunc()), 23)
    882 
    883         self.assertRaises(TypeError, math.trunc)
    884         self.assertRaises(TypeError, math.trunc, 1, 2)
    885         self.assertRaises((AttributeError, TypeError), math.trunc,
    886                           TestNoTrunc())
    887 
    888     def testIsnan(self):
    889         self.assertTrue(math.isnan(float("nan")))
    890         self.assertTrue(math.isnan(float("inf")* 0.))
    891         self.assertFalse(math.isnan(float("inf")))
    892         self.assertFalse(math.isnan(0.))
    893         self.assertFalse(math.isnan(1.))
    894 
    895     def testIsinf(self):
    896         self.assertTrue(math.isinf(float("inf")))
    897         self.assertTrue(math.isinf(float("-inf")))
    898         self.assertTrue(math.isinf(1E400))
    899         self.assertTrue(math.isinf(-1E400))
    900         self.assertFalse(math.isinf(float("nan")))
    901         self.assertFalse(math.isinf(0.))
    902         self.assertFalse(math.isinf(1.))
    903 
    904     # RED_FLAG 16-Oct-2000 Tim
    905     # While 2.0 is more consistent about exceptions than previous releases, it
    906     # still fails this part of the test on some platforms.  For now, we only
    907     # *run* test_exceptions() in verbose mode, so that this isn't normally
    908     # tested.
    909     @unittest.skipUnless(verbose, 'requires verbose mode')
    910     def test_exceptions(self):
    911         try:
    912             x = math.exp(-1000000000)
    913         except:
    914             # mathmodule.c is failing to weed out underflows from libm, or
    915             # we've got an fp format with huge dynamic range
    916             self.fail("underflowing exp() should not have raised "
    917                         "an exception")
    918         if x != 0:
    919             self.fail("underflowing exp() should have returned 0")
    920 
    921         # If this fails, probably using a strict IEEE-754 conforming libm, and x
    922         # is +Inf afterwards.  But Python wants overflows detected by default.
    923         try:
    924             x = math.exp(1000000000)
    925         except OverflowError:
    926             pass
    927         else:
    928             self.fail("overflowing exp() didn't trigger OverflowError")
    929 
    930         # If this fails, it could be a puzzle.  One odd possibility is that
    931         # mathmodule.c's macros are getting confused while comparing
    932         # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
    933         # as a result (and so raising OverflowError instead).
    934         try:
    935             x = math.sqrt(-1.0)
    936         except ValueError:
    937             pass
    938         else:
    939             self.fail("sqrt(-1) didn't raise ValueError")
    940 
    941     @requires_IEEE_754
    942     def test_testfile(self):
    943         for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
    944             # Skip if either the input or result is complex, or if
    945             # flags is nonempty
    946             if ai != 0. or ei != 0. or flags:
    947                 continue
    948             if fn in ['rect', 'polar']:
    949                 # no real versions of rect, polar
    950                 continue
    951             func = getattr(math, fn)
    952             try:
    953                 result = func(ar)
    954             except ValueError:
    955                 message = ("Unexpected ValueError in " +
    956                            "test %s:%s(%r)\n" % (id, fn, ar))
    957                 self.fail(message)
    958             except OverflowError:
    959                 message = ("Unexpected OverflowError in " +
    960                            "test %s:%s(%r)\n" % (id, fn, ar))
    961                 self.fail(message)
    962             self.ftest("%s:%s(%r)" % (id, fn, ar), result, er)
    963 
    964     @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
    965                          "test requires IEEE 754 doubles")
    966     def test_mtestfile(self):
    967         ALLOWED_ERROR = 20  # permitted error, in ulps
    968         fail_fmt = "{}:{}({!r}): expected {!r}, got {!r}"
    969 
    970         failures = []
    971         for id, fn, arg, expected, flags in parse_mtestfile(math_testcases):
    972             func = getattr(math, fn)
    973 
    974             if 'invalid' in flags or 'divide-by-zero' in flags:
    975                 expected = 'ValueError'
    976             elif 'overflow' in flags:
    977                 expected = 'OverflowError'
    978 
    979             try:
    980                 got = func(arg)
    981             except ValueError:
    982                 got = 'ValueError'
    983             except OverflowError:
    984                 got = 'OverflowError'
    985 
    986             accuracy_failure = None
    987             if isinstance(got, float) and isinstance(expected, float):
    988                 if math.isnan(expected) and math.isnan(got):
    989                     continue
    990                 if not math.isnan(expected) and not math.isnan(got):
    991                     if fn == 'lgamma':
    992                         # we use a weaker accuracy test for lgamma;
    993                         # lgamma only achieves an absolute error of
    994                         # a few multiples of the machine accuracy, in
    995                         # general.
    996                         accuracy_failure = acc_check(expected, got,
    997                                                   rel_err = 5e-15,
    998                                                   abs_err = 5e-15)
    999                     elif fn == 'erfc':
   1000                         # erfc has less-than-ideal accuracy for large
   1001                         # arguments (x ~ 25 or so), mainly due to the
   1002                         # error involved in computing exp(-x*x).
   1003                         #
   1004                         # XXX Would be better to weaken this test only
   1005                         # for large x, instead of for all x.
   1006                         accuracy_failure = ulps_check(expected, got, 2000)
   1007 
   1008                     else:
   1009                         accuracy_failure = ulps_check(expected, got, 20)
   1010                     if accuracy_failure is None:
   1011                         continue
   1012 
   1013             if isinstance(got, str) and isinstance(expected, str):
   1014                 if got == expected:
   1015                     continue
   1016 
   1017             fail_msg = fail_fmt.format(id, fn, arg, expected, got)
   1018             if accuracy_failure is not None:
   1019                 fail_msg += ' ({})'.format(accuracy_failure)
   1020             failures.append(fail_msg)
   1021 
   1022         if failures:
   1023             self.fail('Failures in test_mtestfile:\n  ' +
   1024                       '\n  '.join(failures))
   1025 
   1026 
   1027 def test_main():
   1028     from doctest import DocFileSuite
   1029     suite = unittest.TestSuite()
   1030     suite.addTest(unittest.makeSuite(MathTests))
   1031     suite.addTest(DocFileSuite("ieee754.txt"))
   1032     run_unittest(suite)
   1033 
   1034 if __name__ == '__main__':
   1035     test_main()
   1036