blob: 5c35c8cff129b405c7ba43000892eb8b9e698c16 [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 Storchaka5fd5cb82019-11-16 18:00:57 +0200243class FloatLike:
244 def __init__(self, value):
245 self.value = value
246
247 def __float__(self):
248 return self.value
249
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +0300250class IntSubclass(int):
251 pass
252
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300253# Class providing an __index__ method.
254class MyIndexable(object):
255 def __init__(self, value):
256 self.value = value
257
258 def __index__(self):
259 return self.value
260
Thomas Wouters89f507f2006-12-13 04:49:30 +0000261class MathTests(unittest.TestCase):
Guido van Rossumfcce6301996-08-08 18:26:25 +0000262
Mark Dickinson96f774d2016-09-03 19:30:22 +0100263 def ftest(self, name, got, expected, ulp_tol=5, abs_tol=0.0):
264 """Compare arguments expected and got, as floats, if either
265 is a float, using a tolerance expressed in multiples of
266 ulp(expected) or absolutely, whichever is greater.
267
268 As a convenience, when neither argument is a float, and for
269 non-finite floats, exact equality is demanded. Also, nan==nan
270 in this function.
271 """
272 failure = result_check(expected, got, ulp_tol, abs_tol)
273 if failure is not None:
274 self.fail("{}: {}".format(name, failure))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000275
Thomas Wouters89f507f2006-12-13 04:49:30 +0000276 def testConstants(self):
Mark Dickinson96f774d2016-09-03 19:30:22 +0100277 # Ref: Abramowitz & Stegun (Dover, 1965)
278 self.ftest('pi', math.pi, 3.141592653589793238462643)
279 self.ftest('e', math.e, 2.718281828459045235360287)
Guido van Rossum0a891d72016-08-15 09:12:52 -0700280 self.assertEqual(math.tau, 2*math.pi)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000281
Thomas Wouters89f507f2006-12-13 04:49:30 +0000282 def testAcos(self):
283 self.assertRaises(TypeError, math.acos)
284 self.ftest('acos(-1)', math.acos(-1), math.pi)
285 self.ftest('acos(0)', math.acos(0), math.pi/2)
286 self.ftest('acos(1)', math.acos(1), 0)
Christian Heimes53876d92008-04-19 00:31:39 +0000287 self.assertRaises(ValueError, math.acos, INF)
288 self.assertRaises(ValueError, math.acos, NINF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100289 self.assertRaises(ValueError, math.acos, 1 + eps)
290 self.assertRaises(ValueError, math.acos, -1 - eps)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000291 self.assertTrue(math.isnan(math.acos(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000292
293 def testAcosh(self):
294 self.assertRaises(TypeError, math.acosh)
295 self.ftest('acosh(1)', math.acosh(1), 0)
296 self.ftest('acosh(2)', math.acosh(2), 1.3169578969248168)
297 self.assertRaises(ValueError, math.acosh, 0)
298 self.assertRaises(ValueError, math.acosh, -1)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000299 self.assertEqual(math.acosh(INF), INF)
Christian Heimes53876d92008-04-19 00:31:39 +0000300 self.assertRaises(ValueError, math.acosh, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000301 self.assertTrue(math.isnan(math.acosh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000302
Thomas Wouters89f507f2006-12-13 04:49:30 +0000303 def testAsin(self):
304 self.assertRaises(TypeError, math.asin)
305 self.ftest('asin(-1)', math.asin(-1), -math.pi/2)
306 self.ftest('asin(0)', math.asin(0), 0)
307 self.ftest('asin(1)', math.asin(1), math.pi/2)
Christian Heimes53876d92008-04-19 00:31:39 +0000308 self.assertRaises(ValueError, math.asin, INF)
309 self.assertRaises(ValueError, math.asin, NINF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100310 self.assertRaises(ValueError, math.asin, 1 + eps)
311 self.assertRaises(ValueError, math.asin, -1 - eps)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000312 self.assertTrue(math.isnan(math.asin(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000313
314 def testAsinh(self):
315 self.assertRaises(TypeError, math.asinh)
316 self.ftest('asinh(0)', math.asinh(0), 0)
317 self.ftest('asinh(1)', math.asinh(1), 0.88137358701954305)
318 self.ftest('asinh(-1)', math.asinh(-1), -0.88137358701954305)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000319 self.assertEqual(math.asinh(INF), INF)
320 self.assertEqual(math.asinh(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000321 self.assertTrue(math.isnan(math.asinh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000322
Thomas Wouters89f507f2006-12-13 04:49:30 +0000323 def testAtan(self):
324 self.assertRaises(TypeError, math.atan)
325 self.ftest('atan(-1)', math.atan(-1), -math.pi/4)
326 self.ftest('atan(0)', math.atan(0), 0)
327 self.ftest('atan(1)', math.atan(1), math.pi/4)
Christian Heimes53876d92008-04-19 00:31:39 +0000328 self.ftest('atan(inf)', math.atan(INF), math.pi/2)
Christian Heimesa342c012008-04-20 21:01:16 +0000329 self.ftest('atan(-inf)', math.atan(NINF), -math.pi/2)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000330 self.assertTrue(math.isnan(math.atan(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000331
332 def testAtanh(self):
333 self.assertRaises(TypeError, math.atan)
334 self.ftest('atanh(0)', math.atanh(0), 0)
335 self.ftest('atanh(0.5)', math.atanh(0.5), 0.54930614433405489)
336 self.ftest('atanh(-0.5)', math.atanh(-0.5), -0.54930614433405489)
337 self.assertRaises(ValueError, math.atanh, 1)
338 self.assertRaises(ValueError, math.atanh, -1)
339 self.assertRaises(ValueError, math.atanh, INF)
340 self.assertRaises(ValueError, math.atanh, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000341 self.assertTrue(math.isnan(math.atanh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000342
Thomas Wouters89f507f2006-12-13 04:49:30 +0000343 def testAtan2(self):
344 self.assertRaises(TypeError, math.atan2)
345 self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
346 self.ftest('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
347 self.ftest('atan2(0, 1)', math.atan2(0, 1), 0)
348 self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
349 self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000350
Christian Heimese57950f2008-04-21 13:08:03 +0000351 # math.atan2(0, x)
352 self.ftest('atan2(0., -inf)', math.atan2(0., NINF), math.pi)
353 self.ftest('atan2(0., -2.3)', math.atan2(0., -2.3), math.pi)
354 self.ftest('atan2(0., -0.)', math.atan2(0., -0.), math.pi)
355 self.assertEqual(math.atan2(0., 0.), 0.)
356 self.assertEqual(math.atan2(0., 2.3), 0.)
357 self.assertEqual(math.atan2(0., INF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000358 self.assertTrue(math.isnan(math.atan2(0., NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000359 # math.atan2(-0, x)
360 self.ftest('atan2(-0., -inf)', math.atan2(-0., NINF), -math.pi)
361 self.ftest('atan2(-0., -2.3)', math.atan2(-0., -2.3), -math.pi)
362 self.ftest('atan2(-0., -0.)', math.atan2(-0., -0.), -math.pi)
363 self.assertEqual(math.atan2(-0., 0.), -0.)
364 self.assertEqual(math.atan2(-0., 2.3), -0.)
365 self.assertEqual(math.atan2(-0., INF), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000366 self.assertTrue(math.isnan(math.atan2(-0., NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000367 # math.atan2(INF, x)
368 self.ftest('atan2(inf, -inf)', math.atan2(INF, NINF), math.pi*3/4)
369 self.ftest('atan2(inf, -2.3)', math.atan2(INF, -2.3), math.pi/2)
370 self.ftest('atan2(inf, -0.)', math.atan2(INF, -0.0), math.pi/2)
371 self.ftest('atan2(inf, 0.)', math.atan2(INF, 0.0), math.pi/2)
372 self.ftest('atan2(inf, 2.3)', math.atan2(INF, 2.3), math.pi/2)
373 self.ftest('atan2(inf, inf)', math.atan2(INF, INF), math.pi/4)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000374 self.assertTrue(math.isnan(math.atan2(INF, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000375 # math.atan2(NINF, x)
376 self.ftest('atan2(-inf, -inf)', math.atan2(NINF, NINF), -math.pi*3/4)
377 self.ftest('atan2(-inf, -2.3)', math.atan2(NINF, -2.3), -math.pi/2)
378 self.ftest('atan2(-inf, -0.)', math.atan2(NINF, -0.0), -math.pi/2)
379 self.ftest('atan2(-inf, 0.)', math.atan2(NINF, 0.0), -math.pi/2)
380 self.ftest('atan2(-inf, 2.3)', math.atan2(NINF, 2.3), -math.pi/2)
381 self.ftest('atan2(-inf, inf)', math.atan2(NINF, INF), -math.pi/4)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000382 self.assertTrue(math.isnan(math.atan2(NINF, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000383 # math.atan2(+finite, x)
384 self.ftest('atan2(2.3, -inf)', math.atan2(2.3, NINF), math.pi)
385 self.ftest('atan2(2.3, -0.)', math.atan2(2.3, -0.), math.pi/2)
386 self.ftest('atan2(2.3, 0.)', math.atan2(2.3, 0.), math.pi/2)
387 self.assertEqual(math.atan2(2.3, INF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000388 self.assertTrue(math.isnan(math.atan2(2.3, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000389 # math.atan2(-finite, x)
390 self.ftest('atan2(-2.3, -inf)', math.atan2(-2.3, NINF), -math.pi)
391 self.ftest('atan2(-2.3, -0.)', math.atan2(-2.3, -0.), -math.pi/2)
392 self.ftest('atan2(-2.3, 0.)', math.atan2(-2.3, 0.), -math.pi/2)
393 self.assertEqual(math.atan2(-2.3, INF), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000394 self.assertTrue(math.isnan(math.atan2(-2.3, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000395 # math.atan2(NAN, x)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000396 self.assertTrue(math.isnan(math.atan2(NAN, NINF)))
397 self.assertTrue(math.isnan(math.atan2(NAN, -2.3)))
398 self.assertTrue(math.isnan(math.atan2(NAN, -0.)))
399 self.assertTrue(math.isnan(math.atan2(NAN, 0.)))
400 self.assertTrue(math.isnan(math.atan2(NAN, 2.3)))
401 self.assertTrue(math.isnan(math.atan2(NAN, INF)))
402 self.assertTrue(math.isnan(math.atan2(NAN, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000403
Thomas Wouters89f507f2006-12-13 04:49:30 +0000404 def testCeil(self):
405 self.assertRaises(TypeError, math.ceil)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000406 self.assertEqual(int, type(math.ceil(0.5)))
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200407 self.assertEqual(math.ceil(0.5), 1)
408 self.assertEqual(math.ceil(1.0), 1)
409 self.assertEqual(math.ceil(1.5), 2)
410 self.assertEqual(math.ceil(-0.5), 0)
411 self.assertEqual(math.ceil(-1.0), -1)
412 self.assertEqual(math.ceil(-1.5), -1)
413 self.assertEqual(math.ceil(0.0), 0)
414 self.assertEqual(math.ceil(-0.0), 0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000415 #self.assertEqual(math.ceil(INF), INF)
416 #self.assertEqual(math.ceil(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000417 #self.assertTrue(math.isnan(math.ceil(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000418
Guido van Rossum13e05de2007-08-23 22:56:55 +0000419 class TestCeil:
420 def __ceil__(self):
421 return 42
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200422 class FloatCeil(float):
423 def __ceil__(self):
424 return 42
Guido van Rossum13e05de2007-08-23 22:56:55 +0000425 class TestNoCeil:
426 pass
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200427 self.assertEqual(math.ceil(TestCeil()), 42)
428 self.assertEqual(math.ceil(FloatCeil()), 42)
429 self.assertEqual(math.ceil(FloatLike(42.5)), 43)
Guido van Rossum13e05de2007-08-23 22:56:55 +0000430 self.assertRaises(TypeError, math.ceil, TestNoCeil())
431
432 t = TestNoCeil()
433 t.__ceil__ = lambda *args: args
434 self.assertRaises(TypeError, math.ceil, t)
435 self.assertRaises(TypeError, math.ceil, t, 0)
436
Mark Dickinson63566232009-09-18 21:04:19 +0000437 @requires_IEEE_754
438 def testCopysign(self):
Mark Dickinson06b59e02010-02-06 23:16:50 +0000439 self.assertEqual(math.copysign(1, 42), 1.0)
440 self.assertEqual(math.copysign(0., 42), 0.0)
441 self.assertEqual(math.copysign(1., -42), -1.0)
442 self.assertEqual(math.copysign(3, 0.), 3.0)
443 self.assertEqual(math.copysign(4., -0.), -4.0)
444
Mark Dickinson63566232009-09-18 21:04:19 +0000445 self.assertRaises(TypeError, math.copysign)
446 # copysign should let us distinguish signs of zeros
Ezio Melottib3aedd42010-11-20 19:04:17 +0000447 self.assertEqual(math.copysign(1., 0.), 1.)
448 self.assertEqual(math.copysign(1., -0.), -1.)
449 self.assertEqual(math.copysign(INF, 0.), INF)
450 self.assertEqual(math.copysign(INF, -0.), NINF)
451 self.assertEqual(math.copysign(NINF, 0.), INF)
452 self.assertEqual(math.copysign(NINF, -0.), NINF)
Mark Dickinson63566232009-09-18 21:04:19 +0000453 # and of infinities
Ezio Melottib3aedd42010-11-20 19:04:17 +0000454 self.assertEqual(math.copysign(1., INF), 1.)
455 self.assertEqual(math.copysign(1., NINF), -1.)
456 self.assertEqual(math.copysign(INF, INF), INF)
457 self.assertEqual(math.copysign(INF, NINF), NINF)
458 self.assertEqual(math.copysign(NINF, INF), INF)
459 self.assertEqual(math.copysign(NINF, NINF), NINF)
Mark Dickinson06b59e02010-02-06 23:16:50 +0000460 self.assertTrue(math.isnan(math.copysign(NAN, 1.)))
461 self.assertTrue(math.isnan(math.copysign(NAN, INF)))
462 self.assertTrue(math.isnan(math.copysign(NAN, NINF)))
463 self.assertTrue(math.isnan(math.copysign(NAN, NAN)))
Mark Dickinson63566232009-09-18 21:04:19 +0000464 # copysign(INF, NAN) may be INF or it may be NINF, since
465 # we don't know whether the sign bit of NAN is set on any
466 # given platform.
Mark Dickinson06b59e02010-02-06 23:16:50 +0000467 self.assertTrue(math.isinf(math.copysign(INF, NAN)))
Mark Dickinson63566232009-09-18 21:04:19 +0000468 # similarly, copysign(2., NAN) could be 2. or -2.
Ezio Melottib3aedd42010-11-20 19:04:17 +0000469 self.assertEqual(abs(math.copysign(2., NAN)), 2.)
Christian Heimes53876d92008-04-19 00:31:39 +0000470
Thomas Wouters89f507f2006-12-13 04:49:30 +0000471 def testCos(self):
472 self.assertRaises(TypeError, math.cos)
Mark Dickinson96f774d2016-09-03 19:30:22 +0100473 self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0, abs_tol=ulp(1))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000474 self.ftest('cos(0)', math.cos(0), 1)
Mark Dickinson96f774d2016-09-03 19:30:22 +0100475 self.ftest('cos(pi/2)', math.cos(math.pi/2), 0, abs_tol=ulp(1))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000476 self.ftest('cos(pi)', math.cos(math.pi), -1)
Christian Heimes53876d92008-04-19 00:31:39 +0000477 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000478 self.assertTrue(math.isnan(math.cos(INF)))
479 self.assertTrue(math.isnan(math.cos(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +0000480 except ValueError:
481 self.assertRaises(ValueError, math.cos, INF)
482 self.assertRaises(ValueError, math.cos, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000483 self.assertTrue(math.isnan(math.cos(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000484
Paul Monsonf3550692019-06-19 13:09:54 -0700485 @unittest.skipIf(sys.platform == 'win32' and platform.machine() in ('ARM', 'ARM64'),
486 "Windows UCRT is off by 2 ULP this test requires accuracy within 1 ULP")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000487 def testCosh(self):
488 self.assertRaises(TypeError, math.cosh)
489 self.ftest('cosh(0)', math.cosh(0), 1)
490 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 +0000491 self.assertEqual(math.cosh(INF), INF)
492 self.assertEqual(math.cosh(NINF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000493 self.assertTrue(math.isnan(math.cosh(NAN)))
Raymond Hettinger64108af2002-05-13 03:55:01 +0000494
Thomas Wouters89f507f2006-12-13 04:49:30 +0000495 def testDegrees(self):
496 self.assertRaises(TypeError, math.degrees)
497 self.ftest('degrees(pi)', math.degrees(math.pi), 180.0)
498 self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
499 self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100500 self.ftest('degrees(0)', math.degrees(0), 0)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000501
Thomas Wouters89f507f2006-12-13 04:49:30 +0000502 def testExp(self):
503 self.assertRaises(TypeError, math.exp)
504 self.ftest('exp(-1)', math.exp(-1), 1/math.e)
505 self.ftest('exp(0)', math.exp(0), 1)
506 self.ftest('exp(1)', math.exp(1), math.e)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000507 self.assertEqual(math.exp(INF), INF)
508 self.assertEqual(math.exp(NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000509 self.assertTrue(math.isnan(math.exp(NAN)))
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100510 self.assertRaises(OverflowError, math.exp, 1000000)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000511
Thomas Wouters89f507f2006-12-13 04:49:30 +0000512 def testFabs(self):
513 self.assertRaises(TypeError, math.fabs)
514 self.ftest('fabs(-1)', math.fabs(-1), 1)
515 self.ftest('fabs(0)', math.fabs(0), 0)
516 self.ftest('fabs(1)', math.fabs(1), 1)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000517
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000518 def testFactorial(self):
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000519 self.assertEqual(math.factorial(0), 1)
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000520 total = 1
521 for i in range(1, 1000):
522 total *= i
523 self.assertEqual(math.factorial(i), total)
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000524 self.assertEqual(math.factorial(i), py_factorial(i))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000525 self.assertRaises(ValueError, math.factorial, -1)
Mark Dickinson5990d282014-04-10 09:29:39 -0400526 self.assertRaises(ValueError, math.factorial, -10**100)
Mark Dickinson5990d282014-04-10 09:29:39 -0400527
Pablo Galindoe9ba3702018-09-03 22:20:06 +0100528 def testFactorialNonIntegers(self):
Serhiy Storchaka231aad32019-06-17 16:57:27 +0300529 with self.assertWarns(DeprecationWarning):
530 self.assertEqual(math.factorial(5.0), 120)
531 with self.assertWarns(DeprecationWarning):
532 self.assertRaises(ValueError, math.factorial, 5.2)
533 with self.assertWarns(DeprecationWarning):
534 self.assertRaises(ValueError, math.factorial, -1.0)
535 with self.assertWarns(DeprecationWarning):
536 self.assertRaises(ValueError, math.factorial, -1e100)
537 self.assertRaises(TypeError, math.factorial, decimal.Decimal('5'))
538 self.assertRaises(TypeError, math.factorial, decimal.Decimal('5.2'))
Pablo Galindoe9ba3702018-09-03 22:20:06 +0100539 self.assertRaises(TypeError, math.factorial, "5")
540
Mark Dickinson5990d282014-04-10 09:29:39 -0400541 # Other implementations may place different upper bounds.
542 @support.cpython_only
543 def testFactorialHugeInputs(self):
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +0300544 # Currently raises OverflowError for inputs that are too large
Mark Dickinson5990d282014-04-10 09:29:39 -0400545 # to fit into a C long.
546 self.assertRaises(OverflowError, math.factorial, 10**100)
Serhiy Storchaka231aad32019-06-17 16:57:27 +0300547 with self.assertWarns(DeprecationWarning):
548 self.assertRaises(OverflowError, math.factorial, 1e100)
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000549
Thomas Wouters89f507f2006-12-13 04:49:30 +0000550 def testFloor(self):
551 self.assertRaises(TypeError, math.floor)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000552 self.assertEqual(int, type(math.floor(0.5)))
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200553 self.assertEqual(math.floor(0.5), 0)
554 self.assertEqual(math.floor(1.0), 1)
555 self.assertEqual(math.floor(1.5), 1)
556 self.assertEqual(math.floor(-0.5), -1)
557 self.assertEqual(math.floor(-1.0), -1)
558 self.assertEqual(math.floor(-1.5), -2)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000559 #self.assertEqual(math.ceil(INF), INF)
560 #self.assertEqual(math.ceil(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000561 #self.assertTrue(math.isnan(math.floor(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000562
Guido van Rossum13e05de2007-08-23 22:56:55 +0000563 class TestFloor:
564 def __floor__(self):
565 return 42
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200566 class FloatFloor(float):
567 def __floor__(self):
568 return 42
Guido van Rossum13e05de2007-08-23 22:56:55 +0000569 class TestNoFloor:
570 pass
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200571 self.assertEqual(math.floor(TestFloor()), 42)
572 self.assertEqual(math.floor(FloatFloor()), 42)
573 self.assertEqual(math.floor(FloatLike(41.9)), 41)
Guido van Rossum13e05de2007-08-23 22:56:55 +0000574 self.assertRaises(TypeError, math.floor, TestNoFloor())
575
576 t = TestNoFloor()
577 t.__floor__ = lambda *args: args
578 self.assertRaises(TypeError, math.floor, t)
579 self.assertRaises(TypeError, math.floor, t, 0)
580
Thomas Wouters89f507f2006-12-13 04:49:30 +0000581 def testFmod(self):
582 self.assertRaises(TypeError, math.fmod)
Mark Dickinson5bc7a442011-05-03 21:13:40 +0100583 self.ftest('fmod(10, 1)', math.fmod(10, 1), 0.0)
584 self.ftest('fmod(10, 0.5)', math.fmod(10, 0.5), 0.0)
585 self.ftest('fmod(10, 1.5)', math.fmod(10, 1.5), 1.0)
586 self.ftest('fmod(-10, 1)', math.fmod(-10, 1), -0.0)
587 self.ftest('fmod(-10, 0.5)', math.fmod(-10, 0.5), -0.0)
588 self.ftest('fmod(-10, 1.5)', math.fmod(-10, 1.5), -1.0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000589 self.assertTrue(math.isnan(math.fmod(NAN, 1.)))
590 self.assertTrue(math.isnan(math.fmod(1., NAN)))
591 self.assertTrue(math.isnan(math.fmod(NAN, NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000592 self.assertRaises(ValueError, math.fmod, 1., 0.)
593 self.assertRaises(ValueError, math.fmod, INF, 1.)
594 self.assertRaises(ValueError, math.fmod, NINF, 1.)
595 self.assertRaises(ValueError, math.fmod, INF, 0.)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000596 self.assertEqual(math.fmod(3.0, INF), 3.0)
597 self.assertEqual(math.fmod(-3.0, INF), -3.0)
598 self.assertEqual(math.fmod(3.0, NINF), 3.0)
599 self.assertEqual(math.fmod(-3.0, NINF), -3.0)
600 self.assertEqual(math.fmod(0.0, 3.0), 0.0)
601 self.assertEqual(math.fmod(0.0, NINF), 0.0)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000602
Thomas Wouters89f507f2006-12-13 04:49:30 +0000603 def testFrexp(self):
604 self.assertRaises(TypeError, math.frexp)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000605
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000606 def testfrexp(name, result, expected):
607 (mant, exp), (emant, eexp) = result, expected
Thomas Wouters89f507f2006-12-13 04:49:30 +0000608 if abs(mant-emant) > eps or exp != eexp:
609 self.fail('%s returned %r, expected %r'%\
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000610 (name, result, expected))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000611
Thomas Wouters89f507f2006-12-13 04:49:30 +0000612 testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
613 testfrexp('frexp(0)', math.frexp(0), (0, 0))
614 testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
615 testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000616
Ezio Melottib3aedd42010-11-20 19:04:17 +0000617 self.assertEqual(math.frexp(INF)[0], INF)
618 self.assertEqual(math.frexp(NINF)[0], NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000619 self.assertTrue(math.isnan(math.frexp(NAN)[0]))
Christian Heimes53876d92008-04-19 00:31:39 +0000620
Mark Dickinson63566232009-09-18 21:04:19 +0000621 @requires_IEEE_754
Mark Dickinson5c567082009-04-24 16:39:07 +0000622 @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
623 "fsum is not exact on machines with double rounding")
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000624 def testFsum(self):
625 # math.fsum relies on exact rounding for correct operation.
626 # There's a known problem with IA32 floating-point that causes
627 # inexact rounding in some situations, and will cause the
628 # math.fsum tests below to fail; see issue #2937. On non IEEE
629 # 754 platforms, and on IEEE 754 platforms that exhibit the
630 # problem described in issue #2937, we simply skip the whole
631 # test.
632
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000633 # Python version of math.fsum, for comparison. Uses a
634 # different algorithm based on frexp, ldexp and integer
635 # arithmetic.
636 from sys import float_info
637 mant_dig = float_info.mant_dig
638 etiny = float_info.min_exp - mant_dig
639
640 def msum(iterable):
641 """Full precision summation. Compute sum(iterable) without any
642 intermediate accumulation of error. Based on the 'lsum' function
643 at http://code.activestate.com/recipes/393090/
644
645 """
646 tmant, texp = 0, 0
647 for x in iterable:
648 mant, exp = math.frexp(x)
649 mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig
650 if texp > exp:
651 tmant <<= texp-exp
652 texp = exp
653 else:
654 mant <<= exp-texp
655 tmant += mant
656 # Round tmant * 2**texp to a float. The original recipe
657 # used float(str(tmant)) * 2.0**texp for this, but that's
658 # a little unsafe because str -> float conversion can't be
659 # relied upon to do correct rounding on all platforms.
660 tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp)
661 if tail > 0:
662 h = 1 << (tail-1)
663 tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1)
664 texp += tail
665 return math.ldexp(tmant, texp)
666
667 test_values = [
668 ([], 0.0),
669 ([0.0], 0.0),
670 ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
671 ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
672 ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
673 ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
674 ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
675 ([1./n for n in range(1, 1001)],
676 float.fromhex('0x1.df11f45f4e61ap+2')),
677 ([(-1.)**n/n for n in range(1, 1001)],
678 float.fromhex('-0x1.62a2af1bd3624p-1')),
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000679 ([1e16, 1., 1e-16], 10000000000000002.0),
680 ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
681 # exercise code for resizing partials array
682 ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] +
683 [-2.**1022],
684 float.fromhex('0x1.5555555555555p+970')),
685 ]
686
Mark Dickinsonbba873e2019-12-09 08:36:34 -0600687 # Telescoping sum, with exact differences (due to Sterbenz)
688 terms = [1.7**i for i in range(1001)]
689 test_values.append((
690 [terms[i+1] - terms[i] for i in range(1000)] + [-terms[1000]],
691 -terms[0]
692 ))
693
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000694 for i, (vals, expected) in enumerate(test_values):
695 try:
696 actual = math.fsum(vals)
697 except OverflowError:
698 self.fail("test %d failed: got OverflowError, expected %r "
699 "for math.fsum(%.100r)" % (i, expected, vals))
700 except ValueError:
701 self.fail("test %d failed: got ValueError, expected %r "
702 "for math.fsum(%.100r)" % (i, expected, vals))
703 self.assertEqual(actual, expected)
704
705 from random import random, gauss, shuffle
706 for j in range(1000):
707 vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
708 s = 0
709 for i in range(200):
710 v = gauss(0, random()) ** 7 - s
711 s += v
712 vals.append(v)
713 shuffle(vals)
714
715 s = msum(vals)
716 self.assertEqual(msum(vals), math.fsum(vals))
717
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300718 def testGcd(self):
719 gcd = math.gcd
720 self.assertEqual(gcd(0, 0), 0)
721 self.assertEqual(gcd(1, 0), 1)
722 self.assertEqual(gcd(-1, 0), 1)
723 self.assertEqual(gcd(0, 1), 1)
724 self.assertEqual(gcd(0, -1), 1)
725 self.assertEqual(gcd(7, 1), 1)
726 self.assertEqual(gcd(7, -1), 1)
727 self.assertEqual(gcd(-23, 15), 1)
728 self.assertEqual(gcd(120, 84), 12)
729 self.assertEqual(gcd(84, -120), 12)
730 self.assertEqual(gcd(1216342683557601535506311712,
731 436522681849110124616458784), 32)
732 c = 652560
733 x = 434610456570399902378880679233098819019853229470286994367836600566
734 y = 1064502245825115327754847244914921553977
735 a = x * c
736 b = y * c
737 self.assertEqual(gcd(a, b), c)
738 self.assertEqual(gcd(b, a), c)
739 self.assertEqual(gcd(-a, b), c)
740 self.assertEqual(gcd(b, -a), c)
741 self.assertEqual(gcd(a, -b), c)
742 self.assertEqual(gcd(-b, a), c)
743 self.assertEqual(gcd(-a, -b), c)
744 self.assertEqual(gcd(-b, -a), c)
745 c = 576559230871654959816130551884856912003141446781646602790216406874
746 a = x * c
747 b = y * c
748 self.assertEqual(gcd(a, b), c)
749 self.assertEqual(gcd(b, a), c)
750 self.assertEqual(gcd(-a, b), c)
751 self.assertEqual(gcd(b, -a), c)
752 self.assertEqual(gcd(a, -b), c)
753 self.assertEqual(gcd(-b, a), c)
754 self.assertEqual(gcd(-a, -b), c)
755 self.assertEqual(gcd(-b, -a), c)
756
757 self.assertRaises(TypeError, gcd, 120.0, 84)
758 self.assertRaises(TypeError, gcd, 120, 84.0)
759 self.assertEqual(gcd(MyIndexable(120), MyIndexable(84)), 12)
760
Thomas Wouters89f507f2006-12-13 04:49:30 +0000761 def testHypot(self):
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700762 from decimal import Decimal
763 from fractions import Fraction
764
765 hypot = math.hypot
766
767 # Test different numbers of arguments (from zero to five)
768 # against a straightforward pure python implementation
769 args = math.e, math.pi, math.sqrt(2.0), math.gamma(3.5), math.sin(2.1)
770 for i in range(len(args)+1):
771 self.assertAlmostEqual(
772 hypot(*args[:i]),
773 math.sqrt(sum(s**2 for s in args[:i]))
774 )
775
776 # Test allowable types (those with __float__)
777 self.assertEqual(hypot(12.0, 5.0), 13.0)
778 self.assertEqual(hypot(12, 5), 13)
779 self.assertEqual(hypot(Decimal(12), Decimal(5)), 13)
780 self.assertEqual(hypot(Fraction(12, 32), Fraction(5, 32)), Fraction(13, 32))
781 self.assertEqual(hypot(bool(1), bool(0), bool(1), bool(1)), math.sqrt(3))
782
783 # Test corner cases
784 self.assertEqual(hypot(0.0, 0.0), 0.0) # Max input is zero
785 self.assertEqual(hypot(-10.5), 10.5) # Negative input
786 self.assertEqual(hypot(), 0.0) # Negative input
787 self.assertEqual(1.0,
788 math.copysign(1.0, hypot(-0.0)) # Convert negative zero to positive zero
789 )
Raymond Hettinger00414592018-08-12 12:15:23 -0700790 self.assertEqual( # Handling of moving max to the end
791 hypot(1.5, 1.5, 0.5),
792 hypot(1.5, 0.5, 1.5),
793 )
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700794
795 # Test handling of bad arguments
796 with self.assertRaises(TypeError): # Reject keyword args
797 hypot(x=1)
798 with self.assertRaises(TypeError): # Reject values without __float__
799 hypot(1.1, 'string', 2.2)
Raymond Hettinger808180c2019-01-28 13:59:56 -0800800 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
801 with self.assertRaises((ValueError, OverflowError)):
802 hypot(1, int_too_big_for_float)
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700803
804 # Any infinity gives positive infinity.
805 self.assertEqual(hypot(INF), INF)
806 self.assertEqual(hypot(0, INF), INF)
807 self.assertEqual(hypot(10, INF), INF)
808 self.assertEqual(hypot(-10, INF), INF)
809 self.assertEqual(hypot(NAN, INF), INF)
810 self.assertEqual(hypot(INF, NAN), INF)
811 self.assertEqual(hypot(NINF, NAN), INF)
812 self.assertEqual(hypot(NAN, NINF), INF)
813 self.assertEqual(hypot(-INF, INF), INF)
814 self.assertEqual(hypot(-INF, -INF), INF)
815 self.assertEqual(hypot(10, -INF), INF)
816
Raymond Hettinger00414592018-08-12 12:15:23 -0700817 # If no infinity, any NaN gives a NaN.
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700818 self.assertTrue(math.isnan(hypot(NAN)))
819 self.assertTrue(math.isnan(hypot(0, NAN)))
820 self.assertTrue(math.isnan(hypot(NAN, 10)))
821 self.assertTrue(math.isnan(hypot(10, NAN)))
822 self.assertTrue(math.isnan(hypot(NAN, NAN)))
823 self.assertTrue(math.isnan(hypot(NAN)))
824
825 # Verify scaling for extremely large values
826 fourthmax = FLOAT_MAX / 4.0
827 for n in range(32):
828 self.assertEqual(hypot(*([fourthmax]*n)), fourthmax * math.sqrt(n))
829
830 # Verify scaling for extremely small values
831 for exp in range(32):
832 scale = FLOAT_MIN / 2.0 ** exp
833 self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000834
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700835 def testDist(self):
836 from decimal import Decimal as D
837 from fractions import Fraction as F
838
839 dist = math.dist
840 sqrt = math.sqrt
841
Raymond Hettinger808180c2019-01-28 13:59:56 -0800842 # Simple exact cases
843 self.assertEqual(dist((1.0, 2.0, 3.0), (4.0, 2.0, -1.0)), 5.0)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700844 self.assertEqual(dist((1, 2, 3), (4, 2, -1)), 5.0)
845
846 # Test different numbers of arguments (from zero to nine)
847 # against a straightforward pure python implementation
848 for i in range(9):
849 for j in range(5):
850 p = tuple(random.uniform(-5, 5) for k in range(i))
851 q = tuple(random.uniform(-5, 5) for k in range(i))
852 self.assertAlmostEqual(
853 dist(p, q),
854 sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
855 )
856
Raymond Hettinger6b5f1b42019-07-27 14:04:29 -0700857 # Test non-tuple inputs
858 self.assertEqual(dist([1.0, 2.0, 3.0], [4.0, 2.0, -1.0]), 5.0)
859 self.assertEqual(dist(iter([1.0, 2.0, 3.0]), iter([4.0, 2.0, -1.0])), 5.0)
860
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700861 # Test allowable types (those with __float__)
862 self.assertEqual(dist((14.0, 1.0), (2.0, -4.0)), 13.0)
863 self.assertEqual(dist((14, 1), (2, -4)), 13)
864 self.assertEqual(dist((D(14), D(1)), (D(2), D(-4))), D(13))
865 self.assertEqual(dist((F(14, 32), F(1, 32)), (F(2, 32), F(-4, 32))),
866 F(13, 32))
867 self.assertEqual(dist((True, True, False, True, False),
868 (True, False, True, True, False)),
869 sqrt(2.0))
870
871 # Test corner cases
872 self.assertEqual(dist((13.25, 12.5, -3.25),
873 (13.25, 12.5, -3.25)),
874 0.0) # Distance with self is zero
875 self.assertEqual(dist((), ()), 0.0) # Zero-dimensional case
876 self.assertEqual(1.0, # Convert negative zero to positive zero
877 math.copysign(1.0, dist((-0.0,), (0.0,)))
878 )
879 self.assertEqual(1.0, # Convert negative zero to positive zero
880 math.copysign(1.0, dist((0.0,), (-0.0,)))
881 )
Raymond Hettinger00414592018-08-12 12:15:23 -0700882 self.assertEqual( # Handling of moving max to the end
883 dist((1.5, 1.5, 0.5), (0, 0, 0)),
884 dist((1.5, 0.5, 1.5), (0, 0, 0))
885 )
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700886
887 # Verify tuple subclasses are allowed
Raymond Hettinger00414592018-08-12 12:15:23 -0700888 class T(tuple):
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700889 pass
890 self.assertEqual(dist(T((1, 2, 3)), ((4, 2, -1))), 5.0)
891
892 # Test handling of bad arguments
893 with self.assertRaises(TypeError): # Reject keyword args
894 dist(p=(1, 2, 3), q=(4, 5, 6))
895 with self.assertRaises(TypeError): # Too few args
896 dist((1, 2, 3))
897 with self.assertRaises(TypeError): # Too many args
898 dist((1, 2, 3), (4, 5, 6), (7, 8, 9))
899 with self.assertRaises(TypeError): # Scalars not allowed
900 dist(1, 2)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700901 with self.assertRaises(TypeError): # Reject values without __float__
902 dist((1.1, 'string', 2.2), (1, 2, 3))
903 with self.assertRaises(ValueError): # Check dimension agree
904 dist((1, 2, 3, 4), (5, 6, 7))
905 with self.assertRaises(ValueError): # Check dimension agree
906 dist((1, 2, 3), (4, 5, 6, 7))
Ammar Askarcb08a712019-01-12 01:23:41 -0500907 with self.assertRaises(TypeError): # Rejects invalid types
908 dist("abc", "xyz")
Raymond Hettinger808180c2019-01-28 13:59:56 -0800909 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
910 with self.assertRaises((ValueError, OverflowError)):
911 dist((1, int_too_big_for_float), (2, 3))
912 with self.assertRaises((ValueError, OverflowError)):
913 dist((2, 3), (1, int_too_big_for_float))
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700914
Raymond Hettinger00414592018-08-12 12:15:23 -0700915 # Verify that the one dimensional case is equivalent to abs()
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700916 for i in range(20):
917 p, q = random.random(), random.random()
918 self.assertEqual(dist((p,), (q,)), abs(p - q))
919
920 # Test special values
921 values = [NINF, -10.5, -0.0, 0.0, 10.5, INF, NAN]
922 for p in itertools.product(values, repeat=3):
923 for q in itertools.product(values, repeat=3):
924 diffs = [px - qx for px, qx in zip(p, q)]
925 if any(map(math.isinf, diffs)):
926 # Any infinite difference gives positive infinity.
927 self.assertEqual(dist(p, q), INF)
928 elif any(map(math.isnan, diffs)):
Raymond Hettinger00414592018-08-12 12:15:23 -0700929 # If no infinity, any NaN gives a NaN.
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700930 self.assertTrue(math.isnan(dist(p, q)))
931
932 # Verify scaling for extremely large values
933 fourthmax = FLOAT_MAX / 4.0
934 for n in range(32):
935 p = (fourthmax,) * n
936 q = (0.0,) * n
937 self.assertEqual(dist(p, q), fourthmax * math.sqrt(n))
938 self.assertEqual(dist(q, p), fourthmax * math.sqrt(n))
939
940 # Verify scaling for extremely small values
941 for exp in range(32):
942 scale = FLOAT_MIN / 2.0 ** exp
943 p = (4*scale, 3*scale)
944 q = (0.0, 0.0)
945 self.assertEqual(math.dist(p, q), 5*scale)
946 self.assertEqual(math.dist(q, p), 5*scale)
947
Mark Dickinson73934b92019-05-18 12:29:50 +0100948 def testIsqrt(self):
949 # Test a variety of inputs, large and small.
950 test_values = (
951 list(range(1000))
952 + list(range(10**6 - 1000, 10**6 + 1000))
Mark Dickinson5c08ce92019-05-19 17:51:56 +0100953 + [2**e + i for e in range(60, 200) for i in range(-40, 40)]
Mark Dickinson73934b92019-05-18 12:29:50 +0100954 + [3**9999, 10**5001]
955 )
956
957 for value in test_values:
958 with self.subTest(value=value):
959 s = math.isqrt(value)
960 self.assertIs(type(s), int)
961 self.assertLessEqual(s*s, value)
962 self.assertLess(value, (s+1)*(s+1))
963
964 # Negative values
965 with self.assertRaises(ValueError):
966 math.isqrt(-1)
967
968 # Integer-like things
969 s = math.isqrt(True)
970 self.assertIs(type(s), int)
971 self.assertEqual(s, 1)
972
973 s = math.isqrt(False)
974 self.assertIs(type(s), int)
975 self.assertEqual(s, 0)
976
977 class IntegerLike(object):
978 def __init__(self, value):
979 self.value = value
980
981 def __index__(self):
982 return self.value
983
984 s = math.isqrt(IntegerLike(1729))
985 self.assertIs(type(s), int)
986 self.assertEqual(s, 41)
987
988 with self.assertRaises(ValueError):
989 math.isqrt(IntegerLike(-3))
990
991 # Non-integer-like things
992 bad_values = [
993 3.5, "a string", decimal.Decimal("3.5"), 3.5j,
994 100.0, -4.0,
995 ]
996 for value in bad_values:
997 with self.subTest(value=value):
998 with self.assertRaises(TypeError):
999 math.isqrt(value)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -07001000
Thomas Wouters89f507f2006-12-13 04:49:30 +00001001 def testLdexp(self):
1002 self.assertRaises(TypeError, math.ldexp)
1003 self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
1004 self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
1005 self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
1006 self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
Christian Heimes53876d92008-04-19 00:31:39 +00001007 self.assertRaises(OverflowError, math.ldexp, 1., 1000000)
1008 self.assertRaises(OverflowError, math.ldexp, -1., 1000000)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001009 self.assertEqual(math.ldexp(1., -1000000), 0.)
1010 self.assertEqual(math.ldexp(-1., -1000000), -0.)
1011 self.assertEqual(math.ldexp(INF, 30), INF)
1012 self.assertEqual(math.ldexp(NINF, -213), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001013 self.assertTrue(math.isnan(math.ldexp(NAN, 0)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001014
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001015 # large second argument
1016 for n in [10**5, 10**10, 10**20, 10**40]:
Ezio Melottib3aedd42010-11-20 19:04:17 +00001017 self.assertEqual(math.ldexp(INF, -n), INF)
1018 self.assertEqual(math.ldexp(NINF, -n), NINF)
1019 self.assertEqual(math.ldexp(1., -n), 0.)
1020 self.assertEqual(math.ldexp(-1., -n), -0.)
1021 self.assertEqual(math.ldexp(0., -n), 0.)
1022 self.assertEqual(math.ldexp(-0., -n), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001023 self.assertTrue(math.isnan(math.ldexp(NAN, -n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001024
1025 self.assertRaises(OverflowError, math.ldexp, 1., n)
1026 self.assertRaises(OverflowError, math.ldexp, -1., n)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001027 self.assertEqual(math.ldexp(0., n), 0.)
1028 self.assertEqual(math.ldexp(-0., n), -0.)
1029 self.assertEqual(math.ldexp(INF, n), INF)
1030 self.assertEqual(math.ldexp(NINF, n), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001031 self.assertTrue(math.isnan(math.ldexp(NAN, n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001032
Thomas Wouters89f507f2006-12-13 04:49:30 +00001033 def testLog(self):
1034 self.assertRaises(TypeError, math.log)
1035 self.ftest('log(1/e)', math.log(1/math.e), -1)
1036 self.ftest('log(1)', math.log(1), 0)
1037 self.ftest('log(e)', math.log(math.e), 1)
1038 self.ftest('log(32,2)', math.log(32,2), 5)
1039 self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
1040 self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001041 self.ftest('log(10**1000)', math.log(10**1000),
1042 2302.5850929940457)
1043 self.assertRaises(ValueError, math.log, -1.5)
1044 self.assertRaises(ValueError, math.log, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001045 self.assertRaises(ValueError, math.log, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001046 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001047 self.assertTrue(math.isnan(math.log(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001048
1049 def testLog1p(self):
1050 self.assertRaises(TypeError, math.log1p)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001051 for n in [2, 2**90, 2**300]:
1052 self.assertAlmostEqual(math.log1p(n), math.log1p(float(n)))
1053 self.assertRaises(ValueError, math.log1p, -1)
1054 self.assertEqual(math.log1p(INF), INF)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001055
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001056 @requires_IEEE_754
1057 def testLog2(self):
1058 self.assertRaises(TypeError, math.log2)
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001059
1060 # Check some integer values
1061 self.assertEqual(math.log2(1), 0.0)
1062 self.assertEqual(math.log2(2), 1.0)
1063 self.assertEqual(math.log2(4), 2.0)
1064
1065 # Large integer values
1066 self.assertEqual(math.log2(2**1023), 1023.0)
1067 self.assertEqual(math.log2(2**1024), 1024.0)
1068 self.assertEqual(math.log2(2**2000), 2000.0)
1069
1070 self.assertRaises(ValueError, math.log2, -1.5)
1071 self.assertRaises(ValueError, math.log2, NINF)
1072 self.assertTrue(math.isnan(math.log2(NAN)))
1073
Victor Stinnercd9dd372011-05-10 23:40:17 +02001074 @requires_IEEE_754
Victor Stinnerebbbdaf2011-06-01 13:19:07 +02001075 # log2() is not accurate enough on Mac OS X Tiger (10.4)
1076 @support.requires_mac_ver(10, 5)
Victor Stinnercd9dd372011-05-10 23:40:17 +02001077 def testLog2Exact(self):
1078 # Check that we get exact equality for log2 of powers of 2.
1079 actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)]
1080 expected = [float(n) for n in range(-1074, 1024)]
1081 self.assertEqual(actual, expected)
1082
Thomas Wouters89f507f2006-12-13 04:49:30 +00001083 def testLog10(self):
1084 self.assertRaises(TypeError, math.log10)
1085 self.ftest('log10(0.1)', math.log10(0.1), -1)
1086 self.ftest('log10(1)', math.log10(1), 0)
1087 self.ftest('log10(10)', math.log10(10), 1)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001088 self.ftest('log10(10**1000)', math.log10(10**1000), 1000.0)
1089 self.assertRaises(ValueError, math.log10, -1.5)
1090 self.assertRaises(ValueError, math.log10, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001091 self.assertRaises(ValueError, math.log10, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001092 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001093 self.assertTrue(math.isnan(math.log10(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001094
Thomas Wouters89f507f2006-12-13 04:49:30 +00001095 def testModf(self):
1096 self.assertRaises(TypeError, math.modf)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001097
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001098 def testmodf(name, result, expected):
1099 (v1, v2), (e1, e2) = result, expected
Thomas Wouters89f507f2006-12-13 04:49:30 +00001100 if abs(v1-e1) > eps or abs(v2-e2):
1101 self.fail('%s returned %r, expected %r'%\
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001102 (name, result, expected))
Raymond Hettinger64108af2002-05-13 03:55:01 +00001103
Thomas Wouters89f507f2006-12-13 04:49:30 +00001104 testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
1105 testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001106
Ezio Melottib3aedd42010-11-20 19:04:17 +00001107 self.assertEqual(math.modf(INF), (0.0, INF))
1108 self.assertEqual(math.modf(NINF), (-0.0, NINF))
Christian Heimes53876d92008-04-19 00:31:39 +00001109
1110 modf_nan = math.modf(NAN)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001111 self.assertTrue(math.isnan(modf_nan[0]))
1112 self.assertTrue(math.isnan(modf_nan[1]))
Christian Heimes53876d92008-04-19 00:31:39 +00001113
Thomas Wouters89f507f2006-12-13 04:49:30 +00001114 def testPow(self):
1115 self.assertRaises(TypeError, math.pow)
1116 self.ftest('pow(0,1)', math.pow(0,1), 0)
1117 self.ftest('pow(1,0)', math.pow(1,0), 1)
1118 self.ftest('pow(2,1)', math.pow(2,1), 2)
1119 self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
Christian Heimes53876d92008-04-19 00:31:39 +00001120 self.assertEqual(math.pow(INF, 1), INF)
1121 self.assertEqual(math.pow(NINF, 1), NINF)
1122 self.assertEqual((math.pow(1, INF)), 1.)
1123 self.assertEqual((math.pow(1, NINF)), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001124 self.assertTrue(math.isnan(math.pow(NAN, 1)))
1125 self.assertTrue(math.isnan(math.pow(2, NAN)))
1126 self.assertTrue(math.isnan(math.pow(0, NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001127 self.assertEqual(math.pow(1, NAN), 1)
Christian Heimesa342c012008-04-20 21:01:16 +00001128
1129 # pow(0., x)
1130 self.assertEqual(math.pow(0., INF), 0.)
1131 self.assertEqual(math.pow(0., 3.), 0.)
1132 self.assertEqual(math.pow(0., 2.3), 0.)
1133 self.assertEqual(math.pow(0., 2.), 0.)
1134 self.assertEqual(math.pow(0., 0.), 1.)
1135 self.assertEqual(math.pow(0., -0.), 1.)
1136 self.assertRaises(ValueError, math.pow, 0., -2.)
1137 self.assertRaises(ValueError, math.pow, 0., -2.3)
1138 self.assertRaises(ValueError, math.pow, 0., -3.)
1139 self.assertRaises(ValueError, math.pow, 0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001140 self.assertTrue(math.isnan(math.pow(0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001141
1142 # pow(INF, x)
1143 self.assertEqual(math.pow(INF, INF), INF)
1144 self.assertEqual(math.pow(INF, 3.), INF)
1145 self.assertEqual(math.pow(INF, 2.3), INF)
1146 self.assertEqual(math.pow(INF, 2.), INF)
1147 self.assertEqual(math.pow(INF, 0.), 1.)
1148 self.assertEqual(math.pow(INF, -0.), 1.)
1149 self.assertEqual(math.pow(INF, -2.), 0.)
1150 self.assertEqual(math.pow(INF, -2.3), 0.)
1151 self.assertEqual(math.pow(INF, -3.), 0.)
1152 self.assertEqual(math.pow(INF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001153 self.assertTrue(math.isnan(math.pow(INF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001154
1155 # pow(-0., x)
1156 self.assertEqual(math.pow(-0., INF), 0.)
1157 self.assertEqual(math.pow(-0., 3.), -0.)
1158 self.assertEqual(math.pow(-0., 2.3), 0.)
1159 self.assertEqual(math.pow(-0., 2.), 0.)
1160 self.assertEqual(math.pow(-0., 0.), 1.)
1161 self.assertEqual(math.pow(-0., -0.), 1.)
1162 self.assertRaises(ValueError, math.pow, -0., -2.)
1163 self.assertRaises(ValueError, math.pow, -0., -2.3)
1164 self.assertRaises(ValueError, math.pow, -0., -3.)
1165 self.assertRaises(ValueError, math.pow, -0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001166 self.assertTrue(math.isnan(math.pow(-0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001167
1168 # pow(NINF, x)
1169 self.assertEqual(math.pow(NINF, INF), INF)
1170 self.assertEqual(math.pow(NINF, 3.), NINF)
1171 self.assertEqual(math.pow(NINF, 2.3), INF)
1172 self.assertEqual(math.pow(NINF, 2.), INF)
1173 self.assertEqual(math.pow(NINF, 0.), 1.)
1174 self.assertEqual(math.pow(NINF, -0.), 1.)
1175 self.assertEqual(math.pow(NINF, -2.), 0.)
1176 self.assertEqual(math.pow(NINF, -2.3), 0.)
1177 self.assertEqual(math.pow(NINF, -3.), -0.)
1178 self.assertEqual(math.pow(NINF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001179 self.assertTrue(math.isnan(math.pow(NINF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001180
1181 # pow(-1, x)
1182 self.assertEqual(math.pow(-1., INF), 1.)
1183 self.assertEqual(math.pow(-1., 3.), -1.)
1184 self.assertRaises(ValueError, math.pow, -1., 2.3)
1185 self.assertEqual(math.pow(-1., 2.), 1.)
1186 self.assertEqual(math.pow(-1., 0.), 1.)
1187 self.assertEqual(math.pow(-1., -0.), 1.)
1188 self.assertEqual(math.pow(-1., -2.), 1.)
1189 self.assertRaises(ValueError, math.pow, -1., -2.3)
1190 self.assertEqual(math.pow(-1., -3.), -1.)
1191 self.assertEqual(math.pow(-1., NINF), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001192 self.assertTrue(math.isnan(math.pow(-1., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001193
1194 # pow(1, x)
1195 self.assertEqual(math.pow(1., INF), 1.)
1196 self.assertEqual(math.pow(1., 3.), 1.)
1197 self.assertEqual(math.pow(1., 2.3), 1.)
1198 self.assertEqual(math.pow(1., 2.), 1.)
1199 self.assertEqual(math.pow(1., 0.), 1.)
1200 self.assertEqual(math.pow(1., -0.), 1.)
1201 self.assertEqual(math.pow(1., -2.), 1.)
1202 self.assertEqual(math.pow(1., -2.3), 1.)
1203 self.assertEqual(math.pow(1., -3.), 1.)
1204 self.assertEqual(math.pow(1., NINF), 1.)
1205 self.assertEqual(math.pow(1., NAN), 1.)
1206
1207 # pow(x, 0) should be 1 for any x
1208 self.assertEqual(math.pow(2.3, 0.), 1.)
1209 self.assertEqual(math.pow(-2.3, 0.), 1.)
1210 self.assertEqual(math.pow(NAN, 0.), 1.)
1211 self.assertEqual(math.pow(2.3, -0.), 1.)
1212 self.assertEqual(math.pow(-2.3, -0.), 1.)
1213 self.assertEqual(math.pow(NAN, -0.), 1.)
1214
1215 # pow(x, y) is invalid if x is negative and y is not integral
1216 self.assertRaises(ValueError, math.pow, -1., 2.3)
1217 self.assertRaises(ValueError, math.pow, -15., -3.1)
1218
1219 # pow(x, NINF)
1220 self.assertEqual(math.pow(1.9, NINF), 0.)
1221 self.assertEqual(math.pow(1.1, NINF), 0.)
1222 self.assertEqual(math.pow(0.9, NINF), INF)
1223 self.assertEqual(math.pow(0.1, NINF), INF)
1224 self.assertEqual(math.pow(-0.1, NINF), INF)
1225 self.assertEqual(math.pow(-0.9, NINF), INF)
1226 self.assertEqual(math.pow(-1.1, NINF), 0.)
1227 self.assertEqual(math.pow(-1.9, NINF), 0.)
1228
1229 # pow(x, INF)
1230 self.assertEqual(math.pow(1.9, INF), INF)
1231 self.assertEqual(math.pow(1.1, INF), INF)
1232 self.assertEqual(math.pow(0.9, INF), 0.)
1233 self.assertEqual(math.pow(0.1, INF), 0.)
1234 self.assertEqual(math.pow(-0.1, INF), 0.)
1235 self.assertEqual(math.pow(-0.9, INF), 0.)
1236 self.assertEqual(math.pow(-1.1, INF), INF)
1237 self.assertEqual(math.pow(-1.9, INF), INF)
1238
1239 # pow(x, y) should work for x negative, y an integer
1240 self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
1241 self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
1242 self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
1243 self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
1244 self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
1245 self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
1246 self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
1247 self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
1248 self.assertRaises(ValueError, math.pow, -2.0, -0.5)
1249 self.assertRaises(ValueError, math.pow, -2.0, 0.5)
1250
1251 # the following tests have been commented out since they don't
1252 # really belong here: the implementation of ** for floats is
Ezio Melotti13925002011-03-16 11:05:33 +02001253 # independent of the implementation of math.pow
Christian Heimesa342c012008-04-20 21:01:16 +00001254 #self.assertEqual(1**NAN, 1)
1255 #self.assertEqual(1**INF, 1)
1256 #self.assertEqual(1**NINF, 1)
1257 #self.assertEqual(1**0, 1)
1258 #self.assertEqual(1.**NAN, 1)
1259 #self.assertEqual(1.**INF, 1)
1260 #self.assertEqual(1.**NINF, 1)
1261 #self.assertEqual(1.**0, 1)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001262
Thomas Wouters89f507f2006-12-13 04:49:30 +00001263 def testRadians(self):
1264 self.assertRaises(TypeError, math.radians)
1265 self.ftest('radians(180)', math.radians(180), math.pi)
1266 self.ftest('radians(90)', math.radians(90), math.pi/2)
1267 self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001268 self.ftest('radians(0)', math.radians(0), 0)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001269
Mark Dickinsona0ce3752017-04-05 18:34:27 +01001270 @requires_IEEE_754
1271 def testRemainder(self):
1272 from fractions import Fraction
1273
1274 def validate_spec(x, y, r):
1275 """
1276 Check that r matches remainder(x, y) according to the IEEE 754
1277 specification. Assumes that x, y and r are finite and y is nonzero.
1278 """
1279 fx, fy, fr = Fraction(x), Fraction(y), Fraction(r)
1280 # r should not exceed y/2 in absolute value
1281 self.assertLessEqual(abs(fr), abs(fy/2))
1282 # x - r should be an exact integer multiple of y
1283 n = (fx - fr) / fy
1284 self.assertEqual(n, int(n))
1285 if abs(fr) == abs(fy/2):
1286 # If |r| == |y/2|, n should be even.
1287 self.assertEqual(n/2, int(n/2))
1288
1289 # triples (x, y, remainder(x, y)) in hexadecimal form.
1290 testcases = [
1291 # Remainders modulo 1, showing the ties-to-even behaviour.
1292 '-4.0 1 -0.0',
1293 '-3.8 1 0.8',
1294 '-3.0 1 -0.0',
1295 '-2.8 1 -0.8',
1296 '-2.0 1 -0.0',
1297 '-1.8 1 0.8',
1298 '-1.0 1 -0.0',
1299 '-0.8 1 -0.8',
1300 '-0.0 1 -0.0',
1301 ' 0.0 1 0.0',
1302 ' 0.8 1 0.8',
1303 ' 1.0 1 0.0',
1304 ' 1.8 1 -0.8',
1305 ' 2.0 1 0.0',
1306 ' 2.8 1 0.8',
1307 ' 3.0 1 0.0',
1308 ' 3.8 1 -0.8',
1309 ' 4.0 1 0.0',
1310
1311 # Reductions modulo 2*pi
1312 '0x0.0p+0 0x1.921fb54442d18p+2 0x0.0p+0',
1313 '0x1.921fb54442d18p+0 0x1.921fb54442d18p+2 0x1.921fb54442d18p+0',
1314 '0x1.921fb54442d17p+1 0x1.921fb54442d18p+2 0x1.921fb54442d17p+1',
1315 '0x1.921fb54442d18p+1 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1316 '0x1.921fb54442d19p+1 0x1.921fb54442d18p+2 -0x1.921fb54442d17p+1',
1317 '0x1.921fb54442d17p+2 0x1.921fb54442d18p+2 -0x0.0000000000001p+2',
1318 '0x1.921fb54442d18p+2 0x1.921fb54442d18p+2 0x0p0',
1319 '0x1.921fb54442d19p+2 0x1.921fb54442d18p+2 0x0.0000000000001p+2',
1320 '0x1.2d97c7f3321d1p+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1321 '0x1.2d97c7f3321d2p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d18p+1',
1322 '0x1.2d97c7f3321d3p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1323 '0x1.921fb54442d17p+3 0x1.921fb54442d18p+2 -0x0.0000000000001p+3',
1324 '0x1.921fb54442d18p+3 0x1.921fb54442d18p+2 0x0p0',
1325 '0x1.921fb54442d19p+3 0x1.921fb54442d18p+2 0x0.0000000000001p+3',
1326 '0x1.f6a7a2955385dp+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1327 '0x1.f6a7a2955385ep+3 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1328 '0x1.f6a7a2955385fp+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1329 '0x1.1475cc9eedf00p+5 0x1.921fb54442d18p+2 0x1.921fb54442d10p+1',
1330 '0x1.1475cc9eedf01p+5 0x1.921fb54442d18p+2 -0x1.921fb54442d10p+1',
1331
1332 # Symmetry with respect to signs.
1333 ' 1 0.c 0.4',
1334 '-1 0.c -0.4',
1335 ' 1 -0.c 0.4',
1336 '-1 -0.c -0.4',
1337 ' 1.4 0.c -0.4',
1338 '-1.4 0.c 0.4',
1339 ' 1.4 -0.c -0.4',
1340 '-1.4 -0.c 0.4',
1341
1342 # Huge modulus, to check that the underlying algorithm doesn't
1343 # rely on 2.0 * modulus being representable.
1344 '0x1.dp+1023 0x1.4p+1023 0x0.9p+1023',
1345 '0x1.ep+1023 0x1.4p+1023 -0x0.ap+1023',
1346 '0x1.fp+1023 0x1.4p+1023 -0x0.9p+1023',
1347 ]
1348
1349 for case in testcases:
1350 with self.subTest(case=case):
1351 x_hex, y_hex, expected_hex = case.split()
1352 x = float.fromhex(x_hex)
1353 y = float.fromhex(y_hex)
1354 expected = float.fromhex(expected_hex)
1355 validate_spec(x, y, expected)
1356 actual = math.remainder(x, y)
1357 # Cheap way of checking that the floats are
1358 # as identical as we need them to be.
1359 self.assertEqual(actual.hex(), expected.hex())
1360
1361 # Test tiny subnormal modulus: there's potential for
1362 # getting the implementation wrong here (for example,
1363 # by assuming that modulus/2 is exactly representable).
1364 tiny = float.fromhex('1p-1074') # min +ve subnormal
1365 for n in range(-25, 25):
1366 if n == 0:
1367 continue
1368 y = n * tiny
1369 for m in range(100):
1370 x = m * tiny
1371 actual = math.remainder(x, y)
1372 validate_spec(x, y, actual)
1373 actual = math.remainder(-x, y)
1374 validate_spec(-x, y, actual)
1375
1376 # Special values.
1377 # NaNs should propagate as usual.
1378 for value in [NAN, 0.0, -0.0, 2.0, -2.3, NINF, INF]:
1379 self.assertIsNaN(math.remainder(NAN, value))
1380 self.assertIsNaN(math.remainder(value, NAN))
1381
1382 # remainder(x, inf) is x, for non-nan non-infinite x.
1383 for value in [-2.3, -0.0, 0.0, 2.3]:
1384 self.assertEqual(math.remainder(value, INF), value)
1385 self.assertEqual(math.remainder(value, NINF), value)
1386
1387 # remainder(x, 0) and remainder(infinity, x) for non-NaN x are invalid
1388 # operations according to IEEE 754-2008 7.2(f), and should raise.
1389 for value in [NINF, -2.3, -0.0, 0.0, 2.3, INF]:
1390 with self.assertRaises(ValueError):
1391 math.remainder(INF, value)
1392 with self.assertRaises(ValueError):
1393 math.remainder(NINF, value)
1394 with self.assertRaises(ValueError):
1395 math.remainder(value, 0.0)
1396 with self.assertRaises(ValueError):
1397 math.remainder(value, -0.0)
1398
Thomas Wouters89f507f2006-12-13 04:49:30 +00001399 def testSin(self):
1400 self.assertRaises(TypeError, math.sin)
1401 self.ftest('sin(0)', math.sin(0), 0)
1402 self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
1403 self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001404 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001405 self.assertTrue(math.isnan(math.sin(INF)))
1406 self.assertTrue(math.isnan(math.sin(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001407 except ValueError:
1408 self.assertRaises(ValueError, math.sin, INF)
1409 self.assertRaises(ValueError, math.sin, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001410 self.assertTrue(math.isnan(math.sin(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001411
Thomas Wouters89f507f2006-12-13 04:49:30 +00001412 def testSinh(self):
1413 self.assertRaises(TypeError, math.sinh)
1414 self.ftest('sinh(0)', math.sinh(0), 0)
1415 self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
1416 self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001417 self.assertEqual(math.sinh(INF), INF)
1418 self.assertEqual(math.sinh(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001419 self.assertTrue(math.isnan(math.sinh(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001420
Thomas Wouters89f507f2006-12-13 04:49:30 +00001421 def testSqrt(self):
1422 self.assertRaises(TypeError, math.sqrt)
1423 self.ftest('sqrt(0)', math.sqrt(0), 0)
1424 self.ftest('sqrt(1)', math.sqrt(1), 1)
1425 self.ftest('sqrt(4)', math.sqrt(4), 2)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001426 self.assertEqual(math.sqrt(INF), INF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001427 self.assertRaises(ValueError, math.sqrt, -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001428 self.assertRaises(ValueError, math.sqrt, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001429 self.assertTrue(math.isnan(math.sqrt(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001430
Thomas Wouters89f507f2006-12-13 04:49:30 +00001431 def testTan(self):
1432 self.assertRaises(TypeError, math.tan)
1433 self.ftest('tan(0)', math.tan(0), 0)
1434 self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
1435 self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001436 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001437 self.assertTrue(math.isnan(math.tan(INF)))
1438 self.assertTrue(math.isnan(math.tan(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001439 except:
1440 self.assertRaises(ValueError, math.tan, INF)
1441 self.assertRaises(ValueError, math.tan, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001442 self.assertTrue(math.isnan(math.tan(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001443
Thomas Wouters89f507f2006-12-13 04:49:30 +00001444 def testTanh(self):
1445 self.assertRaises(TypeError, math.tanh)
1446 self.ftest('tanh(0)', math.tanh(0), 0)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001447 self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0,
1448 abs_tol=ulp(1))
Christian Heimes53876d92008-04-19 00:31:39 +00001449 self.ftest('tanh(inf)', math.tanh(INF), 1)
1450 self.ftest('tanh(-inf)', math.tanh(NINF), -1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001451 self.assertTrue(math.isnan(math.tanh(NAN)))
Victor Stinnerbe3da382010-11-07 14:14:27 +00001452
1453 @requires_IEEE_754
Victor Stinnerbe3da382010-11-07 14:14:27 +00001454 def testTanhSign(self):
Christian Heimese57950f2008-04-21 13:08:03 +00001455 # check that tanh(-0.) == -0. on IEEE 754 systems
Victor Stinnerbe3da382010-11-07 14:14:27 +00001456 self.assertEqual(math.tanh(-0.), -0.)
1457 self.assertEqual(math.copysign(1., math.tanh(-0.)),
1458 math.copysign(1., -0.))
Tim Peters1d120612000-10-12 06:10:25 +00001459
Christian Heimes400adb02008-02-01 08:12:03 +00001460 def test_trunc(self):
1461 self.assertEqual(math.trunc(1), 1)
1462 self.assertEqual(math.trunc(-1), -1)
1463 self.assertEqual(type(math.trunc(1)), int)
1464 self.assertEqual(type(math.trunc(1.5)), int)
1465 self.assertEqual(math.trunc(1.5), 1)
1466 self.assertEqual(math.trunc(-1.5), -1)
1467 self.assertEqual(math.trunc(1.999999), 1)
1468 self.assertEqual(math.trunc(-1.999999), -1)
1469 self.assertEqual(math.trunc(-0.999999), -0)
1470 self.assertEqual(math.trunc(-100.999), -100)
1471
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001472 class TestTrunc:
Christian Heimes400adb02008-02-01 08:12:03 +00001473 def __trunc__(self):
1474 return 23
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001475 class FloatTrunc(float):
1476 def __trunc__(self):
1477 return 23
1478 class TestNoTrunc:
Christian Heimes400adb02008-02-01 08:12:03 +00001479 pass
1480
1481 self.assertEqual(math.trunc(TestTrunc()), 23)
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001482 self.assertEqual(math.trunc(FloatTrunc()), 23)
Christian Heimes400adb02008-02-01 08:12:03 +00001483
1484 self.assertRaises(TypeError, math.trunc)
1485 self.assertRaises(TypeError, math.trunc, 1, 2)
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001486 self.assertRaises(TypeError, math.trunc, FloatLike(23.5))
Christian Heimes400adb02008-02-01 08:12:03 +00001487 self.assertRaises(TypeError, math.trunc, TestNoTrunc())
1488
Mark Dickinson8e0c9962010-07-11 17:38:24 +00001489 def testIsfinite(self):
1490 self.assertTrue(math.isfinite(0.0))
1491 self.assertTrue(math.isfinite(-0.0))
1492 self.assertTrue(math.isfinite(1.0))
1493 self.assertTrue(math.isfinite(-1.0))
1494 self.assertFalse(math.isfinite(float("nan")))
1495 self.assertFalse(math.isfinite(float("inf")))
1496 self.assertFalse(math.isfinite(float("-inf")))
1497
Christian Heimes072c0f12008-01-03 23:01:04 +00001498 def testIsnan(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001499 self.assertTrue(math.isnan(float("nan")))
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001500 self.assertTrue(math.isnan(float("-nan")))
1501 self.assertTrue(math.isnan(float("inf") * 0.))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001502 self.assertFalse(math.isnan(float("inf")))
1503 self.assertFalse(math.isnan(0.))
1504 self.assertFalse(math.isnan(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001505
1506 def testIsinf(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001507 self.assertTrue(math.isinf(float("inf")))
1508 self.assertTrue(math.isinf(float("-inf")))
1509 self.assertTrue(math.isinf(1E400))
1510 self.assertTrue(math.isinf(-1E400))
1511 self.assertFalse(math.isinf(float("nan")))
1512 self.assertFalse(math.isinf(0.))
1513 self.assertFalse(math.isinf(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001514
Mark Dickinsona5d0c7c2015-01-11 11:55:29 +00001515 @requires_IEEE_754
1516 def test_nan_constant(self):
1517 self.assertTrue(math.isnan(math.nan))
1518
1519 @requires_IEEE_754
1520 def test_inf_constant(self):
1521 self.assertTrue(math.isinf(math.inf))
1522 self.assertGreater(math.inf, 0.0)
1523 self.assertEqual(math.inf, float("inf"))
1524 self.assertEqual(-math.inf, float("-inf"))
1525
Thomas Wouters89f507f2006-12-13 04:49:30 +00001526 # RED_FLAG 16-Oct-2000 Tim
1527 # While 2.0 is more consistent about exceptions than previous releases, it
1528 # still fails this part of the test on some platforms. For now, we only
1529 # *run* test_exceptions() in verbose mode, so that this isn't normally
1530 # tested.
Serhiy Storchaka43767632013-11-03 21:31:38 +02001531 @unittest.skipUnless(verbose, 'requires verbose mode')
1532 def test_exceptions(self):
1533 try:
1534 x = math.exp(-1000000000)
1535 except:
1536 # mathmodule.c is failing to weed out underflows from libm, or
1537 # we've got an fp format with huge dynamic range
1538 self.fail("underflowing exp() should not have raised "
1539 "an exception")
1540 if x != 0:
1541 self.fail("underflowing exp() should have returned 0")
Tim Peters98c81842000-10-16 17:35:13 +00001542
Serhiy Storchaka43767632013-11-03 21:31:38 +02001543 # If this fails, probably using a strict IEEE-754 conforming libm, and x
1544 # is +Inf afterwards. But Python wants overflows detected by default.
1545 try:
1546 x = math.exp(1000000000)
1547 except OverflowError:
1548 pass
1549 else:
1550 self.fail("overflowing exp() didn't trigger OverflowError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001551
Serhiy Storchaka43767632013-11-03 21:31:38 +02001552 # If this fails, it could be a puzzle. One odd possibility is that
1553 # mathmodule.c's macros are getting confused while comparing
1554 # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
1555 # as a result (and so raising OverflowError instead).
1556 try:
1557 x = math.sqrt(-1.0)
1558 except ValueError:
1559 pass
1560 else:
1561 self.fail("sqrt(-1) didn't raise ValueError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001562
Mark Dickinson63566232009-09-18 21:04:19 +00001563 @requires_IEEE_754
Christian Heimes53876d92008-04-19 00:31:39 +00001564 def test_testfile(self):
Mark Dickinson85746542016-09-04 09:58:51 +01001565 # Some tests need to be skipped on ancient OS X versions.
1566 # See issue #27953.
1567 SKIP_ON_TIGER = {'tan0064'}
1568
1569 osx_version = None
1570 if sys.platform == 'darwin':
1571 version_txt = platform.mac_ver()[0]
1572 try:
1573 osx_version = tuple(map(int, version_txt.split('.')))
1574 except ValueError:
1575 pass
1576
Mark Dickinson96f774d2016-09-03 19:30:22 +01001577 fail_fmt = "{}: {}({!r}): {}"
1578
1579 failures = []
Christian Heimes53876d92008-04-19 00:31:39 +00001580 for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001581 # Skip if either the input or result is complex
1582 if ai != 0.0 or ei != 0.0:
Christian Heimes53876d92008-04-19 00:31:39 +00001583 continue
1584 if fn in ['rect', 'polar']:
1585 # no real versions of rect, polar
1586 continue
Mark Dickinson85746542016-09-04 09:58:51 +01001587 # Skip certain tests on OS X 10.4.
1588 if osx_version is not None and osx_version < (10, 5):
1589 if id in SKIP_ON_TIGER:
1590 continue
Mark Dickinson96f774d2016-09-03 19:30:22 +01001591
Christian Heimes53876d92008-04-19 00:31:39 +00001592 func = getattr(math, fn)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001593
1594 if 'invalid' in flags or 'divide-by-zero' in flags:
1595 er = 'ValueError'
1596 elif 'overflow' in flags:
1597 er = 'OverflowError'
1598
Christian Heimesa342c012008-04-20 21:01:16 +00001599 try:
1600 result = func(ar)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001601 except ValueError:
1602 result = 'ValueError'
Benjamin Peterson2b7411d2008-05-26 17:36:47 +00001603 except OverflowError:
Mark Dickinson96f774d2016-09-03 19:30:22 +01001604 result = 'OverflowError'
1605
1606 # Default tolerances
1607 ulp_tol, abs_tol = 5, 0.0
1608
1609 failure = result_check(er, result, ulp_tol, abs_tol)
1610 if failure is None:
1611 continue
1612
1613 msg = fail_fmt.format(id, fn, ar, failure)
1614 failures.append(msg)
1615
1616 if failures:
1617 self.fail('Failures in test_testfile:\n ' +
1618 '\n '.join(failures))
Thomas Wouters89f507f2006-12-13 04:49:30 +00001619
Victor Stinnerbe3da382010-11-07 14:14:27 +00001620 @requires_IEEE_754
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001621 def test_mtestfile(self):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001622 fail_fmt = "{}: {}({!r}): {}"
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001623
1624 failures = []
1625 for id, fn, arg, expected, flags in parse_mtestfile(math_testcases):
1626 func = getattr(math, fn)
1627
1628 if 'invalid' in flags or 'divide-by-zero' in flags:
1629 expected = 'ValueError'
1630 elif 'overflow' in flags:
1631 expected = 'OverflowError'
1632
1633 try:
1634 got = func(arg)
1635 except ValueError:
1636 got = 'ValueError'
1637 except OverflowError:
1638 got = 'OverflowError'
1639
Mark Dickinson96f774d2016-09-03 19:30:22 +01001640 # Default tolerances
1641 ulp_tol, abs_tol = 5, 0.0
Mark Dickinsonbcdf9da2010-06-13 10:52:38 +00001642
Mark Dickinson96f774d2016-09-03 19:30:22 +01001643 # Exceptions to the defaults
1644 if fn == 'gamma':
1645 # Experimental results on one platform gave
1646 # an accuracy of <= 10 ulps across the entire float
1647 # domain. We weaken that to require 20 ulp accuracy.
1648 ulp_tol = 20
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001649
Mark Dickinson96f774d2016-09-03 19:30:22 +01001650 elif fn == 'lgamma':
1651 # we use a weaker accuracy test for lgamma;
1652 # lgamma only achieves an absolute error of
1653 # a few multiples of the machine accuracy, in
1654 # general.
1655 abs_tol = 1e-15
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001656
Mark Dickinson96f774d2016-09-03 19:30:22 +01001657 elif fn == 'erfc' and arg >= 0.0:
1658 # erfc has less-than-ideal accuracy for large
1659 # arguments (x ~ 25 or so), mainly due to the
1660 # error involved in computing exp(-x*x).
1661 #
1662 # Observed between CPython and mpmath at 25 dp:
1663 # x < 0 : err <= 2 ulp
1664 # 0 <= x < 1 : err <= 10 ulp
1665 # 1 <= x < 10 : err <= 100 ulp
1666 # 10 <= x < 20 : err <= 300 ulp
1667 # 20 <= x : < 600 ulp
1668 #
1669 if arg < 1.0:
1670 ulp_tol = 10
1671 elif arg < 10.0:
1672 ulp_tol = 100
1673 else:
1674 ulp_tol = 1000
1675
1676 failure = result_check(expected, got, ulp_tol, abs_tol)
1677 if failure is None:
1678 continue
1679
1680 msg = fail_fmt.format(id, fn, arg, failure)
1681 failures.append(msg)
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001682
1683 if failures:
1684 self.fail('Failures in test_mtestfile:\n ' +
1685 '\n '.join(failures))
1686
Pablo Galindo04114112019-03-09 19:18:08 +00001687 def test_prod(self):
1688 prod = math.prod
1689 self.assertEqual(prod([]), 1)
1690 self.assertEqual(prod([], start=5), 5)
1691 self.assertEqual(prod(list(range(2,8))), 5040)
1692 self.assertEqual(prod(iter(list(range(2,8)))), 5040)
1693 self.assertEqual(prod(range(1, 10), start=10), 3628800)
1694
1695 self.assertEqual(prod([1, 2, 3, 4, 5]), 120)
1696 self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0)
1697 self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0)
1698 self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0)
1699
1700 # Test overflow in fast-path for integers
1701 self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32)
1702 # Test overflow in fast-path for floats
1703 self.assertEqual(prod([1.0, 1.0, 2**32, 1, 1]), float(2**32))
1704
1705 self.assertRaises(TypeError, prod)
1706 self.assertRaises(TypeError, prod, 42)
1707 self.assertRaises(TypeError, prod, ['a', 'b', 'c'])
1708 self.assertRaises(TypeError, prod, ['a', 'b', 'c'], '')
1709 self.assertRaises(TypeError, prod, [b'a', b'c'], b'')
1710 values = [bytearray(b'a'), bytearray(b'b')]
1711 self.assertRaises(TypeError, prod, values, bytearray(b''))
1712 self.assertRaises(TypeError, prod, [[1], [2], [3]])
1713 self.assertRaises(TypeError, prod, [{2:3}])
1714 self.assertRaises(TypeError, prod, [{2:3}]*2, {2:3})
1715 self.assertRaises(TypeError, prod, [[1], [2], [3]], [])
1716 with self.assertRaises(TypeError):
1717 prod([10, 20], [30, 40]) # start is a keyword-only argument
1718
1719 self.assertEqual(prod([0, 1, 2, 3]), 0)
1720 self.assertEqual(prod([1, 0, 2, 3]), 0)
1721 self.assertEqual(prod([1, 2, 3, 0]), 0)
1722
1723 def _naive_prod(iterable, start=1):
1724 for elem in iterable:
1725 start *= elem
1726 return start
1727
1728 # Big integers
1729
1730 iterable = range(1, 10000)
1731 self.assertEqual(prod(iterable), _naive_prod(iterable))
1732 iterable = range(-10000, -1)
1733 self.assertEqual(prod(iterable), _naive_prod(iterable))
1734 iterable = range(-1000, 1000)
1735 self.assertEqual(prod(iterable), 0)
1736
1737 # Big floats
1738
1739 iterable = [float(x) for x in range(1, 1000)]
1740 self.assertEqual(prod(iterable), _naive_prod(iterable))
1741 iterable = [float(x) for x in range(-1000, -1)]
1742 self.assertEqual(prod(iterable), _naive_prod(iterable))
1743 iterable = [float(x) for x in range(-1000, 1000)]
1744 self.assertIsNaN(prod(iterable))
1745
1746 # Float tests
1747
1748 self.assertIsNaN(prod([1, 2, 3, float("nan"), 2, 3]))
1749 self.assertIsNaN(prod([1, 0, float("nan"), 2, 3]))
1750 self.assertIsNaN(prod([1, float("nan"), 0, 3]))
1751 self.assertIsNaN(prod([1, float("inf"), float("nan"),3]))
1752 self.assertIsNaN(prod([1, float("-inf"), float("nan"),3]))
1753 self.assertIsNaN(prod([1, float("nan"), float("inf"),3]))
1754 self.assertIsNaN(prod([1, float("nan"), float("-inf"),3]))
1755
1756 self.assertEqual(prod([1, 2, 3, float('inf'),-3,4]), float('-inf'))
1757 self.assertEqual(prod([1, 2, 3, float('-inf'),-3,4]), float('inf'))
1758
1759 self.assertIsNaN(prod([1,2,0,float('inf'), -3, 4]))
1760 self.assertIsNaN(prod([1,2,0,float('-inf'), -3, 4]))
1761 self.assertIsNaN(prod([1, 2, 3, float('inf'), -3, 0, 3]))
1762 self.assertIsNaN(prod([1, 2, 3, float('-inf'), -3, 0, 2]))
1763
1764 # Type preservation
1765
1766 self.assertEqual(type(prod([1, 2, 3, 4, 5, 6])), int)
1767 self.assertEqual(type(prod([1, 2.0, 3, 4, 5, 6])), float)
1768 self.assertEqual(type(prod(range(1, 10000))), int)
1769 self.assertEqual(type(prod(range(1, 10000), start=1.0)), float)
1770 self.assertEqual(type(prod([1, decimal.Decimal(2.0), 3, 4, 5, 6])),
1771 decimal.Decimal)
1772
Mark Dickinsona0ce3752017-04-05 18:34:27 +01001773 # Custom assertions.
1774
1775 def assertIsNaN(self, value):
1776 if not math.isnan(value):
1777 self.fail("Expected a NaN, got {!r}.".format(value))
1778
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001779
Tal Einatd5519ed2015-05-31 22:05:00 +03001780class IsCloseTests(unittest.TestCase):
Mike53f7a7c2017-12-14 14:04:53 +03001781 isclose = math.isclose # subclasses should override this
Tal Einatd5519ed2015-05-31 22:05:00 +03001782
1783 def assertIsClose(self, a, b, *args, **kwargs):
1784 self.assertTrue(self.isclose(a, b, *args, **kwargs),
1785 msg="%s and %s should be close!" % (a, b))
1786
1787 def assertIsNotClose(self, a, b, *args, **kwargs):
1788 self.assertFalse(self.isclose(a, b, *args, **kwargs),
1789 msg="%s and %s should not be close!" % (a, b))
1790
1791 def assertAllClose(self, examples, *args, **kwargs):
1792 for a, b in examples:
1793 self.assertIsClose(a, b, *args, **kwargs)
1794
1795 def assertAllNotClose(self, examples, *args, **kwargs):
1796 for a, b in examples:
1797 self.assertIsNotClose(a, b, *args, **kwargs)
1798
1799 def test_negative_tolerances(self):
1800 # ValueError should be raised if either tolerance is less than zero
1801 with self.assertRaises(ValueError):
1802 self.assertIsClose(1, 1, rel_tol=-1e-100)
1803 with self.assertRaises(ValueError):
1804 self.assertIsClose(1, 1, rel_tol=1e-100, abs_tol=-1e10)
1805
1806 def test_identical(self):
1807 # identical values must test as close
1808 identical_examples = [(2.0, 2.0),
1809 (0.1e200, 0.1e200),
1810 (1.123e-300, 1.123e-300),
1811 (12345, 12345.0),
1812 (0.0, -0.0),
1813 (345678, 345678)]
1814 self.assertAllClose(identical_examples, rel_tol=0.0, abs_tol=0.0)
1815
1816 def test_eight_decimal_places(self):
1817 # examples that are close to 1e-8, but not 1e-9
1818 eight_decimal_places_examples = [(1e8, 1e8 + 1),
1819 (-1e-8, -1.000000009e-8),
1820 (1.12345678, 1.12345679)]
1821 self.assertAllClose(eight_decimal_places_examples, rel_tol=1e-8)
1822 self.assertAllNotClose(eight_decimal_places_examples, rel_tol=1e-9)
1823
1824 def test_near_zero(self):
1825 # values close to zero
1826 near_zero_examples = [(1e-9, 0.0),
1827 (-1e-9, 0.0),
1828 (-1e-150, 0.0)]
1829 # these should not be close to any rel_tol
1830 self.assertAllNotClose(near_zero_examples, rel_tol=0.9)
1831 # these should be close to abs_tol=1e-8
1832 self.assertAllClose(near_zero_examples, abs_tol=1e-8)
1833
1834 def test_identical_infinite(self):
1835 # these are close regardless of tolerance -- i.e. they are equal
1836 self.assertIsClose(INF, INF)
1837 self.assertIsClose(INF, INF, abs_tol=0.0)
1838 self.assertIsClose(NINF, NINF)
1839 self.assertIsClose(NINF, NINF, abs_tol=0.0)
1840
1841 def test_inf_ninf_nan(self):
1842 # these should never be close (following IEEE 754 rules for equality)
1843 not_close_examples = [(NAN, NAN),
1844 (NAN, 1e-100),
1845 (1e-100, NAN),
1846 (INF, NAN),
1847 (NAN, INF),
1848 (INF, NINF),
1849 (INF, 1.0),
1850 (1.0, INF),
1851 (INF, 1e308),
1852 (1e308, INF)]
1853 # use largest reasonable tolerance
1854 self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999)
1855
1856 def test_zero_tolerance(self):
1857 # test with zero tolerance
1858 zero_tolerance_close_examples = [(1.0, 1.0),
1859 (-3.4, -3.4),
1860 (-1e-300, -1e-300)]
1861 self.assertAllClose(zero_tolerance_close_examples, rel_tol=0.0)
1862
1863 zero_tolerance_not_close_examples = [(1.0, 1.000000000000001),
1864 (0.99999999999999, 1.0),
1865 (1.0e200, .999999999999999e200)]
1866 self.assertAllNotClose(zero_tolerance_not_close_examples, rel_tol=0.0)
1867
Martin Pantereb995702016-07-28 01:11:04 +00001868 def test_asymmetry(self):
1869 # test the asymmetry example from PEP 485
Tal Einatd5519ed2015-05-31 22:05:00 +03001870 self.assertAllClose([(9, 10), (10, 9)], rel_tol=0.1)
1871
1872 def test_integers(self):
1873 # test with integer values
1874 integer_examples = [(100000001, 100000000),
1875 (123456789, 123456788)]
1876
1877 self.assertAllClose(integer_examples, rel_tol=1e-8)
1878 self.assertAllNotClose(integer_examples, rel_tol=1e-9)
1879
1880 def test_decimals(self):
1881 # test with Decimal values
1882 from decimal import Decimal
1883
1884 decimal_examples = [(Decimal('1.00000001'), Decimal('1.0')),
1885 (Decimal('1.00000001e-20'), Decimal('1.0e-20')),
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001886 (Decimal('1.00000001e-100'), Decimal('1.0e-100')),
1887 (Decimal('1.00000001e20'), Decimal('1.0e20'))]
Tal Einatd5519ed2015-05-31 22:05:00 +03001888 self.assertAllClose(decimal_examples, rel_tol=1e-8)
1889 self.assertAllNotClose(decimal_examples, rel_tol=1e-9)
1890
1891 def test_fractions(self):
1892 # test with Fraction values
1893 from fractions import Fraction
1894
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001895 fraction_examples = [
1896 (Fraction(1, 100000000) + 1, Fraction(1)),
1897 (Fraction(100000001), Fraction(100000000)),
1898 (Fraction(10**8 + 1, 10**28), Fraction(1, 10**20))]
Tal Einatd5519ed2015-05-31 22:05:00 +03001899 self.assertAllClose(fraction_examples, rel_tol=1e-8)
1900 self.assertAllNotClose(fraction_examples, rel_tol=1e-9)
1901
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001902 def testPerm(self):
1903 perm = math.perm
1904 factorial = math.factorial
Min ho Kim96e12d52019-07-22 06:12:33 +10001905 # Test if factorial definition is satisfied
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001906 for n in range(100):
1907 for k in range(n + 1):
1908 self.assertEqual(perm(n, k),
1909 factorial(n) // factorial(n - k))
1910
1911 # Test for Pascal's identity
1912 for n in range(1, 100):
1913 for k in range(1, n):
1914 self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k))
1915
1916 # Test corner cases
1917 for n in range(1, 100):
1918 self.assertEqual(perm(n, 0), 1)
1919 self.assertEqual(perm(n, 1), n)
1920 self.assertEqual(perm(n, n), factorial(n))
1921
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001922 # Test one argument form
1923 for n in range(20):
1924 self.assertEqual(perm(n), factorial(n))
1925 self.assertEqual(perm(n, None), factorial(n))
1926
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001927 # Raises TypeError if any argument is non-integer or argument count is
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001928 # not 1 or 2
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001929 self.assertRaises(TypeError, perm, 10, 1.0)
1930 self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
1931 self.assertRaises(TypeError, perm, 10, "1")
1932 self.assertRaises(TypeError, perm, 10.0, 1)
1933 self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
1934 self.assertRaises(TypeError, perm, "10", 1)
1935
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001936 self.assertRaises(TypeError, perm)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001937 self.assertRaises(TypeError, perm, 10, 1, 3)
1938 self.assertRaises(TypeError, perm)
1939
1940 # Raises Value error if not k or n are negative numbers
1941 self.assertRaises(ValueError, perm, -1, 1)
1942 self.assertRaises(ValueError, perm, -2**1000, 1)
1943 self.assertRaises(ValueError, perm, 1, -1)
1944 self.assertRaises(ValueError, perm, 1, -2**1000)
1945
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07001946 # Returns zero if k is greater than n
1947 self.assertEqual(perm(1, 2), 0)
1948 self.assertEqual(perm(1, 2**1000), 0)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001949
1950 n = 2**1000
1951 self.assertEqual(perm(n, 0), 1)
1952 self.assertEqual(perm(n, 1), n)
1953 self.assertEqual(perm(n, 2), n * (n-1))
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +03001954 if support.check_impl_detail(cpython=True):
1955 self.assertRaises(OverflowError, perm, n, n)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001956
1957 for n, k in (True, True), (True, False), (False, False):
1958 self.assertEqual(perm(n, k), 1)
1959 self.assertIs(type(perm(n, k)), int)
1960 self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20)
1961 self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20)
1962 for k in range(3):
1963 self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int)
1964 self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int)
1965
Yash Aggarwal4a686502019-06-01 12:51:27 +05301966 def testComb(self):
1967 comb = math.comb
1968 factorial = math.factorial
Min ho Kim96e12d52019-07-22 06:12:33 +10001969 # Test if factorial definition is satisfied
Yash Aggarwal4a686502019-06-01 12:51:27 +05301970 for n in range(100):
1971 for k in range(n + 1):
1972 self.assertEqual(comb(n, k), factorial(n)
1973 // (factorial(k) * factorial(n - k)))
1974
1975 # Test for Pascal's identity
1976 for n in range(1, 100):
1977 for k in range(1, n):
1978 self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k))
1979
1980 # Test corner cases
1981 for n in range(100):
1982 self.assertEqual(comb(n, 0), 1)
1983 self.assertEqual(comb(n, n), 1)
1984
1985 for n in range(1, 100):
1986 self.assertEqual(comb(n, 1), n)
1987 self.assertEqual(comb(n, n - 1), n)
1988
1989 # Test Symmetry
1990 for n in range(100):
1991 for k in range(n // 2):
1992 self.assertEqual(comb(n, k), comb(n, n - k))
1993
1994 # Raises TypeError if any argument is non-integer or argument count is
1995 # not 2
1996 self.assertRaises(TypeError, comb, 10, 1.0)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001997 self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0))
Yash Aggarwal4a686502019-06-01 12:51:27 +05301998 self.assertRaises(TypeError, comb, 10, "1")
Yash Aggarwal4a686502019-06-01 12:51:27 +05301999 self.assertRaises(TypeError, comb, 10.0, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03002000 self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1)
2001 self.assertRaises(TypeError, comb, "10", 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05302002
2003 self.assertRaises(TypeError, comb, 10)
2004 self.assertRaises(TypeError, comb, 10, 1, 3)
2005 self.assertRaises(TypeError, comb)
2006
2007 # Raises Value error if not k or n are negative numbers
2008 self.assertRaises(ValueError, comb, -1, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03002009 self.assertRaises(ValueError, comb, -2**1000, 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05302010 self.assertRaises(ValueError, comb, 1, -1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03002011 self.assertRaises(ValueError, comb, 1, -2**1000)
Yash Aggarwal4a686502019-06-01 12:51:27 +05302012
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07002013 # Returns zero if k is greater than n
2014 self.assertEqual(comb(1, 2), 0)
2015 self.assertEqual(comb(1, 2**1000), 0)
Yash Aggarwal4a686502019-06-01 12:51:27 +05302016
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03002017 n = 2**1000
2018 self.assertEqual(comb(n, 0), 1)
2019 self.assertEqual(comb(n, 1), n)
2020 self.assertEqual(comb(n, 2), n * (n-1) // 2)
2021 self.assertEqual(comb(n, n), 1)
2022 self.assertEqual(comb(n, n-1), n)
2023 self.assertEqual(comb(n, n-2), n * (n-1) // 2)
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +03002024 if support.check_impl_detail(cpython=True):
2025 self.assertRaises(OverflowError, comb, n, n//2)
Yash Aggarwal4a686502019-06-01 12:51:27 +05302026
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03002027 for n, k in (True, True), (True, False), (False, False):
2028 self.assertEqual(comb(n, k), 1)
2029 self.assertIs(type(comb(n, k)), int)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03002030 self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03002031 self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03002032 for k in range(3):
2033 self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int)
2034 self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int)
Yash Aggarwal4a686502019-06-01 12:51:27 +05302035
Pablo Galindo42079072019-02-10 19:56:58 +00002036
Thomas Wouters89f507f2006-12-13 04:49:30 +00002037def test_main():
Christian Heimes53876d92008-04-19 00:31:39 +00002038 from doctest import DocFileSuite
2039 suite = unittest.TestSuite()
2040 suite.addTest(unittest.makeSuite(MathTests))
Tal Einatd5519ed2015-05-31 22:05:00 +03002041 suite.addTest(unittest.makeSuite(IsCloseTests))
Christian Heimes53876d92008-04-19 00:31:39 +00002042 suite.addTest(DocFileSuite("ieee754.txt"))
2043 run_unittest(suite)
Thomas Wouters89f507f2006-12-13 04:49:30 +00002044
2045if __name__ == '__main__':
2046 test_main()