blob: c237bc1942e6558f9554c18e098d485603f0bd47 [file] [log] [blame]
Guido van Rossumfcce6301996-08-08 18:26:25 +00001# Python test set -- math module
2# XXXX Should not do tests around zero only
3
Eric Smithf24a0d92010-12-04 13:32:18 +00004from test.support import run_unittest, verbose, requires_IEEE_754
Victor Stinnerfce92332011-06-01 12:28:04 +02005from test import support
Thomas Wouters89f507f2006-12-13 04:49:30 +00006import unittest
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -07007import itertools
Pablo Galindoe9ba3702018-09-03 22:20:06 +01008import decimal
Thomas Wouters89f507f2006-12-13 04:49:30 +00009import math
Christian Heimes53876d92008-04-19 00:31:39 +000010import os
Mark Dickinson85746542016-09-04 09:58:51 +010011import platform
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -070012import random
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000013import struct
Mark Dickinson85746542016-09-04 09:58:51 +010014import sys
Victor Stinner8f4ef3b2019-07-01 18:28:25 +020015
Guido van Rossumfcce6301996-08-08 18:26:25 +000016
Christian Heimes53876d92008-04-19 00:31:39 +000017eps = 1E-05
18NAN = float('nan')
19INF = float('inf')
20NINF = float('-inf')
Mark Dickinson31ba1c32016-09-04 12:29:14 +010021FLOAT_MAX = sys.float_info.max
Raymond Hettingerc6dabe32018-07-28 07:48:04 -070022FLOAT_MIN = sys.float_info.min
Christian Heimes53876d92008-04-19 00:31:39 +000023
Mark Dickinson5c567082009-04-24 16:39:07 +000024# detect evidence of double-rounding: fsum is not always correctly
25# rounded on machines that suffer from double rounding.
26x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer
27HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4)
28
Christian Heimes53876d92008-04-19 00:31:39 +000029# locate file with test values
30if __name__ == '__main__':
31 file = sys.argv[0]
32else:
33 file = __file__
34test_dir = os.path.dirname(file) or os.curdir
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000035math_testcases = os.path.join(test_dir, 'math_testcases.txt')
Christian Heimes53876d92008-04-19 00:31:39 +000036test_file = os.path.join(test_dir, 'cmath_testcases.txt')
37
Mark Dickinson96f774d2016-09-03 19:30:22 +010038
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000039def to_ulps(x):
40 """Convert a non-NaN float x to an integer, in such a way that
41 adjacent floats are converted to adjacent integers. Then
42 abs(ulps(x) - ulps(y)) gives the difference in ulps between two
43 floats.
44
45 The results from this function will only make sense on platforms
Mark Dickinson96f774d2016-09-03 19:30:22 +010046 where native doubles are represented in IEEE 754 binary64 format.
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000047
Mark Dickinson96f774d2016-09-03 19:30:22 +010048 Note: 0.0 and -0.0 are converted to 0 and -1, respectively.
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000049 """
Mark Dickinsond412ab52009-10-17 07:10:00 +000050 n = struct.unpack('<q', struct.pack('<d', x))[0]
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000051 if n < 0:
52 n = ~(n+2**63)
53 return n
54
Mark Dickinson05d2e082009-12-11 20:17:17 +000055
Mark Dickinson96f774d2016-09-03 19:30:22 +010056def ulp(x):
57 """Return the value of the least significant bit of a
58 float x, such that the first float bigger than x is x+ulp(x).
59 Then, given an expected result x and a tolerance of n ulps,
60 the result y should be such that abs(y-x) <= n * ulp(x).
61 The results from this function will only make sense on platforms
62 where native doubles are represented in IEEE 754 binary64 format.
63 """
64 x = abs(float(x))
65 if math.isnan(x) or math.isinf(x):
66 return x
Mark Dickinson05d2e082009-12-11 20:17:17 +000067
Mark Dickinson96f774d2016-09-03 19:30:22 +010068 # Find next float up from x.
69 n = struct.unpack('<q', struct.pack('<d', x))[0]
70 x_next = struct.unpack('<d', struct.pack('<q', n + 1))[0]
71 if math.isinf(x_next):
72 # Corner case: x was the largest finite float. Then it's
73 # not an exact power of two, so we can take the difference
74 # between x and the previous float.
75 x_prev = struct.unpack('<d', struct.pack('<q', n - 1))[0]
76 return x - x_prev
77 else:
78 return x_next - x
Mark Dickinson05d2e082009-12-11 20:17:17 +000079
Mark Dickinson4c8a9a22010-05-15 17:02:38 +000080# Here's a pure Python version of the math.factorial algorithm, for
81# documentation and comparison purposes.
82#
83# Formula:
84#
85# factorial(n) = factorial_odd_part(n) << (n - count_set_bits(n))
86#
87# where
88#
89# factorial_odd_part(n) = product_{i >= 0} product_{0 < j <= n >> i; j odd} j
90#
91# The outer product above is an infinite product, but once i >= n.bit_length,
92# (n >> i) < 1 and the corresponding term of the product is empty. So only the
93# finitely many terms for 0 <= i < n.bit_length() contribute anything.
94#
95# We iterate downwards from i == n.bit_length() - 1 to i == 0. The inner
96# product in the formula above starts at 1 for i == n.bit_length(); for each i
97# < n.bit_length() we get the inner product for i from that for i + 1 by
98# multiplying by all j in {n >> i+1 < j <= n >> i; j odd}. In Python terms,
99# this set is range((n >> i+1) + 1 | 1, (n >> i) + 1 | 1, 2).
100
101def count_set_bits(n):
102 """Number of '1' bits in binary expansion of a nonnnegative integer."""
103 return 1 + count_set_bits(n & n - 1) if n else 0
104
105def partial_product(start, stop):
106 """Product of integers in range(start, stop, 2), computed recursively.
107 start and stop should both be odd, with start <= stop.
108
109 """
110 numfactors = (stop - start) >> 1
111 if not numfactors:
112 return 1
113 elif numfactors == 1:
114 return start
115 else:
116 mid = (start + numfactors) | 1
117 return partial_product(start, mid) * partial_product(mid, stop)
118
119def py_factorial(n):
120 """Factorial of nonnegative integer n, via "Binary Split Factorial Formula"
121 described at http://www.luschny.de/math/factorial/binarysplitfact.html
122
123 """
124 inner = outer = 1
125 for i in reversed(range(n.bit_length())):
126 inner *= partial_product((n >> i + 1) + 1 | 1, (n >> i) + 1 | 1)
127 outer *= inner
128 return outer << (n - count_set_bits(n))
129
Mark Dickinson96f774d2016-09-03 19:30:22 +0100130def ulp_abs_check(expected, got, ulp_tol, abs_tol):
131 """Given finite floats `expected` and `got`, check that they're
132 approximately equal to within the given number of ulps or the
133 given absolute tolerance, whichever is bigger.
Mark Dickinson05d2e082009-12-11 20:17:17 +0000134
Mark Dickinson96f774d2016-09-03 19:30:22 +0100135 Returns None on success and an error message on failure.
136 """
137 ulp_error = abs(to_ulps(expected) - to_ulps(got))
138 abs_error = abs(expected - got)
139
140 # Succeed if either abs_error <= abs_tol or ulp_error <= ulp_tol.
141 if abs_error <= abs_tol or ulp_error <= ulp_tol:
Mark Dickinson05d2e082009-12-11 20:17:17 +0000142 return None
Mark Dickinson96f774d2016-09-03 19:30:22 +0100143 else:
144 fmt = ("error = {:.3g} ({:d} ulps); "
145 "permitted error = {:.3g} or {:d} ulps")
146 return fmt.format(abs_error, ulp_error, abs_tol, ulp_tol)
Mark Dickinson12c4bdb2009-09-28 19:21:11 +0000147
148def parse_mtestfile(fname):
149 """Parse a file with test values
150
151 -- starts a comment
152 blank lines, or lines containing only a comment, are ignored
153 other lines are expected to have the form
154 id fn arg -> expected [flag]*
155
156 """
157 with open(fname) as fp:
158 for line in fp:
159 # strip comments, and skip blank lines
160 if '--' in line:
161 line = line[:line.index('--')]
162 if not line.strip():
163 continue
164
165 lhs, rhs = line.split('->')
166 id, fn, arg = lhs.split()
167 rhs_pieces = rhs.split()
168 exp = rhs_pieces[0]
169 flags = rhs_pieces[1:]
170
171 yield (id, fn, float(arg), float(exp), flags)
172
Mark Dickinson96f774d2016-09-03 19:30:22 +0100173
Christian Heimes53876d92008-04-19 00:31:39 +0000174def parse_testfile(fname):
175 """Parse a file with test values
176
177 Empty lines or lines starting with -- are ignored
178 yields id, fn, arg_real, arg_imag, exp_real, exp_imag
179 """
180 with open(fname) as fp:
181 for line in fp:
182 # skip comment lines and blank lines
183 if line.startswith('--') or not line.strip():
184 continue
185
186 lhs, rhs = line.split('->')
187 id, fn, arg_real, arg_imag = lhs.split()
188 rhs_pieces = rhs.split()
189 exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1]
190 flags = rhs_pieces[2:]
191
192 yield (id, fn,
193 float(arg_real), float(arg_imag),
194 float(exp_real), float(exp_imag),
Mark Dickinson96f774d2016-09-03 19:30:22 +0100195 flags)
196
197
198def result_check(expected, got, ulp_tol=5, abs_tol=0.0):
199 # Common logic of MathTests.(ftest, test_testcases, test_mtestcases)
200 """Compare arguments expected and got, as floats, if either
201 is a float, using a tolerance expressed in multiples of
202 ulp(expected) or absolutely (if given and greater).
203
204 As a convenience, when neither argument is a float, and for
205 non-finite floats, exact equality is demanded. Also, nan==nan
206 as far as this function is concerned.
207
208 Returns None on success and an error message on failure.
209 """
210
211 # Check exactly equal (applies also to strings representing exceptions)
212 if got == expected:
213 return None
214
215 failure = "not equal"
216
217 # Turn mixed float and int comparison (e.g. floor()) to all-float
218 if isinstance(expected, float) and isinstance(got, int):
219 got = float(got)
220 elif isinstance(got, float) and isinstance(expected, int):
221 expected = float(expected)
222
223 if isinstance(expected, float) and isinstance(got, float):
224 if math.isnan(expected) and math.isnan(got):
225 # Pass, since both nan
226 failure = None
227 elif math.isinf(expected) or math.isinf(got):
228 # We already know they're not equal, drop through to failure
229 pass
230 else:
231 # Both are finite floats (now). Are they close enough?
232 failure = ulp_abs_check(expected, got, ulp_tol, abs_tol)
233
234 # arguments are not equal, and if numeric, are too far apart
235 if failure is not None:
236 fail_fmt = "expected {!r}, got {!r}"
237 fail_msg = fail_fmt.format(expected, got)
238 fail_msg += ' ({})'.format(failure)
239 return fail_msg
240 else:
241 return None
Guido van Rossumfcce6301996-08-08 18:26:25 +0000242
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +0300243class IntSubclass(int):
244 pass
245
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300246# Class providing an __index__ method.
247class MyIndexable(object):
248 def __init__(self, value):
249 self.value = value
250
251 def __index__(self):
252 return self.value
253
Thomas Wouters89f507f2006-12-13 04:49:30 +0000254class MathTests(unittest.TestCase):
Guido van Rossumfcce6301996-08-08 18:26:25 +0000255
Mark Dickinson96f774d2016-09-03 19:30:22 +0100256 def ftest(self, name, got, expected, ulp_tol=5, abs_tol=0.0):
257 """Compare arguments expected and got, as floats, if either
258 is a float, using a tolerance expressed in multiples of
259 ulp(expected) or absolutely, whichever is greater.
260
261 As a convenience, when neither argument is a float, and for
262 non-finite floats, exact equality is demanded. Also, nan==nan
263 in this function.
264 """
265 failure = result_check(expected, got, ulp_tol, abs_tol)
266 if failure is not None:
267 self.fail("{}: {}".format(name, failure))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000268
Thomas Wouters89f507f2006-12-13 04:49:30 +0000269 def testConstants(self):
Mark Dickinson96f774d2016-09-03 19:30:22 +0100270 # Ref: Abramowitz & Stegun (Dover, 1965)
271 self.ftest('pi', math.pi, 3.141592653589793238462643)
272 self.ftest('e', math.e, 2.718281828459045235360287)
Guido van Rossum0a891d72016-08-15 09:12:52 -0700273 self.assertEqual(math.tau, 2*math.pi)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000274
Thomas Wouters89f507f2006-12-13 04:49:30 +0000275 def testAcos(self):
276 self.assertRaises(TypeError, math.acos)
277 self.ftest('acos(-1)', math.acos(-1), math.pi)
278 self.ftest('acos(0)', math.acos(0), math.pi/2)
279 self.ftest('acos(1)', math.acos(1), 0)
Christian Heimes53876d92008-04-19 00:31:39 +0000280 self.assertRaises(ValueError, math.acos, INF)
281 self.assertRaises(ValueError, math.acos, NINF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100282 self.assertRaises(ValueError, math.acos, 1 + eps)
283 self.assertRaises(ValueError, math.acos, -1 - eps)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000284 self.assertTrue(math.isnan(math.acos(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000285
286 def testAcosh(self):
287 self.assertRaises(TypeError, math.acosh)
288 self.ftest('acosh(1)', math.acosh(1), 0)
289 self.ftest('acosh(2)', math.acosh(2), 1.3169578969248168)
290 self.assertRaises(ValueError, math.acosh, 0)
291 self.assertRaises(ValueError, math.acosh, -1)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000292 self.assertEqual(math.acosh(INF), INF)
Christian Heimes53876d92008-04-19 00:31:39 +0000293 self.assertRaises(ValueError, math.acosh, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000294 self.assertTrue(math.isnan(math.acosh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000295
Thomas Wouters89f507f2006-12-13 04:49:30 +0000296 def testAsin(self):
297 self.assertRaises(TypeError, math.asin)
298 self.ftest('asin(-1)', math.asin(-1), -math.pi/2)
299 self.ftest('asin(0)', math.asin(0), 0)
300 self.ftest('asin(1)', math.asin(1), math.pi/2)
Christian Heimes53876d92008-04-19 00:31:39 +0000301 self.assertRaises(ValueError, math.asin, INF)
302 self.assertRaises(ValueError, math.asin, NINF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100303 self.assertRaises(ValueError, math.asin, 1 + eps)
304 self.assertRaises(ValueError, math.asin, -1 - eps)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000305 self.assertTrue(math.isnan(math.asin(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000306
307 def testAsinh(self):
308 self.assertRaises(TypeError, math.asinh)
309 self.ftest('asinh(0)', math.asinh(0), 0)
310 self.ftest('asinh(1)', math.asinh(1), 0.88137358701954305)
311 self.ftest('asinh(-1)', math.asinh(-1), -0.88137358701954305)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000312 self.assertEqual(math.asinh(INF), INF)
313 self.assertEqual(math.asinh(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000314 self.assertTrue(math.isnan(math.asinh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000315
Thomas Wouters89f507f2006-12-13 04:49:30 +0000316 def testAtan(self):
317 self.assertRaises(TypeError, math.atan)
318 self.ftest('atan(-1)', math.atan(-1), -math.pi/4)
319 self.ftest('atan(0)', math.atan(0), 0)
320 self.ftest('atan(1)', math.atan(1), math.pi/4)
Christian Heimes53876d92008-04-19 00:31:39 +0000321 self.ftest('atan(inf)', math.atan(INF), math.pi/2)
Christian Heimesa342c012008-04-20 21:01:16 +0000322 self.ftest('atan(-inf)', math.atan(NINF), -math.pi/2)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000323 self.assertTrue(math.isnan(math.atan(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000324
325 def testAtanh(self):
326 self.assertRaises(TypeError, math.atan)
327 self.ftest('atanh(0)', math.atanh(0), 0)
328 self.ftest('atanh(0.5)', math.atanh(0.5), 0.54930614433405489)
329 self.ftest('atanh(-0.5)', math.atanh(-0.5), -0.54930614433405489)
330 self.assertRaises(ValueError, math.atanh, 1)
331 self.assertRaises(ValueError, math.atanh, -1)
332 self.assertRaises(ValueError, math.atanh, INF)
333 self.assertRaises(ValueError, math.atanh, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000334 self.assertTrue(math.isnan(math.atanh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000335
Thomas Wouters89f507f2006-12-13 04:49:30 +0000336 def testAtan2(self):
337 self.assertRaises(TypeError, math.atan2)
338 self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
339 self.ftest('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
340 self.ftest('atan2(0, 1)', math.atan2(0, 1), 0)
341 self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
342 self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000343
Christian Heimese57950f2008-04-21 13:08:03 +0000344 # math.atan2(0, x)
345 self.ftest('atan2(0., -inf)', math.atan2(0., NINF), math.pi)
346 self.ftest('atan2(0., -2.3)', math.atan2(0., -2.3), math.pi)
347 self.ftest('atan2(0., -0.)', math.atan2(0., -0.), math.pi)
348 self.assertEqual(math.atan2(0., 0.), 0.)
349 self.assertEqual(math.atan2(0., 2.3), 0.)
350 self.assertEqual(math.atan2(0., INF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000351 self.assertTrue(math.isnan(math.atan2(0., NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000352 # math.atan2(-0, x)
353 self.ftest('atan2(-0., -inf)', math.atan2(-0., NINF), -math.pi)
354 self.ftest('atan2(-0., -2.3)', math.atan2(-0., -2.3), -math.pi)
355 self.ftest('atan2(-0., -0.)', math.atan2(-0., -0.), -math.pi)
356 self.assertEqual(math.atan2(-0., 0.), -0.)
357 self.assertEqual(math.atan2(-0., 2.3), -0.)
358 self.assertEqual(math.atan2(-0., INF), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000359 self.assertTrue(math.isnan(math.atan2(-0., NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000360 # math.atan2(INF, x)
361 self.ftest('atan2(inf, -inf)', math.atan2(INF, NINF), math.pi*3/4)
362 self.ftest('atan2(inf, -2.3)', math.atan2(INF, -2.3), math.pi/2)
363 self.ftest('atan2(inf, -0.)', math.atan2(INF, -0.0), math.pi/2)
364 self.ftest('atan2(inf, 0.)', math.atan2(INF, 0.0), math.pi/2)
365 self.ftest('atan2(inf, 2.3)', math.atan2(INF, 2.3), math.pi/2)
366 self.ftest('atan2(inf, inf)', math.atan2(INF, INF), math.pi/4)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000367 self.assertTrue(math.isnan(math.atan2(INF, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000368 # math.atan2(NINF, x)
369 self.ftest('atan2(-inf, -inf)', math.atan2(NINF, NINF), -math.pi*3/4)
370 self.ftest('atan2(-inf, -2.3)', math.atan2(NINF, -2.3), -math.pi/2)
371 self.ftest('atan2(-inf, -0.)', math.atan2(NINF, -0.0), -math.pi/2)
372 self.ftest('atan2(-inf, 0.)', math.atan2(NINF, 0.0), -math.pi/2)
373 self.ftest('atan2(-inf, 2.3)', math.atan2(NINF, 2.3), -math.pi/2)
374 self.ftest('atan2(-inf, inf)', math.atan2(NINF, INF), -math.pi/4)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000375 self.assertTrue(math.isnan(math.atan2(NINF, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000376 # math.atan2(+finite, x)
377 self.ftest('atan2(2.3, -inf)', math.atan2(2.3, NINF), math.pi)
378 self.ftest('atan2(2.3, -0.)', math.atan2(2.3, -0.), math.pi/2)
379 self.ftest('atan2(2.3, 0.)', math.atan2(2.3, 0.), math.pi/2)
380 self.assertEqual(math.atan2(2.3, INF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000381 self.assertTrue(math.isnan(math.atan2(2.3, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000382 # math.atan2(-finite, x)
383 self.ftest('atan2(-2.3, -inf)', math.atan2(-2.3, NINF), -math.pi)
384 self.ftest('atan2(-2.3, -0.)', math.atan2(-2.3, -0.), -math.pi/2)
385 self.ftest('atan2(-2.3, 0.)', math.atan2(-2.3, 0.), -math.pi/2)
386 self.assertEqual(math.atan2(-2.3, INF), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000387 self.assertTrue(math.isnan(math.atan2(-2.3, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000388 # math.atan2(NAN, x)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000389 self.assertTrue(math.isnan(math.atan2(NAN, NINF)))
390 self.assertTrue(math.isnan(math.atan2(NAN, -2.3)))
391 self.assertTrue(math.isnan(math.atan2(NAN, -0.)))
392 self.assertTrue(math.isnan(math.atan2(NAN, 0.)))
393 self.assertTrue(math.isnan(math.atan2(NAN, 2.3)))
394 self.assertTrue(math.isnan(math.atan2(NAN, INF)))
395 self.assertTrue(math.isnan(math.atan2(NAN, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000396
Thomas Wouters89f507f2006-12-13 04:49:30 +0000397 def testCeil(self):
398 self.assertRaises(TypeError, math.ceil)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000399 self.assertEqual(int, type(math.ceil(0.5)))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000400 self.ftest('ceil(0.5)', math.ceil(0.5), 1)
401 self.ftest('ceil(1.0)', math.ceil(1.0), 1)
402 self.ftest('ceil(1.5)', math.ceil(1.5), 2)
403 self.ftest('ceil(-0.5)', math.ceil(-0.5), 0)
404 self.ftest('ceil(-1.0)', math.ceil(-1.0), -1)
405 self.ftest('ceil(-1.5)', math.ceil(-1.5), -1)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000406 #self.assertEqual(math.ceil(INF), INF)
407 #self.assertEqual(math.ceil(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000408 #self.assertTrue(math.isnan(math.ceil(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000409
Guido van Rossum13e05de2007-08-23 22:56:55 +0000410 class TestCeil:
411 def __ceil__(self):
412 return 42
413 class TestNoCeil:
414 pass
415 self.ftest('ceil(TestCeil())', math.ceil(TestCeil()), 42)
416 self.assertRaises(TypeError, math.ceil, TestNoCeil())
417
418 t = TestNoCeil()
419 t.__ceil__ = lambda *args: args
420 self.assertRaises(TypeError, math.ceil, t)
421 self.assertRaises(TypeError, math.ceil, t, 0)
422
Mark Dickinson63566232009-09-18 21:04:19 +0000423 @requires_IEEE_754
424 def testCopysign(self):
Mark Dickinson06b59e02010-02-06 23:16:50 +0000425 self.assertEqual(math.copysign(1, 42), 1.0)
426 self.assertEqual(math.copysign(0., 42), 0.0)
427 self.assertEqual(math.copysign(1., -42), -1.0)
428 self.assertEqual(math.copysign(3, 0.), 3.0)
429 self.assertEqual(math.copysign(4., -0.), -4.0)
430
Mark Dickinson63566232009-09-18 21:04:19 +0000431 self.assertRaises(TypeError, math.copysign)
432 # copysign should let us distinguish signs of zeros
Ezio Melottib3aedd42010-11-20 19:04:17 +0000433 self.assertEqual(math.copysign(1., 0.), 1.)
434 self.assertEqual(math.copysign(1., -0.), -1.)
435 self.assertEqual(math.copysign(INF, 0.), INF)
436 self.assertEqual(math.copysign(INF, -0.), NINF)
437 self.assertEqual(math.copysign(NINF, 0.), INF)
438 self.assertEqual(math.copysign(NINF, -0.), NINF)
Mark Dickinson63566232009-09-18 21:04:19 +0000439 # and of infinities
Ezio Melottib3aedd42010-11-20 19:04:17 +0000440 self.assertEqual(math.copysign(1., INF), 1.)
441 self.assertEqual(math.copysign(1., NINF), -1.)
442 self.assertEqual(math.copysign(INF, INF), INF)
443 self.assertEqual(math.copysign(INF, NINF), NINF)
444 self.assertEqual(math.copysign(NINF, INF), INF)
445 self.assertEqual(math.copysign(NINF, NINF), NINF)
Mark Dickinson06b59e02010-02-06 23:16:50 +0000446 self.assertTrue(math.isnan(math.copysign(NAN, 1.)))
447 self.assertTrue(math.isnan(math.copysign(NAN, INF)))
448 self.assertTrue(math.isnan(math.copysign(NAN, NINF)))
449 self.assertTrue(math.isnan(math.copysign(NAN, NAN)))
Mark Dickinson63566232009-09-18 21:04:19 +0000450 # copysign(INF, NAN) may be INF or it may be NINF, since
451 # we don't know whether the sign bit of NAN is set on any
452 # given platform.
Mark Dickinson06b59e02010-02-06 23:16:50 +0000453 self.assertTrue(math.isinf(math.copysign(INF, NAN)))
Mark Dickinson63566232009-09-18 21:04:19 +0000454 # similarly, copysign(2., NAN) could be 2. or -2.
Ezio Melottib3aedd42010-11-20 19:04:17 +0000455 self.assertEqual(abs(math.copysign(2., NAN)), 2.)
Christian Heimes53876d92008-04-19 00:31:39 +0000456
Thomas Wouters89f507f2006-12-13 04:49:30 +0000457 def testCos(self):
458 self.assertRaises(TypeError, math.cos)
Mark Dickinson96f774d2016-09-03 19:30:22 +0100459 self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0, abs_tol=ulp(1))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000460 self.ftest('cos(0)', math.cos(0), 1)
Mark Dickinson96f774d2016-09-03 19:30:22 +0100461 self.ftest('cos(pi/2)', math.cos(math.pi/2), 0, abs_tol=ulp(1))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000462 self.ftest('cos(pi)', math.cos(math.pi), -1)
Christian Heimes53876d92008-04-19 00:31:39 +0000463 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000464 self.assertTrue(math.isnan(math.cos(INF)))
465 self.assertTrue(math.isnan(math.cos(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +0000466 except ValueError:
467 self.assertRaises(ValueError, math.cos, INF)
468 self.assertRaises(ValueError, math.cos, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000469 self.assertTrue(math.isnan(math.cos(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000470
Paul Monsonf3550692019-06-19 13:09:54 -0700471 @unittest.skipIf(sys.platform == 'win32' and platform.machine() in ('ARM', 'ARM64'),
472 "Windows UCRT is off by 2 ULP this test requires accuracy within 1 ULP")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000473 def testCosh(self):
474 self.assertRaises(TypeError, math.cosh)
475 self.ftest('cosh(0)', math.cosh(0), 1)
476 self.ftest('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
Ezio Melottib3aedd42010-11-20 19:04:17 +0000477 self.assertEqual(math.cosh(INF), INF)
478 self.assertEqual(math.cosh(NINF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000479 self.assertTrue(math.isnan(math.cosh(NAN)))
Raymond Hettinger64108af2002-05-13 03:55:01 +0000480
Thomas Wouters89f507f2006-12-13 04:49:30 +0000481 def testDegrees(self):
482 self.assertRaises(TypeError, math.degrees)
483 self.ftest('degrees(pi)', math.degrees(math.pi), 180.0)
484 self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
485 self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100486 self.ftest('degrees(0)', math.degrees(0), 0)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000487
Thomas Wouters89f507f2006-12-13 04:49:30 +0000488 def testExp(self):
489 self.assertRaises(TypeError, math.exp)
490 self.ftest('exp(-1)', math.exp(-1), 1/math.e)
491 self.ftest('exp(0)', math.exp(0), 1)
492 self.ftest('exp(1)', math.exp(1), math.e)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000493 self.assertEqual(math.exp(INF), INF)
494 self.assertEqual(math.exp(NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000495 self.assertTrue(math.isnan(math.exp(NAN)))
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100496 self.assertRaises(OverflowError, math.exp, 1000000)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000497
Thomas Wouters89f507f2006-12-13 04:49:30 +0000498 def testFabs(self):
499 self.assertRaises(TypeError, math.fabs)
500 self.ftest('fabs(-1)', math.fabs(-1), 1)
501 self.ftest('fabs(0)', math.fabs(0), 0)
502 self.ftest('fabs(1)', math.fabs(1), 1)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000503
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000504 def testFactorial(self):
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000505 self.assertEqual(math.factorial(0), 1)
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000506 total = 1
507 for i in range(1, 1000):
508 total *= i
509 self.assertEqual(math.factorial(i), total)
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000510 self.assertEqual(math.factorial(i), py_factorial(i))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000511 self.assertRaises(ValueError, math.factorial, -1)
Mark Dickinson5990d282014-04-10 09:29:39 -0400512 self.assertRaises(ValueError, math.factorial, -10**100)
Mark Dickinson5990d282014-04-10 09:29:39 -0400513
Pablo Galindoe9ba3702018-09-03 22:20:06 +0100514 def testFactorialNonIntegers(self):
Serhiy Storchaka231aad32019-06-17 16:57:27 +0300515 with self.assertWarns(DeprecationWarning):
516 self.assertEqual(math.factorial(5.0), 120)
517 with self.assertWarns(DeprecationWarning):
518 self.assertRaises(ValueError, math.factorial, 5.2)
519 with self.assertWarns(DeprecationWarning):
520 self.assertRaises(ValueError, math.factorial, -1.0)
521 with self.assertWarns(DeprecationWarning):
522 self.assertRaises(ValueError, math.factorial, -1e100)
523 self.assertRaises(TypeError, math.factorial, decimal.Decimal('5'))
524 self.assertRaises(TypeError, math.factorial, decimal.Decimal('5.2'))
Pablo Galindoe9ba3702018-09-03 22:20:06 +0100525 self.assertRaises(TypeError, math.factorial, "5")
526
Mark Dickinson5990d282014-04-10 09:29:39 -0400527 # Other implementations may place different upper bounds.
528 @support.cpython_only
529 def testFactorialHugeInputs(self):
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +0300530 # Currently raises OverflowError for inputs that are too large
Mark Dickinson5990d282014-04-10 09:29:39 -0400531 # to fit into a C long.
532 self.assertRaises(OverflowError, math.factorial, 10**100)
Serhiy Storchaka231aad32019-06-17 16:57:27 +0300533 with self.assertWarns(DeprecationWarning):
534 self.assertRaises(OverflowError, math.factorial, 1e100)
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000535
Thomas Wouters89f507f2006-12-13 04:49:30 +0000536 def testFloor(self):
537 self.assertRaises(TypeError, math.floor)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000538 self.assertEqual(int, type(math.floor(0.5)))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000539 self.ftest('floor(0.5)', math.floor(0.5), 0)
540 self.ftest('floor(1.0)', math.floor(1.0), 1)
541 self.ftest('floor(1.5)', math.floor(1.5), 1)
542 self.ftest('floor(-0.5)', math.floor(-0.5), -1)
543 self.ftest('floor(-1.0)', math.floor(-1.0), -1)
544 self.ftest('floor(-1.5)', math.floor(-1.5), -2)
Guido van Rossum806c2462007-08-06 23:33:07 +0000545 # pow() relies on floor() to check for integers
546 # This fails on some platforms - so check it here
547 self.ftest('floor(1.23e167)', math.floor(1.23e167), 1.23e167)
548 self.ftest('floor(-1.23e167)', math.floor(-1.23e167), -1.23e167)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000549 #self.assertEqual(math.ceil(INF), INF)
550 #self.assertEqual(math.ceil(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000551 #self.assertTrue(math.isnan(math.floor(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000552
Guido van Rossum13e05de2007-08-23 22:56:55 +0000553 class TestFloor:
554 def __floor__(self):
555 return 42
556 class TestNoFloor:
557 pass
558 self.ftest('floor(TestFloor())', math.floor(TestFloor()), 42)
559 self.assertRaises(TypeError, math.floor, TestNoFloor())
560
561 t = TestNoFloor()
562 t.__floor__ = lambda *args: args
563 self.assertRaises(TypeError, math.floor, t)
564 self.assertRaises(TypeError, math.floor, t, 0)
565
Thomas Wouters89f507f2006-12-13 04:49:30 +0000566 def testFmod(self):
567 self.assertRaises(TypeError, math.fmod)
Mark Dickinson5bc7a442011-05-03 21:13:40 +0100568 self.ftest('fmod(10, 1)', math.fmod(10, 1), 0.0)
569 self.ftest('fmod(10, 0.5)', math.fmod(10, 0.5), 0.0)
570 self.ftest('fmod(10, 1.5)', math.fmod(10, 1.5), 1.0)
571 self.ftest('fmod(-10, 1)', math.fmod(-10, 1), -0.0)
572 self.ftest('fmod(-10, 0.5)', math.fmod(-10, 0.5), -0.0)
573 self.ftest('fmod(-10, 1.5)', math.fmod(-10, 1.5), -1.0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000574 self.assertTrue(math.isnan(math.fmod(NAN, 1.)))
575 self.assertTrue(math.isnan(math.fmod(1., NAN)))
576 self.assertTrue(math.isnan(math.fmod(NAN, NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000577 self.assertRaises(ValueError, math.fmod, 1., 0.)
578 self.assertRaises(ValueError, math.fmod, INF, 1.)
579 self.assertRaises(ValueError, math.fmod, NINF, 1.)
580 self.assertRaises(ValueError, math.fmod, INF, 0.)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000581 self.assertEqual(math.fmod(3.0, INF), 3.0)
582 self.assertEqual(math.fmod(-3.0, INF), -3.0)
583 self.assertEqual(math.fmod(3.0, NINF), 3.0)
584 self.assertEqual(math.fmod(-3.0, NINF), -3.0)
585 self.assertEqual(math.fmod(0.0, 3.0), 0.0)
586 self.assertEqual(math.fmod(0.0, NINF), 0.0)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000587
Thomas Wouters89f507f2006-12-13 04:49:30 +0000588 def testFrexp(self):
589 self.assertRaises(TypeError, math.frexp)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000590
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000591 def testfrexp(name, result, expected):
592 (mant, exp), (emant, eexp) = result, expected
Thomas Wouters89f507f2006-12-13 04:49:30 +0000593 if abs(mant-emant) > eps or exp != eexp:
594 self.fail('%s returned %r, expected %r'%\
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000595 (name, result, expected))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000596
Thomas Wouters89f507f2006-12-13 04:49:30 +0000597 testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
598 testfrexp('frexp(0)', math.frexp(0), (0, 0))
599 testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
600 testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000601
Ezio Melottib3aedd42010-11-20 19:04:17 +0000602 self.assertEqual(math.frexp(INF)[0], INF)
603 self.assertEqual(math.frexp(NINF)[0], NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000604 self.assertTrue(math.isnan(math.frexp(NAN)[0]))
Christian Heimes53876d92008-04-19 00:31:39 +0000605
Mark Dickinson63566232009-09-18 21:04:19 +0000606 @requires_IEEE_754
Mark Dickinson5c567082009-04-24 16:39:07 +0000607 @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
608 "fsum is not exact on machines with double rounding")
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000609 def testFsum(self):
610 # math.fsum relies on exact rounding for correct operation.
611 # There's a known problem with IA32 floating-point that causes
612 # inexact rounding in some situations, and will cause the
613 # math.fsum tests below to fail; see issue #2937. On non IEEE
614 # 754 platforms, and on IEEE 754 platforms that exhibit the
615 # problem described in issue #2937, we simply skip the whole
616 # test.
617
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000618 # Python version of math.fsum, for comparison. Uses a
619 # different algorithm based on frexp, ldexp and integer
620 # arithmetic.
621 from sys import float_info
622 mant_dig = float_info.mant_dig
623 etiny = float_info.min_exp - mant_dig
624
625 def msum(iterable):
626 """Full precision summation. Compute sum(iterable) without any
627 intermediate accumulation of error. Based on the 'lsum' function
628 at http://code.activestate.com/recipes/393090/
629
630 """
631 tmant, texp = 0, 0
632 for x in iterable:
633 mant, exp = math.frexp(x)
634 mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig
635 if texp > exp:
636 tmant <<= texp-exp
637 texp = exp
638 else:
639 mant <<= exp-texp
640 tmant += mant
641 # Round tmant * 2**texp to a float. The original recipe
642 # used float(str(tmant)) * 2.0**texp for this, but that's
643 # a little unsafe because str -> float conversion can't be
644 # relied upon to do correct rounding on all platforms.
645 tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp)
646 if tail > 0:
647 h = 1 << (tail-1)
648 tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1)
649 texp += tail
650 return math.ldexp(tmant, texp)
651
652 test_values = [
653 ([], 0.0),
654 ([0.0], 0.0),
655 ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
656 ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
657 ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
658 ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
659 ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
660 ([1./n for n in range(1, 1001)],
661 float.fromhex('0x1.df11f45f4e61ap+2')),
662 ([(-1.)**n/n for n in range(1, 1001)],
663 float.fromhex('-0x1.62a2af1bd3624p-1')),
664 ([1.7**(i+1)-1.7**i for i in range(1000)] + [-1.7**1000], -1.0),
665 ([1e16, 1., 1e-16], 10000000000000002.0),
666 ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
667 # exercise code for resizing partials array
668 ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] +
669 [-2.**1022],
670 float.fromhex('0x1.5555555555555p+970')),
671 ]
672
673 for i, (vals, expected) in enumerate(test_values):
674 try:
675 actual = math.fsum(vals)
676 except OverflowError:
677 self.fail("test %d failed: got OverflowError, expected %r "
678 "for math.fsum(%.100r)" % (i, expected, vals))
679 except ValueError:
680 self.fail("test %d failed: got ValueError, expected %r "
681 "for math.fsum(%.100r)" % (i, expected, vals))
682 self.assertEqual(actual, expected)
683
684 from random import random, gauss, shuffle
685 for j in range(1000):
686 vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
687 s = 0
688 for i in range(200):
689 v = gauss(0, random()) ** 7 - s
690 s += v
691 vals.append(v)
692 shuffle(vals)
693
694 s = msum(vals)
695 self.assertEqual(msum(vals), math.fsum(vals))
696
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300697 def testGcd(self):
698 gcd = math.gcd
699 self.assertEqual(gcd(0, 0), 0)
700 self.assertEqual(gcd(1, 0), 1)
701 self.assertEqual(gcd(-1, 0), 1)
702 self.assertEqual(gcd(0, 1), 1)
703 self.assertEqual(gcd(0, -1), 1)
704 self.assertEqual(gcd(7, 1), 1)
705 self.assertEqual(gcd(7, -1), 1)
706 self.assertEqual(gcd(-23, 15), 1)
707 self.assertEqual(gcd(120, 84), 12)
708 self.assertEqual(gcd(84, -120), 12)
709 self.assertEqual(gcd(1216342683557601535506311712,
710 436522681849110124616458784), 32)
711 c = 652560
712 x = 434610456570399902378880679233098819019853229470286994367836600566
713 y = 1064502245825115327754847244914921553977
714 a = x * c
715 b = y * c
716 self.assertEqual(gcd(a, b), c)
717 self.assertEqual(gcd(b, a), c)
718 self.assertEqual(gcd(-a, b), c)
719 self.assertEqual(gcd(b, -a), c)
720 self.assertEqual(gcd(a, -b), c)
721 self.assertEqual(gcd(-b, a), c)
722 self.assertEqual(gcd(-a, -b), c)
723 self.assertEqual(gcd(-b, -a), c)
724 c = 576559230871654959816130551884856912003141446781646602790216406874
725 a = x * c
726 b = y * c
727 self.assertEqual(gcd(a, b), c)
728 self.assertEqual(gcd(b, a), c)
729 self.assertEqual(gcd(-a, b), c)
730 self.assertEqual(gcd(b, -a), c)
731 self.assertEqual(gcd(a, -b), c)
732 self.assertEqual(gcd(-b, a), c)
733 self.assertEqual(gcd(-a, -b), c)
734 self.assertEqual(gcd(-b, -a), c)
735
736 self.assertRaises(TypeError, gcd, 120.0, 84)
737 self.assertRaises(TypeError, gcd, 120, 84.0)
738 self.assertEqual(gcd(MyIndexable(120), MyIndexable(84)), 12)
739
Thomas Wouters89f507f2006-12-13 04:49:30 +0000740 def testHypot(self):
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700741 from decimal import Decimal
742 from fractions import Fraction
743
744 hypot = math.hypot
745
746 # Test different numbers of arguments (from zero to five)
747 # against a straightforward pure python implementation
748 args = math.e, math.pi, math.sqrt(2.0), math.gamma(3.5), math.sin(2.1)
749 for i in range(len(args)+1):
750 self.assertAlmostEqual(
751 hypot(*args[:i]),
752 math.sqrt(sum(s**2 for s in args[:i]))
753 )
754
755 # Test allowable types (those with __float__)
756 self.assertEqual(hypot(12.0, 5.0), 13.0)
757 self.assertEqual(hypot(12, 5), 13)
758 self.assertEqual(hypot(Decimal(12), Decimal(5)), 13)
759 self.assertEqual(hypot(Fraction(12, 32), Fraction(5, 32)), Fraction(13, 32))
760 self.assertEqual(hypot(bool(1), bool(0), bool(1), bool(1)), math.sqrt(3))
761
762 # Test corner cases
763 self.assertEqual(hypot(0.0, 0.0), 0.0) # Max input is zero
764 self.assertEqual(hypot(-10.5), 10.5) # Negative input
765 self.assertEqual(hypot(), 0.0) # Negative input
766 self.assertEqual(1.0,
767 math.copysign(1.0, hypot(-0.0)) # Convert negative zero to positive zero
768 )
Raymond Hettinger00414592018-08-12 12:15:23 -0700769 self.assertEqual( # Handling of moving max to the end
770 hypot(1.5, 1.5, 0.5),
771 hypot(1.5, 0.5, 1.5),
772 )
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700773
774 # Test handling of bad arguments
775 with self.assertRaises(TypeError): # Reject keyword args
776 hypot(x=1)
777 with self.assertRaises(TypeError): # Reject values without __float__
778 hypot(1.1, 'string', 2.2)
Raymond Hettinger808180c2019-01-28 13:59:56 -0800779 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
780 with self.assertRaises((ValueError, OverflowError)):
781 hypot(1, int_too_big_for_float)
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700782
783 # Any infinity gives positive infinity.
784 self.assertEqual(hypot(INF), INF)
785 self.assertEqual(hypot(0, INF), INF)
786 self.assertEqual(hypot(10, INF), INF)
787 self.assertEqual(hypot(-10, INF), INF)
788 self.assertEqual(hypot(NAN, INF), INF)
789 self.assertEqual(hypot(INF, NAN), INF)
790 self.assertEqual(hypot(NINF, NAN), INF)
791 self.assertEqual(hypot(NAN, NINF), INF)
792 self.assertEqual(hypot(-INF, INF), INF)
793 self.assertEqual(hypot(-INF, -INF), INF)
794 self.assertEqual(hypot(10, -INF), INF)
795
Raymond Hettinger00414592018-08-12 12:15:23 -0700796 # If no infinity, any NaN gives a NaN.
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700797 self.assertTrue(math.isnan(hypot(NAN)))
798 self.assertTrue(math.isnan(hypot(0, NAN)))
799 self.assertTrue(math.isnan(hypot(NAN, 10)))
800 self.assertTrue(math.isnan(hypot(10, NAN)))
801 self.assertTrue(math.isnan(hypot(NAN, NAN)))
802 self.assertTrue(math.isnan(hypot(NAN)))
803
804 # Verify scaling for extremely large values
805 fourthmax = FLOAT_MAX / 4.0
806 for n in range(32):
807 self.assertEqual(hypot(*([fourthmax]*n)), fourthmax * math.sqrt(n))
808
809 # Verify scaling for extremely small values
810 for exp in range(32):
811 scale = FLOAT_MIN / 2.0 ** exp
812 self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000813
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700814 def testDist(self):
815 from decimal import Decimal as D
816 from fractions import Fraction as F
817
818 dist = math.dist
819 sqrt = math.sqrt
820
Raymond Hettinger808180c2019-01-28 13:59:56 -0800821 # Simple exact cases
822 self.assertEqual(dist((1.0, 2.0, 3.0), (4.0, 2.0, -1.0)), 5.0)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700823 self.assertEqual(dist((1, 2, 3), (4, 2, -1)), 5.0)
824
825 # Test different numbers of arguments (from zero to nine)
826 # against a straightforward pure python implementation
827 for i in range(9):
828 for j in range(5):
829 p = tuple(random.uniform(-5, 5) for k in range(i))
830 q = tuple(random.uniform(-5, 5) for k in range(i))
831 self.assertAlmostEqual(
832 dist(p, q),
833 sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
834 )
835
Raymond Hettinger6b5f1b42019-07-27 14:04:29 -0700836 # Test non-tuple inputs
837 self.assertEqual(dist([1.0, 2.0, 3.0], [4.0, 2.0, -1.0]), 5.0)
838 self.assertEqual(dist(iter([1.0, 2.0, 3.0]), iter([4.0, 2.0, -1.0])), 5.0)
839
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700840 # Test allowable types (those with __float__)
841 self.assertEqual(dist((14.0, 1.0), (2.0, -4.0)), 13.0)
842 self.assertEqual(dist((14, 1), (2, -4)), 13)
843 self.assertEqual(dist((D(14), D(1)), (D(2), D(-4))), D(13))
844 self.assertEqual(dist((F(14, 32), F(1, 32)), (F(2, 32), F(-4, 32))),
845 F(13, 32))
846 self.assertEqual(dist((True, True, False, True, False),
847 (True, False, True, True, False)),
848 sqrt(2.0))
849
850 # Test corner cases
851 self.assertEqual(dist((13.25, 12.5, -3.25),
852 (13.25, 12.5, -3.25)),
853 0.0) # Distance with self is zero
854 self.assertEqual(dist((), ()), 0.0) # Zero-dimensional case
855 self.assertEqual(1.0, # Convert negative zero to positive zero
856 math.copysign(1.0, dist((-0.0,), (0.0,)))
857 )
858 self.assertEqual(1.0, # Convert negative zero to positive zero
859 math.copysign(1.0, dist((0.0,), (-0.0,)))
860 )
Raymond Hettinger00414592018-08-12 12:15:23 -0700861 self.assertEqual( # Handling of moving max to the end
862 dist((1.5, 1.5, 0.5), (0, 0, 0)),
863 dist((1.5, 0.5, 1.5), (0, 0, 0))
864 )
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700865
866 # Verify tuple subclasses are allowed
Raymond Hettinger00414592018-08-12 12:15:23 -0700867 class T(tuple):
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700868 pass
869 self.assertEqual(dist(T((1, 2, 3)), ((4, 2, -1))), 5.0)
870
871 # Test handling of bad arguments
872 with self.assertRaises(TypeError): # Reject keyword args
873 dist(p=(1, 2, 3), q=(4, 5, 6))
874 with self.assertRaises(TypeError): # Too few args
875 dist((1, 2, 3))
876 with self.assertRaises(TypeError): # Too many args
877 dist((1, 2, 3), (4, 5, 6), (7, 8, 9))
878 with self.assertRaises(TypeError): # Scalars not allowed
879 dist(1, 2)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700880 with self.assertRaises(TypeError): # Reject values without __float__
881 dist((1.1, 'string', 2.2), (1, 2, 3))
882 with self.assertRaises(ValueError): # Check dimension agree
883 dist((1, 2, 3, 4), (5, 6, 7))
884 with self.assertRaises(ValueError): # Check dimension agree
885 dist((1, 2, 3), (4, 5, 6, 7))
Ammar Askarcb08a712019-01-12 01:23:41 -0500886 with self.assertRaises(TypeError): # Rejects invalid types
887 dist("abc", "xyz")
Raymond Hettinger808180c2019-01-28 13:59:56 -0800888 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
889 with self.assertRaises((ValueError, OverflowError)):
890 dist((1, int_too_big_for_float), (2, 3))
891 with self.assertRaises((ValueError, OverflowError)):
892 dist((2, 3), (1, int_too_big_for_float))
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700893
Raymond Hettinger00414592018-08-12 12:15:23 -0700894 # Verify that the one dimensional case is equivalent to abs()
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700895 for i in range(20):
896 p, q = random.random(), random.random()
897 self.assertEqual(dist((p,), (q,)), abs(p - q))
898
899 # Test special values
900 values = [NINF, -10.5, -0.0, 0.0, 10.5, INF, NAN]
901 for p in itertools.product(values, repeat=3):
902 for q in itertools.product(values, repeat=3):
903 diffs = [px - qx for px, qx in zip(p, q)]
904 if any(map(math.isinf, diffs)):
905 # Any infinite difference gives positive infinity.
906 self.assertEqual(dist(p, q), INF)
907 elif any(map(math.isnan, diffs)):
Raymond Hettinger00414592018-08-12 12:15:23 -0700908 # If no infinity, any NaN gives a NaN.
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700909 self.assertTrue(math.isnan(dist(p, q)))
910
911 # Verify scaling for extremely large values
912 fourthmax = FLOAT_MAX / 4.0
913 for n in range(32):
914 p = (fourthmax,) * n
915 q = (0.0,) * n
916 self.assertEqual(dist(p, q), fourthmax * math.sqrt(n))
917 self.assertEqual(dist(q, p), fourthmax * math.sqrt(n))
918
919 # Verify scaling for extremely small values
920 for exp in range(32):
921 scale = FLOAT_MIN / 2.0 ** exp
922 p = (4*scale, 3*scale)
923 q = (0.0, 0.0)
924 self.assertEqual(math.dist(p, q), 5*scale)
925 self.assertEqual(math.dist(q, p), 5*scale)
926
Mark Dickinson73934b92019-05-18 12:29:50 +0100927 def testIsqrt(self):
928 # Test a variety of inputs, large and small.
929 test_values = (
930 list(range(1000))
931 + list(range(10**6 - 1000, 10**6 + 1000))
Mark Dickinson5c08ce92019-05-19 17:51:56 +0100932 + [2**e + i for e in range(60, 200) for i in range(-40, 40)]
Mark Dickinson73934b92019-05-18 12:29:50 +0100933 + [3**9999, 10**5001]
934 )
935
936 for value in test_values:
937 with self.subTest(value=value):
938 s = math.isqrt(value)
939 self.assertIs(type(s), int)
940 self.assertLessEqual(s*s, value)
941 self.assertLess(value, (s+1)*(s+1))
942
943 # Negative values
944 with self.assertRaises(ValueError):
945 math.isqrt(-1)
946
947 # Integer-like things
948 s = math.isqrt(True)
949 self.assertIs(type(s), int)
950 self.assertEqual(s, 1)
951
952 s = math.isqrt(False)
953 self.assertIs(type(s), int)
954 self.assertEqual(s, 0)
955
956 class IntegerLike(object):
957 def __init__(self, value):
958 self.value = value
959
960 def __index__(self):
961 return self.value
962
963 s = math.isqrt(IntegerLike(1729))
964 self.assertIs(type(s), int)
965 self.assertEqual(s, 41)
966
967 with self.assertRaises(ValueError):
968 math.isqrt(IntegerLike(-3))
969
970 # Non-integer-like things
971 bad_values = [
972 3.5, "a string", decimal.Decimal("3.5"), 3.5j,
973 100.0, -4.0,
974 ]
975 for value in bad_values:
976 with self.subTest(value=value):
977 with self.assertRaises(TypeError):
978 math.isqrt(value)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700979
Thomas Wouters89f507f2006-12-13 04:49:30 +0000980 def testLdexp(self):
981 self.assertRaises(TypeError, math.ldexp)
982 self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
983 self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
984 self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
985 self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
Christian Heimes53876d92008-04-19 00:31:39 +0000986 self.assertRaises(OverflowError, math.ldexp, 1., 1000000)
987 self.assertRaises(OverflowError, math.ldexp, -1., 1000000)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000988 self.assertEqual(math.ldexp(1., -1000000), 0.)
989 self.assertEqual(math.ldexp(-1., -1000000), -0.)
990 self.assertEqual(math.ldexp(INF, 30), INF)
991 self.assertEqual(math.ldexp(NINF, -213), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000992 self.assertTrue(math.isnan(math.ldexp(NAN, 0)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000993
Alexandre Vassalotti6461e102008-05-15 22:09:29 +0000994 # large second argument
995 for n in [10**5, 10**10, 10**20, 10**40]:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000996 self.assertEqual(math.ldexp(INF, -n), INF)
997 self.assertEqual(math.ldexp(NINF, -n), NINF)
998 self.assertEqual(math.ldexp(1., -n), 0.)
999 self.assertEqual(math.ldexp(-1., -n), -0.)
1000 self.assertEqual(math.ldexp(0., -n), 0.)
1001 self.assertEqual(math.ldexp(-0., -n), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001002 self.assertTrue(math.isnan(math.ldexp(NAN, -n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001003
1004 self.assertRaises(OverflowError, math.ldexp, 1., n)
1005 self.assertRaises(OverflowError, math.ldexp, -1., n)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001006 self.assertEqual(math.ldexp(0., n), 0.)
1007 self.assertEqual(math.ldexp(-0., n), -0.)
1008 self.assertEqual(math.ldexp(INF, n), INF)
1009 self.assertEqual(math.ldexp(NINF, n), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001010 self.assertTrue(math.isnan(math.ldexp(NAN, n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001011
Thomas Wouters89f507f2006-12-13 04:49:30 +00001012 def testLog(self):
1013 self.assertRaises(TypeError, math.log)
1014 self.ftest('log(1/e)', math.log(1/math.e), -1)
1015 self.ftest('log(1)', math.log(1), 0)
1016 self.ftest('log(e)', math.log(math.e), 1)
1017 self.ftest('log(32,2)', math.log(32,2), 5)
1018 self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
1019 self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001020 self.ftest('log(10**1000)', math.log(10**1000),
1021 2302.5850929940457)
1022 self.assertRaises(ValueError, math.log, -1.5)
1023 self.assertRaises(ValueError, math.log, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001024 self.assertRaises(ValueError, math.log, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001025 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001026 self.assertTrue(math.isnan(math.log(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001027
1028 def testLog1p(self):
1029 self.assertRaises(TypeError, math.log1p)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001030 for n in [2, 2**90, 2**300]:
1031 self.assertAlmostEqual(math.log1p(n), math.log1p(float(n)))
1032 self.assertRaises(ValueError, math.log1p, -1)
1033 self.assertEqual(math.log1p(INF), INF)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001034
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001035 @requires_IEEE_754
1036 def testLog2(self):
1037 self.assertRaises(TypeError, math.log2)
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001038
1039 # Check some integer values
1040 self.assertEqual(math.log2(1), 0.0)
1041 self.assertEqual(math.log2(2), 1.0)
1042 self.assertEqual(math.log2(4), 2.0)
1043
1044 # Large integer values
1045 self.assertEqual(math.log2(2**1023), 1023.0)
1046 self.assertEqual(math.log2(2**1024), 1024.0)
1047 self.assertEqual(math.log2(2**2000), 2000.0)
1048
1049 self.assertRaises(ValueError, math.log2, -1.5)
1050 self.assertRaises(ValueError, math.log2, NINF)
1051 self.assertTrue(math.isnan(math.log2(NAN)))
1052
Victor Stinnercd9dd372011-05-10 23:40:17 +02001053 @requires_IEEE_754
Victor Stinnerebbbdaf2011-06-01 13:19:07 +02001054 # log2() is not accurate enough on Mac OS X Tiger (10.4)
1055 @support.requires_mac_ver(10, 5)
Victor Stinnercd9dd372011-05-10 23:40:17 +02001056 def testLog2Exact(self):
1057 # Check that we get exact equality for log2 of powers of 2.
1058 actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)]
1059 expected = [float(n) for n in range(-1074, 1024)]
1060 self.assertEqual(actual, expected)
1061
Thomas Wouters89f507f2006-12-13 04:49:30 +00001062 def testLog10(self):
1063 self.assertRaises(TypeError, math.log10)
1064 self.ftest('log10(0.1)', math.log10(0.1), -1)
1065 self.ftest('log10(1)', math.log10(1), 0)
1066 self.ftest('log10(10)', math.log10(10), 1)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001067 self.ftest('log10(10**1000)', math.log10(10**1000), 1000.0)
1068 self.assertRaises(ValueError, math.log10, -1.5)
1069 self.assertRaises(ValueError, math.log10, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001070 self.assertRaises(ValueError, math.log10, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001071 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001072 self.assertTrue(math.isnan(math.log10(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001073
Thomas Wouters89f507f2006-12-13 04:49:30 +00001074 def testModf(self):
1075 self.assertRaises(TypeError, math.modf)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001076
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001077 def testmodf(name, result, expected):
1078 (v1, v2), (e1, e2) = result, expected
Thomas Wouters89f507f2006-12-13 04:49:30 +00001079 if abs(v1-e1) > eps or abs(v2-e2):
1080 self.fail('%s returned %r, expected %r'%\
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001081 (name, result, expected))
Raymond Hettinger64108af2002-05-13 03:55:01 +00001082
Thomas Wouters89f507f2006-12-13 04:49:30 +00001083 testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
1084 testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001085
Ezio Melottib3aedd42010-11-20 19:04:17 +00001086 self.assertEqual(math.modf(INF), (0.0, INF))
1087 self.assertEqual(math.modf(NINF), (-0.0, NINF))
Christian Heimes53876d92008-04-19 00:31:39 +00001088
1089 modf_nan = math.modf(NAN)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001090 self.assertTrue(math.isnan(modf_nan[0]))
1091 self.assertTrue(math.isnan(modf_nan[1]))
Christian Heimes53876d92008-04-19 00:31:39 +00001092
Thomas Wouters89f507f2006-12-13 04:49:30 +00001093 def testPow(self):
1094 self.assertRaises(TypeError, math.pow)
1095 self.ftest('pow(0,1)', math.pow(0,1), 0)
1096 self.ftest('pow(1,0)', math.pow(1,0), 1)
1097 self.ftest('pow(2,1)', math.pow(2,1), 2)
1098 self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
Christian Heimes53876d92008-04-19 00:31:39 +00001099 self.assertEqual(math.pow(INF, 1), INF)
1100 self.assertEqual(math.pow(NINF, 1), NINF)
1101 self.assertEqual((math.pow(1, INF)), 1.)
1102 self.assertEqual((math.pow(1, NINF)), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001103 self.assertTrue(math.isnan(math.pow(NAN, 1)))
1104 self.assertTrue(math.isnan(math.pow(2, NAN)))
1105 self.assertTrue(math.isnan(math.pow(0, NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001106 self.assertEqual(math.pow(1, NAN), 1)
Christian Heimesa342c012008-04-20 21:01:16 +00001107
1108 # pow(0., x)
1109 self.assertEqual(math.pow(0., INF), 0.)
1110 self.assertEqual(math.pow(0., 3.), 0.)
1111 self.assertEqual(math.pow(0., 2.3), 0.)
1112 self.assertEqual(math.pow(0., 2.), 0.)
1113 self.assertEqual(math.pow(0., 0.), 1.)
1114 self.assertEqual(math.pow(0., -0.), 1.)
1115 self.assertRaises(ValueError, math.pow, 0., -2.)
1116 self.assertRaises(ValueError, math.pow, 0., -2.3)
1117 self.assertRaises(ValueError, math.pow, 0., -3.)
1118 self.assertRaises(ValueError, math.pow, 0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001119 self.assertTrue(math.isnan(math.pow(0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001120
1121 # pow(INF, x)
1122 self.assertEqual(math.pow(INF, INF), INF)
1123 self.assertEqual(math.pow(INF, 3.), INF)
1124 self.assertEqual(math.pow(INF, 2.3), INF)
1125 self.assertEqual(math.pow(INF, 2.), INF)
1126 self.assertEqual(math.pow(INF, 0.), 1.)
1127 self.assertEqual(math.pow(INF, -0.), 1.)
1128 self.assertEqual(math.pow(INF, -2.), 0.)
1129 self.assertEqual(math.pow(INF, -2.3), 0.)
1130 self.assertEqual(math.pow(INF, -3.), 0.)
1131 self.assertEqual(math.pow(INF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001132 self.assertTrue(math.isnan(math.pow(INF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001133
1134 # pow(-0., x)
1135 self.assertEqual(math.pow(-0., INF), 0.)
1136 self.assertEqual(math.pow(-0., 3.), -0.)
1137 self.assertEqual(math.pow(-0., 2.3), 0.)
1138 self.assertEqual(math.pow(-0., 2.), 0.)
1139 self.assertEqual(math.pow(-0., 0.), 1.)
1140 self.assertEqual(math.pow(-0., -0.), 1.)
1141 self.assertRaises(ValueError, math.pow, -0., -2.)
1142 self.assertRaises(ValueError, math.pow, -0., -2.3)
1143 self.assertRaises(ValueError, math.pow, -0., -3.)
1144 self.assertRaises(ValueError, math.pow, -0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001145 self.assertTrue(math.isnan(math.pow(-0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001146
1147 # pow(NINF, x)
1148 self.assertEqual(math.pow(NINF, INF), INF)
1149 self.assertEqual(math.pow(NINF, 3.), NINF)
1150 self.assertEqual(math.pow(NINF, 2.3), INF)
1151 self.assertEqual(math.pow(NINF, 2.), INF)
1152 self.assertEqual(math.pow(NINF, 0.), 1.)
1153 self.assertEqual(math.pow(NINF, -0.), 1.)
1154 self.assertEqual(math.pow(NINF, -2.), 0.)
1155 self.assertEqual(math.pow(NINF, -2.3), 0.)
1156 self.assertEqual(math.pow(NINF, -3.), -0.)
1157 self.assertEqual(math.pow(NINF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001158 self.assertTrue(math.isnan(math.pow(NINF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001159
1160 # pow(-1, x)
1161 self.assertEqual(math.pow(-1., INF), 1.)
1162 self.assertEqual(math.pow(-1., 3.), -1.)
1163 self.assertRaises(ValueError, math.pow, -1., 2.3)
1164 self.assertEqual(math.pow(-1., 2.), 1.)
1165 self.assertEqual(math.pow(-1., 0.), 1.)
1166 self.assertEqual(math.pow(-1., -0.), 1.)
1167 self.assertEqual(math.pow(-1., -2.), 1.)
1168 self.assertRaises(ValueError, math.pow, -1., -2.3)
1169 self.assertEqual(math.pow(-1., -3.), -1.)
1170 self.assertEqual(math.pow(-1., NINF), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001171 self.assertTrue(math.isnan(math.pow(-1., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001172
1173 # pow(1, x)
1174 self.assertEqual(math.pow(1., INF), 1.)
1175 self.assertEqual(math.pow(1., 3.), 1.)
1176 self.assertEqual(math.pow(1., 2.3), 1.)
1177 self.assertEqual(math.pow(1., 2.), 1.)
1178 self.assertEqual(math.pow(1., 0.), 1.)
1179 self.assertEqual(math.pow(1., -0.), 1.)
1180 self.assertEqual(math.pow(1., -2.), 1.)
1181 self.assertEqual(math.pow(1., -2.3), 1.)
1182 self.assertEqual(math.pow(1., -3.), 1.)
1183 self.assertEqual(math.pow(1., NINF), 1.)
1184 self.assertEqual(math.pow(1., NAN), 1.)
1185
1186 # pow(x, 0) should be 1 for any x
1187 self.assertEqual(math.pow(2.3, 0.), 1.)
1188 self.assertEqual(math.pow(-2.3, 0.), 1.)
1189 self.assertEqual(math.pow(NAN, 0.), 1.)
1190 self.assertEqual(math.pow(2.3, -0.), 1.)
1191 self.assertEqual(math.pow(-2.3, -0.), 1.)
1192 self.assertEqual(math.pow(NAN, -0.), 1.)
1193
1194 # pow(x, y) is invalid if x is negative and y is not integral
1195 self.assertRaises(ValueError, math.pow, -1., 2.3)
1196 self.assertRaises(ValueError, math.pow, -15., -3.1)
1197
1198 # pow(x, NINF)
1199 self.assertEqual(math.pow(1.9, NINF), 0.)
1200 self.assertEqual(math.pow(1.1, NINF), 0.)
1201 self.assertEqual(math.pow(0.9, NINF), INF)
1202 self.assertEqual(math.pow(0.1, NINF), INF)
1203 self.assertEqual(math.pow(-0.1, NINF), INF)
1204 self.assertEqual(math.pow(-0.9, NINF), INF)
1205 self.assertEqual(math.pow(-1.1, NINF), 0.)
1206 self.assertEqual(math.pow(-1.9, NINF), 0.)
1207
1208 # pow(x, INF)
1209 self.assertEqual(math.pow(1.9, INF), INF)
1210 self.assertEqual(math.pow(1.1, INF), INF)
1211 self.assertEqual(math.pow(0.9, INF), 0.)
1212 self.assertEqual(math.pow(0.1, INF), 0.)
1213 self.assertEqual(math.pow(-0.1, INF), 0.)
1214 self.assertEqual(math.pow(-0.9, INF), 0.)
1215 self.assertEqual(math.pow(-1.1, INF), INF)
1216 self.assertEqual(math.pow(-1.9, INF), INF)
1217
1218 # pow(x, y) should work for x negative, y an integer
1219 self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
1220 self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
1221 self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
1222 self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
1223 self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
1224 self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
1225 self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
1226 self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
1227 self.assertRaises(ValueError, math.pow, -2.0, -0.5)
1228 self.assertRaises(ValueError, math.pow, -2.0, 0.5)
1229
1230 # the following tests have been commented out since they don't
1231 # really belong here: the implementation of ** for floats is
Ezio Melotti13925002011-03-16 11:05:33 +02001232 # independent of the implementation of math.pow
Christian Heimesa342c012008-04-20 21:01:16 +00001233 #self.assertEqual(1**NAN, 1)
1234 #self.assertEqual(1**INF, 1)
1235 #self.assertEqual(1**NINF, 1)
1236 #self.assertEqual(1**0, 1)
1237 #self.assertEqual(1.**NAN, 1)
1238 #self.assertEqual(1.**INF, 1)
1239 #self.assertEqual(1.**NINF, 1)
1240 #self.assertEqual(1.**0, 1)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001241
Thomas Wouters89f507f2006-12-13 04:49:30 +00001242 def testRadians(self):
1243 self.assertRaises(TypeError, math.radians)
1244 self.ftest('radians(180)', math.radians(180), math.pi)
1245 self.ftest('radians(90)', math.radians(90), math.pi/2)
1246 self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001247 self.ftest('radians(0)', math.radians(0), 0)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001248
Mark Dickinsona0ce3752017-04-05 18:34:27 +01001249 @requires_IEEE_754
1250 def testRemainder(self):
1251 from fractions import Fraction
1252
1253 def validate_spec(x, y, r):
1254 """
1255 Check that r matches remainder(x, y) according to the IEEE 754
1256 specification. Assumes that x, y and r are finite and y is nonzero.
1257 """
1258 fx, fy, fr = Fraction(x), Fraction(y), Fraction(r)
1259 # r should not exceed y/2 in absolute value
1260 self.assertLessEqual(abs(fr), abs(fy/2))
1261 # x - r should be an exact integer multiple of y
1262 n = (fx - fr) / fy
1263 self.assertEqual(n, int(n))
1264 if abs(fr) == abs(fy/2):
1265 # If |r| == |y/2|, n should be even.
1266 self.assertEqual(n/2, int(n/2))
1267
1268 # triples (x, y, remainder(x, y)) in hexadecimal form.
1269 testcases = [
1270 # Remainders modulo 1, showing the ties-to-even behaviour.
1271 '-4.0 1 -0.0',
1272 '-3.8 1 0.8',
1273 '-3.0 1 -0.0',
1274 '-2.8 1 -0.8',
1275 '-2.0 1 -0.0',
1276 '-1.8 1 0.8',
1277 '-1.0 1 -0.0',
1278 '-0.8 1 -0.8',
1279 '-0.0 1 -0.0',
1280 ' 0.0 1 0.0',
1281 ' 0.8 1 0.8',
1282 ' 1.0 1 0.0',
1283 ' 1.8 1 -0.8',
1284 ' 2.0 1 0.0',
1285 ' 2.8 1 0.8',
1286 ' 3.0 1 0.0',
1287 ' 3.8 1 -0.8',
1288 ' 4.0 1 0.0',
1289
1290 # Reductions modulo 2*pi
1291 '0x0.0p+0 0x1.921fb54442d18p+2 0x0.0p+0',
1292 '0x1.921fb54442d18p+0 0x1.921fb54442d18p+2 0x1.921fb54442d18p+0',
1293 '0x1.921fb54442d17p+1 0x1.921fb54442d18p+2 0x1.921fb54442d17p+1',
1294 '0x1.921fb54442d18p+1 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1295 '0x1.921fb54442d19p+1 0x1.921fb54442d18p+2 -0x1.921fb54442d17p+1',
1296 '0x1.921fb54442d17p+2 0x1.921fb54442d18p+2 -0x0.0000000000001p+2',
1297 '0x1.921fb54442d18p+2 0x1.921fb54442d18p+2 0x0p0',
1298 '0x1.921fb54442d19p+2 0x1.921fb54442d18p+2 0x0.0000000000001p+2',
1299 '0x1.2d97c7f3321d1p+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1300 '0x1.2d97c7f3321d2p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d18p+1',
1301 '0x1.2d97c7f3321d3p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1302 '0x1.921fb54442d17p+3 0x1.921fb54442d18p+2 -0x0.0000000000001p+3',
1303 '0x1.921fb54442d18p+3 0x1.921fb54442d18p+2 0x0p0',
1304 '0x1.921fb54442d19p+3 0x1.921fb54442d18p+2 0x0.0000000000001p+3',
1305 '0x1.f6a7a2955385dp+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1306 '0x1.f6a7a2955385ep+3 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1307 '0x1.f6a7a2955385fp+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1308 '0x1.1475cc9eedf00p+5 0x1.921fb54442d18p+2 0x1.921fb54442d10p+1',
1309 '0x1.1475cc9eedf01p+5 0x1.921fb54442d18p+2 -0x1.921fb54442d10p+1',
1310
1311 # Symmetry with respect to signs.
1312 ' 1 0.c 0.4',
1313 '-1 0.c -0.4',
1314 ' 1 -0.c 0.4',
1315 '-1 -0.c -0.4',
1316 ' 1.4 0.c -0.4',
1317 '-1.4 0.c 0.4',
1318 ' 1.4 -0.c -0.4',
1319 '-1.4 -0.c 0.4',
1320
1321 # Huge modulus, to check that the underlying algorithm doesn't
1322 # rely on 2.0 * modulus being representable.
1323 '0x1.dp+1023 0x1.4p+1023 0x0.9p+1023',
1324 '0x1.ep+1023 0x1.4p+1023 -0x0.ap+1023',
1325 '0x1.fp+1023 0x1.4p+1023 -0x0.9p+1023',
1326 ]
1327
1328 for case in testcases:
1329 with self.subTest(case=case):
1330 x_hex, y_hex, expected_hex = case.split()
1331 x = float.fromhex(x_hex)
1332 y = float.fromhex(y_hex)
1333 expected = float.fromhex(expected_hex)
1334 validate_spec(x, y, expected)
1335 actual = math.remainder(x, y)
1336 # Cheap way of checking that the floats are
1337 # as identical as we need them to be.
1338 self.assertEqual(actual.hex(), expected.hex())
1339
1340 # Test tiny subnormal modulus: there's potential for
1341 # getting the implementation wrong here (for example,
1342 # by assuming that modulus/2 is exactly representable).
1343 tiny = float.fromhex('1p-1074') # min +ve subnormal
1344 for n in range(-25, 25):
1345 if n == 0:
1346 continue
1347 y = n * tiny
1348 for m in range(100):
1349 x = m * tiny
1350 actual = math.remainder(x, y)
1351 validate_spec(x, y, actual)
1352 actual = math.remainder(-x, y)
1353 validate_spec(-x, y, actual)
1354
1355 # Special values.
1356 # NaNs should propagate as usual.
1357 for value in [NAN, 0.0, -0.0, 2.0, -2.3, NINF, INF]:
1358 self.assertIsNaN(math.remainder(NAN, value))
1359 self.assertIsNaN(math.remainder(value, NAN))
1360
1361 # remainder(x, inf) is x, for non-nan non-infinite x.
1362 for value in [-2.3, -0.0, 0.0, 2.3]:
1363 self.assertEqual(math.remainder(value, INF), value)
1364 self.assertEqual(math.remainder(value, NINF), value)
1365
1366 # remainder(x, 0) and remainder(infinity, x) for non-NaN x are invalid
1367 # operations according to IEEE 754-2008 7.2(f), and should raise.
1368 for value in [NINF, -2.3, -0.0, 0.0, 2.3, INF]:
1369 with self.assertRaises(ValueError):
1370 math.remainder(INF, value)
1371 with self.assertRaises(ValueError):
1372 math.remainder(NINF, value)
1373 with self.assertRaises(ValueError):
1374 math.remainder(value, 0.0)
1375 with self.assertRaises(ValueError):
1376 math.remainder(value, -0.0)
1377
Thomas Wouters89f507f2006-12-13 04:49:30 +00001378 def testSin(self):
1379 self.assertRaises(TypeError, math.sin)
1380 self.ftest('sin(0)', math.sin(0), 0)
1381 self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
1382 self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001383 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001384 self.assertTrue(math.isnan(math.sin(INF)))
1385 self.assertTrue(math.isnan(math.sin(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001386 except ValueError:
1387 self.assertRaises(ValueError, math.sin, INF)
1388 self.assertRaises(ValueError, math.sin, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001389 self.assertTrue(math.isnan(math.sin(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001390
Thomas Wouters89f507f2006-12-13 04:49:30 +00001391 def testSinh(self):
1392 self.assertRaises(TypeError, math.sinh)
1393 self.ftest('sinh(0)', math.sinh(0), 0)
1394 self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
1395 self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001396 self.assertEqual(math.sinh(INF), INF)
1397 self.assertEqual(math.sinh(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001398 self.assertTrue(math.isnan(math.sinh(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001399
Thomas Wouters89f507f2006-12-13 04:49:30 +00001400 def testSqrt(self):
1401 self.assertRaises(TypeError, math.sqrt)
1402 self.ftest('sqrt(0)', math.sqrt(0), 0)
1403 self.ftest('sqrt(1)', math.sqrt(1), 1)
1404 self.ftest('sqrt(4)', math.sqrt(4), 2)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001405 self.assertEqual(math.sqrt(INF), INF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001406 self.assertRaises(ValueError, math.sqrt, -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001407 self.assertRaises(ValueError, math.sqrt, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001408 self.assertTrue(math.isnan(math.sqrt(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001409
Thomas Wouters89f507f2006-12-13 04:49:30 +00001410 def testTan(self):
1411 self.assertRaises(TypeError, math.tan)
1412 self.ftest('tan(0)', math.tan(0), 0)
1413 self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
1414 self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001415 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001416 self.assertTrue(math.isnan(math.tan(INF)))
1417 self.assertTrue(math.isnan(math.tan(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001418 except:
1419 self.assertRaises(ValueError, math.tan, INF)
1420 self.assertRaises(ValueError, math.tan, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001421 self.assertTrue(math.isnan(math.tan(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001422
Thomas Wouters89f507f2006-12-13 04:49:30 +00001423 def testTanh(self):
1424 self.assertRaises(TypeError, math.tanh)
1425 self.ftest('tanh(0)', math.tanh(0), 0)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001426 self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0,
1427 abs_tol=ulp(1))
Christian Heimes53876d92008-04-19 00:31:39 +00001428 self.ftest('tanh(inf)', math.tanh(INF), 1)
1429 self.ftest('tanh(-inf)', math.tanh(NINF), -1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001430 self.assertTrue(math.isnan(math.tanh(NAN)))
Victor Stinnerbe3da382010-11-07 14:14:27 +00001431
1432 @requires_IEEE_754
Victor Stinnerbe3da382010-11-07 14:14:27 +00001433 def testTanhSign(self):
Christian Heimese57950f2008-04-21 13:08:03 +00001434 # check that tanh(-0.) == -0. on IEEE 754 systems
Victor Stinnerbe3da382010-11-07 14:14:27 +00001435 self.assertEqual(math.tanh(-0.), -0.)
1436 self.assertEqual(math.copysign(1., math.tanh(-0.)),
1437 math.copysign(1., -0.))
Tim Peters1d120612000-10-12 06:10:25 +00001438
Christian Heimes400adb02008-02-01 08:12:03 +00001439 def test_trunc(self):
1440 self.assertEqual(math.trunc(1), 1)
1441 self.assertEqual(math.trunc(-1), -1)
1442 self.assertEqual(type(math.trunc(1)), int)
1443 self.assertEqual(type(math.trunc(1.5)), int)
1444 self.assertEqual(math.trunc(1.5), 1)
1445 self.assertEqual(math.trunc(-1.5), -1)
1446 self.assertEqual(math.trunc(1.999999), 1)
1447 self.assertEqual(math.trunc(-1.999999), -1)
1448 self.assertEqual(math.trunc(-0.999999), -0)
1449 self.assertEqual(math.trunc(-100.999), -100)
1450
1451 class TestTrunc(object):
1452 def __trunc__(self):
1453 return 23
1454
1455 class TestNoTrunc(object):
1456 pass
1457
1458 self.assertEqual(math.trunc(TestTrunc()), 23)
1459
1460 self.assertRaises(TypeError, math.trunc)
1461 self.assertRaises(TypeError, math.trunc, 1, 2)
1462 self.assertRaises(TypeError, math.trunc, TestNoTrunc())
1463
Mark Dickinson8e0c9962010-07-11 17:38:24 +00001464 def testIsfinite(self):
1465 self.assertTrue(math.isfinite(0.0))
1466 self.assertTrue(math.isfinite(-0.0))
1467 self.assertTrue(math.isfinite(1.0))
1468 self.assertTrue(math.isfinite(-1.0))
1469 self.assertFalse(math.isfinite(float("nan")))
1470 self.assertFalse(math.isfinite(float("inf")))
1471 self.assertFalse(math.isfinite(float("-inf")))
1472
Christian Heimes072c0f12008-01-03 23:01:04 +00001473 def testIsnan(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001474 self.assertTrue(math.isnan(float("nan")))
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001475 self.assertTrue(math.isnan(float("-nan")))
1476 self.assertTrue(math.isnan(float("inf") * 0.))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001477 self.assertFalse(math.isnan(float("inf")))
1478 self.assertFalse(math.isnan(0.))
1479 self.assertFalse(math.isnan(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001480
1481 def testIsinf(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001482 self.assertTrue(math.isinf(float("inf")))
1483 self.assertTrue(math.isinf(float("-inf")))
1484 self.assertTrue(math.isinf(1E400))
1485 self.assertTrue(math.isinf(-1E400))
1486 self.assertFalse(math.isinf(float("nan")))
1487 self.assertFalse(math.isinf(0.))
1488 self.assertFalse(math.isinf(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001489
Mark Dickinsona5d0c7c2015-01-11 11:55:29 +00001490 @requires_IEEE_754
1491 def test_nan_constant(self):
1492 self.assertTrue(math.isnan(math.nan))
1493
1494 @requires_IEEE_754
1495 def test_inf_constant(self):
1496 self.assertTrue(math.isinf(math.inf))
1497 self.assertGreater(math.inf, 0.0)
1498 self.assertEqual(math.inf, float("inf"))
1499 self.assertEqual(-math.inf, float("-inf"))
1500
Thomas Wouters89f507f2006-12-13 04:49:30 +00001501 # RED_FLAG 16-Oct-2000 Tim
1502 # While 2.0 is more consistent about exceptions than previous releases, it
1503 # still fails this part of the test on some platforms. For now, we only
1504 # *run* test_exceptions() in verbose mode, so that this isn't normally
1505 # tested.
Serhiy Storchaka43767632013-11-03 21:31:38 +02001506 @unittest.skipUnless(verbose, 'requires verbose mode')
1507 def test_exceptions(self):
1508 try:
1509 x = math.exp(-1000000000)
1510 except:
1511 # mathmodule.c is failing to weed out underflows from libm, or
1512 # we've got an fp format with huge dynamic range
1513 self.fail("underflowing exp() should not have raised "
1514 "an exception")
1515 if x != 0:
1516 self.fail("underflowing exp() should have returned 0")
Tim Peters98c81842000-10-16 17:35:13 +00001517
Serhiy Storchaka43767632013-11-03 21:31:38 +02001518 # If this fails, probably using a strict IEEE-754 conforming libm, and x
1519 # is +Inf afterwards. But Python wants overflows detected by default.
1520 try:
1521 x = math.exp(1000000000)
1522 except OverflowError:
1523 pass
1524 else:
1525 self.fail("overflowing exp() didn't trigger OverflowError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001526
Serhiy Storchaka43767632013-11-03 21:31:38 +02001527 # If this fails, it could be a puzzle. One odd possibility is that
1528 # mathmodule.c's macros are getting confused while comparing
1529 # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
1530 # as a result (and so raising OverflowError instead).
1531 try:
1532 x = math.sqrt(-1.0)
1533 except ValueError:
1534 pass
1535 else:
1536 self.fail("sqrt(-1) didn't raise ValueError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001537
Mark Dickinson63566232009-09-18 21:04:19 +00001538 @requires_IEEE_754
Christian Heimes53876d92008-04-19 00:31:39 +00001539 def test_testfile(self):
Mark Dickinson85746542016-09-04 09:58:51 +01001540 # Some tests need to be skipped on ancient OS X versions.
1541 # See issue #27953.
1542 SKIP_ON_TIGER = {'tan0064'}
1543
1544 osx_version = None
1545 if sys.platform == 'darwin':
1546 version_txt = platform.mac_ver()[0]
1547 try:
1548 osx_version = tuple(map(int, version_txt.split('.')))
1549 except ValueError:
1550 pass
1551
Mark Dickinson96f774d2016-09-03 19:30:22 +01001552 fail_fmt = "{}: {}({!r}): {}"
1553
1554 failures = []
Christian Heimes53876d92008-04-19 00:31:39 +00001555 for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001556 # Skip if either the input or result is complex
1557 if ai != 0.0 or ei != 0.0:
Christian Heimes53876d92008-04-19 00:31:39 +00001558 continue
1559 if fn in ['rect', 'polar']:
1560 # no real versions of rect, polar
1561 continue
Mark Dickinson85746542016-09-04 09:58:51 +01001562 # Skip certain tests on OS X 10.4.
1563 if osx_version is not None and osx_version < (10, 5):
1564 if id in SKIP_ON_TIGER:
1565 continue
Mark Dickinson96f774d2016-09-03 19:30:22 +01001566
Christian Heimes53876d92008-04-19 00:31:39 +00001567 func = getattr(math, fn)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001568
1569 if 'invalid' in flags or 'divide-by-zero' in flags:
1570 er = 'ValueError'
1571 elif 'overflow' in flags:
1572 er = 'OverflowError'
1573
Christian Heimesa342c012008-04-20 21:01:16 +00001574 try:
1575 result = func(ar)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001576 except ValueError:
1577 result = 'ValueError'
Benjamin Peterson2b7411d2008-05-26 17:36:47 +00001578 except OverflowError:
Mark Dickinson96f774d2016-09-03 19:30:22 +01001579 result = 'OverflowError'
1580
1581 # Default tolerances
1582 ulp_tol, abs_tol = 5, 0.0
1583
1584 failure = result_check(er, result, ulp_tol, abs_tol)
1585 if failure is None:
1586 continue
1587
1588 msg = fail_fmt.format(id, fn, ar, failure)
1589 failures.append(msg)
1590
1591 if failures:
1592 self.fail('Failures in test_testfile:\n ' +
1593 '\n '.join(failures))
Thomas Wouters89f507f2006-12-13 04:49:30 +00001594
Victor Stinnerbe3da382010-11-07 14:14:27 +00001595 @requires_IEEE_754
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001596 def test_mtestfile(self):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001597 fail_fmt = "{}: {}({!r}): {}"
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001598
1599 failures = []
1600 for id, fn, arg, expected, flags in parse_mtestfile(math_testcases):
1601 func = getattr(math, fn)
1602
1603 if 'invalid' in flags or 'divide-by-zero' in flags:
1604 expected = 'ValueError'
1605 elif 'overflow' in flags:
1606 expected = 'OverflowError'
1607
1608 try:
1609 got = func(arg)
1610 except ValueError:
1611 got = 'ValueError'
1612 except OverflowError:
1613 got = 'OverflowError'
1614
Mark Dickinson96f774d2016-09-03 19:30:22 +01001615 # Default tolerances
1616 ulp_tol, abs_tol = 5, 0.0
Mark Dickinsonbcdf9da2010-06-13 10:52:38 +00001617
Mark Dickinson96f774d2016-09-03 19:30:22 +01001618 # Exceptions to the defaults
1619 if fn == 'gamma':
1620 # Experimental results on one platform gave
1621 # an accuracy of <= 10 ulps across the entire float
1622 # domain. We weaken that to require 20 ulp accuracy.
1623 ulp_tol = 20
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001624
Mark Dickinson96f774d2016-09-03 19:30:22 +01001625 elif fn == 'lgamma':
1626 # we use a weaker accuracy test for lgamma;
1627 # lgamma only achieves an absolute error of
1628 # a few multiples of the machine accuracy, in
1629 # general.
1630 abs_tol = 1e-15
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001631
Mark Dickinson96f774d2016-09-03 19:30:22 +01001632 elif fn == 'erfc' and arg >= 0.0:
1633 # erfc has less-than-ideal accuracy for large
1634 # arguments (x ~ 25 or so), mainly due to the
1635 # error involved in computing exp(-x*x).
1636 #
1637 # Observed between CPython and mpmath at 25 dp:
1638 # x < 0 : err <= 2 ulp
1639 # 0 <= x < 1 : err <= 10 ulp
1640 # 1 <= x < 10 : err <= 100 ulp
1641 # 10 <= x < 20 : err <= 300 ulp
1642 # 20 <= x : < 600 ulp
1643 #
1644 if arg < 1.0:
1645 ulp_tol = 10
1646 elif arg < 10.0:
1647 ulp_tol = 100
1648 else:
1649 ulp_tol = 1000
1650
1651 failure = result_check(expected, got, ulp_tol, abs_tol)
1652 if failure is None:
1653 continue
1654
1655 msg = fail_fmt.format(id, fn, arg, failure)
1656 failures.append(msg)
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001657
1658 if failures:
1659 self.fail('Failures in test_mtestfile:\n ' +
1660 '\n '.join(failures))
1661
Pablo Galindo04114112019-03-09 19:18:08 +00001662 def test_prod(self):
1663 prod = math.prod
1664 self.assertEqual(prod([]), 1)
1665 self.assertEqual(prod([], start=5), 5)
1666 self.assertEqual(prod(list(range(2,8))), 5040)
1667 self.assertEqual(prod(iter(list(range(2,8)))), 5040)
1668 self.assertEqual(prod(range(1, 10), start=10), 3628800)
1669
1670 self.assertEqual(prod([1, 2, 3, 4, 5]), 120)
1671 self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0)
1672 self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0)
1673 self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0)
1674
1675 # Test overflow in fast-path for integers
1676 self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32)
1677 # Test overflow in fast-path for floats
1678 self.assertEqual(prod([1.0, 1.0, 2**32, 1, 1]), float(2**32))
1679
1680 self.assertRaises(TypeError, prod)
1681 self.assertRaises(TypeError, prod, 42)
1682 self.assertRaises(TypeError, prod, ['a', 'b', 'c'])
1683 self.assertRaises(TypeError, prod, ['a', 'b', 'c'], '')
1684 self.assertRaises(TypeError, prod, [b'a', b'c'], b'')
1685 values = [bytearray(b'a'), bytearray(b'b')]
1686 self.assertRaises(TypeError, prod, values, bytearray(b''))
1687 self.assertRaises(TypeError, prod, [[1], [2], [3]])
1688 self.assertRaises(TypeError, prod, [{2:3}])
1689 self.assertRaises(TypeError, prod, [{2:3}]*2, {2:3})
1690 self.assertRaises(TypeError, prod, [[1], [2], [3]], [])
1691 with self.assertRaises(TypeError):
1692 prod([10, 20], [30, 40]) # start is a keyword-only argument
1693
1694 self.assertEqual(prod([0, 1, 2, 3]), 0)
1695 self.assertEqual(prod([1, 0, 2, 3]), 0)
1696 self.assertEqual(prod([1, 2, 3, 0]), 0)
1697
1698 def _naive_prod(iterable, start=1):
1699 for elem in iterable:
1700 start *= elem
1701 return start
1702
1703 # Big integers
1704
1705 iterable = range(1, 10000)
1706 self.assertEqual(prod(iterable), _naive_prod(iterable))
1707 iterable = range(-10000, -1)
1708 self.assertEqual(prod(iterable), _naive_prod(iterable))
1709 iterable = range(-1000, 1000)
1710 self.assertEqual(prod(iterable), 0)
1711
1712 # Big floats
1713
1714 iterable = [float(x) for x in range(1, 1000)]
1715 self.assertEqual(prod(iterable), _naive_prod(iterable))
1716 iterable = [float(x) for x in range(-1000, -1)]
1717 self.assertEqual(prod(iterable), _naive_prod(iterable))
1718 iterable = [float(x) for x in range(-1000, 1000)]
1719 self.assertIsNaN(prod(iterable))
1720
1721 # Float tests
1722
1723 self.assertIsNaN(prod([1, 2, 3, float("nan"), 2, 3]))
1724 self.assertIsNaN(prod([1, 0, float("nan"), 2, 3]))
1725 self.assertIsNaN(prod([1, float("nan"), 0, 3]))
1726 self.assertIsNaN(prod([1, float("inf"), float("nan"),3]))
1727 self.assertIsNaN(prod([1, float("-inf"), float("nan"),3]))
1728 self.assertIsNaN(prod([1, float("nan"), float("inf"),3]))
1729 self.assertIsNaN(prod([1, float("nan"), float("-inf"),3]))
1730
1731 self.assertEqual(prod([1, 2, 3, float('inf'),-3,4]), float('-inf'))
1732 self.assertEqual(prod([1, 2, 3, float('-inf'),-3,4]), float('inf'))
1733
1734 self.assertIsNaN(prod([1,2,0,float('inf'), -3, 4]))
1735 self.assertIsNaN(prod([1,2,0,float('-inf'), -3, 4]))
1736 self.assertIsNaN(prod([1, 2, 3, float('inf'), -3, 0, 3]))
1737 self.assertIsNaN(prod([1, 2, 3, float('-inf'), -3, 0, 2]))
1738
1739 # Type preservation
1740
1741 self.assertEqual(type(prod([1, 2, 3, 4, 5, 6])), int)
1742 self.assertEqual(type(prod([1, 2.0, 3, 4, 5, 6])), float)
1743 self.assertEqual(type(prod(range(1, 10000))), int)
1744 self.assertEqual(type(prod(range(1, 10000), start=1.0)), float)
1745 self.assertEqual(type(prod([1, decimal.Decimal(2.0), 3, 4, 5, 6])),
1746 decimal.Decimal)
1747
Mark Dickinsona0ce3752017-04-05 18:34:27 +01001748 # Custom assertions.
1749
1750 def assertIsNaN(self, value):
1751 if not math.isnan(value):
1752 self.fail("Expected a NaN, got {!r}.".format(value))
1753
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001754
Tal Einatd5519ed2015-05-31 22:05:00 +03001755class IsCloseTests(unittest.TestCase):
Mike53f7a7c2017-12-14 14:04:53 +03001756 isclose = math.isclose # subclasses should override this
Tal Einatd5519ed2015-05-31 22:05:00 +03001757
1758 def assertIsClose(self, a, b, *args, **kwargs):
1759 self.assertTrue(self.isclose(a, b, *args, **kwargs),
1760 msg="%s and %s should be close!" % (a, b))
1761
1762 def assertIsNotClose(self, a, b, *args, **kwargs):
1763 self.assertFalse(self.isclose(a, b, *args, **kwargs),
1764 msg="%s and %s should not be close!" % (a, b))
1765
1766 def assertAllClose(self, examples, *args, **kwargs):
1767 for a, b in examples:
1768 self.assertIsClose(a, b, *args, **kwargs)
1769
1770 def assertAllNotClose(self, examples, *args, **kwargs):
1771 for a, b in examples:
1772 self.assertIsNotClose(a, b, *args, **kwargs)
1773
1774 def test_negative_tolerances(self):
1775 # ValueError should be raised if either tolerance is less than zero
1776 with self.assertRaises(ValueError):
1777 self.assertIsClose(1, 1, rel_tol=-1e-100)
1778 with self.assertRaises(ValueError):
1779 self.assertIsClose(1, 1, rel_tol=1e-100, abs_tol=-1e10)
1780
1781 def test_identical(self):
1782 # identical values must test as close
1783 identical_examples = [(2.0, 2.0),
1784 (0.1e200, 0.1e200),
1785 (1.123e-300, 1.123e-300),
1786 (12345, 12345.0),
1787 (0.0, -0.0),
1788 (345678, 345678)]
1789 self.assertAllClose(identical_examples, rel_tol=0.0, abs_tol=0.0)
1790
1791 def test_eight_decimal_places(self):
1792 # examples that are close to 1e-8, but not 1e-9
1793 eight_decimal_places_examples = [(1e8, 1e8 + 1),
1794 (-1e-8, -1.000000009e-8),
1795 (1.12345678, 1.12345679)]
1796 self.assertAllClose(eight_decimal_places_examples, rel_tol=1e-8)
1797 self.assertAllNotClose(eight_decimal_places_examples, rel_tol=1e-9)
1798
1799 def test_near_zero(self):
1800 # values close to zero
1801 near_zero_examples = [(1e-9, 0.0),
1802 (-1e-9, 0.0),
1803 (-1e-150, 0.0)]
1804 # these should not be close to any rel_tol
1805 self.assertAllNotClose(near_zero_examples, rel_tol=0.9)
1806 # these should be close to abs_tol=1e-8
1807 self.assertAllClose(near_zero_examples, abs_tol=1e-8)
1808
1809 def test_identical_infinite(self):
1810 # these are close regardless of tolerance -- i.e. they are equal
1811 self.assertIsClose(INF, INF)
1812 self.assertIsClose(INF, INF, abs_tol=0.0)
1813 self.assertIsClose(NINF, NINF)
1814 self.assertIsClose(NINF, NINF, abs_tol=0.0)
1815
1816 def test_inf_ninf_nan(self):
1817 # these should never be close (following IEEE 754 rules for equality)
1818 not_close_examples = [(NAN, NAN),
1819 (NAN, 1e-100),
1820 (1e-100, NAN),
1821 (INF, NAN),
1822 (NAN, INF),
1823 (INF, NINF),
1824 (INF, 1.0),
1825 (1.0, INF),
1826 (INF, 1e308),
1827 (1e308, INF)]
1828 # use largest reasonable tolerance
1829 self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999)
1830
1831 def test_zero_tolerance(self):
1832 # test with zero tolerance
1833 zero_tolerance_close_examples = [(1.0, 1.0),
1834 (-3.4, -3.4),
1835 (-1e-300, -1e-300)]
1836 self.assertAllClose(zero_tolerance_close_examples, rel_tol=0.0)
1837
1838 zero_tolerance_not_close_examples = [(1.0, 1.000000000000001),
1839 (0.99999999999999, 1.0),
1840 (1.0e200, .999999999999999e200)]
1841 self.assertAllNotClose(zero_tolerance_not_close_examples, rel_tol=0.0)
1842
Martin Pantereb995702016-07-28 01:11:04 +00001843 def test_asymmetry(self):
1844 # test the asymmetry example from PEP 485
Tal Einatd5519ed2015-05-31 22:05:00 +03001845 self.assertAllClose([(9, 10), (10, 9)], rel_tol=0.1)
1846
1847 def test_integers(self):
1848 # test with integer values
1849 integer_examples = [(100000001, 100000000),
1850 (123456789, 123456788)]
1851
1852 self.assertAllClose(integer_examples, rel_tol=1e-8)
1853 self.assertAllNotClose(integer_examples, rel_tol=1e-9)
1854
1855 def test_decimals(self):
1856 # test with Decimal values
1857 from decimal import Decimal
1858
1859 decimal_examples = [(Decimal('1.00000001'), Decimal('1.0')),
1860 (Decimal('1.00000001e-20'), Decimal('1.0e-20')),
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001861 (Decimal('1.00000001e-100'), Decimal('1.0e-100')),
1862 (Decimal('1.00000001e20'), Decimal('1.0e20'))]
Tal Einatd5519ed2015-05-31 22:05:00 +03001863 self.assertAllClose(decimal_examples, rel_tol=1e-8)
1864 self.assertAllNotClose(decimal_examples, rel_tol=1e-9)
1865
1866 def test_fractions(self):
1867 # test with Fraction values
1868 from fractions import Fraction
1869
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001870 fraction_examples = [
1871 (Fraction(1, 100000000) + 1, Fraction(1)),
1872 (Fraction(100000001), Fraction(100000000)),
1873 (Fraction(10**8 + 1, 10**28), Fraction(1, 10**20))]
Tal Einatd5519ed2015-05-31 22:05:00 +03001874 self.assertAllClose(fraction_examples, rel_tol=1e-8)
1875 self.assertAllNotClose(fraction_examples, rel_tol=1e-9)
1876
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001877 def testPerm(self):
1878 perm = math.perm
1879 factorial = math.factorial
Min ho Kim96e12d52019-07-22 06:12:33 +10001880 # Test if factorial definition is satisfied
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001881 for n in range(100):
1882 for k in range(n + 1):
1883 self.assertEqual(perm(n, k),
1884 factorial(n) // factorial(n - k))
1885
1886 # Test for Pascal's identity
1887 for n in range(1, 100):
1888 for k in range(1, n):
1889 self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k))
1890
1891 # Test corner cases
1892 for n in range(1, 100):
1893 self.assertEqual(perm(n, 0), 1)
1894 self.assertEqual(perm(n, 1), n)
1895 self.assertEqual(perm(n, n), factorial(n))
1896
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001897 # Test one argument form
1898 for n in range(20):
1899 self.assertEqual(perm(n), factorial(n))
1900 self.assertEqual(perm(n, None), factorial(n))
1901
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001902 # Raises TypeError if any argument is non-integer or argument count is
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001903 # not 1 or 2
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001904 self.assertRaises(TypeError, perm, 10, 1.0)
1905 self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
1906 self.assertRaises(TypeError, perm, 10, "1")
1907 self.assertRaises(TypeError, perm, 10.0, 1)
1908 self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
1909 self.assertRaises(TypeError, perm, "10", 1)
1910
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001911 self.assertRaises(TypeError, perm)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001912 self.assertRaises(TypeError, perm, 10, 1, 3)
1913 self.assertRaises(TypeError, perm)
1914
1915 # Raises Value error if not k or n are negative numbers
1916 self.assertRaises(ValueError, perm, -1, 1)
1917 self.assertRaises(ValueError, perm, -2**1000, 1)
1918 self.assertRaises(ValueError, perm, 1, -1)
1919 self.assertRaises(ValueError, perm, 1, -2**1000)
1920
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07001921 # Returns zero if k is greater than n
1922 self.assertEqual(perm(1, 2), 0)
1923 self.assertEqual(perm(1, 2**1000), 0)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001924
1925 n = 2**1000
1926 self.assertEqual(perm(n, 0), 1)
1927 self.assertEqual(perm(n, 1), n)
1928 self.assertEqual(perm(n, 2), n * (n-1))
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +03001929 if support.check_impl_detail(cpython=True):
1930 self.assertRaises(OverflowError, perm, n, n)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001931
1932 for n, k in (True, True), (True, False), (False, False):
1933 self.assertEqual(perm(n, k), 1)
1934 self.assertIs(type(perm(n, k)), int)
1935 self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20)
1936 self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20)
1937 for k in range(3):
1938 self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int)
1939 self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int)
1940
Yash Aggarwal4a686502019-06-01 12:51:27 +05301941 def testComb(self):
1942 comb = math.comb
1943 factorial = math.factorial
Min ho Kim96e12d52019-07-22 06:12:33 +10001944 # Test if factorial definition is satisfied
Yash Aggarwal4a686502019-06-01 12:51:27 +05301945 for n in range(100):
1946 for k in range(n + 1):
1947 self.assertEqual(comb(n, k), factorial(n)
1948 // (factorial(k) * factorial(n - k)))
1949
1950 # Test for Pascal's identity
1951 for n in range(1, 100):
1952 for k in range(1, n):
1953 self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k))
1954
1955 # Test corner cases
1956 for n in range(100):
1957 self.assertEqual(comb(n, 0), 1)
1958 self.assertEqual(comb(n, n), 1)
1959
1960 for n in range(1, 100):
1961 self.assertEqual(comb(n, 1), n)
1962 self.assertEqual(comb(n, n - 1), n)
1963
1964 # Test Symmetry
1965 for n in range(100):
1966 for k in range(n // 2):
1967 self.assertEqual(comb(n, k), comb(n, n - k))
1968
1969 # Raises TypeError if any argument is non-integer or argument count is
1970 # not 2
1971 self.assertRaises(TypeError, comb, 10, 1.0)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001972 self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0))
Yash Aggarwal4a686502019-06-01 12:51:27 +05301973 self.assertRaises(TypeError, comb, 10, "1")
Yash Aggarwal4a686502019-06-01 12:51:27 +05301974 self.assertRaises(TypeError, comb, 10.0, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001975 self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1)
1976 self.assertRaises(TypeError, comb, "10", 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301977
1978 self.assertRaises(TypeError, comb, 10)
1979 self.assertRaises(TypeError, comb, 10, 1, 3)
1980 self.assertRaises(TypeError, comb)
1981
1982 # Raises Value error if not k or n are negative numbers
1983 self.assertRaises(ValueError, comb, -1, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001984 self.assertRaises(ValueError, comb, -2**1000, 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301985 self.assertRaises(ValueError, comb, 1, -1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001986 self.assertRaises(ValueError, comb, 1, -2**1000)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301987
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07001988 # Returns zero if k is greater than n
1989 self.assertEqual(comb(1, 2), 0)
1990 self.assertEqual(comb(1, 2**1000), 0)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301991
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001992 n = 2**1000
1993 self.assertEqual(comb(n, 0), 1)
1994 self.assertEqual(comb(n, 1), n)
1995 self.assertEqual(comb(n, 2), n * (n-1) // 2)
1996 self.assertEqual(comb(n, n), 1)
1997 self.assertEqual(comb(n, n-1), n)
1998 self.assertEqual(comb(n, n-2), n * (n-1) // 2)
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +03001999 if support.check_impl_detail(cpython=True):
2000 self.assertRaises(OverflowError, comb, n, n//2)
Yash Aggarwal4a686502019-06-01 12:51:27 +05302001
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03002002 for n, k in (True, True), (True, False), (False, False):
2003 self.assertEqual(comb(n, k), 1)
2004 self.assertIs(type(comb(n, k)), int)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03002005 self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03002006 self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03002007 for k in range(3):
2008 self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int)
2009 self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int)
Yash Aggarwal4a686502019-06-01 12:51:27 +05302010
Pablo Galindo42079072019-02-10 19:56:58 +00002011
Thomas Wouters89f507f2006-12-13 04:49:30 +00002012def test_main():
Christian Heimes53876d92008-04-19 00:31:39 +00002013 from doctest import DocFileSuite
2014 suite = unittest.TestSuite()
2015 suite.addTest(unittest.makeSuite(MathTests))
Tal Einatd5519ed2015-05-31 22:05:00 +03002016 suite.addTest(unittest.makeSuite(IsCloseTests))
Christian Heimes53876d92008-04-19 00:31:39 +00002017 suite.addTest(DocFileSuite("ieee754.txt"))
2018 run_unittest(suite)
Thomas Wouters89f507f2006-12-13 04:49:30 +00002019
2020if __name__ == '__main__':
2021 test_main()