• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Python test set -- math module
2# XXXX Should not do tests around zero only
3
4from test.support import verbose, requires_IEEE_754
5from test import support
6import unittest
7import fractions
8import itertools
9import decimal
10import math
11import os
12import platform
13import random
14import struct
15import sys
16
17
18eps = 1E-05
19NAN = float('nan')
20INF = float('inf')
21NINF = float('-inf')
22FLOAT_MAX = sys.float_info.max
23FLOAT_MIN = sys.float_info.min
24
25# detect evidence of double-rounding: fsum is not always correctly
26# rounded on machines that suffer from double rounding.
27x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer
28HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4)
29
30# locate file with test values
31if __name__ == '__main__':
32    file = sys.argv[0]
33else:
34    file = __file__
35test_dir = os.path.dirname(file) or os.curdir
36math_testcases = os.path.join(test_dir, 'mathdata', 'math_testcases.txt')
37test_file = os.path.join(test_dir, 'mathdata', 'cmath_testcases.txt')
38
39
40def to_ulps(x):
41    """Convert a non-NaN float x to an integer, in such a way that
42    adjacent floats are converted to adjacent integers.  Then
43    abs(ulps(x) - ulps(y)) gives the difference in ulps between two
44    floats.
45
46    The results from this function will only make sense on platforms
47    where native doubles are represented in IEEE 754 binary64 format.
48
49    Note: 0.0 and -0.0 are converted to 0 and -1, respectively.
50    """
51    n = struct.unpack('<q', struct.pack('<d', x))[0]
52    if n < 0:
53        n = ~(n+2**63)
54    return n
55
56
57# Here's a pure Python version of the math.factorial algorithm, for
58# documentation and comparison purposes.
59#
60# Formula:
61#
62#   factorial(n) = factorial_odd_part(n) << (n - count_set_bits(n))
63#
64# where
65#
66#   factorial_odd_part(n) = product_{i >= 0} product_{0 < j <= n >> i; j odd} j
67#
68# The outer product above is an infinite product, but once i >= n.bit_length,
69# (n >> i) < 1 and the corresponding term of the product is empty.  So only the
70# finitely many terms for 0 <= i < n.bit_length() contribute anything.
71#
72# We iterate downwards from i == n.bit_length() - 1 to i == 0.  The inner
73# product in the formula above starts at 1 for i == n.bit_length(); for each i
74# < n.bit_length() we get the inner product for i from that for i + 1 by
75# multiplying by all j in {n >> i+1 < j <= n >> i; j odd}.  In Python terms,
76# this set is range((n >> i+1) + 1 | 1, (n >> i) + 1 | 1, 2).
77
78def count_set_bits(n):
79    """Number of '1' bits in binary expansion of a nonnnegative integer."""
80    return 1 + count_set_bits(n & n - 1) if n else 0
81
82def partial_product(start, stop):
83    """Product of integers in range(start, stop, 2), computed recursively.
84    start and stop should both be odd, with start <= stop.
85
86    """
87    numfactors = (stop - start) >> 1
88    if not numfactors:
89        return 1
90    elif numfactors == 1:
91        return start
92    else:
93        mid = (start + numfactors) | 1
94        return partial_product(start, mid) * partial_product(mid, stop)
95
96def py_factorial(n):
97    """Factorial of nonnegative integer n, via "Binary Split Factorial Formula"
98    described at http://www.luschny.de/math/factorial/binarysplitfact.html
99
100    """
101    inner = outer = 1
102    for i in reversed(range(n.bit_length())):
103        inner *= partial_product((n >> i + 1) + 1 | 1, (n >> i) + 1 | 1)
104        outer *= inner
105    return outer << (n - count_set_bits(n))
106
107def ulp_abs_check(expected, got, ulp_tol, abs_tol):
108    """Given finite floats `expected` and `got`, check that they're
109    approximately equal to within the given number of ulps or the
110    given absolute tolerance, whichever is bigger.
111
112    Returns None on success and an error message on failure.
113    """
114    ulp_error = abs(to_ulps(expected) - to_ulps(got))
115    abs_error = abs(expected - got)
116
117    # Succeed if either abs_error <= abs_tol or ulp_error <= ulp_tol.
118    if abs_error <= abs_tol or ulp_error <= ulp_tol:
119        return None
120    else:
121        fmt = ("error = {:.3g} ({:d} ulps); "
122               "permitted error = {:.3g} or {:d} ulps")
123        return fmt.format(abs_error, ulp_error, abs_tol, ulp_tol)
124
125def parse_mtestfile(fname):
126    """Parse a file with test values
127
128    -- starts a comment
129    blank lines, or lines containing only a comment, are ignored
130    other lines are expected to have the form
131      id fn arg -> expected [flag]*
132
133    """
134    with open(fname, encoding="utf-8") as fp:
135        for line in fp:
136            # strip comments, and skip blank lines
137            if '--' in line:
138                line = line[:line.index('--')]
139            if not line.strip():
140                continue
141
142            lhs, rhs = line.split('->')
143            id, fn, arg = lhs.split()
144            rhs_pieces = rhs.split()
145            exp = rhs_pieces[0]
146            flags = rhs_pieces[1:]
147
148            yield (id, fn, float(arg), float(exp), flags)
149
150
151def parse_testfile(fname):
152    """Parse a file with test values
153
154    Empty lines or lines starting with -- are ignored
155    yields id, fn, arg_real, arg_imag, exp_real, exp_imag
156    """
157    with open(fname, encoding="utf-8") as fp:
158        for line in fp:
159            # skip comment lines and blank lines
160            if line.startswith('--') or not line.strip():
161                continue
162
163            lhs, rhs = line.split('->')
164            id, fn, arg_real, arg_imag = lhs.split()
165            rhs_pieces = rhs.split()
166            exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1]
167            flags = rhs_pieces[2:]
168
169            yield (id, fn,
170                   float(arg_real), float(arg_imag),
171                   float(exp_real), float(exp_imag),
172                   flags)
173
174
175def result_check(expected, got, ulp_tol=5, abs_tol=0.0):
176    # Common logic of MathTests.(ftest, test_testcases, test_mtestcases)
177    """Compare arguments expected and got, as floats, if either
178    is a float, using a tolerance expressed in multiples of
179    ulp(expected) or absolutely (if given and greater).
180
181    As a convenience, when neither argument is a float, and for
182    non-finite floats, exact equality is demanded. Also, nan==nan
183    as far as this function is concerned.
184
185    Returns None on success and an error message on failure.
186    """
187
188    # Check exactly equal (applies also to strings representing exceptions)
189    if got == expected:
190        if not got and not expected:
191            if math.copysign(1, got) != math.copysign(1, expected):
192                return f"expected {expected}, got {got} (zero has wrong sign)"
193        return None
194
195    failure = "not equal"
196
197    # Turn mixed float and int comparison (e.g. floor()) to all-float
198    if isinstance(expected, float) and isinstance(got, int):
199        got = float(got)
200    elif isinstance(got, float) and isinstance(expected, int):
201        expected = float(expected)
202
203    if isinstance(expected, float) and isinstance(got, float):
204        if math.isnan(expected) and math.isnan(got):
205            # Pass, since both nan
206            failure = None
207        elif math.isinf(expected) or math.isinf(got):
208            # We already know they're not equal, drop through to failure
209            pass
210        else:
211            # Both are finite floats (now). Are they close enough?
212            failure = ulp_abs_check(expected, got, ulp_tol, abs_tol)
213
214    # arguments are not equal, and if numeric, are too far apart
215    if failure is not None:
216        fail_fmt = "expected {!r}, got {!r}"
217        fail_msg = fail_fmt.format(expected, got)
218        fail_msg += ' ({})'.format(failure)
219        return fail_msg
220    else:
221        return None
222
223class FloatLike:
224    def __init__(self, value):
225        self.value = value
226
227    def __float__(self):
228        return self.value
229
230class IntSubclass(int):
231    pass
232
233# Class providing an __index__ method.
234class MyIndexable(object):
235    def __init__(self, value):
236        self.value = value
237
238    def __index__(self):
239        return self.value
240
241class BadDescr:
242    def __get__(self, obj, objtype=None):
243        raise ValueError
244
245class MathTests(unittest.TestCase):
246
247    def ftest(self, name, got, expected, ulp_tol=5, abs_tol=0.0):
248        """Compare arguments expected and got, as floats, if either
249        is a float, using a tolerance expressed in multiples of
250        ulp(expected) or absolutely, whichever is greater.
251
252        As a convenience, when neither argument is a float, and for
253        non-finite floats, exact equality is demanded. Also, nan==nan
254        in this function.
255        """
256        failure = result_check(expected, got, ulp_tol, abs_tol)
257        if failure is not None:
258            self.fail("{}: {}".format(name, failure))
259
260    def testConstants(self):
261        # Ref: Abramowitz & Stegun (Dover, 1965)
262        self.ftest('pi', math.pi, 3.141592653589793238462643)
263        self.ftest('e', math.e, 2.718281828459045235360287)
264        self.assertEqual(math.tau, 2*math.pi)
265
266    def testAcos(self):
267        self.assertRaises(TypeError, math.acos)
268        self.ftest('acos(-1)', math.acos(-1), math.pi)
269        self.ftest('acos(0)', math.acos(0), math.pi/2)
270        self.ftest('acos(1)', math.acos(1), 0)
271        self.assertRaises(ValueError, math.acos, INF)
272        self.assertRaises(ValueError, math.acos, NINF)
273        self.assertRaises(ValueError, math.acos, 1 + eps)
274        self.assertRaises(ValueError, math.acos, -1 - eps)
275        self.assertTrue(math.isnan(math.acos(NAN)))
276
277    def testAcosh(self):
278        self.assertRaises(TypeError, math.acosh)
279        self.ftest('acosh(1)', math.acosh(1), 0)
280        self.ftest('acosh(2)', math.acosh(2), 1.3169578969248168)
281        self.assertRaises(ValueError, math.acosh, 0)
282        self.assertRaises(ValueError, math.acosh, -1)
283        self.assertEqual(math.acosh(INF), INF)
284        self.assertRaises(ValueError, math.acosh, NINF)
285        self.assertTrue(math.isnan(math.acosh(NAN)))
286
287    def testAsin(self):
288        self.assertRaises(TypeError, math.asin)
289        self.ftest('asin(-1)', math.asin(-1), -math.pi/2)
290        self.ftest('asin(0)', math.asin(0), 0)
291        self.ftest('asin(1)', math.asin(1), math.pi/2)
292        self.assertRaises(ValueError, math.asin, INF)
293        self.assertRaises(ValueError, math.asin, NINF)
294        self.assertRaises(ValueError, math.asin, 1 + eps)
295        self.assertRaises(ValueError, math.asin, -1 - eps)
296        self.assertTrue(math.isnan(math.asin(NAN)))
297
298    def testAsinh(self):
299        self.assertRaises(TypeError, math.asinh)
300        self.ftest('asinh(0)', math.asinh(0), 0)
301        self.ftest('asinh(1)', math.asinh(1), 0.88137358701954305)
302        self.ftest('asinh(-1)', math.asinh(-1), -0.88137358701954305)
303        self.assertEqual(math.asinh(INF), INF)
304        self.assertEqual(math.asinh(NINF), NINF)
305        self.assertTrue(math.isnan(math.asinh(NAN)))
306
307    def testAtan(self):
308        self.assertRaises(TypeError, math.atan)
309        self.ftest('atan(-1)', math.atan(-1), -math.pi/4)
310        self.ftest('atan(0)', math.atan(0), 0)
311        self.ftest('atan(1)', math.atan(1), math.pi/4)
312        self.ftest('atan(inf)', math.atan(INF), math.pi/2)
313        self.ftest('atan(-inf)', math.atan(NINF), -math.pi/2)
314        self.assertTrue(math.isnan(math.atan(NAN)))
315
316    def testAtanh(self):
317        self.assertRaises(TypeError, math.atan)
318        self.ftest('atanh(0)', math.atanh(0), 0)
319        self.ftest('atanh(0.5)', math.atanh(0.5), 0.54930614433405489)
320        self.ftest('atanh(-0.5)', math.atanh(-0.5), -0.54930614433405489)
321        self.assertRaises(ValueError, math.atanh, 1)
322        self.assertRaises(ValueError, math.atanh, -1)
323        self.assertRaises(ValueError, math.atanh, INF)
324        self.assertRaises(ValueError, math.atanh, NINF)
325        self.assertTrue(math.isnan(math.atanh(NAN)))
326
327    def testAtan2(self):
328        self.assertRaises(TypeError, math.atan2)
329        self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
330        self.ftest('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
331        self.ftest('atan2(0, 1)', math.atan2(0, 1), 0)
332        self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
333        self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
334        self.ftest('atan2(1, -1)', math.atan2(1, -1), 3*math.pi/4)
335
336        # math.atan2(0, x)
337        self.ftest('atan2(0., -inf)', math.atan2(0., NINF), math.pi)
338        self.ftest('atan2(0., -2.3)', math.atan2(0., -2.3), math.pi)
339        self.ftest('atan2(0., -0.)', math.atan2(0., -0.), math.pi)
340        self.assertEqual(math.atan2(0., 0.), 0.)
341        self.assertEqual(math.atan2(0., 2.3), 0.)
342        self.assertEqual(math.atan2(0., INF), 0.)
343        self.assertTrue(math.isnan(math.atan2(0., NAN)))
344        # math.atan2(-0, x)
345        self.ftest('atan2(-0., -inf)', math.atan2(-0., NINF), -math.pi)
346        self.ftest('atan2(-0., -2.3)', math.atan2(-0., -2.3), -math.pi)
347        self.ftest('atan2(-0., -0.)', math.atan2(-0., -0.), -math.pi)
348        self.assertEqual(math.atan2(-0., 0.), -0.)
349        self.assertEqual(math.atan2(-0., 2.3), -0.)
350        self.assertEqual(math.atan2(-0., INF), -0.)
351        self.assertTrue(math.isnan(math.atan2(-0., NAN)))
352        # math.atan2(INF, x)
353        self.ftest('atan2(inf, -inf)', math.atan2(INF, NINF), math.pi*3/4)
354        self.ftest('atan2(inf, -2.3)', math.atan2(INF, -2.3), math.pi/2)
355        self.ftest('atan2(inf, -0.)', math.atan2(INF, -0.0), math.pi/2)
356        self.ftest('atan2(inf, 0.)', math.atan2(INF, 0.0), math.pi/2)
357        self.ftest('atan2(inf, 2.3)', math.atan2(INF, 2.3), math.pi/2)
358        self.ftest('atan2(inf, inf)', math.atan2(INF, INF), math.pi/4)
359        self.assertTrue(math.isnan(math.atan2(INF, NAN)))
360        # math.atan2(NINF, x)
361        self.ftest('atan2(-inf, -inf)', math.atan2(NINF, NINF), -math.pi*3/4)
362        self.ftest('atan2(-inf, -2.3)', math.atan2(NINF, -2.3), -math.pi/2)
363        self.ftest('atan2(-inf, -0.)', math.atan2(NINF, -0.0), -math.pi/2)
364        self.ftest('atan2(-inf, 0.)', math.atan2(NINF, 0.0), -math.pi/2)
365        self.ftest('atan2(-inf, 2.3)', math.atan2(NINF, 2.3), -math.pi/2)
366        self.ftest('atan2(-inf, inf)', math.atan2(NINF, INF), -math.pi/4)
367        self.assertTrue(math.isnan(math.atan2(NINF, NAN)))
368        # math.atan2(+finite, x)
369        self.ftest('atan2(2.3, -inf)', math.atan2(2.3, NINF), math.pi)
370        self.ftest('atan2(2.3, -0.)', math.atan2(2.3, -0.), math.pi/2)
371        self.ftest('atan2(2.3, 0.)', math.atan2(2.3, 0.), math.pi/2)
372        self.assertEqual(math.atan2(2.3, INF), 0.)
373        self.assertTrue(math.isnan(math.atan2(2.3, NAN)))
374        # math.atan2(-finite, x)
375        self.ftest('atan2(-2.3, -inf)', math.atan2(-2.3, NINF), -math.pi)
376        self.ftest('atan2(-2.3, -0.)', math.atan2(-2.3, -0.), -math.pi/2)
377        self.ftest('atan2(-2.3, 0.)', math.atan2(-2.3, 0.), -math.pi/2)
378        self.assertEqual(math.atan2(-2.3, INF), -0.)
379        self.assertTrue(math.isnan(math.atan2(-2.3, NAN)))
380        # math.atan2(NAN, x)
381        self.assertTrue(math.isnan(math.atan2(NAN, NINF)))
382        self.assertTrue(math.isnan(math.atan2(NAN, -2.3)))
383        self.assertTrue(math.isnan(math.atan2(NAN, -0.)))
384        self.assertTrue(math.isnan(math.atan2(NAN, 0.)))
385        self.assertTrue(math.isnan(math.atan2(NAN, 2.3)))
386        self.assertTrue(math.isnan(math.atan2(NAN, INF)))
387        self.assertTrue(math.isnan(math.atan2(NAN, NAN)))
388
389    def testCbrt(self):
390        self.assertRaises(TypeError, math.cbrt)
391        self.ftest('cbrt(0)', math.cbrt(0), 0)
392        self.ftest('cbrt(1)', math.cbrt(1), 1)
393        self.ftest('cbrt(8)', math.cbrt(8), 2)
394        self.ftest('cbrt(0.0)', math.cbrt(0.0), 0.0)
395        self.ftest('cbrt(-0.0)', math.cbrt(-0.0), -0.0)
396        self.ftest('cbrt(1.2)', math.cbrt(1.2), 1.062658569182611)
397        self.ftest('cbrt(-2.6)', math.cbrt(-2.6), -1.375068867074141)
398        self.ftest('cbrt(27)', math.cbrt(27), 3)
399        self.ftest('cbrt(-1)', math.cbrt(-1), -1)
400        self.ftest('cbrt(-27)', math.cbrt(-27), -3)
401        self.assertEqual(math.cbrt(INF), INF)
402        self.assertEqual(math.cbrt(NINF), NINF)
403        self.assertTrue(math.isnan(math.cbrt(NAN)))
404
405    def testCeil(self):
406        self.assertRaises(TypeError, math.ceil)
407        self.assertEqual(int, type(math.ceil(0.5)))
408        self.assertEqual(math.ceil(0.5), 1)
409        self.assertEqual(math.ceil(1.0), 1)
410        self.assertEqual(math.ceil(1.5), 2)
411        self.assertEqual(math.ceil(-0.5), 0)
412        self.assertEqual(math.ceil(-1.0), -1)
413        self.assertEqual(math.ceil(-1.5), -1)
414        self.assertEqual(math.ceil(0.0), 0)
415        self.assertEqual(math.ceil(-0.0), 0)
416        #self.assertEqual(math.ceil(INF), INF)
417        #self.assertEqual(math.ceil(NINF), NINF)
418        #self.assertTrue(math.isnan(math.ceil(NAN)))
419
420        class TestCeil:
421            def __ceil__(self):
422                return 42
423        class FloatCeil(float):
424            def __ceil__(self):
425                return 42
426        class TestNoCeil:
427            pass
428        class TestBadCeil:
429            __ceil__ = BadDescr()
430        self.assertEqual(math.ceil(TestCeil()), 42)
431        self.assertEqual(math.ceil(FloatCeil()), 42)
432        self.assertEqual(math.ceil(FloatLike(42.5)), 43)
433        self.assertRaises(TypeError, math.ceil, TestNoCeil())
434        self.assertRaises(ValueError, math.ceil, TestBadCeil())
435
436        t = TestNoCeil()
437        t.__ceil__ = lambda *args: args
438        self.assertRaises(TypeError, math.ceil, t)
439        self.assertRaises(TypeError, math.ceil, t, 0)
440
441        self.assertEqual(math.ceil(FloatLike(+1.0)), +1.0)
442        self.assertEqual(math.ceil(FloatLike(-1.0)), -1.0)
443
444    @requires_IEEE_754
445    def testCopysign(self):
446        self.assertEqual(math.copysign(1, 42), 1.0)
447        self.assertEqual(math.copysign(0., 42), 0.0)
448        self.assertEqual(math.copysign(1., -42), -1.0)
449        self.assertEqual(math.copysign(3, 0.), 3.0)
450        self.assertEqual(math.copysign(4., -0.), -4.0)
451
452        self.assertRaises(TypeError, math.copysign)
453        # copysign should let us distinguish signs of zeros
454        self.assertEqual(math.copysign(1., 0.), 1.)
455        self.assertEqual(math.copysign(1., -0.), -1.)
456        self.assertEqual(math.copysign(INF, 0.), INF)
457        self.assertEqual(math.copysign(INF, -0.), NINF)
458        self.assertEqual(math.copysign(NINF, 0.), INF)
459        self.assertEqual(math.copysign(NINF, -0.), NINF)
460        # and of infinities
461        self.assertEqual(math.copysign(1., INF), 1.)
462        self.assertEqual(math.copysign(1., NINF), -1.)
463        self.assertEqual(math.copysign(INF, INF), INF)
464        self.assertEqual(math.copysign(INF, NINF), NINF)
465        self.assertEqual(math.copysign(NINF, INF), INF)
466        self.assertEqual(math.copysign(NINF, NINF), NINF)
467        self.assertTrue(math.isnan(math.copysign(NAN, 1.)))
468        self.assertTrue(math.isnan(math.copysign(NAN, INF)))
469        self.assertTrue(math.isnan(math.copysign(NAN, NINF)))
470        self.assertTrue(math.isnan(math.copysign(NAN, NAN)))
471        # copysign(INF, NAN) may be INF or it may be NINF, since
472        # we don't know whether the sign bit of NAN is set on any
473        # given platform.
474        self.assertTrue(math.isinf(math.copysign(INF, NAN)))
475        # similarly, copysign(2., NAN) could be 2. or -2.
476        self.assertEqual(abs(math.copysign(2., NAN)), 2.)
477
478    def testCos(self):
479        self.assertRaises(TypeError, math.cos)
480        self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0, abs_tol=math.ulp(1))
481        self.ftest('cos(0)', math.cos(0), 1)
482        self.ftest('cos(pi/2)', math.cos(math.pi/2), 0, abs_tol=math.ulp(1))
483        self.ftest('cos(pi)', math.cos(math.pi), -1)
484        try:
485            self.assertTrue(math.isnan(math.cos(INF)))
486            self.assertTrue(math.isnan(math.cos(NINF)))
487        except ValueError:
488            self.assertRaises(ValueError, math.cos, INF)
489            self.assertRaises(ValueError, math.cos, NINF)
490        self.assertTrue(math.isnan(math.cos(NAN)))
491
492    @unittest.skipIf(sys.platform == 'win32' and platform.machine() in ('ARM', 'ARM64'),
493                    "Windows UCRT is off by 2 ULP this test requires accuracy within 1 ULP")
494    def testCosh(self):
495        self.assertRaises(TypeError, math.cosh)
496        self.ftest('cosh(0)', math.cosh(0), 1)
497        self.ftest('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
498        self.assertEqual(math.cosh(INF), INF)
499        self.assertEqual(math.cosh(NINF), INF)
500        self.assertTrue(math.isnan(math.cosh(NAN)))
501
502    def testDegrees(self):
503        self.assertRaises(TypeError, math.degrees)
504        self.ftest('degrees(pi)', math.degrees(math.pi), 180.0)
505        self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
506        self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
507        self.ftest('degrees(0)', math.degrees(0), 0)
508
509    def testExp(self):
510        self.assertRaises(TypeError, math.exp)
511        self.ftest('exp(-1)', math.exp(-1), 1/math.e)
512        self.ftest('exp(0)', math.exp(0), 1)
513        self.ftest('exp(1)', math.exp(1), math.e)
514        self.assertEqual(math.exp(INF), INF)
515        self.assertEqual(math.exp(NINF), 0.)
516        self.assertTrue(math.isnan(math.exp(NAN)))
517        self.assertRaises(OverflowError, math.exp, 1000000)
518
519    def testExp2(self):
520        self.assertRaises(TypeError, math.exp2)
521        self.ftest('exp2(-1)', math.exp2(-1), 0.5)
522        self.ftest('exp2(0)', math.exp2(0), 1)
523        self.ftest('exp2(1)', math.exp2(1), 2)
524        self.ftest('exp2(2.3)', math.exp2(2.3), 4.924577653379665)
525        self.assertEqual(math.exp2(INF), INF)
526        self.assertEqual(math.exp2(NINF), 0.)
527        self.assertTrue(math.isnan(math.exp2(NAN)))
528        self.assertRaises(OverflowError, math.exp2, 1000000)
529
530    def testFabs(self):
531        self.assertRaises(TypeError, math.fabs)
532        self.ftest('fabs(-1)', math.fabs(-1), 1)
533        self.ftest('fabs(0)', math.fabs(0), 0)
534        self.ftest('fabs(1)', math.fabs(1), 1)
535
536    def testFactorial(self):
537        self.assertEqual(math.factorial(0), 1)
538        total = 1
539        for i in range(1, 1000):
540            total *= i
541            self.assertEqual(math.factorial(i), total)
542            self.assertEqual(math.factorial(i), py_factorial(i))
543        self.assertRaises(ValueError, math.factorial, -1)
544        self.assertRaises(ValueError, math.factorial, -10**100)
545
546    def testFactorialNonIntegers(self):
547        self.assertRaises(TypeError, math.factorial, 5.0)
548        self.assertRaises(TypeError, math.factorial, 5.2)
549        self.assertRaises(TypeError, math.factorial, -1.0)
550        self.assertRaises(TypeError, math.factorial, -1e100)
551        self.assertRaises(TypeError, math.factorial, decimal.Decimal('5'))
552        self.assertRaises(TypeError, math.factorial, decimal.Decimal('5.2'))
553        self.assertRaises(TypeError, math.factorial, "5")
554
555    # Other implementations may place different upper bounds.
556    @support.cpython_only
557    def testFactorialHugeInputs(self):
558        # Currently raises OverflowError for inputs that are too large
559        # to fit into a C long.
560        self.assertRaises(OverflowError, math.factorial, 10**100)
561        self.assertRaises(TypeError, math.factorial, 1e100)
562
563    def testFloor(self):
564        self.assertRaises(TypeError, math.floor)
565        self.assertEqual(int, type(math.floor(0.5)))
566        self.assertEqual(math.floor(0.5), 0)
567        self.assertEqual(math.floor(1.0), 1)
568        self.assertEqual(math.floor(1.5), 1)
569        self.assertEqual(math.floor(-0.5), -1)
570        self.assertEqual(math.floor(-1.0), -1)
571        self.assertEqual(math.floor(-1.5), -2)
572        #self.assertEqual(math.ceil(INF), INF)
573        #self.assertEqual(math.ceil(NINF), NINF)
574        #self.assertTrue(math.isnan(math.floor(NAN)))
575
576        class TestFloor:
577            def __floor__(self):
578                return 42
579        class FloatFloor(float):
580            def __floor__(self):
581                return 42
582        class TestNoFloor:
583            pass
584        class TestBadFloor:
585            __floor__ = BadDescr()
586        self.assertEqual(math.floor(TestFloor()), 42)
587        self.assertEqual(math.floor(FloatFloor()), 42)
588        self.assertEqual(math.floor(FloatLike(41.9)), 41)
589        self.assertRaises(TypeError, math.floor, TestNoFloor())
590        self.assertRaises(ValueError, math.floor, TestBadFloor())
591
592        t = TestNoFloor()
593        t.__floor__ = lambda *args: args
594        self.assertRaises(TypeError, math.floor, t)
595        self.assertRaises(TypeError, math.floor, t, 0)
596
597        self.assertEqual(math.floor(FloatLike(+1.0)), +1.0)
598        self.assertEqual(math.floor(FloatLike(-1.0)), -1.0)
599
600    def testFmod(self):
601        self.assertRaises(TypeError, math.fmod)
602        self.ftest('fmod(10, 1)', math.fmod(10, 1), 0.0)
603        self.ftest('fmod(10, 0.5)', math.fmod(10, 0.5), 0.0)
604        self.ftest('fmod(10, 1.5)', math.fmod(10, 1.5), 1.0)
605        self.ftest('fmod(-10, 1)', math.fmod(-10, 1), -0.0)
606        self.ftest('fmod(-10, 0.5)', math.fmod(-10, 0.5), -0.0)
607        self.ftest('fmod(-10, 1.5)', math.fmod(-10, 1.5), -1.0)
608        self.assertTrue(math.isnan(math.fmod(NAN, 1.)))
609        self.assertTrue(math.isnan(math.fmod(1., NAN)))
610        self.assertTrue(math.isnan(math.fmod(NAN, NAN)))
611        self.assertRaises(ValueError, math.fmod, 1., 0.)
612        self.assertRaises(ValueError, math.fmod, INF, 1.)
613        self.assertRaises(ValueError, math.fmod, NINF, 1.)
614        self.assertRaises(ValueError, math.fmod, INF, 0.)
615        self.assertEqual(math.fmod(3.0, INF), 3.0)
616        self.assertEqual(math.fmod(-3.0, INF), -3.0)
617        self.assertEqual(math.fmod(3.0, NINF), 3.0)
618        self.assertEqual(math.fmod(-3.0, NINF), -3.0)
619        self.assertEqual(math.fmod(0.0, 3.0), 0.0)
620        self.assertEqual(math.fmod(0.0, NINF), 0.0)
621        self.assertRaises(ValueError, math.fmod, INF, INF)
622
623    def testFrexp(self):
624        self.assertRaises(TypeError, math.frexp)
625
626        def testfrexp(name, result, expected):
627            (mant, exp), (emant, eexp) = result, expected
628            if abs(mant-emant) > eps or exp != eexp:
629                self.fail('%s returned %r, expected %r'%\
630                          (name, result, expected))
631
632        testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
633        testfrexp('frexp(0)', math.frexp(0), (0, 0))
634        testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
635        testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
636
637        self.assertEqual(math.frexp(INF)[0], INF)
638        self.assertEqual(math.frexp(NINF)[0], NINF)
639        self.assertTrue(math.isnan(math.frexp(NAN)[0]))
640
641    @requires_IEEE_754
642    @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
643                         "fsum is not exact on machines with double rounding")
644    def testFsum(self):
645        # math.fsum relies on exact rounding for correct operation.
646        # There's a known problem with IA32 floating-point that causes
647        # inexact rounding in some situations, and will cause the
648        # math.fsum tests below to fail; see issue #2937.  On non IEEE
649        # 754 platforms, and on IEEE 754 platforms that exhibit the
650        # problem described in issue #2937, we simply skip the whole
651        # test.
652
653        # Python version of math.fsum, for comparison.  Uses a
654        # different algorithm based on frexp, ldexp and integer
655        # arithmetic.
656        from sys import float_info
657        mant_dig = float_info.mant_dig
658        etiny = float_info.min_exp - mant_dig
659
660        def msum(iterable):
661            """Full precision summation.  Compute sum(iterable) without any
662            intermediate accumulation of error.  Based on the 'lsum' function
663            at https://code.activestate.com/recipes/393090-binary-floating-point-summation-accurate-to-full-p/
664
665            """
666            tmant, texp = 0, 0
667            for x in iterable:
668                mant, exp = math.frexp(x)
669                mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig
670                if texp > exp:
671                    tmant <<= texp-exp
672                    texp = exp
673                else:
674                    mant <<= exp-texp
675                tmant += mant
676            # Round tmant * 2**texp to a float.  The original recipe
677            # used float(str(tmant)) * 2.0**texp for this, but that's
678            # a little unsafe because str -> float conversion can't be
679            # relied upon to do correct rounding on all platforms.
680            tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp)
681            if tail > 0:
682                h = 1 << (tail-1)
683                tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1)
684                texp += tail
685            return math.ldexp(tmant, texp)
686
687        test_values = [
688            ([], 0.0),
689            ([0.0], 0.0),
690            ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
691            ([1e100, 1.0, -1e100, 1e-100, 1e50, -1, -1e50], 1e-100),
692            ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
693            ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
694            ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
695            ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
696            ([1./n for n in range(1, 1001)],
697             float.fromhex('0x1.df11f45f4e61ap+2')),
698            ([(-1.)**n/n for n in range(1, 1001)],
699             float.fromhex('-0x1.62a2af1bd3624p-1')),
700            ([1e16, 1., 1e-16], 10000000000000002.0),
701            ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
702            # exercise code for resizing partials array
703            ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] +
704             [-2.**1022],
705             float.fromhex('0x1.5555555555555p+970')),
706            ]
707
708        # Telescoping sum, with exact differences (due to Sterbenz)
709        terms = [1.7**i for i in range(1001)]
710        test_values.append((
711            [terms[i+1] - terms[i] for i in range(1000)] + [-terms[1000]],
712            -terms[0]
713        ))
714
715        for i, (vals, expected) in enumerate(test_values):
716            try:
717                actual = math.fsum(vals)
718            except OverflowError:
719                self.fail("test %d failed: got OverflowError, expected %r "
720                          "for math.fsum(%.100r)" % (i, expected, vals))
721            except ValueError:
722                self.fail("test %d failed: got ValueError, expected %r "
723                          "for math.fsum(%.100r)" % (i, expected, vals))
724            self.assertEqual(actual, expected)
725
726        from random import random, gauss, shuffle
727        for j in range(1000):
728            vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
729            s = 0
730            for i in range(200):
731                v = gauss(0, random()) ** 7 - s
732                s += v
733                vals.append(v)
734            shuffle(vals)
735
736            s = msum(vals)
737            self.assertEqual(msum(vals), math.fsum(vals))
738
739        self.assertEqual(math.fsum([1.0, math.inf]), math.inf)
740        self.assertTrue(math.isnan(math.fsum([math.nan, 1.0])))
741        self.assertEqual(math.fsum([1e100, FloatLike(1.0), -1e100, 1e-100,
742                                    1e50, FloatLike(-1.0), -1e50]), 1e-100)
743        self.assertRaises(OverflowError, math.fsum, [1e+308, 1e+308])
744        self.assertRaises(ValueError, math.fsum, [math.inf, -math.inf])
745        self.assertRaises(TypeError, math.fsum, ['spam'])
746        self.assertRaises(TypeError, math.fsum, 1)
747        self.assertRaises(OverflowError, math.fsum, [10**1000])
748
749        def bad_iter():
750            yield 1.0
751            raise ZeroDivisionError
752
753        self.assertRaises(ZeroDivisionError, math.fsum, bad_iter())
754
755    def testGcd(self):
756        gcd = math.gcd
757        self.assertEqual(gcd(0, 0), 0)
758        self.assertEqual(gcd(1, 0), 1)
759        self.assertEqual(gcd(-1, 0), 1)
760        self.assertEqual(gcd(0, 1), 1)
761        self.assertEqual(gcd(0, -1), 1)
762        self.assertEqual(gcd(7, 1), 1)
763        self.assertEqual(gcd(7, -1), 1)
764        self.assertEqual(gcd(-23, 15), 1)
765        self.assertEqual(gcd(120, 84), 12)
766        self.assertEqual(gcd(84, -120), 12)
767        self.assertEqual(gcd(1216342683557601535506311712,
768                             436522681849110124616458784), 32)
769
770        x = 434610456570399902378880679233098819019853229470286994367836600566
771        y = 1064502245825115327754847244914921553977
772        for c in (652560,
773                  576559230871654959816130551884856912003141446781646602790216406874):
774            a = x * c
775            b = y * c
776            self.assertEqual(gcd(a, b), c)
777            self.assertEqual(gcd(b, a), c)
778            self.assertEqual(gcd(-a, b), c)
779            self.assertEqual(gcd(b, -a), c)
780            self.assertEqual(gcd(a, -b), c)
781            self.assertEqual(gcd(-b, a), c)
782            self.assertEqual(gcd(-a, -b), c)
783            self.assertEqual(gcd(-b, -a), c)
784
785        self.assertEqual(gcd(), 0)
786        self.assertEqual(gcd(120), 120)
787        self.assertEqual(gcd(-120), 120)
788        self.assertEqual(gcd(120, 84, 102), 6)
789        self.assertEqual(gcd(120, 1, 84), 1)
790
791        self.assertRaises(TypeError, gcd, 120.0)
792        self.assertRaises(TypeError, gcd, 120.0, 84)
793        self.assertRaises(TypeError, gcd, 120, 84.0)
794        self.assertRaises(TypeError, gcd, 120, 1, 84.0)
795        self.assertEqual(gcd(MyIndexable(120), MyIndexable(84)), 12)
796
797    def testHypot(self):
798        from decimal import Decimal
799        from fractions import Fraction
800
801        hypot = math.hypot
802
803        # Test different numbers of arguments (from zero to five)
804        # against a straightforward pure python implementation
805        args = math.e, math.pi, math.sqrt(2.0), math.gamma(3.5), math.sin(2.1)
806        for i in range(len(args)+1):
807            self.assertAlmostEqual(
808                hypot(*args[:i]),
809                math.sqrt(sum(s**2 for s in args[:i]))
810            )
811
812        # Test allowable types (those with __float__)
813        self.assertEqual(hypot(12.0, 5.0), 13.0)
814        self.assertEqual(hypot(12, 5), 13)
815        self.assertEqual(hypot(0.75, -1), 1.25)
816        self.assertEqual(hypot(-1, 0.75), 1.25)
817        self.assertEqual(hypot(0.75, FloatLike(-1.)), 1.25)
818        self.assertEqual(hypot(FloatLike(-1.), 0.75), 1.25)
819        self.assertEqual(hypot(Decimal(12), Decimal(5)), 13)
820        self.assertEqual(hypot(Fraction(12, 32), Fraction(5, 32)), Fraction(13, 32))
821        self.assertEqual(hypot(True, False, True, True, True), 2.0)
822
823        # Test corner cases
824        self.assertEqual(hypot(0.0, 0.0), 0.0)     # Max input is zero
825        self.assertEqual(hypot(-10.5), 10.5)       # Negative input
826        self.assertEqual(hypot(), 0.0)             # Negative input
827        self.assertEqual(1.0,
828            math.copysign(1.0, hypot(-0.0))        # Convert negative zero to positive zero
829        )
830        self.assertEqual(                          # Handling of moving max to the end
831            hypot(1.5, 1.5, 0.5),
832            hypot(1.5, 0.5, 1.5),
833        )
834
835        # Test handling of bad arguments
836        with self.assertRaises(TypeError):         # Reject keyword args
837            hypot(x=1)
838        with self.assertRaises(TypeError):         # Reject values without __float__
839            hypot(1.1, 'string', 2.2)
840        int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
841        with self.assertRaises((ValueError, OverflowError)):
842            hypot(1, int_too_big_for_float)
843
844        # Any infinity gives positive infinity.
845        self.assertEqual(hypot(INF), INF)
846        self.assertEqual(hypot(0, INF), INF)
847        self.assertEqual(hypot(10, INF), INF)
848        self.assertEqual(hypot(-10, INF), INF)
849        self.assertEqual(hypot(NAN, INF), INF)
850        self.assertEqual(hypot(INF, NAN), INF)
851        self.assertEqual(hypot(NINF, NAN), INF)
852        self.assertEqual(hypot(NAN, NINF), INF)
853        self.assertEqual(hypot(-INF, INF), INF)
854        self.assertEqual(hypot(-INF, -INF), INF)
855        self.assertEqual(hypot(10, -INF), INF)
856
857        # If no infinity, any NaN gives a NaN.
858        self.assertTrue(math.isnan(hypot(NAN)))
859        self.assertTrue(math.isnan(hypot(0, NAN)))
860        self.assertTrue(math.isnan(hypot(NAN, 10)))
861        self.assertTrue(math.isnan(hypot(10, NAN)))
862        self.assertTrue(math.isnan(hypot(NAN, NAN)))
863        self.assertTrue(math.isnan(hypot(NAN)))
864
865        # Verify scaling for extremely large values
866        fourthmax = FLOAT_MAX / 4.0
867        for n in range(32):
868            self.assertTrue(math.isclose(hypot(*([fourthmax]*n)),
869                                         fourthmax * math.sqrt(n)))
870
871        # Verify scaling for extremely small values
872        for exp in range(32):
873            scale = FLOAT_MIN / 2.0 ** exp
874            self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale)
875
876        self.assertRaises(TypeError, math.hypot, *([1.0]*18), 'spam')
877
878    @requires_IEEE_754
879    @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
880                     "hypot() loses accuracy on machines with double rounding")
881    def testHypotAccuracy(self):
882        # Verify improved accuracy in cases that were known to be inaccurate.
883        #
884        # The new algorithm's accuracy depends on IEEE 754 arithmetic
885        # guarantees, on having the usual ROUND HALF EVEN rounding mode, on
886        # the system not having double rounding due to extended precision,
887        # and on the compiler maintaining the specified order of operations.
888        #
889        # This test is known to succeed on most of our builds.  If it fails
890        # some build, we either need to add another skipIf if the cause is
891        # identifiable; otherwise, we can remove this test entirely.
892
893        hypot = math.hypot
894        Decimal = decimal.Decimal
895        high_precision = decimal.Context(prec=500)
896
897        for hx, hy in [
898            # Cases with a 1 ulp error in Python 3.7 compiled with Clang
899            ('0x1.10e89518dca48p+29', '0x1.1970f7565b7efp+30'),
900            ('0x1.10106eb4b44a2p+29', '0x1.ef0596cdc97f8p+29'),
901            ('0x1.459c058e20bb7p+30', '0x1.993ca009b9178p+29'),
902            ('0x1.378371ae67c0cp+30', '0x1.fbe6619854b4cp+29'),
903            ('0x1.f4cd0574fb97ap+29', '0x1.50fe31669340ep+30'),
904            ('0x1.494b2cdd3d446p+29', '0x1.212a5367b4c7cp+29'),
905            ('0x1.f84e649f1e46dp+29', '0x1.1fa56bef8eec4p+30'),
906            ('0x1.2e817edd3d6fap+30', '0x1.eb0814f1e9602p+29'),
907            ('0x1.0d3a6e3d04245p+29', '0x1.32a62fea52352p+30'),
908            ('0x1.888e19611bfc5p+29', '0x1.52b8e70b24353p+29'),
909
910            # Cases with 2 ulp error in Python 3.8
911            ('0x1.538816d48a13fp+29', '0x1.7967c5ca43e16p+29'),
912            ('0x1.57b47b7234530p+29', '0x1.74e2c7040e772p+29'),
913            ('0x1.821b685e9b168p+30', '0x1.677dc1c1e3dc6p+29'),
914            ('0x1.9e8247f67097bp+29', '0x1.24bd2dc4f4baep+29'),
915            ('0x1.b73b59e0cb5f9p+29', '0x1.da899ab784a97p+28'),
916            ('0x1.94a8d2842a7cfp+30', '0x1.326a51d4d8d8ap+30'),
917            ('0x1.e930b9cd99035p+29', '0x1.5a1030e18dff9p+30'),
918            ('0x1.1592bbb0e4690p+29', '0x1.a9c337b33fb9ap+29'),
919            ('0x1.1243a50751fd4p+29', '0x1.a5a10175622d9p+29'),
920            ('0x1.57a8596e74722p+30', '0x1.42d1af9d04da9p+30'),
921
922            # Cases with 1 ulp error in version fff3c28052e6b0
923            ('0x1.ee7dbd9565899p+29', '0x1.7ab4d6fc6e4b4p+29'),
924            ('0x1.5c6bfbec5c4dcp+30', '0x1.02511184b4970p+30'),
925            ('0x1.59dcebba995cap+30', '0x1.50ca7e7c38854p+29'),
926            ('0x1.768cdd94cf5aap+29', '0x1.9cfdc5571d38ep+29'),
927            ('0x1.dcf137d60262ep+29', '0x1.1101621990b3ep+30'),
928            ('0x1.3a2d006e288b0p+30', '0x1.e9a240914326cp+29'),
929            ('0x1.62a32f7f53c61p+29', '0x1.47eb6cd72684fp+29'),
930            ('0x1.d3bcb60748ef2p+29', '0x1.3f13c4056312cp+30'),
931            ('0x1.282bdb82f17f3p+30', '0x1.640ba4c4eed3ap+30'),
932            ('0x1.89d8c423ea0c6p+29', '0x1.d35dcfe902bc3p+29'),
933        ]:
934            x = float.fromhex(hx)
935            y = float.fromhex(hy)
936            with self.subTest(hx=hx, hy=hy, x=x, y=y):
937                with decimal.localcontext(high_precision):
938                    z = float((Decimal(x)**2 + Decimal(y)**2).sqrt())
939                self.assertEqual(hypot(x, y), z)
940
941    def testDist(self):
942        from decimal import Decimal as D
943        from fractions import Fraction as F
944
945        dist = math.dist
946        sqrt = math.sqrt
947
948        # Simple exact cases
949        self.assertEqual(dist((1.0, 2.0, 3.0), (4.0, 2.0, -1.0)), 5.0)
950        self.assertEqual(dist((1, 2, 3), (4, 2, -1)), 5.0)
951
952        # Test different numbers of arguments (from zero to nine)
953        # against a straightforward pure python implementation
954        for i in range(9):
955            for j in range(5):
956                p = tuple(random.uniform(-5, 5) for k in range(i))
957                q = tuple(random.uniform(-5, 5) for k in range(i))
958                self.assertAlmostEqual(
959                    dist(p, q),
960                    sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
961                )
962
963        # Test non-tuple inputs
964        self.assertEqual(dist([1.0, 2.0, 3.0], [4.0, 2.0, -1.0]), 5.0)
965        self.assertEqual(dist(iter([1.0, 2.0, 3.0]), iter([4.0, 2.0, -1.0])), 5.0)
966
967        # Test allowable types (those with __float__)
968        self.assertEqual(dist((14.0, 1.0), (2.0, -4.0)), 13.0)
969        self.assertEqual(dist((14, 1), (2, -4)), 13)
970        self.assertEqual(dist((FloatLike(14.), 1), (2, -4)), 13)
971        self.assertEqual(dist((11, 1), (FloatLike(-1.), -4)), 13)
972        self.assertEqual(dist((14, FloatLike(-1.)), (2, -6)), 13)
973        self.assertEqual(dist((14, -1), (2, -6)), 13)
974        self.assertEqual(dist((D(14), D(1)), (D(2), D(-4))), D(13))
975        self.assertEqual(dist((F(14, 32), F(1, 32)), (F(2, 32), F(-4, 32))),
976                         F(13, 32))
977        self.assertEqual(dist((True, True, False, False, True, True),
978                              (True, False, True, False, False, False)),
979                         2.0)
980
981        # Test corner cases
982        self.assertEqual(dist((13.25, 12.5, -3.25),
983                              (13.25, 12.5, -3.25)),
984                         0.0)                      # Distance with self is zero
985        self.assertEqual(dist((), ()), 0.0)        # Zero-dimensional case
986        self.assertEqual(1.0,                      # Convert negative zero to positive zero
987            math.copysign(1.0, dist((-0.0,), (0.0,)))
988        )
989        self.assertEqual(1.0,                      # Convert negative zero to positive zero
990            math.copysign(1.0, dist((0.0,), (-0.0,)))
991        )
992        self.assertEqual(                          # Handling of moving max to the end
993            dist((1.5, 1.5, 0.5), (0, 0, 0)),
994            dist((1.5, 0.5, 1.5), (0, 0, 0))
995        )
996
997        # Verify tuple subclasses are allowed
998        class T(tuple):
999            pass
1000        self.assertEqual(dist(T((1, 2, 3)), ((4, 2, -1))), 5.0)
1001
1002        # Test handling of bad arguments
1003        with self.assertRaises(TypeError):         # Reject keyword args
1004            dist(p=(1, 2, 3), q=(4, 5, 6))
1005        with self.assertRaises(TypeError):         # Too few args
1006            dist((1, 2, 3))
1007        with self.assertRaises(TypeError):         # Too many args
1008            dist((1, 2, 3), (4, 5, 6), (7, 8, 9))
1009        with self.assertRaises(TypeError):         # Scalars not allowed
1010            dist(1, 2)
1011        with self.assertRaises(TypeError):         # Reject values without __float__
1012            dist((1.1, 'string', 2.2), (1, 2, 3))
1013        with self.assertRaises(ValueError):        # Check dimension agree
1014            dist((1, 2, 3, 4), (5, 6, 7))
1015        with self.assertRaises(ValueError):        # Check dimension agree
1016            dist((1, 2, 3), (4, 5, 6, 7))
1017        with self.assertRaises(TypeError):
1018            dist((1,)*17 + ("spam",), (1,)*18)
1019        with self.assertRaises(TypeError):         # Rejects invalid types
1020            dist("abc", "xyz")
1021        int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
1022        with self.assertRaises((ValueError, OverflowError)):
1023            dist((1, int_too_big_for_float), (2, 3))
1024        with self.assertRaises((ValueError, OverflowError)):
1025            dist((2, 3), (1, int_too_big_for_float))
1026        with self.assertRaises(TypeError):
1027            dist((1,), 2)
1028        with self.assertRaises(TypeError):
1029            dist([1], 2)
1030
1031        class BadFloat:
1032            __float__ = BadDescr()
1033
1034        with self.assertRaises(ValueError):
1035            dist([1], [BadFloat()])
1036
1037        # Verify that the one dimensional case is equivalent to abs()
1038        for i in range(20):
1039            p, q = random.random(), random.random()
1040            self.assertEqual(dist((p,), (q,)), abs(p - q))
1041
1042        # Test special values
1043        values = [NINF, -10.5, -0.0, 0.0, 10.5, INF, NAN]
1044        for p in itertools.product(values, repeat=3):
1045            for q in itertools.product(values, repeat=3):
1046                diffs = [px - qx for px, qx in zip(p, q)]
1047                if any(map(math.isinf, diffs)):
1048                    # Any infinite difference gives positive infinity.
1049                    self.assertEqual(dist(p, q), INF)
1050                elif any(map(math.isnan, diffs)):
1051                    # If no infinity, any NaN gives a NaN.
1052                    self.assertTrue(math.isnan(dist(p, q)))
1053
1054        # Verify scaling for extremely large values
1055        fourthmax = FLOAT_MAX / 4.0
1056        for n in range(32):
1057            p = (fourthmax,) * n
1058            q = (0.0,) * n
1059            self.assertTrue(math.isclose(dist(p, q), fourthmax * math.sqrt(n)))
1060            self.assertTrue(math.isclose(dist(q, p), fourthmax * math.sqrt(n)))
1061
1062        # Verify scaling for extremely small values
1063        for exp in range(32):
1064            scale = FLOAT_MIN / 2.0 ** exp
1065            p = (4*scale, 3*scale)
1066            q = (0.0, 0.0)
1067            self.assertEqual(math.dist(p, q), 5*scale)
1068            self.assertEqual(math.dist(q, p), 5*scale)
1069
1070    def test_math_dist_leak(self):
1071        # gh-98897: Check for error handling does not leak memory
1072        with self.assertRaises(ValueError):
1073            math.dist([1, 2], [3, 4, 5])
1074
1075    def testIsqrt(self):
1076        # Test a variety of inputs, large and small.
1077        test_values = (
1078            list(range(1000))
1079            + list(range(10**6 - 1000, 10**6 + 1000))
1080            + [2**e + i for e in range(60, 200) for i in range(-40, 40)]
1081            + [3**9999, 10**5001]
1082        )
1083
1084        for value in test_values:
1085            with self.subTest(value=value):
1086                s = math.isqrt(value)
1087                self.assertIs(type(s), int)
1088                self.assertLessEqual(s*s, value)
1089                self.assertLess(value, (s+1)*(s+1))
1090
1091        # Negative values
1092        with self.assertRaises(ValueError):
1093            math.isqrt(-1)
1094
1095        # Integer-like things
1096        s = math.isqrt(True)
1097        self.assertIs(type(s), int)
1098        self.assertEqual(s, 1)
1099
1100        s = math.isqrt(False)
1101        self.assertIs(type(s), int)
1102        self.assertEqual(s, 0)
1103
1104        class IntegerLike(object):
1105            def __init__(self, value):
1106                self.value = value
1107
1108            def __index__(self):
1109                return self.value
1110
1111        s = math.isqrt(IntegerLike(1729))
1112        self.assertIs(type(s), int)
1113        self.assertEqual(s, 41)
1114
1115        with self.assertRaises(ValueError):
1116            math.isqrt(IntegerLike(-3))
1117
1118        # Non-integer-like things
1119        bad_values = [
1120            3.5, "a string", decimal.Decimal("3.5"), 3.5j,
1121            100.0, -4.0,
1122        ]
1123        for value in bad_values:
1124            with self.subTest(value=value):
1125                with self.assertRaises(TypeError):
1126                    math.isqrt(value)
1127
1128    def test_lcm(self):
1129        lcm = math.lcm
1130        self.assertEqual(lcm(0, 0), 0)
1131        self.assertEqual(lcm(1, 0), 0)
1132        self.assertEqual(lcm(-1, 0), 0)
1133        self.assertEqual(lcm(0, 1), 0)
1134        self.assertEqual(lcm(0, -1), 0)
1135        self.assertEqual(lcm(7, 1), 7)
1136        self.assertEqual(lcm(7, -1), 7)
1137        self.assertEqual(lcm(-23, 15), 345)
1138        self.assertEqual(lcm(120, 84), 840)
1139        self.assertEqual(lcm(84, -120), 840)
1140        self.assertEqual(lcm(1216342683557601535506311712,
1141                             436522681849110124616458784),
1142                             16592536571065866494401400422922201534178938447014944)
1143
1144        x = 43461045657039990237
1145        y = 10645022458251153277
1146        for c in (652560,
1147                  57655923087165495981):
1148            a = x * c
1149            b = y * c
1150            d = x * y * c
1151            self.assertEqual(lcm(a, b), d)
1152            self.assertEqual(lcm(b, a), d)
1153            self.assertEqual(lcm(-a, b), d)
1154            self.assertEqual(lcm(b, -a), d)
1155            self.assertEqual(lcm(a, -b), d)
1156            self.assertEqual(lcm(-b, a), d)
1157            self.assertEqual(lcm(-a, -b), d)
1158            self.assertEqual(lcm(-b, -a), d)
1159
1160        self.assertEqual(lcm(), 1)
1161        self.assertEqual(lcm(120), 120)
1162        self.assertEqual(lcm(-120), 120)
1163        self.assertEqual(lcm(120, 84, 102), 14280)
1164        self.assertEqual(lcm(120, 0, 84), 0)
1165
1166        self.assertRaises(TypeError, lcm, 120.0)
1167        self.assertRaises(TypeError, lcm, 120.0, 84)
1168        self.assertRaises(TypeError, lcm, 120, 84.0)
1169        self.assertRaises(TypeError, lcm, 120, 0, 84.0)
1170        self.assertEqual(lcm(MyIndexable(120), MyIndexable(84)), 840)
1171
1172    def testLdexp(self):
1173        self.assertRaises(TypeError, math.ldexp)
1174        self.assertRaises(TypeError, math.ldexp, 2.0, 1.1)
1175        self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
1176        self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
1177        self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
1178        self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
1179        self.assertRaises(OverflowError, math.ldexp, 1., 1000000)
1180        self.assertRaises(OverflowError, math.ldexp, -1., 1000000)
1181        self.assertEqual(math.ldexp(1., -1000000), 0.)
1182        self.assertEqual(math.ldexp(-1., -1000000), -0.)
1183        self.assertEqual(math.ldexp(INF, 30), INF)
1184        self.assertEqual(math.ldexp(NINF, -213), NINF)
1185        self.assertTrue(math.isnan(math.ldexp(NAN, 0)))
1186
1187        # large second argument
1188        for n in [10**5, 10**10, 10**20, 10**40]:
1189            self.assertEqual(math.ldexp(INF, -n), INF)
1190            self.assertEqual(math.ldexp(NINF, -n), NINF)
1191            self.assertEqual(math.ldexp(1., -n), 0.)
1192            self.assertEqual(math.ldexp(-1., -n), -0.)
1193            self.assertEqual(math.ldexp(0., -n), 0.)
1194            self.assertEqual(math.ldexp(-0., -n), -0.)
1195            self.assertTrue(math.isnan(math.ldexp(NAN, -n)))
1196
1197            self.assertRaises(OverflowError, math.ldexp, 1., n)
1198            self.assertRaises(OverflowError, math.ldexp, -1., n)
1199            self.assertEqual(math.ldexp(0., n), 0.)
1200            self.assertEqual(math.ldexp(-0., n), -0.)
1201            self.assertEqual(math.ldexp(INF, n), INF)
1202            self.assertEqual(math.ldexp(NINF, n), NINF)
1203            self.assertTrue(math.isnan(math.ldexp(NAN, n)))
1204
1205    def testLog(self):
1206        self.assertRaises(TypeError, math.log)
1207        self.assertRaises(TypeError, math.log, 1, 2, 3)
1208        self.ftest('log(1/e)', math.log(1/math.e), -1)
1209        self.ftest('log(1)', math.log(1), 0)
1210        self.ftest('log(e)', math.log(math.e), 1)
1211        self.ftest('log(32,2)', math.log(32,2), 5)
1212        self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
1213        self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
1214        self.ftest('log(10**1000)', math.log(10**1000),
1215                   2302.5850929940457)
1216        self.assertRaises(ValueError, math.log, -1.5)
1217        self.assertRaises(ValueError, math.log, -10**1000)
1218        self.assertRaises(ValueError, math.log, 10, -10)
1219        self.assertRaises(ValueError, math.log, NINF)
1220        self.assertEqual(math.log(INF), INF)
1221        self.assertTrue(math.isnan(math.log(NAN)))
1222
1223    def testLog1p(self):
1224        self.assertRaises(TypeError, math.log1p)
1225        for n in [2, 2**90, 2**300]:
1226            self.assertAlmostEqual(math.log1p(n), math.log1p(float(n)))
1227        self.assertRaises(ValueError, math.log1p, -1)
1228        self.assertEqual(math.log1p(INF), INF)
1229
1230    @requires_IEEE_754
1231    def testLog2(self):
1232        self.assertRaises(TypeError, math.log2)
1233
1234        # Check some integer values
1235        self.assertEqual(math.log2(1), 0.0)
1236        self.assertEqual(math.log2(2), 1.0)
1237        self.assertEqual(math.log2(4), 2.0)
1238
1239        # Large integer values
1240        self.assertEqual(math.log2(2**1023), 1023.0)
1241        self.assertEqual(math.log2(2**1024), 1024.0)
1242        self.assertEqual(math.log2(2**2000), 2000.0)
1243
1244        self.assertRaises(ValueError, math.log2, -1.5)
1245        self.assertRaises(ValueError, math.log2, NINF)
1246        self.assertTrue(math.isnan(math.log2(NAN)))
1247
1248    @requires_IEEE_754
1249    # log2() is not accurate enough on Mac OS X Tiger (10.4)
1250    @support.requires_mac_ver(10, 5)
1251    def testLog2Exact(self):
1252        # Check that we get exact equality for log2 of powers of 2.
1253        actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)]
1254        expected = [float(n) for n in range(-1074, 1024)]
1255        self.assertEqual(actual, expected)
1256
1257    def testLog10(self):
1258        self.assertRaises(TypeError, math.log10)
1259        self.ftest('log10(0.1)', math.log10(0.1), -1)
1260        self.ftest('log10(1)', math.log10(1), 0)
1261        self.ftest('log10(10)', math.log10(10), 1)
1262        self.ftest('log10(10**1000)', math.log10(10**1000), 1000.0)
1263        self.assertRaises(ValueError, math.log10, -1.5)
1264        self.assertRaises(ValueError, math.log10, -10**1000)
1265        self.assertRaises(ValueError, math.log10, NINF)
1266        self.assertEqual(math.log(INF), INF)
1267        self.assertTrue(math.isnan(math.log10(NAN)))
1268
1269    def testSumProd(self):
1270        sumprod = math.sumprod
1271        Decimal = decimal.Decimal
1272        Fraction = fractions.Fraction
1273
1274        # Core functionality
1275        self.assertEqual(sumprod(iter([10, 20, 30]), (1, 2, 3)), 140)
1276        self.assertEqual(sumprod([1.5, 2.5], [3.5, 4.5]), 16.5)
1277        self.assertEqual(sumprod([], []), 0)
1278        self.assertEqual(sumprod([-1], [1.]), -1)
1279        self.assertEqual(sumprod([1.], [-1]), -1)
1280
1281        # Type preservation and coercion
1282        for v in [
1283            (10, 20, 30),
1284            (1.5, -2.5),
1285            (Fraction(3, 5), Fraction(4, 5)),
1286            (Decimal(3.5), Decimal(4.5)),
1287            (2.5, 10),             # float/int
1288            (2.5, Fraction(3, 5)), # float/fraction
1289            (25, Fraction(3, 5)),  # int/fraction
1290            (25, Decimal(4.5)),    # int/decimal
1291        ]:
1292            for p, q in [(v, v), (v, v[::-1])]:
1293                with self.subTest(p=p, q=q):
1294                    expected = sum(p_i * q_i for p_i, q_i in zip(p, q, strict=True))
1295                    actual = sumprod(p, q)
1296                    self.assertEqual(expected, actual)
1297                    self.assertEqual(type(expected), type(actual))
1298
1299        # Bad arguments
1300        self.assertRaises(TypeError, sumprod)               # No args
1301        self.assertRaises(TypeError, sumprod, [])           # One arg
1302        self.assertRaises(TypeError, sumprod, [], [], [])   # Three args
1303        self.assertRaises(TypeError, sumprod, None, [10])   # Non-iterable
1304        self.assertRaises(TypeError, sumprod, [10], None)   # Non-iterable
1305        self.assertRaises(TypeError, sumprod, ['x'], [1.0])
1306
1307        # Uneven lengths
1308        self.assertRaises(ValueError, sumprod, [10, 20], [30])
1309        self.assertRaises(ValueError, sumprod, [10], [20, 30])
1310
1311        # Overflows
1312        self.assertEqual(sumprod([10**20], [1]), 10**20)
1313        self.assertEqual(sumprod([1], [10**20]), 10**20)
1314        self.assertEqual(sumprod([10**10], [10**10]), 10**20)
1315        self.assertEqual(sumprod([10**7]*10**5, [10**7]*10**5), 10**19)
1316        self.assertRaises(OverflowError, sumprod, [10**1000], [1.0])
1317        self.assertRaises(OverflowError, sumprod, [1.0], [10**1000])
1318
1319        # Error in iterator
1320        def raise_after(n):
1321            for i in range(n):
1322                yield i
1323            raise RuntimeError
1324        with self.assertRaises(RuntimeError):
1325            sumprod(range(10), raise_after(5))
1326        with self.assertRaises(RuntimeError):
1327            sumprod(raise_after(5), range(10))
1328
1329        from test.test_iter import BasicIterClass
1330
1331        self.assertEqual(sumprod(BasicIterClass(1), [1]), 0)
1332        self.assertEqual(sumprod([1], BasicIterClass(1)), 0)
1333
1334        # Error in multiplication
1335        class BadMultiply:
1336            def __mul__(self, other):
1337                raise RuntimeError
1338            def __rmul__(self, other):
1339                raise RuntimeError
1340        with self.assertRaises(RuntimeError):
1341            sumprod([10, BadMultiply(), 30], [1, 2, 3])
1342        with self.assertRaises(RuntimeError):
1343            sumprod([1, 2, 3], [10, BadMultiply(), 30])
1344
1345        # Error in addition
1346        with self.assertRaises(TypeError):
1347            sumprod(['abc', 3], [5, 10])
1348        with self.assertRaises(TypeError):
1349            sumprod([5, 10], ['abc', 3])
1350
1351        # Special values should give the same as the pure python recipe
1352        self.assertEqual(sumprod([10.1, math.inf], [20.2, 30.3]), math.inf)
1353        self.assertEqual(sumprod([10.1, math.inf], [math.inf, 30.3]), math.inf)
1354        self.assertEqual(sumprod([10.1, math.inf], [math.inf, math.inf]), math.inf)
1355        self.assertEqual(sumprod([10.1, -math.inf], [20.2, 30.3]), -math.inf)
1356        self.assertTrue(math.isnan(sumprod([10.1, math.inf], [-math.inf, math.inf])))
1357        self.assertTrue(math.isnan(sumprod([10.1, math.nan], [20.2, 30.3])))
1358        self.assertTrue(math.isnan(sumprod([10.1, math.inf], [math.nan, 30.3])))
1359        self.assertTrue(math.isnan(sumprod([10.1, math.inf], [20.3, math.nan])))
1360
1361        # Error cases that arose during development
1362        args = ((-5, -5, 10), (1.5, 4611686018427387904, 2305843009213693952))
1363        self.assertEqual(sumprod(*args), 0.0)
1364
1365
1366    @requires_IEEE_754
1367    @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
1368                         "sumprod() accuracy not guaranteed on machines with double rounding")
1369    @support.cpython_only    # Other implementations may choose a different algorithm
1370    def test_sumprod_accuracy(self):
1371        sumprod = math.sumprod
1372        self.assertEqual(sumprod([0.1] * 10, [1]*10), 1.0)
1373        self.assertEqual(sumprod([0.1] * 20, [True, False] * 10), 1.0)
1374        self.assertEqual(sumprod([True, False] * 10, [0.1] * 20), 1.0)
1375        self.assertEqual(sumprod([1.0, 10E100, 1.0, -10E100], [1.0]*4), 2.0)
1376
1377    @support.requires_resource('cpu')
1378    def test_sumprod_stress(self):
1379        sumprod = math.sumprod
1380        product = itertools.product
1381        Decimal = decimal.Decimal
1382        Fraction = fractions.Fraction
1383
1384        class Int(int):
1385            def __add__(self, other):
1386                return Int(int(self) + int(other))
1387            def __mul__(self, other):
1388                return Int(int(self) * int(other))
1389            __radd__ = __add__
1390            __rmul__ = __mul__
1391            def __repr__(self):
1392                return f'Int({int(self)})'
1393
1394        class Flt(float):
1395            def __add__(self, other):
1396                return Int(int(self) + int(other))
1397            def __mul__(self, other):
1398                return Int(int(self) * int(other))
1399            __radd__ = __add__
1400            __rmul__ = __mul__
1401            def __repr__(self):
1402                return f'Flt({int(self)})'
1403
1404        def baseline_sumprod(p, q):
1405            """This defines the target behavior including exceptions and special values.
1406            However, it is subject to rounding errors, so float inputs should be exactly
1407            representable with only a few bits.
1408            """
1409            total = 0
1410            for p_i, q_i in zip(p, q, strict=True):
1411                total += p_i * q_i
1412            return total
1413
1414        def run(func, *args):
1415            "Make comparing functions easier. Returns error status, type, and result."
1416            try:
1417                result = func(*args)
1418            except (AssertionError, NameError):
1419                raise
1420            except Exception as e:
1421                return type(e), None, 'None'
1422            return None, type(result), repr(result)
1423
1424        pools = [
1425            (-5, 10, -2**20, 2**31, 2**40, 2**61, 2**62, 2**80, 1.5, Int(7)),
1426            (5.25, -3.5, 4.75, 11.25, 400.5, 0.046875, 0.25, -1.0, -0.078125),
1427            (-19.0*2**500, 11*2**1000, -3*2**1500, 17*2*333,
1428               5.25, -3.25, -3.0*2**(-333),  3, 2**513),
1429            (3.75, 2.5, -1.5, float('inf'), -float('inf'), float('NaN'), 14,
1430                9, 3+4j, Flt(13), 0.0),
1431            (13.25, -4.25, Decimal('10.5'), Decimal('-2.25'), Fraction(13, 8),
1432                 Fraction(-11, 16), 4.75 + 0.125j, 97, -41, Int(3)),
1433            (Decimal('6.125'), Decimal('12.375'), Decimal('-2.75'), Decimal(0),
1434                 Decimal('Inf'), -Decimal('Inf'), Decimal('NaN'), 12, 13.5),
1435            (-2.0 ** -1000, 11*2**1000, 3, 7, -37*2**32, -2*2**-537, -2*2**-538,
1436                 2*2**-513),
1437            (-7 * 2.0 ** -510, 5 * 2.0 ** -520, 17, -19.0, -6.25),
1438            (11.25, -3.75, -0.625, 23.375, True, False, 7, Int(5)),
1439        ]
1440
1441        for pool in pools:
1442            for size in range(4):
1443                for args1 in product(pool, repeat=size):
1444                    for args2 in product(pool, repeat=size):
1445                        args = (args1, args2)
1446                        self.assertEqual(
1447                            run(baseline_sumprod, *args),
1448                            run(sumprod, *args),
1449                            args,
1450                        )
1451
1452    @requires_IEEE_754
1453    @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
1454                         "sumprod() accuracy not guaranteed on machines with double rounding")
1455    @support.cpython_only    # Other implementations may choose a different algorithm
1456    @support.requires_resource('cpu')
1457    def test_sumprod_extended_precision_accuracy(self):
1458        import operator
1459        from fractions import Fraction
1460        from itertools import starmap
1461        from collections import namedtuple
1462        from math import log2, exp2, fabs
1463        from random import choices, uniform, shuffle
1464        from statistics import median
1465
1466        DotExample = namedtuple('DotExample', ('x', 'y', 'target_sumprod', 'condition'))
1467
1468        def DotExact(x, y):
1469            vec1 = map(Fraction, x)
1470            vec2 = map(Fraction, y)
1471            return sum(starmap(operator.mul, zip(vec1, vec2, strict=True)))
1472
1473        def Condition(x, y):
1474            return 2.0 * DotExact(map(abs, x), map(abs, y)) / abs(DotExact(x, y))
1475
1476        def linspace(lo, hi, n):
1477            width = (hi - lo) / (n - 1)
1478            return [lo + width * i for i in range(n)]
1479
1480        def GenDot(n, c):
1481            """ Algorithm 6.1 (GenDot) works as follows. The condition number (5.7) of
1482            the dot product xT y is proportional to the degree of cancellation. In
1483            order to achieve a prescribed cancellation, we generate the first half of
1484            the vectors x and y randomly within a large exponent range. This range is
1485            chosen according to the anticipated condition number. The second half of x
1486            and y is then constructed choosing xi randomly with decreasing exponent,
1487            and calculating yi such that some cancellation occurs. Finally, we permute
1488            the vectors x, y randomly and calculate the achieved condition number.
1489            """
1490
1491            assert n >= 6
1492            n2 = n // 2
1493            x = [0.0] * n
1494            y = [0.0] * n
1495            b = log2(c)
1496
1497            # First half with exponents from 0 to |_b/2_| and random ints in between
1498            e = choices(range(int(b/2)), k=n2)
1499            e[0] = int(b / 2) + 1
1500            e[-1] = 0.0
1501
1502            x[:n2] = [uniform(-1.0, 1.0) * exp2(p) for p in e]
1503            y[:n2] = [uniform(-1.0, 1.0) * exp2(p) for p in e]
1504
1505            # Second half
1506            e = list(map(round, linspace(b/2, 0.0 , n-n2)))
1507            for i in range(n2, n):
1508                x[i] = uniform(-1.0, 1.0) * exp2(e[i - n2])
1509                y[i] = (uniform(-1.0, 1.0) * exp2(e[i - n2]) - DotExact(x, y)) / x[i]
1510
1511            # Shuffle
1512            pairs = list(zip(x, y))
1513            shuffle(pairs)
1514            x, y = zip(*pairs)
1515
1516            return DotExample(x, y, DotExact(x, y), Condition(x, y))
1517
1518        def RelativeError(res, ex):
1519            x, y, target_sumprod, condition = ex
1520            n = DotExact(list(x) + [-res], list(y) + [1])
1521            return fabs(n / target_sumprod)
1522
1523        def Trial(dotfunc, c, n):
1524            ex = GenDot(10, c)
1525            res = dotfunc(ex.x, ex.y)
1526            return RelativeError(res, ex)
1527
1528        times = 1000          # Number of trials
1529        n = 20                # Length of vectors
1530        c = 1e30              # Target condition number
1531
1532        # If the following test fails, it means that the C math library
1533        # implementation of fma() is not compliant with the C99 standard
1534        # and is inaccurate.  To solve this problem, make a new build
1535        # with the symbol UNRELIABLE_FMA defined.  That will enable a
1536        # slower but accurate code path that avoids the fma() call.
1537        relative_err = median(Trial(math.sumprod, c, n) for i in range(times))
1538        self.assertLess(relative_err, 1e-16)
1539
1540    def testModf(self):
1541        self.assertRaises(TypeError, math.modf)
1542
1543        def testmodf(name, result, expected):
1544            (v1, v2), (e1, e2) = result, expected
1545            if abs(v1-e1) > eps or abs(v2-e2):
1546                self.fail('%s returned %r, expected %r'%\
1547                          (name, result, expected))
1548
1549        testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
1550        testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
1551
1552        self.assertEqual(math.modf(INF), (0.0, INF))
1553        self.assertEqual(math.modf(NINF), (-0.0, NINF))
1554
1555        modf_nan = math.modf(NAN)
1556        self.assertTrue(math.isnan(modf_nan[0]))
1557        self.assertTrue(math.isnan(modf_nan[1]))
1558
1559    def testPow(self):
1560        self.assertRaises(TypeError, math.pow)
1561        self.ftest('pow(0,1)', math.pow(0,1), 0)
1562        self.ftest('pow(1,0)', math.pow(1,0), 1)
1563        self.ftest('pow(2,1)', math.pow(2,1), 2)
1564        self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
1565        self.assertEqual(math.pow(INF, 1), INF)
1566        self.assertEqual(math.pow(NINF, 1), NINF)
1567        self.assertEqual((math.pow(1, INF)), 1.)
1568        self.assertEqual((math.pow(1, NINF)), 1.)
1569        self.assertTrue(math.isnan(math.pow(NAN, 1)))
1570        self.assertTrue(math.isnan(math.pow(2, NAN)))
1571        self.assertTrue(math.isnan(math.pow(0, NAN)))
1572        self.assertEqual(math.pow(1, NAN), 1)
1573        self.assertRaises(OverflowError, math.pow, 1e+100, 1e+100)
1574
1575        # pow(0., x)
1576        self.assertEqual(math.pow(0., INF), 0.)
1577        self.assertEqual(math.pow(0., 3.), 0.)
1578        self.assertEqual(math.pow(0., 2.3), 0.)
1579        self.assertEqual(math.pow(0., 2.), 0.)
1580        self.assertEqual(math.pow(0., 0.), 1.)
1581        self.assertEqual(math.pow(0., -0.), 1.)
1582        self.assertRaises(ValueError, math.pow, 0., -2.)
1583        self.assertRaises(ValueError, math.pow, 0., -2.3)
1584        self.assertRaises(ValueError, math.pow, 0., -3.)
1585        self.assertEqual(math.pow(0., NINF), INF)
1586        self.assertTrue(math.isnan(math.pow(0., NAN)))
1587
1588        # pow(INF, x)
1589        self.assertEqual(math.pow(INF, INF), INF)
1590        self.assertEqual(math.pow(INF, 3.), INF)
1591        self.assertEqual(math.pow(INF, 2.3), INF)
1592        self.assertEqual(math.pow(INF, 2.), INF)
1593        self.assertEqual(math.pow(INF, 0.), 1.)
1594        self.assertEqual(math.pow(INF, -0.), 1.)
1595        self.assertEqual(math.pow(INF, -2.), 0.)
1596        self.assertEqual(math.pow(INF, -2.3), 0.)
1597        self.assertEqual(math.pow(INF, -3.), 0.)
1598        self.assertEqual(math.pow(INF, NINF), 0.)
1599        self.assertTrue(math.isnan(math.pow(INF, NAN)))
1600
1601        # pow(-0., x)
1602        self.assertEqual(math.pow(-0., INF), 0.)
1603        self.assertEqual(math.pow(-0., 3.), -0.)
1604        self.assertEqual(math.pow(-0., 2.3), 0.)
1605        self.assertEqual(math.pow(-0., 2.), 0.)
1606        self.assertEqual(math.pow(-0., 0.), 1.)
1607        self.assertEqual(math.pow(-0., -0.), 1.)
1608        self.assertRaises(ValueError, math.pow, -0., -2.)
1609        self.assertRaises(ValueError, math.pow, -0., -2.3)
1610        self.assertRaises(ValueError, math.pow, -0., -3.)
1611        self.assertEqual(math.pow(-0., NINF), INF)
1612        self.assertTrue(math.isnan(math.pow(-0., NAN)))
1613
1614        # pow(NINF, x)
1615        self.assertEqual(math.pow(NINF, INF), INF)
1616        self.assertEqual(math.pow(NINF, 3.), NINF)
1617        self.assertEqual(math.pow(NINF, 2.3), INF)
1618        self.assertEqual(math.pow(NINF, 2.), INF)
1619        self.assertEqual(math.pow(NINF, 0.), 1.)
1620        self.assertEqual(math.pow(NINF, -0.), 1.)
1621        self.assertEqual(math.pow(NINF, -2.), 0.)
1622        self.assertEqual(math.pow(NINF, -2.3), 0.)
1623        self.assertEqual(math.pow(NINF, -3.), -0.)
1624        self.assertEqual(math.pow(NINF, NINF), 0.)
1625        self.assertTrue(math.isnan(math.pow(NINF, NAN)))
1626
1627        # pow(-1, x)
1628        self.assertEqual(math.pow(-1., INF), 1.)
1629        self.assertEqual(math.pow(-1., 3.), -1.)
1630        self.assertRaises(ValueError, math.pow, -1., 2.3)
1631        self.assertEqual(math.pow(-1., 2.), 1.)
1632        self.assertEqual(math.pow(-1., 0.), 1.)
1633        self.assertEqual(math.pow(-1., -0.), 1.)
1634        self.assertEqual(math.pow(-1., -2.), 1.)
1635        self.assertRaises(ValueError, math.pow, -1., -2.3)
1636        self.assertEqual(math.pow(-1., -3.), -1.)
1637        self.assertEqual(math.pow(-1., NINF), 1.)
1638        self.assertTrue(math.isnan(math.pow(-1., NAN)))
1639
1640        # pow(1, x)
1641        self.assertEqual(math.pow(1., INF), 1.)
1642        self.assertEqual(math.pow(1., 3.), 1.)
1643        self.assertEqual(math.pow(1., 2.3), 1.)
1644        self.assertEqual(math.pow(1., 2.), 1.)
1645        self.assertEqual(math.pow(1., 0.), 1.)
1646        self.assertEqual(math.pow(1., -0.), 1.)
1647        self.assertEqual(math.pow(1., -2.), 1.)
1648        self.assertEqual(math.pow(1., -2.3), 1.)
1649        self.assertEqual(math.pow(1., -3.), 1.)
1650        self.assertEqual(math.pow(1., NINF), 1.)
1651        self.assertEqual(math.pow(1., NAN), 1.)
1652
1653        # pow(x, 0) should be 1 for any x
1654        self.assertEqual(math.pow(2.3, 0.), 1.)
1655        self.assertEqual(math.pow(-2.3, 0.), 1.)
1656        self.assertEqual(math.pow(NAN, 0.), 1.)
1657        self.assertEqual(math.pow(2.3, -0.), 1.)
1658        self.assertEqual(math.pow(-2.3, -0.), 1.)
1659        self.assertEqual(math.pow(NAN, -0.), 1.)
1660
1661        # pow(x, y) is invalid if x is negative and y is not integral
1662        self.assertRaises(ValueError, math.pow, -1., 2.3)
1663        self.assertRaises(ValueError, math.pow, -15., -3.1)
1664
1665        # pow(x, NINF)
1666        self.assertEqual(math.pow(1.9, NINF), 0.)
1667        self.assertEqual(math.pow(1.1, NINF), 0.)
1668        self.assertEqual(math.pow(0.9, NINF), INF)
1669        self.assertEqual(math.pow(0.1, NINF), INF)
1670        self.assertEqual(math.pow(-0.1, NINF), INF)
1671        self.assertEqual(math.pow(-0.9, NINF), INF)
1672        self.assertEqual(math.pow(-1.1, NINF), 0.)
1673        self.assertEqual(math.pow(-1.9, NINF), 0.)
1674
1675        # pow(x, INF)
1676        self.assertEqual(math.pow(1.9, INF), INF)
1677        self.assertEqual(math.pow(1.1, INF), INF)
1678        self.assertEqual(math.pow(0.9, INF), 0.)
1679        self.assertEqual(math.pow(0.1, INF), 0.)
1680        self.assertEqual(math.pow(-0.1, INF), 0.)
1681        self.assertEqual(math.pow(-0.9, INF), 0.)
1682        self.assertEqual(math.pow(-1.1, INF), INF)
1683        self.assertEqual(math.pow(-1.9, INF), INF)
1684
1685        # pow(x, y) should work for x negative, y an integer
1686        self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
1687        self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
1688        self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
1689        self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
1690        self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
1691        self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
1692        self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
1693        self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
1694        self.assertRaises(ValueError, math.pow, -2.0, -0.5)
1695        self.assertRaises(ValueError, math.pow, -2.0, 0.5)
1696
1697        # the following tests have been commented out since they don't
1698        # really belong here:  the implementation of ** for floats is
1699        # independent of the implementation of math.pow
1700        #self.assertEqual(1**NAN, 1)
1701        #self.assertEqual(1**INF, 1)
1702        #self.assertEqual(1**NINF, 1)
1703        #self.assertEqual(1**0, 1)
1704        #self.assertEqual(1.**NAN, 1)
1705        #self.assertEqual(1.**INF, 1)
1706        #self.assertEqual(1.**NINF, 1)
1707        #self.assertEqual(1.**0, 1)
1708
1709    def testRadians(self):
1710        self.assertRaises(TypeError, math.radians)
1711        self.ftest('radians(180)', math.radians(180), math.pi)
1712        self.ftest('radians(90)', math.radians(90), math.pi/2)
1713        self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
1714        self.ftest('radians(0)', math.radians(0), 0)
1715
1716    @requires_IEEE_754
1717    def testRemainder(self):
1718        from fractions import Fraction
1719
1720        def validate_spec(x, y, r):
1721            """
1722            Check that r matches remainder(x, y) according to the IEEE 754
1723            specification. Assumes that x, y and r are finite and y is nonzero.
1724            """
1725            fx, fy, fr = Fraction(x), Fraction(y), Fraction(r)
1726            # r should not exceed y/2 in absolute value
1727            self.assertLessEqual(abs(fr), abs(fy/2))
1728            # x - r should be an exact integer multiple of y
1729            n = (fx - fr) / fy
1730            self.assertEqual(n, int(n))
1731            if abs(fr) == abs(fy/2):
1732                # If |r| == |y/2|, n should be even.
1733                self.assertEqual(n/2, int(n/2))
1734
1735        # triples (x, y, remainder(x, y)) in hexadecimal form.
1736        testcases = [
1737            # Remainders modulo 1, showing the ties-to-even behaviour.
1738            '-4.0 1 -0.0',
1739            '-3.8 1  0.8',
1740            '-3.0 1 -0.0',
1741            '-2.8 1 -0.8',
1742            '-2.0 1 -0.0',
1743            '-1.8 1  0.8',
1744            '-1.0 1 -0.0',
1745            '-0.8 1 -0.8',
1746            '-0.0 1 -0.0',
1747            ' 0.0 1  0.0',
1748            ' 0.8 1  0.8',
1749            ' 1.0 1  0.0',
1750            ' 1.8 1 -0.8',
1751            ' 2.0 1  0.0',
1752            ' 2.8 1  0.8',
1753            ' 3.0 1  0.0',
1754            ' 3.8 1 -0.8',
1755            ' 4.0 1  0.0',
1756
1757            # Reductions modulo 2*pi
1758            '0x0.0p+0 0x1.921fb54442d18p+2 0x0.0p+0',
1759            '0x1.921fb54442d18p+0 0x1.921fb54442d18p+2  0x1.921fb54442d18p+0',
1760            '0x1.921fb54442d17p+1 0x1.921fb54442d18p+2  0x1.921fb54442d17p+1',
1761            '0x1.921fb54442d18p+1 0x1.921fb54442d18p+2  0x1.921fb54442d18p+1',
1762            '0x1.921fb54442d19p+1 0x1.921fb54442d18p+2 -0x1.921fb54442d17p+1',
1763            '0x1.921fb54442d17p+2 0x1.921fb54442d18p+2 -0x0.0000000000001p+2',
1764            '0x1.921fb54442d18p+2 0x1.921fb54442d18p+2  0x0p0',
1765            '0x1.921fb54442d19p+2 0x1.921fb54442d18p+2  0x0.0000000000001p+2',
1766            '0x1.2d97c7f3321d1p+3 0x1.921fb54442d18p+2  0x1.921fb54442d14p+1',
1767            '0x1.2d97c7f3321d2p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d18p+1',
1768            '0x1.2d97c7f3321d3p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1769            '0x1.921fb54442d17p+3 0x1.921fb54442d18p+2 -0x0.0000000000001p+3',
1770            '0x1.921fb54442d18p+3 0x1.921fb54442d18p+2  0x0p0',
1771            '0x1.921fb54442d19p+3 0x1.921fb54442d18p+2  0x0.0000000000001p+3',
1772            '0x1.f6a7a2955385dp+3 0x1.921fb54442d18p+2  0x1.921fb54442d14p+1',
1773            '0x1.f6a7a2955385ep+3 0x1.921fb54442d18p+2  0x1.921fb54442d18p+1',
1774            '0x1.f6a7a2955385fp+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1775            '0x1.1475cc9eedf00p+5 0x1.921fb54442d18p+2  0x1.921fb54442d10p+1',
1776            '0x1.1475cc9eedf01p+5 0x1.921fb54442d18p+2 -0x1.921fb54442d10p+1',
1777
1778            # Symmetry with respect to signs.
1779            ' 1  0.c  0.4',
1780            '-1  0.c -0.4',
1781            ' 1 -0.c  0.4',
1782            '-1 -0.c -0.4',
1783            ' 1.4  0.c -0.4',
1784            '-1.4  0.c  0.4',
1785            ' 1.4 -0.c -0.4',
1786            '-1.4 -0.c  0.4',
1787
1788            # Huge modulus, to check that the underlying algorithm doesn't
1789            # rely on 2.0 * modulus being representable.
1790            '0x1.dp+1023 0x1.4p+1023  0x0.9p+1023',
1791            '0x1.ep+1023 0x1.4p+1023 -0x0.ap+1023',
1792            '0x1.fp+1023 0x1.4p+1023 -0x0.9p+1023',
1793        ]
1794
1795        for case in testcases:
1796            with self.subTest(case=case):
1797                x_hex, y_hex, expected_hex = case.split()
1798                x = float.fromhex(x_hex)
1799                y = float.fromhex(y_hex)
1800                expected = float.fromhex(expected_hex)
1801                validate_spec(x, y, expected)
1802                actual = math.remainder(x, y)
1803                # Cheap way of checking that the floats are
1804                # as identical as we need them to be.
1805                self.assertEqual(actual.hex(), expected.hex())
1806
1807        # Test tiny subnormal modulus: there's potential for
1808        # getting the implementation wrong here (for example,
1809        # by assuming that modulus/2 is exactly representable).
1810        tiny = float.fromhex('1p-1074')  # min +ve subnormal
1811        for n in range(-25, 25):
1812            if n == 0:
1813                continue
1814            y = n * tiny
1815            for m in range(100):
1816                x = m * tiny
1817                actual = math.remainder(x, y)
1818                validate_spec(x, y, actual)
1819                actual = math.remainder(-x, y)
1820                validate_spec(-x, y, actual)
1821
1822        # Special values.
1823        # NaNs should propagate as usual.
1824        for value in [NAN, 0.0, -0.0, 2.0, -2.3, NINF, INF]:
1825            self.assertIsNaN(math.remainder(NAN, value))
1826            self.assertIsNaN(math.remainder(value, NAN))
1827
1828        # remainder(x, inf) is x, for non-nan non-infinite x.
1829        for value in [-2.3, -0.0, 0.0, 2.3]:
1830            self.assertEqual(math.remainder(value, INF), value)
1831            self.assertEqual(math.remainder(value, NINF), value)
1832
1833        # remainder(x, 0) and remainder(infinity, x) for non-NaN x are invalid
1834        # operations according to IEEE 754-2008 7.2(f), and should raise.
1835        for value in [NINF, -2.3, -0.0, 0.0, 2.3, INF]:
1836            with self.assertRaises(ValueError):
1837                math.remainder(INF, value)
1838            with self.assertRaises(ValueError):
1839                math.remainder(NINF, value)
1840            with self.assertRaises(ValueError):
1841                math.remainder(value, 0.0)
1842            with self.assertRaises(ValueError):
1843                math.remainder(value, -0.0)
1844
1845    def testSin(self):
1846        self.assertRaises(TypeError, math.sin)
1847        self.ftest('sin(0)', math.sin(0), 0)
1848        self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
1849        self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
1850        try:
1851            self.assertTrue(math.isnan(math.sin(INF)))
1852            self.assertTrue(math.isnan(math.sin(NINF)))
1853        except ValueError:
1854            self.assertRaises(ValueError, math.sin, INF)
1855            self.assertRaises(ValueError, math.sin, NINF)
1856        self.assertTrue(math.isnan(math.sin(NAN)))
1857
1858    def testSinh(self):
1859        self.assertRaises(TypeError, math.sinh)
1860        self.ftest('sinh(0)', math.sinh(0), 0)
1861        self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
1862        self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
1863        self.assertEqual(math.sinh(INF), INF)
1864        self.assertEqual(math.sinh(NINF), NINF)
1865        self.assertTrue(math.isnan(math.sinh(NAN)))
1866
1867    def testSqrt(self):
1868        self.assertRaises(TypeError, math.sqrt)
1869        self.ftest('sqrt(0)', math.sqrt(0), 0)
1870        self.ftest('sqrt(0)', math.sqrt(0.0), 0.0)
1871        self.ftest('sqrt(2.5)', math.sqrt(2.5), 1.5811388300841898)
1872        self.ftest('sqrt(0.25)', math.sqrt(0.25), 0.5)
1873        self.ftest('sqrt(25.25)', math.sqrt(25.25), 5.024937810560445)
1874        self.ftest('sqrt(1)', math.sqrt(1), 1)
1875        self.ftest('sqrt(4)', math.sqrt(4), 2)
1876        self.assertEqual(math.sqrt(INF), INF)
1877        self.assertRaises(ValueError, math.sqrt, -1)
1878        self.assertRaises(ValueError, math.sqrt, NINF)
1879        self.assertTrue(math.isnan(math.sqrt(NAN)))
1880
1881    def testTan(self):
1882        self.assertRaises(TypeError, math.tan)
1883        self.ftest('tan(0)', math.tan(0), 0)
1884        self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
1885        self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
1886        try:
1887            self.assertTrue(math.isnan(math.tan(INF)))
1888            self.assertTrue(math.isnan(math.tan(NINF)))
1889        except ValueError:
1890            self.assertRaises(ValueError, math.tan, INF)
1891            self.assertRaises(ValueError, math.tan, NINF)
1892        self.assertTrue(math.isnan(math.tan(NAN)))
1893
1894    def testTanh(self):
1895        self.assertRaises(TypeError, math.tanh)
1896        self.ftest('tanh(0)', math.tanh(0), 0)
1897        self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0,
1898                   abs_tol=math.ulp(1))
1899        self.ftest('tanh(inf)', math.tanh(INF), 1)
1900        self.ftest('tanh(-inf)', math.tanh(NINF), -1)
1901        self.assertTrue(math.isnan(math.tanh(NAN)))
1902
1903    @requires_IEEE_754
1904    def testTanhSign(self):
1905        # check that tanh(-0.) == -0. on IEEE 754 systems
1906        self.assertEqual(math.tanh(-0.), -0.)
1907        self.assertEqual(math.copysign(1., math.tanh(-0.)),
1908                         math.copysign(1., -0.))
1909
1910    def test_trunc(self):
1911        self.assertEqual(math.trunc(1), 1)
1912        self.assertEqual(math.trunc(-1), -1)
1913        self.assertEqual(type(math.trunc(1)), int)
1914        self.assertEqual(type(math.trunc(1.5)), int)
1915        self.assertEqual(math.trunc(1.5), 1)
1916        self.assertEqual(math.trunc(-1.5), -1)
1917        self.assertEqual(math.trunc(1.999999), 1)
1918        self.assertEqual(math.trunc(-1.999999), -1)
1919        self.assertEqual(math.trunc(-0.999999), -0)
1920        self.assertEqual(math.trunc(-100.999), -100)
1921
1922        class TestTrunc:
1923            def __trunc__(self):
1924                return 23
1925        class FloatTrunc(float):
1926            def __trunc__(self):
1927                return 23
1928        class TestNoTrunc:
1929            pass
1930        class TestBadTrunc:
1931            __trunc__ = BadDescr()
1932
1933        self.assertEqual(math.trunc(TestTrunc()), 23)
1934        self.assertEqual(math.trunc(FloatTrunc()), 23)
1935
1936        self.assertRaises(TypeError, math.trunc)
1937        self.assertRaises(TypeError, math.trunc, 1, 2)
1938        self.assertRaises(TypeError, math.trunc, FloatLike(23.5))
1939        self.assertRaises(TypeError, math.trunc, TestNoTrunc())
1940        self.assertRaises(ValueError, math.trunc, TestBadTrunc())
1941
1942    def testIsfinite(self):
1943        self.assertTrue(math.isfinite(0.0))
1944        self.assertTrue(math.isfinite(-0.0))
1945        self.assertTrue(math.isfinite(1.0))
1946        self.assertTrue(math.isfinite(-1.0))
1947        self.assertFalse(math.isfinite(float("nan")))
1948        self.assertFalse(math.isfinite(float("inf")))
1949        self.assertFalse(math.isfinite(float("-inf")))
1950
1951    def testIsnan(self):
1952        self.assertTrue(math.isnan(float("nan")))
1953        self.assertTrue(math.isnan(float("-nan")))
1954        self.assertTrue(math.isnan(float("inf") * 0.))
1955        self.assertFalse(math.isnan(float("inf")))
1956        self.assertFalse(math.isnan(0.))
1957        self.assertFalse(math.isnan(1.))
1958
1959    def testIsinf(self):
1960        self.assertTrue(math.isinf(float("inf")))
1961        self.assertTrue(math.isinf(float("-inf")))
1962        self.assertTrue(math.isinf(1E400))
1963        self.assertTrue(math.isinf(-1E400))
1964        self.assertFalse(math.isinf(float("nan")))
1965        self.assertFalse(math.isinf(0.))
1966        self.assertFalse(math.isinf(1.))
1967
1968    def test_nan_constant(self):
1969        # `math.nan` must be a quiet NaN with positive sign bit
1970        self.assertTrue(math.isnan(math.nan))
1971        self.assertEqual(math.copysign(1., math.nan), 1.)
1972
1973    def test_inf_constant(self):
1974        self.assertTrue(math.isinf(math.inf))
1975        self.assertGreater(math.inf, 0.0)
1976        self.assertEqual(math.inf, float("inf"))
1977        self.assertEqual(-math.inf, float("-inf"))
1978
1979    # RED_FLAG 16-Oct-2000 Tim
1980    # While 2.0 is more consistent about exceptions than previous releases, it
1981    # still fails this part of the test on some platforms.  For now, we only
1982    # *run* test_exceptions() in verbose mode, so that this isn't normally
1983    # tested.
1984    @unittest.skipUnless(verbose, 'requires verbose mode')
1985    def test_exceptions(self):
1986        try:
1987            x = math.exp(-1000000000)
1988        except:
1989            # mathmodule.c is failing to weed out underflows from libm, or
1990            # we've got an fp format with huge dynamic range
1991            self.fail("underflowing exp() should not have raised "
1992                        "an exception")
1993        if x != 0:
1994            self.fail("underflowing exp() should have returned 0")
1995
1996        # If this fails, probably using a strict IEEE-754 conforming libm, and x
1997        # is +Inf afterwards.  But Python wants overflows detected by default.
1998        try:
1999            x = math.exp(1000000000)
2000        except OverflowError:
2001            pass
2002        else:
2003            self.fail("overflowing exp() didn't trigger OverflowError")
2004
2005        # If this fails, it could be a puzzle.  One odd possibility is that
2006        # mathmodule.c's macros are getting confused while comparing
2007        # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
2008        # as a result (and so raising OverflowError instead).
2009        try:
2010            x = math.sqrt(-1.0)
2011        except ValueError:
2012            pass
2013        else:
2014            self.fail("sqrt(-1) didn't raise ValueError")
2015
2016    @requires_IEEE_754
2017    def test_testfile(self):
2018        # Some tests need to be skipped on ancient OS X versions.
2019        # See issue #27953.
2020        SKIP_ON_TIGER = {'tan0064'}
2021
2022        osx_version = None
2023        if sys.platform == 'darwin':
2024            version_txt = platform.mac_ver()[0]
2025            try:
2026                osx_version = tuple(map(int, version_txt.split('.')))
2027            except ValueError:
2028                pass
2029
2030        fail_fmt = "{}: {}({!r}): {}"
2031
2032        failures = []
2033        for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
2034            # Skip if either the input or result is complex
2035            if ai != 0.0 or ei != 0.0:
2036                continue
2037            if fn in ['rect', 'polar']:
2038                # no real versions of rect, polar
2039                continue
2040            # Skip certain tests on OS X 10.4.
2041            if osx_version is not None and osx_version < (10, 5):
2042                if id in SKIP_ON_TIGER:
2043                    continue
2044
2045            func = getattr(math, fn)
2046
2047            if 'invalid' in flags or 'divide-by-zero' in flags:
2048                er = 'ValueError'
2049            elif 'overflow' in flags:
2050                er = 'OverflowError'
2051
2052            try:
2053                result = func(ar)
2054            except ValueError:
2055                result = 'ValueError'
2056            except OverflowError:
2057                result = 'OverflowError'
2058
2059            # C99+ says for math.h's sqrt: If the argument is +∞ or ±0, it is
2060            # returned, unmodified.  On another hand, for csqrt: If z is ±0+0i,
2061            # the result is +0+0i.  Lets correct zero sign of er to follow
2062            # first convention.
2063            if id in ['sqrt0002', 'sqrt0003', 'sqrt1001', 'sqrt1023']:
2064                er = math.copysign(er, ar)
2065
2066            # Default tolerances
2067            ulp_tol, abs_tol = 5, 0.0
2068
2069            failure = result_check(er, result, ulp_tol, abs_tol)
2070            if failure is None:
2071                continue
2072
2073            msg = fail_fmt.format(id, fn, ar, failure)
2074            failures.append(msg)
2075
2076        if failures:
2077            self.fail('Failures in test_testfile:\n  ' +
2078                      '\n  '.join(failures))
2079
2080    @requires_IEEE_754
2081    def test_mtestfile(self):
2082        fail_fmt = "{}: {}({!r}): {}"
2083
2084        failures = []
2085        for id, fn, arg, expected, flags in parse_mtestfile(math_testcases):
2086            func = getattr(math, fn)
2087
2088            if 'invalid' in flags or 'divide-by-zero' in flags:
2089                expected = 'ValueError'
2090            elif 'overflow' in flags:
2091                expected = 'OverflowError'
2092
2093            try:
2094                got = func(arg)
2095            except ValueError:
2096                got = 'ValueError'
2097            except OverflowError:
2098                got = 'OverflowError'
2099
2100            # Default tolerances
2101            ulp_tol, abs_tol = 5, 0.0
2102
2103            # Exceptions to the defaults
2104            if fn == 'gamma':
2105                # Experimental results on one platform gave
2106                # an accuracy of <= 10 ulps across the entire float
2107                # domain. We weaken that to require 20 ulp accuracy.
2108                ulp_tol = 20
2109
2110            elif fn == 'lgamma':
2111                # we use a weaker accuracy test for lgamma;
2112                # lgamma only achieves an absolute error of
2113                # a few multiples of the machine accuracy, in
2114                # general.
2115                abs_tol = 1e-15
2116
2117            elif fn == 'erfc' and arg >= 0.0:
2118                # erfc has less-than-ideal accuracy for large
2119                # arguments (x ~ 25 or so), mainly due to the
2120                # error involved in computing exp(-x*x).
2121                #
2122                # Observed between CPython and mpmath at 25 dp:
2123                #       x <  0 : err <= 2 ulp
2124                #  0 <= x <  1 : err <= 10 ulp
2125                #  1 <= x < 10 : err <= 100 ulp
2126                # 10 <= x < 20 : err <= 300 ulp
2127                # 20 <= x      : < 600 ulp
2128                #
2129                if arg < 1.0:
2130                    ulp_tol = 10
2131                elif arg < 10.0:
2132                    ulp_tol = 100
2133                else:
2134                    ulp_tol = 1000
2135
2136            failure = result_check(expected, got, ulp_tol, abs_tol)
2137            if failure is None:
2138                continue
2139
2140            msg = fail_fmt.format(id, fn, arg, failure)
2141            failures.append(msg)
2142
2143        if failures:
2144            self.fail('Failures in test_mtestfile:\n  ' +
2145                      '\n  '.join(failures))
2146
2147    def test_prod(self):
2148        from fractions import Fraction as F
2149
2150        prod = math.prod
2151        self.assertEqual(prod([]), 1)
2152        self.assertEqual(prod([], start=5), 5)
2153        self.assertEqual(prod(list(range(2,8))), 5040)
2154        self.assertEqual(prod(iter(list(range(2,8)))), 5040)
2155        self.assertEqual(prod(range(1, 10), start=10), 3628800)
2156
2157        self.assertEqual(prod([1, 2, 3, 4, 5]), 120)
2158        self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0)
2159        self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0)
2160        self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0)
2161        self.assertEqual(prod([1., F(3, 2)]), 1.5)
2162
2163        # Error in multiplication
2164        class BadMultiply:
2165            def __rmul__(self, other):
2166                raise RuntimeError
2167        with self.assertRaises(RuntimeError):
2168            prod([10., BadMultiply()])
2169
2170        # Test overflow in fast-path for integers
2171        self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32)
2172        # Test overflow in fast-path for floats
2173        self.assertEqual(prod([1.0, 1.0, 2**32, 1, 1]), float(2**32))
2174
2175        self.assertRaises(TypeError, prod)
2176        self.assertRaises(TypeError, prod, 42)
2177        self.assertRaises(TypeError, prod, ['a', 'b', 'c'])
2178        self.assertRaises(TypeError, prod, ['a', 'b', 'c'], start='')
2179        self.assertRaises(TypeError, prod, [b'a', b'c'], start=b'')
2180        values = [bytearray(b'a'), bytearray(b'b')]
2181        self.assertRaises(TypeError, prod, values, start=bytearray(b''))
2182        self.assertRaises(TypeError, prod, [[1], [2], [3]])
2183        self.assertRaises(TypeError, prod, [{2:3}])
2184        self.assertRaises(TypeError, prod, [{2:3}]*2, start={2:3})
2185        self.assertRaises(TypeError, prod, [[1], [2], [3]], start=[])
2186
2187        # Some odd cases
2188        self.assertEqual(prod([2, 3], start='ab'), 'abababababab')
2189        self.assertEqual(prod([2, 3], start=[1, 2]), [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2])
2190        self.assertEqual(prod([], start={2: 3}), {2:3})
2191
2192        with self.assertRaises(TypeError):
2193            prod([10, 20], 1)     # start is a keyword-only argument
2194
2195        self.assertEqual(prod([0, 1, 2, 3]), 0)
2196        self.assertEqual(prod([1, 0, 2, 3]), 0)
2197        self.assertEqual(prod([1, 2, 3, 0]), 0)
2198
2199        def _naive_prod(iterable, start=1):
2200            for elem in iterable:
2201                start *= elem
2202            return start
2203
2204        # Big integers
2205
2206        iterable = range(1, 10000)
2207        self.assertEqual(prod(iterable), _naive_prod(iterable))
2208        iterable = range(-10000, -1)
2209        self.assertEqual(prod(iterable), _naive_prod(iterable))
2210        iterable = range(-1000, 1000)
2211        self.assertEqual(prod(iterable), 0)
2212
2213        # Big floats
2214
2215        iterable = [float(x) for x in range(1, 1000)]
2216        self.assertEqual(prod(iterable), _naive_prod(iterable))
2217        iterable = [float(x) for x in range(-1000, -1)]
2218        self.assertEqual(prod(iterable), _naive_prod(iterable))
2219        iterable = [float(x) for x in range(-1000, 1000)]
2220        self.assertIsNaN(prod(iterable))
2221
2222        # Float tests
2223
2224        self.assertIsNaN(prod([1, 2, 3, float("nan"), 2, 3]))
2225        self.assertIsNaN(prod([1, 0, float("nan"), 2, 3]))
2226        self.assertIsNaN(prod([1, float("nan"), 0, 3]))
2227        self.assertIsNaN(prod([1, float("inf"), float("nan"),3]))
2228        self.assertIsNaN(prod([1, float("-inf"), float("nan"),3]))
2229        self.assertIsNaN(prod([1, float("nan"), float("inf"),3]))
2230        self.assertIsNaN(prod([1, float("nan"), float("-inf"),3]))
2231
2232        self.assertEqual(prod([1, 2, 3, float('inf'),-3,4]), float('-inf'))
2233        self.assertEqual(prod([1, 2, 3, float('-inf'),-3,4]), float('inf'))
2234
2235        self.assertIsNaN(prod([1,2,0,float('inf'), -3, 4]))
2236        self.assertIsNaN(prod([1,2,0,float('-inf'), -3, 4]))
2237        self.assertIsNaN(prod([1, 2, 3, float('inf'), -3, 0, 3]))
2238        self.assertIsNaN(prod([1, 2, 3, float('-inf'), -3, 0, 2]))
2239
2240        # Type preservation
2241
2242        self.assertEqual(type(prod([1, 2, 3, 4, 5, 6])), int)
2243        self.assertEqual(type(prod([1, 2.0, 3, 4, 5, 6])), float)
2244        self.assertEqual(type(prod(range(1, 10000))), int)
2245        self.assertEqual(type(prod(range(1, 10000), start=1.0)), float)
2246        self.assertEqual(type(prod([1, decimal.Decimal(2.0), 3, 4, 5, 6])),
2247                         decimal.Decimal)
2248
2249    def testPerm(self):
2250        perm = math.perm
2251        factorial = math.factorial
2252        # Test if factorial definition is satisfied
2253        for n in range(500):
2254            for k in (range(n + 1) if n < 100 else range(30) if n < 200 else range(10)):
2255                self.assertEqual(perm(n, k),
2256                                 factorial(n) // factorial(n - k))
2257
2258        # Test for Pascal's identity
2259        for n in range(1, 100):
2260            for k in range(1, n):
2261                self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k))
2262
2263        # Test corner cases
2264        for n in range(1, 100):
2265            self.assertEqual(perm(n, 0), 1)
2266            self.assertEqual(perm(n, 1), n)
2267            self.assertEqual(perm(n, n), factorial(n))
2268
2269        # Test one argument form
2270        for n in range(20):
2271            self.assertEqual(perm(n), factorial(n))
2272            self.assertEqual(perm(n, None), factorial(n))
2273
2274        # Raises TypeError if any argument is non-integer or argument count is
2275        # not 1 or 2
2276        self.assertRaises(TypeError, perm, 10, 1.0)
2277        self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
2278        self.assertRaises(TypeError, perm, 10, "1")
2279        self.assertRaises(TypeError, perm, 10.0, 1)
2280        self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
2281        self.assertRaises(TypeError, perm, "10", 1)
2282
2283        self.assertRaises(TypeError, perm)
2284        self.assertRaises(TypeError, perm, 10, 1, 3)
2285        self.assertRaises(TypeError, perm)
2286
2287        # Raises Value error if not k or n are negative numbers
2288        self.assertRaises(ValueError, perm, -1, 1)
2289        self.assertRaises(ValueError, perm, -2**1000, 1)
2290        self.assertRaises(ValueError, perm, 1, -1)
2291        self.assertRaises(ValueError, perm, 1, -2**1000)
2292
2293        # Returns zero if k is greater than n
2294        self.assertEqual(perm(1, 2), 0)
2295        self.assertEqual(perm(1, 2**1000), 0)
2296
2297        n = 2**1000
2298        self.assertEqual(perm(n, 0), 1)
2299        self.assertEqual(perm(n, 1), n)
2300        self.assertEqual(perm(n, 2), n * (n-1))
2301        if support.check_impl_detail(cpython=True):
2302            self.assertRaises(OverflowError, perm, n, n)
2303
2304        for n, k in (True, True), (True, False), (False, False):
2305            self.assertEqual(perm(n, k), 1)
2306            self.assertIs(type(perm(n, k)), int)
2307        self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20)
2308        self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20)
2309        for k in range(3):
2310            self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int)
2311            self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int)
2312
2313    def testComb(self):
2314        comb = math.comb
2315        factorial = math.factorial
2316        # Test if factorial definition is satisfied
2317        for n in range(500):
2318            for k in (range(n + 1) if n < 100 else range(30) if n < 200 else range(10)):
2319                self.assertEqual(comb(n, k), factorial(n)
2320                    // (factorial(k) * factorial(n - k)))
2321
2322        # Test for Pascal's identity
2323        for n in range(1, 100):
2324            for k in range(1, n):
2325                self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k))
2326
2327        # Test corner cases
2328        for n in range(100):
2329            self.assertEqual(comb(n, 0), 1)
2330            self.assertEqual(comb(n, n), 1)
2331
2332        for n in range(1, 100):
2333            self.assertEqual(comb(n, 1), n)
2334            self.assertEqual(comb(n, n - 1), n)
2335
2336        # Test Symmetry
2337        for n in range(100):
2338            for k in range(n // 2):
2339                self.assertEqual(comb(n, k), comb(n, n - k))
2340
2341        # Raises TypeError if any argument is non-integer or argument count is
2342        # not 2
2343        self.assertRaises(TypeError, comb, 10, 1.0)
2344        self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0))
2345        self.assertRaises(TypeError, comb, 10, "1")
2346        self.assertRaises(TypeError, comb, 10.0, 1)
2347        self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1)
2348        self.assertRaises(TypeError, comb, "10", 1)
2349
2350        self.assertRaises(TypeError, comb, 10)
2351        self.assertRaises(TypeError, comb, 10, 1, 3)
2352        self.assertRaises(TypeError, comb)
2353
2354        # Raises Value error if not k or n are negative numbers
2355        self.assertRaises(ValueError, comb, -1, 1)
2356        self.assertRaises(ValueError, comb, -2**1000, 1)
2357        self.assertRaises(ValueError, comb, 1, -1)
2358        self.assertRaises(ValueError, comb, 1, -2**1000)
2359
2360        # Returns zero if k is greater than n
2361        self.assertEqual(comb(1, 2), 0)
2362        self.assertEqual(comb(1, 2**1000), 0)
2363
2364        n = 2**1000
2365        self.assertEqual(comb(n, 0), 1)
2366        self.assertEqual(comb(n, 1), n)
2367        self.assertEqual(comb(n, 2), n * (n-1) // 2)
2368        self.assertEqual(comb(n, n), 1)
2369        self.assertEqual(comb(n, n-1), n)
2370        self.assertEqual(comb(n, n-2), n * (n-1) // 2)
2371        if support.check_impl_detail(cpython=True):
2372            self.assertRaises(OverflowError, comb, n, n//2)
2373
2374        for n, k in (True, True), (True, False), (False, False):
2375            self.assertEqual(comb(n, k), 1)
2376            self.assertIs(type(comb(n, k)), int)
2377        self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10)
2378        self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10)
2379        for k in range(3):
2380            self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int)
2381            self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int)
2382
2383    @requires_IEEE_754
2384    def test_nextafter(self):
2385        # around 2^52 and 2^63
2386        self.assertEqual(math.nextafter(4503599627370496.0, -INF),
2387                         4503599627370495.5)
2388        self.assertEqual(math.nextafter(4503599627370496.0, INF),
2389                         4503599627370497.0)
2390        self.assertEqual(math.nextafter(9223372036854775808.0, 0.0),
2391                         9223372036854774784.0)
2392        self.assertEqual(math.nextafter(-9223372036854775808.0, 0.0),
2393                         -9223372036854774784.0)
2394
2395        # around 1.0
2396        self.assertEqual(math.nextafter(1.0, -INF),
2397                         float.fromhex('0x1.fffffffffffffp-1'))
2398        self.assertEqual(math.nextafter(1.0, INF),
2399                         float.fromhex('0x1.0000000000001p+0'))
2400        self.assertEqual(math.nextafter(1.0, -INF, steps=1),
2401                         float.fromhex('0x1.fffffffffffffp-1'))
2402        self.assertEqual(math.nextafter(1.0, INF, steps=1),
2403                         float.fromhex('0x1.0000000000001p+0'))
2404        self.assertEqual(math.nextafter(1.0, -INF, steps=3),
2405                         float.fromhex('0x1.ffffffffffffdp-1'))
2406        self.assertEqual(math.nextafter(1.0, INF, steps=3),
2407                         float.fromhex('0x1.0000000000003p+0'))
2408
2409        # x == y: y is returned
2410        for steps in range(1, 5):
2411            self.assertEqual(math.nextafter(2.0, 2.0, steps=steps), 2.0)
2412            self.assertEqualSign(math.nextafter(-0.0, +0.0, steps=steps), +0.0)
2413            self.assertEqualSign(math.nextafter(+0.0, -0.0, steps=steps), -0.0)
2414
2415        # around 0.0
2416        smallest_subnormal = sys.float_info.min * sys.float_info.epsilon
2417        self.assertEqual(math.nextafter(+0.0, INF), smallest_subnormal)
2418        self.assertEqual(math.nextafter(-0.0, INF), smallest_subnormal)
2419        self.assertEqual(math.nextafter(+0.0, -INF), -smallest_subnormal)
2420        self.assertEqual(math.nextafter(-0.0, -INF), -smallest_subnormal)
2421        self.assertEqualSign(math.nextafter(smallest_subnormal, +0.0), +0.0)
2422        self.assertEqualSign(math.nextafter(-smallest_subnormal, +0.0), -0.0)
2423        self.assertEqualSign(math.nextafter(smallest_subnormal, -0.0), +0.0)
2424        self.assertEqualSign(math.nextafter(-smallest_subnormal, -0.0), -0.0)
2425
2426        # around infinity
2427        largest_normal = sys.float_info.max
2428        self.assertEqual(math.nextafter(INF, 0.0), largest_normal)
2429        self.assertEqual(math.nextafter(-INF, 0.0), -largest_normal)
2430        self.assertEqual(math.nextafter(largest_normal, INF), INF)
2431        self.assertEqual(math.nextafter(-largest_normal, -INF), -INF)
2432
2433        # NaN
2434        self.assertIsNaN(math.nextafter(NAN, 1.0))
2435        self.assertIsNaN(math.nextafter(1.0, NAN))
2436        self.assertIsNaN(math.nextafter(NAN, NAN))
2437
2438        self.assertEqual(1.0, math.nextafter(1.0, INF, steps=0))
2439        with self.assertRaises(ValueError):
2440            math.nextafter(1.0, INF, steps=-1)
2441
2442
2443    @requires_IEEE_754
2444    def test_ulp(self):
2445        self.assertEqual(math.ulp(1.0), sys.float_info.epsilon)
2446        # use int ** int rather than float ** int to not rely on pow() accuracy
2447        self.assertEqual(math.ulp(2 ** 52), 1.0)
2448        self.assertEqual(math.ulp(2 ** 53), 2.0)
2449        self.assertEqual(math.ulp(2 ** 64), 4096.0)
2450
2451        # min and max
2452        self.assertEqual(math.ulp(0.0),
2453                         sys.float_info.min * sys.float_info.epsilon)
2454        self.assertEqual(math.ulp(FLOAT_MAX),
2455                         FLOAT_MAX - math.nextafter(FLOAT_MAX, -INF))
2456
2457        # special cases
2458        self.assertEqual(math.ulp(INF), INF)
2459        self.assertIsNaN(math.ulp(math.nan))
2460
2461        # negative number: ulp(-x) == ulp(x)
2462        for x in (0.0, 1.0, 2 ** 52, 2 ** 64, INF):
2463            with self.subTest(x=x):
2464                self.assertEqual(math.ulp(-x), math.ulp(x))
2465
2466    def test_issue39871(self):
2467        # A SystemError should not be raised if the first arg to atan2(),
2468        # copysign(), or remainder() cannot be converted to a float.
2469        class F:
2470            def __float__(self):
2471                self.converted = True
2472                1/0
2473        for func in math.atan2, math.copysign, math.remainder:
2474            y = F()
2475            with self.assertRaises(TypeError):
2476                func("not a number", y)
2477
2478            # There should not have been any attempt to convert the second
2479            # argument to a float.
2480            self.assertFalse(getattr(y, "converted", False))
2481
2482    def test_input_exceptions(self):
2483        self.assertRaises(TypeError, math.exp, "spam")
2484        self.assertRaises(TypeError, math.erf, "spam")
2485        self.assertRaises(TypeError, math.atan2, "spam", 1.0)
2486        self.assertRaises(TypeError, math.atan2, 1.0, "spam")
2487        self.assertRaises(TypeError, math.atan2, 1.0)
2488        self.assertRaises(TypeError, math.atan2, 1.0, 2.0, 3.0)
2489
2490    # Custom assertions.
2491
2492    def assertIsNaN(self, value):
2493        if not math.isnan(value):
2494            self.fail("Expected a NaN, got {!r}.".format(value))
2495
2496    def assertEqualSign(self, x, y):
2497        """Similar to assertEqual(), but compare also the sign with copysign().
2498
2499        Function useful to compare signed zeros.
2500        """
2501        self.assertEqual(x, y)
2502        self.assertEqual(math.copysign(1.0, x), math.copysign(1.0, y))
2503
2504
2505class IsCloseTests(unittest.TestCase):
2506    isclose = math.isclose  # subclasses should override this
2507
2508    def assertIsClose(self, a, b, *args, **kwargs):
2509        self.assertTrue(self.isclose(a, b, *args, **kwargs),
2510                        msg="%s and %s should be close!" % (a, b))
2511
2512    def assertIsNotClose(self, a, b, *args, **kwargs):
2513        self.assertFalse(self.isclose(a, b, *args, **kwargs),
2514                         msg="%s and %s should not be close!" % (a, b))
2515
2516    def assertAllClose(self, examples, *args, **kwargs):
2517        for a, b in examples:
2518            self.assertIsClose(a, b, *args, **kwargs)
2519
2520    def assertAllNotClose(self, examples, *args, **kwargs):
2521        for a, b in examples:
2522            self.assertIsNotClose(a, b, *args, **kwargs)
2523
2524    def test_negative_tolerances(self):
2525        # ValueError should be raised if either tolerance is less than zero
2526        with self.assertRaises(ValueError):
2527            self.assertIsClose(1, 1, rel_tol=-1e-100)
2528        with self.assertRaises(ValueError):
2529            self.assertIsClose(1, 1, rel_tol=1e-100, abs_tol=-1e10)
2530
2531    def test_identical(self):
2532        # identical values must test as close
2533        identical_examples = [(2.0, 2.0),
2534                              (0.1e200, 0.1e200),
2535                              (1.123e-300, 1.123e-300),
2536                              (12345, 12345.0),
2537                              (0.0, -0.0),
2538                              (345678, 345678)]
2539        self.assertAllClose(identical_examples, rel_tol=0.0, abs_tol=0.0)
2540
2541    def test_eight_decimal_places(self):
2542        # examples that are close to 1e-8, but not 1e-9
2543        eight_decimal_places_examples = [(1e8, 1e8 + 1),
2544                                         (-1e-8, -1.000000009e-8),
2545                                         (1.12345678, 1.12345679)]
2546        self.assertAllClose(eight_decimal_places_examples, rel_tol=1e-8)
2547        self.assertAllNotClose(eight_decimal_places_examples, rel_tol=1e-9)
2548
2549    def test_near_zero(self):
2550        # values close to zero
2551        near_zero_examples = [(1e-9, 0.0),
2552                              (-1e-9, 0.0),
2553                              (-1e-150, 0.0)]
2554        # these should not be close to any rel_tol
2555        self.assertAllNotClose(near_zero_examples, rel_tol=0.9)
2556        # these should be close to abs_tol=1e-8
2557        self.assertAllClose(near_zero_examples, abs_tol=1e-8)
2558
2559    def test_identical_infinite(self):
2560        # these are close regardless of tolerance -- i.e. they are equal
2561        self.assertIsClose(INF, INF)
2562        self.assertIsClose(INF, INF, abs_tol=0.0)
2563        self.assertIsClose(NINF, NINF)
2564        self.assertIsClose(NINF, NINF, abs_tol=0.0)
2565
2566    def test_inf_ninf_nan(self):
2567        # these should never be close (following IEEE 754 rules for equality)
2568        not_close_examples = [(NAN, NAN),
2569                              (NAN, 1e-100),
2570                              (1e-100, NAN),
2571                              (INF, NAN),
2572                              (NAN, INF),
2573                              (INF, NINF),
2574                              (INF, 1.0),
2575                              (1.0, INF),
2576                              (INF, 1e308),
2577                              (1e308, INF)]
2578        # use largest reasonable tolerance
2579        self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999)
2580
2581    def test_zero_tolerance(self):
2582        # test with zero tolerance
2583        zero_tolerance_close_examples = [(1.0, 1.0),
2584                                         (-3.4, -3.4),
2585                                         (-1e-300, -1e-300)]
2586        self.assertAllClose(zero_tolerance_close_examples, rel_tol=0.0)
2587
2588        zero_tolerance_not_close_examples = [(1.0, 1.000000000000001),
2589                                             (0.99999999999999, 1.0),
2590                                             (1.0e200, .999999999999999e200)]
2591        self.assertAllNotClose(zero_tolerance_not_close_examples, rel_tol=0.0)
2592
2593    def test_asymmetry(self):
2594        # test the asymmetry example from PEP 485
2595        self.assertAllClose([(9, 10), (10, 9)], rel_tol=0.1)
2596
2597    def test_integers(self):
2598        # test with integer values
2599        integer_examples = [(100000001, 100000000),
2600                            (123456789, 123456788)]
2601
2602        self.assertAllClose(integer_examples, rel_tol=1e-8)
2603        self.assertAllNotClose(integer_examples, rel_tol=1e-9)
2604
2605    def test_decimals(self):
2606        # test with Decimal values
2607        from decimal import Decimal
2608
2609        decimal_examples = [(Decimal('1.00000001'), Decimal('1.0')),
2610                            (Decimal('1.00000001e-20'), Decimal('1.0e-20')),
2611                            (Decimal('1.00000001e-100'), Decimal('1.0e-100')),
2612                            (Decimal('1.00000001e20'), Decimal('1.0e20'))]
2613        self.assertAllClose(decimal_examples, rel_tol=1e-8)
2614        self.assertAllNotClose(decimal_examples, rel_tol=1e-9)
2615
2616    def test_fractions(self):
2617        # test with Fraction values
2618        from fractions import Fraction
2619
2620        fraction_examples = [
2621            (Fraction(1, 100000000) + 1, Fraction(1)),
2622            (Fraction(100000001), Fraction(100000000)),
2623            (Fraction(10**8 + 1, 10**28), Fraction(1, 10**20))]
2624        self.assertAllClose(fraction_examples, rel_tol=1e-8)
2625        self.assertAllNotClose(fraction_examples, rel_tol=1e-9)
2626
2627
2628class FMATests(unittest.TestCase):
2629    """ Tests for math.fma. """
2630
2631    def test_fma_nan_results(self):
2632        # Selected representative values.
2633        values = [
2634            -math.inf, -1e300, -2.3, -1e-300, -0.0,
2635            0.0, 1e-300, 2.3, 1e300, math.inf, math.nan
2636        ]
2637
2638        # If any input is a NaN, the result should be a NaN, too.
2639        for a, b in itertools.product(values, repeat=2):
2640            self.assertIsNaN(math.fma(math.nan, a, b))
2641            self.assertIsNaN(math.fma(a, math.nan, b))
2642            self.assertIsNaN(math.fma(a, b, math.nan))
2643
2644    def test_fma_infinities(self):
2645        # Cases involving infinite inputs or results.
2646        positives = [1e-300, 2.3, 1e300, math.inf]
2647        finites = [-1e300, -2.3, -1e-300, -0.0, 0.0, 1e-300, 2.3, 1e300]
2648        non_nans = [-math.inf, -2.3, -0.0, 0.0, 2.3, math.inf]
2649
2650        # ValueError due to inf * 0 computation.
2651        for c in non_nans:
2652            for infinity in [math.inf, -math.inf]:
2653                for zero in [0.0, -0.0]:
2654                    with self.assertRaises(ValueError):
2655                        math.fma(infinity, zero, c)
2656                    with self.assertRaises(ValueError):
2657                        math.fma(zero, infinity, c)
2658
2659        # ValueError when a*b and c both infinite of opposite signs.
2660        for b in positives:
2661            with self.assertRaises(ValueError):
2662                math.fma(math.inf, b, -math.inf)
2663            with self.assertRaises(ValueError):
2664                math.fma(math.inf, -b, math.inf)
2665            with self.assertRaises(ValueError):
2666                math.fma(-math.inf, -b, -math.inf)
2667            with self.assertRaises(ValueError):
2668                math.fma(-math.inf, b, math.inf)
2669            with self.assertRaises(ValueError):
2670                math.fma(b, math.inf, -math.inf)
2671            with self.assertRaises(ValueError):
2672                math.fma(-b, math.inf, math.inf)
2673            with self.assertRaises(ValueError):
2674                math.fma(-b, -math.inf, -math.inf)
2675            with self.assertRaises(ValueError):
2676                math.fma(b, -math.inf, math.inf)
2677
2678        # Infinite result when a*b and c both infinite of the same sign.
2679        for b in positives:
2680            self.assertEqual(math.fma(math.inf, b, math.inf), math.inf)
2681            self.assertEqual(math.fma(math.inf, -b, -math.inf), -math.inf)
2682            self.assertEqual(math.fma(-math.inf, -b, math.inf), math.inf)
2683            self.assertEqual(math.fma(-math.inf, b, -math.inf), -math.inf)
2684            self.assertEqual(math.fma(b, math.inf, math.inf), math.inf)
2685            self.assertEqual(math.fma(-b, math.inf, -math.inf), -math.inf)
2686            self.assertEqual(math.fma(-b, -math.inf, math.inf), math.inf)
2687            self.assertEqual(math.fma(b, -math.inf, -math.inf), -math.inf)
2688
2689        # Infinite result when a*b finite, c infinite.
2690        for a, b in itertools.product(finites, finites):
2691            self.assertEqual(math.fma(a, b, math.inf), math.inf)
2692            self.assertEqual(math.fma(a, b, -math.inf), -math.inf)
2693
2694        # Infinite result when a*b infinite, c finite.
2695        for b, c in itertools.product(positives, finites):
2696            self.assertEqual(math.fma(math.inf, b, c), math.inf)
2697            self.assertEqual(math.fma(-math.inf, b, c), -math.inf)
2698            self.assertEqual(math.fma(-math.inf, -b, c), math.inf)
2699            self.assertEqual(math.fma(math.inf, -b, c), -math.inf)
2700
2701            self.assertEqual(math.fma(b, math.inf, c), math.inf)
2702            self.assertEqual(math.fma(b, -math.inf, c), -math.inf)
2703            self.assertEqual(math.fma(-b, -math.inf, c), math.inf)
2704            self.assertEqual(math.fma(-b, math.inf, c), -math.inf)
2705
2706    # gh-73468: On some platforms, libc fma() doesn't implement IEE 754-2008
2707    # properly: it doesn't use the right sign when the result is zero.
2708    @unittest.skipIf(
2709        sys.platform.startswith(("freebsd", "wasi", "netbsd"))
2710        or (sys.platform == "android" and platform.machine() == "x86_64"),
2711        f"this platform doesn't implement IEE 754-2008 properly")
2712    def test_fma_zero_result(self):
2713        nonnegative_finites = [0.0, 1e-300, 2.3, 1e300]
2714
2715        # Zero results from exact zero inputs.
2716        for b in nonnegative_finites:
2717            self.assertIsPositiveZero(math.fma(0.0, b, 0.0))
2718            self.assertIsPositiveZero(math.fma(0.0, b, -0.0))
2719            self.assertIsNegativeZero(math.fma(0.0, -b, -0.0))
2720            self.assertIsPositiveZero(math.fma(0.0, -b, 0.0))
2721            self.assertIsPositiveZero(math.fma(-0.0, -b, 0.0))
2722            self.assertIsPositiveZero(math.fma(-0.0, -b, -0.0))
2723            self.assertIsNegativeZero(math.fma(-0.0, b, -0.0))
2724            self.assertIsPositiveZero(math.fma(-0.0, b, 0.0))
2725
2726            self.assertIsPositiveZero(math.fma(b, 0.0, 0.0))
2727            self.assertIsPositiveZero(math.fma(b, 0.0, -0.0))
2728            self.assertIsNegativeZero(math.fma(-b, 0.0, -0.0))
2729            self.assertIsPositiveZero(math.fma(-b, 0.0, 0.0))
2730            self.assertIsPositiveZero(math.fma(-b, -0.0, 0.0))
2731            self.assertIsPositiveZero(math.fma(-b, -0.0, -0.0))
2732            self.assertIsNegativeZero(math.fma(b, -0.0, -0.0))
2733            self.assertIsPositiveZero(math.fma(b, -0.0, 0.0))
2734
2735        # Exact zero result from nonzero inputs.
2736        self.assertIsPositiveZero(math.fma(2.0, 2.0, -4.0))
2737        self.assertIsPositiveZero(math.fma(2.0, -2.0, 4.0))
2738        self.assertIsPositiveZero(math.fma(-2.0, -2.0, -4.0))
2739        self.assertIsPositiveZero(math.fma(-2.0, 2.0, 4.0))
2740
2741        # Underflow to zero.
2742        tiny = 1e-300
2743        self.assertIsPositiveZero(math.fma(tiny, tiny, 0.0))
2744        self.assertIsNegativeZero(math.fma(tiny, -tiny, 0.0))
2745        self.assertIsPositiveZero(math.fma(-tiny, -tiny, 0.0))
2746        self.assertIsNegativeZero(math.fma(-tiny, tiny, 0.0))
2747        self.assertIsPositiveZero(math.fma(tiny, tiny, -0.0))
2748        self.assertIsNegativeZero(math.fma(tiny, -tiny, -0.0))
2749        self.assertIsPositiveZero(math.fma(-tiny, -tiny, -0.0))
2750        self.assertIsNegativeZero(math.fma(-tiny, tiny, -0.0))
2751
2752        # Corner case where rounding the multiplication would
2753        # give the wrong result.
2754        x = float.fromhex('0x1p-500')
2755        y = float.fromhex('0x1p-550')
2756        z = float.fromhex('0x1p-1000')
2757        self.assertIsNegativeZero(math.fma(x-y, x+y, -z))
2758        self.assertIsPositiveZero(math.fma(y-x, x+y, z))
2759        self.assertIsNegativeZero(math.fma(y-x, -(x+y), -z))
2760        self.assertIsPositiveZero(math.fma(x-y, -(x+y), z))
2761
2762    def test_fma_overflow(self):
2763        a = b = float.fromhex('0x1p512')
2764        c = float.fromhex('0x1p1023')
2765        # Overflow from multiplication.
2766        with self.assertRaises(OverflowError):
2767            math.fma(a, b, 0.0)
2768        self.assertEqual(math.fma(a, b/2.0, 0.0), c)
2769        # Overflow from the addition.
2770        with self.assertRaises(OverflowError):
2771            math.fma(a, b/2.0, c)
2772        # No overflow, even though a*b overflows a float.
2773        self.assertEqual(math.fma(a, b, -c), c)
2774
2775        # Extreme case: a * b is exactly at the overflow boundary, so the
2776        # tiniest offset makes a difference between overflow and a finite
2777        # result.
2778        a = float.fromhex('0x1.ffffffc000000p+511')
2779        b = float.fromhex('0x1.0000002000000p+512')
2780        c = float.fromhex('0x0.0000000000001p-1022')
2781        with self.assertRaises(OverflowError):
2782            math.fma(a, b, 0.0)
2783        with self.assertRaises(OverflowError):
2784            math.fma(a, b, c)
2785        self.assertEqual(math.fma(a, b, -c),
2786                         float.fromhex('0x1.fffffffffffffp+1023'))
2787
2788        # Another extreme case: here a*b is about as large as possible subject
2789        # to math.fma(a, b, c) being finite.
2790        a = float.fromhex('0x1.ae565943785f9p+512')
2791        b = float.fromhex('0x1.3094665de9db8p+512')
2792        c = float.fromhex('0x1.fffffffffffffp+1023')
2793        self.assertEqual(math.fma(a, b, -c), c)
2794
2795    def test_fma_single_round(self):
2796        a = float.fromhex('0x1p-50')
2797        self.assertEqual(math.fma(a - 1.0, a + 1.0, 1.0), a*a)
2798
2799    def test_random(self):
2800        # A collection of randomly generated inputs for which the naive FMA
2801        # (with two rounds) gives a different result from a singly-rounded FMA.
2802
2803        # tuples (a, b, c, expected)
2804        test_values = [
2805            ('0x1.694adde428b44p-1', '0x1.371b0d64caed7p-1',
2806             '0x1.f347e7b8deab8p-4', '0x1.19f10da56c8adp-1'),
2807            ('0x1.605401ccc6ad6p-2', '0x1.ce3a40bf56640p-2',
2808             '0x1.96e3bf7bf2e20p-2', '0x1.1af6d8aa83101p-1'),
2809            ('0x1.e5abd653a67d4p-2', '0x1.a2e400209b3e6p-1',
2810             '0x1.a90051422ce13p-1', '0x1.37d68cc8c0fbbp+0'),
2811            ('0x1.f94e8efd54700p-2', '0x1.123065c812cebp-1',
2812             '0x1.458f86fb6ccd0p-1', '0x1.ccdcee26a3ff3p-1'),
2813            ('0x1.bd926f1eedc96p-1', '0x1.eee9ca68c5740p-1',
2814             '0x1.960c703eb3298p-2', '0x1.3cdcfb4fdb007p+0'),
2815            ('0x1.27348350fbccdp-1', '0x1.3b073914a53f1p-1',
2816             '0x1.e300da5c2b4cbp-1', '0x1.4c51e9a3c4e29p+0'),
2817            ('0x1.2774f00b3497bp-1', '0x1.7038ec336bff0p-2',
2818             '0x1.2f6f2ccc3576bp-1', '0x1.99ad9f9c2688bp-1'),
2819            ('0x1.51d5a99300e5cp-1', '0x1.5cd74abd445a1p-1',
2820             '0x1.8880ab0bbe530p-1', '0x1.3756f96b91129p+0'),
2821            ('0x1.73cb965b821b8p-2', '0x1.218fd3d8d5371p-1',
2822             '0x1.d1ea966a1f758p-2', '0x1.5217b8fd90119p-1'),
2823            ('0x1.4aa98e890b046p-1', '0x1.954d85dff1041p-1',
2824             '0x1.122b59317ebdfp-1', '0x1.0bf644b340cc5p+0'),
2825            ('0x1.e28f29e44750fp-1', '0x1.4bcc4fdcd18fep-1',
2826             '0x1.fd47f81298259p-1', '0x1.9b000afbc9995p+0'),
2827            ('0x1.d2e850717fe78p-3', '0x1.1dd7531c303afp-1',
2828             '0x1.e0869746a2fc2p-2', '0x1.316df6eb26439p-1'),
2829            ('0x1.cf89c75ee6fbap-2', '0x1.b23decdc66825p-1',
2830             '0x1.3d1fe76ac6168p-1', '0x1.00d8ea4c12abbp+0'),
2831            ('0x1.3265ae6f05572p-2', '0x1.16d7ec285f7a2p-1',
2832             '0x1.0b8405b3827fbp-1', '0x1.5ef33c118a001p-1'),
2833            ('0x1.c4d1bf55ec1a5p-1', '0x1.bc59618459e12p-2',
2834             '0x1.ce5b73dc1773dp-1', '0x1.496cf6164f99bp+0'),
2835            ('0x1.d350026ac3946p-1', '0x1.9a234e149a68cp-2',
2836             '0x1.f5467b1911fd6p-2', '0x1.b5cee3225caa5p-1'),
2837        ]
2838        for a_hex, b_hex, c_hex, expected_hex in test_values:
2839            a = float.fromhex(a_hex)
2840            b = float.fromhex(b_hex)
2841            c = float.fromhex(c_hex)
2842            expected = float.fromhex(expected_hex)
2843            self.assertEqual(math.fma(a, b, c), expected)
2844            self.assertEqual(math.fma(b, a, c), expected)
2845
2846    # Custom assertions.
2847    def assertIsNaN(self, value):
2848        self.assertTrue(
2849            math.isnan(value),
2850            msg="Expected a NaN, got {!r}".format(value)
2851        )
2852
2853    def assertIsPositiveZero(self, value):
2854        self.assertTrue(
2855            value == 0 and math.copysign(1, value) > 0,
2856            msg="Expected a positive zero, got {!r}".format(value)
2857        )
2858
2859    def assertIsNegativeZero(self, value):
2860        self.assertTrue(
2861            value == 0 and math.copysign(1, value) < 0,
2862            msg="Expected a negative zero, got {!r}".format(value)
2863        )
2864
2865
2866def load_tests(loader, tests, pattern):
2867    from doctest import DocFileSuite
2868    tests.addTest(DocFileSuite(os.path.join("mathdata", "ieee754.txt")))
2869    return tests
2870
2871if __name__ == '__main__':
2872    unittest.main()
2873