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
603    def testLog1p(self):
604        self.assertRaises(TypeError, math.log1p)
605        self.ftest('log1p(1/e -1)', math.log1p(1/math.e-1), -1)
606        self.ftest('log1p(0)', math.log1p(0), 0)
607        self.ftest('log1p(e-1)', math.log1p(math.e-1), 1)
608        self.ftest('log1p(1)', math.log1p(1), math.log(2))
609        self.assertEqual(math.log1p(INF), INF)
610        self.assertRaises(ValueError, math.log1p, NINF)
611        self.assertTrue(math.isnan(math.log1p(NAN)))
612        n= 2**90
613        self.assertAlmostEqual(math.log1p(n), 62.383246250395075)
614        self.assertAlmostEqual(math.log1p(n), math.log1p(float(n)))
615
616    def testLog10(self):
617        self.assertRaises(TypeError, math.log10)
618        self.ftest('log10(0.1)', math.log10(0.1), -1)
619        self.ftest('log10(1)', math.log10(1), 0)
620        self.ftest('log10(10)', math.log10(10), 1)
621        self.assertEqual(math.log(INF), INF)
622        self.assertRaises(ValueError, math.log10, NINF)
623        self.assertTrue(math.isnan(math.log10(NAN)))
624
625    def testModf(self):
626        self.assertRaises(TypeError, math.modf)
627
628        def testmodf(name, result, expected):
629            (v1, v2), (e1, e2) = result, expected
630            if abs(v1-e1) > eps or abs(v2-e2):
631                self.fail('%s returned %r, expected %r'%\
632                          (name, (v1,v2), (e1,e2)))
633
634        testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
635        testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
636
637        self.assertEqual(math.modf(INF), (0.0, INF))
638        self.assertEqual(math.modf(NINF), (-0.0, NINF))
639
640        modf_nan = math.modf(NAN)
641        self.assertTrue(math.isnan(modf_nan[0]))
642        self.assertTrue(math.isnan(modf_nan[1]))
643
644    def testPow(self):
645        self.assertRaises(TypeError, math.pow)
646        self.ftest('pow(0,1)', math.pow(0,1), 0)
647        self.ftest('pow(1,0)', math.pow(1,0), 1)
648        self.ftest('pow(2,1)', math.pow(2,1), 2)
649        self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
650        self.assertEqual(math.pow(INF, 1), INF)
651        self.assertEqual(math.pow(NINF, 1), NINF)
652        self.assertEqual((math.pow(1, INF)), 1.)
653        self.assertEqual((math.pow(1, NINF)), 1.)
654        self.assertTrue(math.isnan(math.pow(NAN, 1)))
655        self.assertTrue(math.isnan(math.pow(2, NAN)))
656        self.assertTrue(math.isnan(math.pow(0, NAN)))
657        self.assertEqual(math.pow(1, NAN), 1)
658
659        # pow(0., x)
660        self.assertEqual(math.pow(0., INF), 0.)
661        self.assertEqual(math.pow(0., 3.), 0.)
662        self.assertEqual(math.pow(0., 2.3), 0.)
663        self.assertEqual(math.pow(0., 2.), 0.)
664        self.assertEqual(math.pow(0., 0.), 1.)
665        self.assertEqual(math.pow(0., -0.), 1.)
666        self.assertRaises(ValueError, math.pow, 0., -2.)
667        self.assertRaises(ValueError, math.pow, 0., -2.3)
668        self.assertRaises(ValueError, math.pow, 0., -3.)
669        self.assertRaises(ValueError, math.pow, 0., NINF)
670        self.assertTrue(math.isnan(math.pow(0., NAN)))
671
672        # pow(INF, x)
673        self.assertEqual(math.pow(INF, INF), INF)
674        self.assertEqual(math.pow(INF, 3.), INF)
675        self.assertEqual(math.pow(INF, 2.3), INF)
676        self.assertEqual(math.pow(INF, 2.), INF)
677        self.assertEqual(math.pow(INF, 0.), 1.)
678        self.assertEqual(math.pow(INF, -0.), 1.)
679        self.assertEqual(math.pow(INF, -2.), 0.)
680        self.assertEqual(math.pow(INF, -2.3), 0.)
681        self.assertEqual(math.pow(INF, -3.), 0.)
682        self.assertEqual(math.pow(INF, NINF), 0.)
683        self.assertTrue(math.isnan(math.pow(INF, NAN)))
684
685        # pow(-0., x)
686        self.assertEqual(math.pow(-0., INF), 0.)
687        self.assertEqual(math.pow(-0., 3.), -0.)
688        self.assertEqual(math.pow(-0., 2.3), 0.)
689        self.assertEqual(math.pow(-0., 2.), 0.)
690        self.assertEqual(math.pow(-0., 0.), 1.)
691        self.assertEqual(math.pow(-0., -0.), 1.)
692        self.assertRaises(ValueError, math.pow, -0., -2.)
693        self.assertRaises(ValueError, math.pow, -0., -2.3)
694        self.assertRaises(ValueError, math.pow, -0., -3.)
695        self.assertRaises(ValueError, math.pow, -0., NINF)
696        self.assertTrue(math.isnan(math.pow(-0., NAN)))
697
698        # pow(NINF, x)
699        self.assertEqual(math.pow(NINF, INF), INF)
700        self.assertEqual(math.pow(NINF, 3.), NINF)
701        self.assertEqual(math.pow(NINF, 2.3), INF)
702        self.assertEqual(math.pow(NINF, 2.), INF)
703        self.assertEqual(math.pow(NINF, 0.), 1.)
704        self.assertEqual(math.pow(NINF, -0.), 1.)
705        self.assertEqual(math.pow(NINF, -2.), 0.)
706        self.assertEqual(math.pow(NINF, -2.3), 0.)
707        self.assertEqual(math.pow(NINF, -3.), -0.)
708        self.assertEqual(math.pow(NINF, NINF), 0.)
709        self.assertTrue(math.isnan(math.pow(NINF, NAN)))
710
711        # pow(-1, x)
712        self.assertEqual(math.pow(-1., INF), 1.)
713        self.assertEqual(math.pow(-1., 3.), -1.)
714        self.assertRaises(ValueError, math.pow, -1., 2.3)
715        self.assertEqual(math.pow(-1., 2.), 1.)
716        self.assertEqual(math.pow(-1., 0.), 1.)
717        self.assertEqual(math.pow(-1., -0.), 1.)
718        self.assertEqual(math.pow(-1., -2.), 1.)
719        self.assertRaises(ValueError, math.pow, -1., -2.3)
720        self.assertEqual(math.pow(-1., -3.), -1.)
721        self.assertEqual(math.pow(-1., NINF), 1.)
722        self.assertTrue(math.isnan(math.pow(-1., NAN)))
723
724        # pow(1, x)
725        self.assertEqual(math.pow(1., INF), 1.)
726        self.assertEqual(math.pow(1., 3.), 1.)
727        self.assertEqual(math.pow(1., 2.3), 1.)
728        self.assertEqual(math.pow(1., 2.), 1.)
729        self.assertEqual(math.pow(1., 0.), 1.)
730        self.assertEqual(math.pow(1., -0.), 1.)
731        self.assertEqual(math.pow(1., -2.), 1.)
732        self.assertEqual(math.pow(1., -2.3), 1.)
733        self.assertEqual(math.pow(1., -3.), 1.)
734        self.assertEqual(math.pow(1., NINF), 1.)
735        self.assertEqual(math.pow(1., NAN), 1.)
736
737        # pow(x, 0) should be 1 for any x
738        self.assertEqual(math.pow(2.3, 0.), 1.)
739        self.assertEqual(math.pow(-2.3, 0.), 1.)
740        self.assertEqual(math.pow(NAN, 0.), 1.)
741        self.assertEqual(math.pow(2.3, -0.), 1.)
742        self.assertEqual(math.pow(-2.3, -0.), 1.)
743        self.assertEqual(math.pow(NAN, -0.), 1.)
744
745        # pow(x, y) is invalid if x is negative and y is not integral
746        self.assertRaises(ValueError, math.pow, -1., 2.3)
747        self.assertRaises(ValueError, math.pow, -15., -3.1)
748
749        # pow(x, NINF)
750        self.assertEqual(math.pow(1.9, NINF), 0.)
751        self.assertEqual(math.pow(1.1, NINF), 0.)
752        self.assertEqual(math.pow(0.9, NINF), INF)
753        self.assertEqual(math.pow(0.1, NINF), INF)
754        self.assertEqual(math.pow(-0.1, NINF), INF)
755        self.assertEqual(math.pow(-0.9, NINF), INF)
756        self.assertEqual(math.pow(-1.1, NINF), 0.)
757        self.assertEqual(math.pow(-1.9, NINF), 0.)
758
759        # pow(x, INF)
760        self.assertEqual(math.pow(1.9, INF), INF)
761        self.assertEqual(math.pow(1.1, INF), INF)
762        self.assertEqual(math.pow(0.9, INF), 0.)
763        self.assertEqual(math.pow(0.1, INF), 0.)
764        self.assertEqual(math.pow(-0.1, INF), 0.)
765        self.assertEqual(math.pow(-0.9, INF), 0.)
766        self.assertEqual(math.pow(-1.1, INF), INF)
767        self.assertEqual(math.pow(-1.9, INF), INF)
768
769        # pow(x, y) should work for x negative, y an integer
770        self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
771        self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
772        self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
773        self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
774        self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
775        self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
776        self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
777        self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
778        self.assertRaises(ValueError, math.pow, -2.0, -0.5)
779        self.assertRaises(ValueError, math.pow, -2.0, 0.5)
780
781        # the following tests have been commented out since they don't
782        # really belong here:  the implementation of ** for floats is
783        # independent of the implementation of math.pow
784        #self.assertEqual(1**NAN, 1)
785        #self.assertEqual(1**INF, 1)
786        #self.assertEqual(1**NINF, 1)
787        #self.assertEqual(1**0, 1)
788        #self.assertEqual(1.**NAN, 1)
789        #self.assertEqual(1.**INF, 1)
790        #self.assertEqual(1.**NINF, 1)
791        #self.assertEqual(1.**0, 1)
792
793    def testRadians(self):
794        self.assertRaises(TypeError, math.radians)
795        self.ftest('radians(180)', math.radians(180), math.pi)
796        self.ftest('radians(90)', math.radians(90), math.pi/2)
797        self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
798
799    def testSin(self):
800        self.assertRaises(TypeError, math.sin)
801        self.ftest('sin(0)', math.sin(0), 0)
802        self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
803        self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
804        try:
805            self.assertTrue(math.isnan(math.sin(INF)))
806            self.assertTrue(math.isnan(math.sin(NINF)))
807        except ValueError:
808            self.assertRaises(ValueError, math.sin, INF)
809            self.assertRaises(ValueError, math.sin, NINF)
810        self.assertTrue(math.isnan(math.sin(NAN)))
811
812    def testSinh(self):
813        self.assertRaises(TypeError, math.sinh)
814        self.ftest('sinh(0)', math.sinh(0), 0)
815        self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
816        self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
817        self.assertEqual(math.sinh(INF), INF)
818        self.assertEqual(math.sinh(NINF), NINF)
819        self.assertTrue(math.isnan(math.sinh(NAN)))
820
821    def testSqrt(self):
822        self.assertRaises(TypeError, math.sqrt)
823        self.ftest('sqrt(0)', math.sqrt(0), 0)
824        self.ftest('sqrt(1)', math.sqrt(1), 1)
825        self.ftest('sqrt(4)', math.sqrt(4), 2)
826        self.assertEqual(math.sqrt(INF), INF)
827        self.assertRaises(ValueError, math.sqrt, NINF)
828        self.assertTrue(math.isnan(math.sqrt(NAN)))
829
830    def testTan(self):
831        self.assertRaises(TypeError, math.tan)
832        self.ftest('tan(0)', math.tan(0), 0)
833        self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
834        self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
835        try:
836            self.assertTrue(math.isnan(math.tan(INF)))
837            self.assertTrue(math.isnan(math.tan(NINF)))
838        except:
839            self.assertRaises(ValueError, math.tan, INF)
840            self.assertRaises(ValueError, math.tan, NINF)
841        self.assertTrue(math.isnan(math.tan(NAN)))
842
843    def testTanh(self):
844        self.assertRaises(TypeError, math.tanh)
845        self.ftest('tanh(0)', math.tanh(0), 0)
846        self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
847        self.ftest('tanh(inf)', math.tanh(INF), 1)
848        self.ftest('tanh(-inf)', math.tanh(NINF), -1)
849        self.assertTrue(math.isnan(math.tanh(NAN)))
850        # check that tanh(-0.) == -0. on IEEE 754 systems
851        if float.__getformat__("double").startswith("IEEE"):
852            self.assertEqual(math.tanh(-0.), -0.)
853            self.assertEqual(math.copysign(1., math.tanh(-0.)),
854                             math.copysign(1., -0.))
855
856    def test_trunc(self):
857        self.assertEqual(math.trunc(1), 1)
858        self.assertEqual(math.trunc(-1), -1)
859        self.assertEqual(type(math.trunc(1)), int)
860        self.assertEqual(type(math.trunc(1.5)), int)
861        self.assertEqual(math.trunc(1.5), 1)
862        self.assertEqual(math.trunc(-1.5), -1)
863        self.assertEqual(math.trunc(1.999999), 1)
864        self.assertEqual(math.trunc(-1.999999), -1)
865        self.assertEqual(math.trunc(-0.999999), -0)
866        self.assertEqual(math.trunc(-100.999), -100)
867
868        class TestTrunc(object):
869            def __trunc__(self):
870                return 23
871
872        class TestNoTrunc(object):
873            pass
874
875        self.assertEqual(math.trunc(TestTrunc()), 23)
876
877        self.assertRaises(TypeError, math.trunc)
878        self.assertRaises(TypeError, math.trunc, 1, 2)
879        self.assertRaises((AttributeError, TypeError), math.trunc,
880                          TestNoTrunc())
881
882    def testIsnan(self):
883        self.assertTrue(math.isnan(float("nan")))
884        self.assertTrue(math.isnan(float("inf")* 0.))
885        self.assertFalse(math.isnan(float("inf")))
886        self.assertFalse(math.isnan(0.))
887        self.assertFalse(math.isnan(1.))
888
889    def testIsinf(self):
890        self.assertTrue(math.isinf(float("inf")))
891        self.assertTrue(math.isinf(float("-inf")))
892        self.assertTrue(math.isinf(1E400))
893        self.assertTrue(math.isinf(-1E400))
894        self.assertFalse(math.isinf(float("nan")))
895        self.assertFalse(math.isinf(0.))
896        self.assertFalse(math.isinf(1.))
897
898    # RED_FLAG 16-Oct-2000 Tim
899    # While 2.0 is more consistent about exceptions than previous releases, it
900    # still fails this part of the test on some platforms.  For now, we only
901    # *run* test_exceptions() in verbose mode, so that this isn't normally
902    # tested.
903
904    if verbose:
905        def test_exceptions(self):
906            try:
907                x = math.exp(-1000000000)
908            except:
909                # mathmodule.c is failing to weed out underflows from libm, or
910                # we've got an fp format with huge dynamic range
911                self.fail("underflowing exp() should not have raised "
912                          "an exception")
913            if x != 0:
914                self.fail("underflowing exp() should have returned 0")
915
916            # If this fails, probably using a strict IEEE-754 conforming libm, and x
917            # is +Inf afterwards.  But Python wants overflows detected by default.
918            try:
919                x = math.exp(1000000000)
920            except OverflowError:
921                pass
922            else:
923                self.fail("overflowing exp() didn't trigger OverflowError")
924
925            # If this fails, it could be a puzzle.  One odd possibility is that
926            # mathmodule.c's macros are getting confused while comparing
927            # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
928            # as a result (and so raising OverflowError instead).
929            try:
930                x = math.sqrt(-1.0)
931            except ValueError:
932                pass
933            else:
934                self.fail("sqrt(-1) didn't raise ValueError")
935
936    @requires_IEEE_754
937    def test_testfile(self):
938        for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
939            # Skip if either the input or result is complex, or if
940            # flags is nonempty
941            if ai != 0. or ei != 0. or flags:
942                continue
943            if fn in ['rect', 'polar']:
944                # no real versions of rect, polar
945                continue
946            func = getattr(math, fn)
947            try:
948                result = func(ar)
949            except ValueError:
950                message = ("Unexpected ValueError in " +
951                           "test %s:%s(%r)\n" % (id, fn, ar))
952                self.fail(message)
953            except OverflowError:
954                message = ("Unexpected OverflowError in " +
955                           "test %s:%s(%r)\n" % (id, fn, ar))
956                self.fail(message)
957            self.ftest("%s:%s(%r)" % (id, fn, ar), result, er)
958
959    @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
960                         "test requires IEEE 754 doubles")
961    def test_mtestfile(self):
962        ALLOWED_ERROR = 20  # permitted error, in ulps
963        fail_fmt = "{}:{}({!r}): expected {!r}, got {!r}"
964
965        failures = []
966        for id, fn, arg, expected, flags in parse_mtestfile(math_testcases):
967            func = getattr(math, fn)
968
969            if 'invalid' in flags or 'divide-by-zero' in flags:
970                expected = 'ValueError'
971            elif 'overflow' in flags:
972                expected = 'OverflowError'
973
974            try:
975                got = func(arg)
976            except ValueError:
977                got = 'ValueError'
978            except OverflowError:
979                got = 'OverflowError'
980
981            accuracy_failure = None
982            if isinstance(got, float) and isinstance(expected, float):
983                if math.isnan(expected) and math.isnan(got):
984                    continue
985                if not math.isnan(expected) and not math.isnan(got):
986                    if fn == 'lgamma':
987                        # we use a weaker accuracy test for lgamma;
988                        # lgamma only achieves an absolute error of
989                        # a few multiples of the machine accuracy, in
990                        # general.
991                        accuracy_failure = acc_check(expected, got,
992                                                  rel_err = 5e-15,
993                                                  abs_err = 5e-15)
994                    elif fn == 'erfc':
995                        # erfc has less-than-ideal accuracy for large
996                        # arguments (x ~ 25 or so), mainly due to the
997                        # error involved in computing exp(-x*x).
998                        #
999                        # XXX Would be better to weaken this test only
1000                        # for large x, instead of for all x.
1001                        accuracy_failure = ulps_check(expected, got, 2000)
1002
1003                    else:
1004                        accuracy_failure = ulps_check(expected, got, 20)
1005                    if accuracy_failure is None:
1006                        continue
1007
1008            if isinstance(got, str) and isinstance(expected, str):
1009                if got == expected:
1010                    continue
1011
1012            fail_msg = fail_fmt.format(id, fn, arg, expected, got)
1013            if accuracy_failure is not None:
1014                fail_msg += ' ({})'.format(accuracy_failure)
1015            failures.append(fail_msg)
1016
1017        if failures:
1018            self.fail('Failures in test_mtestfile:\n  ' +
1019                      '\n  '.join(failures))
1020
1021
1022def test_main():
1023    from doctest import DocFileSuite
1024    suite = unittest.TestSuite()
1025    suite.addTest(unittest.makeSuite(MathTests))
1026    suite.addTest(DocFileSuite("ieee754.txt"))
1027    run_unittest(suite)
1028
1029if __name__ == '__main__':
1030    test_main()
1031