• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Python test set -- math module
2# XXXX Should not do tests around zero only
3
4from test.test_support import run_unittest, verbose
5import unittest
6import math
7import os
8import sys
9import random
10import struct
11
12eps = 1E-05
13NAN = float('nan')
14INF = float('inf')
15NINF = float('-inf')
16
17# decorator for skipping tests on non-IEEE 754 platforms
18requires_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.
24x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer
25HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4)
26
27# locate file with test values
28if __name__ == '__main__':
29    file = sys.argv[0]
30else:
31    file = __file__
32test_dir = os.path.dirname(file) or os.curdir
33math_testcases = os.path.join(test_dir, 'math_testcases.txt')
34test_file = os.path.join(test_dir, 'cmath_testcases.txt')
35
36def 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
51def 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
63def 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
82def 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
107def 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
131class 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
1027def 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
1034if __name__ == '__main__':
1035    test_main()
1036