python (3.12.0)

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