blob: 3d128749bec40faa8a3b2163df2d1789aa4362f1 [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 Dickinson4c8a9a22010-05-15 17:02:38 +000056# Here's a pure Python version of the math.factorial algorithm, for
57# documentation and comparison purposes.
58#
59# Formula:
60#
61# factorial(n) = factorial_odd_part(n) << (n - count_set_bits(n))
62#
63# where
64#
65# factorial_odd_part(n) = product_{i >= 0} product_{0 < j <= n >> i; j odd} j
66#
67# The outer product above is an infinite product, but once i >= n.bit_length,
68# (n >> i) < 1 and the corresponding term of the product is empty. So only the
69# finitely many terms for 0 <= i < n.bit_length() contribute anything.
70#
71# We iterate downwards from i == n.bit_length() - 1 to i == 0. The inner
72# product in the formula above starts at 1 for i == n.bit_length(); for each i
73# < n.bit_length() we get the inner product for i from that for i + 1 by
74# multiplying by all j in {n >> i+1 < j <= n >> i; j odd}. In Python terms,
75# this set is range((n >> i+1) + 1 | 1, (n >> i) + 1 | 1, 2).
76
77def count_set_bits(n):
78 """Number of '1' bits in binary expansion of a nonnnegative integer."""
79 return 1 + count_set_bits(n & n - 1) if n else 0
80
81def partial_product(start, stop):
82 """Product of integers in range(start, stop, 2), computed recursively.
83 start and stop should both be odd, with start <= stop.
84
85 """
86 numfactors = (stop - start) >> 1
87 if not numfactors:
88 return 1
89 elif numfactors == 1:
90 return start
91 else:
92 mid = (start + numfactors) | 1
93 return partial_product(start, mid) * partial_product(mid, stop)
94
95def py_factorial(n):
96 """Factorial of nonnegative integer n, via "Binary Split Factorial Formula"
97 described at http://www.luschny.de/math/factorial/binarysplitfact.html
98
99 """
100 inner = outer = 1
101 for i in reversed(range(n.bit_length())):
102 inner *= partial_product((n >> i + 1) + 1 | 1, (n >> i) + 1 | 1)
103 outer *= inner
104 return outer << (n - count_set_bits(n))
105
Mark Dickinson96f774d2016-09-03 19:30:22 +0100106def ulp_abs_check(expected, got, ulp_tol, abs_tol):
107 """Given finite floats `expected` and `got`, check that they're
108 approximately equal to within the given number of ulps or the
109 given absolute tolerance, whichever is bigger.
Mark Dickinson05d2e082009-12-11 20:17:17 +0000110
Mark Dickinson96f774d2016-09-03 19:30:22 +0100111 Returns None on success and an error message on failure.
112 """
113 ulp_error = abs(to_ulps(expected) - to_ulps(got))
114 abs_error = abs(expected - got)
115
116 # Succeed if either abs_error <= abs_tol or ulp_error <= ulp_tol.
117 if abs_error <= abs_tol or ulp_error <= ulp_tol:
Mark Dickinson05d2e082009-12-11 20:17:17 +0000118 return None
Mark Dickinson96f774d2016-09-03 19:30:22 +0100119 else:
120 fmt = ("error = {:.3g} ({:d} ulps); "
121 "permitted error = {:.3g} or {:d} ulps")
122 return fmt.format(abs_error, ulp_error, abs_tol, ulp_tol)
Mark Dickinson12c4bdb2009-09-28 19:21:11 +0000123
124def parse_mtestfile(fname):
125 """Parse a file with test values
126
127 -- starts a comment
128 blank lines, or lines containing only a comment, are ignored
129 other lines are expected to have the form
130 id fn arg -> expected [flag]*
131
132 """
Inada Naoki35715d12021-04-04 09:01:23 +0900133 with open(fname, encoding="utf-8") as fp:
Mark Dickinson12c4bdb2009-09-28 19:21:11 +0000134 for line in fp:
135 # strip comments, and skip blank lines
136 if '--' in line:
137 line = line[:line.index('--')]
138 if not line.strip():
139 continue
140
141 lhs, rhs = line.split('->')
142 id, fn, arg = lhs.split()
143 rhs_pieces = rhs.split()
144 exp = rhs_pieces[0]
145 flags = rhs_pieces[1:]
146
147 yield (id, fn, float(arg), float(exp), flags)
148
Mark Dickinson96f774d2016-09-03 19:30:22 +0100149
Christian Heimes53876d92008-04-19 00:31:39 +0000150def parse_testfile(fname):
151 """Parse a file with test values
152
153 Empty lines or lines starting with -- are ignored
154 yields id, fn, arg_real, arg_imag, exp_real, exp_imag
155 """
Inada Naoki35715d12021-04-04 09:01:23 +0900156 with open(fname, encoding="utf-8") as fp:
Christian Heimes53876d92008-04-19 00:31:39 +0000157 for line in fp:
158 # skip comment lines and blank lines
159 if line.startswith('--') or not line.strip():
160 continue
161
162 lhs, rhs = line.split('->')
163 id, fn, arg_real, arg_imag = lhs.split()
164 rhs_pieces = rhs.split()
165 exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1]
166 flags = rhs_pieces[2:]
167
168 yield (id, fn,
169 float(arg_real), float(arg_imag),
170 float(exp_real), float(exp_imag),
Mark Dickinson96f774d2016-09-03 19:30:22 +0100171 flags)
172
173
174def result_check(expected, got, ulp_tol=5, abs_tol=0.0):
175 # Common logic of MathTests.(ftest, test_testcases, test_mtestcases)
176 """Compare arguments expected and got, as floats, if either
177 is a float, using a tolerance expressed in multiples of
178 ulp(expected) or absolutely (if given and greater).
179
180 As a convenience, when neither argument is a float, and for
181 non-finite floats, exact equality is demanded. Also, nan==nan
182 as far as this function is concerned.
183
184 Returns None on success and an error message on failure.
185 """
186
187 # Check exactly equal (applies also to strings representing exceptions)
188 if got == expected:
189 return None
190
191 failure = "not equal"
192
193 # Turn mixed float and int comparison (e.g. floor()) to all-float
194 if isinstance(expected, float) and isinstance(got, int):
195 got = float(got)
196 elif isinstance(got, float) and isinstance(expected, int):
197 expected = float(expected)
198
199 if isinstance(expected, float) and isinstance(got, float):
200 if math.isnan(expected) and math.isnan(got):
201 # Pass, since both nan
202 failure = None
203 elif math.isinf(expected) or math.isinf(got):
204 # We already know they're not equal, drop through to failure
205 pass
206 else:
207 # Both are finite floats (now). Are they close enough?
208 failure = ulp_abs_check(expected, got, ulp_tol, abs_tol)
209
210 # arguments are not equal, and if numeric, are too far apart
211 if failure is not None:
212 fail_fmt = "expected {!r}, got {!r}"
213 fail_msg = fail_fmt.format(expected, got)
214 fail_msg += ' ({})'.format(failure)
215 return fail_msg
216 else:
217 return None
Guido van Rossumfcce6301996-08-08 18:26:25 +0000218
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200219class FloatLike:
220 def __init__(self, value):
221 self.value = value
222
223 def __float__(self):
224 return self.value
225
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +0300226class IntSubclass(int):
227 pass
228
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300229# Class providing an __index__ method.
230class MyIndexable(object):
231 def __init__(self, value):
232 self.value = value
233
234 def __index__(self):
235 return self.value
236
Thomas Wouters89f507f2006-12-13 04:49:30 +0000237class MathTests(unittest.TestCase):
Guido van Rossumfcce6301996-08-08 18:26:25 +0000238
Mark Dickinson96f774d2016-09-03 19:30:22 +0100239 def ftest(self, name, got, expected, ulp_tol=5, abs_tol=0.0):
240 """Compare arguments expected and got, as floats, if either
241 is a float, using a tolerance expressed in multiples of
242 ulp(expected) or absolutely, whichever is greater.
243
244 As a convenience, when neither argument is a float, and for
245 non-finite floats, exact equality is demanded. Also, nan==nan
246 in this function.
247 """
248 failure = result_check(expected, got, ulp_tol, abs_tol)
249 if failure is not None:
250 self.fail("{}: {}".format(name, failure))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000251
Thomas Wouters89f507f2006-12-13 04:49:30 +0000252 def testConstants(self):
Mark Dickinson96f774d2016-09-03 19:30:22 +0100253 # Ref: Abramowitz & Stegun (Dover, 1965)
254 self.ftest('pi', math.pi, 3.141592653589793238462643)
255 self.ftest('e', math.e, 2.718281828459045235360287)
Guido van Rossum0a891d72016-08-15 09:12:52 -0700256 self.assertEqual(math.tau, 2*math.pi)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000257
Thomas Wouters89f507f2006-12-13 04:49:30 +0000258 def testAcos(self):
259 self.assertRaises(TypeError, math.acos)
260 self.ftest('acos(-1)', math.acos(-1), math.pi)
261 self.ftest('acos(0)', math.acos(0), math.pi/2)
262 self.ftest('acos(1)', math.acos(1), 0)
Christian Heimes53876d92008-04-19 00:31:39 +0000263 self.assertRaises(ValueError, math.acos, INF)
264 self.assertRaises(ValueError, math.acos, NINF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100265 self.assertRaises(ValueError, math.acos, 1 + eps)
266 self.assertRaises(ValueError, math.acos, -1 - eps)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000267 self.assertTrue(math.isnan(math.acos(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000268
269 def testAcosh(self):
270 self.assertRaises(TypeError, math.acosh)
271 self.ftest('acosh(1)', math.acosh(1), 0)
272 self.ftest('acosh(2)', math.acosh(2), 1.3169578969248168)
273 self.assertRaises(ValueError, math.acosh, 0)
274 self.assertRaises(ValueError, math.acosh, -1)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000275 self.assertEqual(math.acosh(INF), INF)
Christian Heimes53876d92008-04-19 00:31:39 +0000276 self.assertRaises(ValueError, math.acosh, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000277 self.assertTrue(math.isnan(math.acosh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000278
Thomas Wouters89f507f2006-12-13 04:49:30 +0000279 def testAsin(self):
280 self.assertRaises(TypeError, math.asin)
281 self.ftest('asin(-1)', math.asin(-1), -math.pi/2)
282 self.ftest('asin(0)', math.asin(0), 0)
283 self.ftest('asin(1)', math.asin(1), math.pi/2)
Christian Heimes53876d92008-04-19 00:31:39 +0000284 self.assertRaises(ValueError, math.asin, INF)
285 self.assertRaises(ValueError, math.asin, NINF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100286 self.assertRaises(ValueError, math.asin, 1 + eps)
287 self.assertRaises(ValueError, math.asin, -1 - eps)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000288 self.assertTrue(math.isnan(math.asin(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000289
290 def testAsinh(self):
291 self.assertRaises(TypeError, math.asinh)
292 self.ftest('asinh(0)', math.asinh(0), 0)
293 self.ftest('asinh(1)', math.asinh(1), 0.88137358701954305)
294 self.ftest('asinh(-1)', math.asinh(-1), -0.88137358701954305)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000295 self.assertEqual(math.asinh(INF), INF)
296 self.assertEqual(math.asinh(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000297 self.assertTrue(math.isnan(math.asinh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000298
Thomas Wouters89f507f2006-12-13 04:49:30 +0000299 def testAtan(self):
300 self.assertRaises(TypeError, math.atan)
301 self.ftest('atan(-1)', math.atan(-1), -math.pi/4)
302 self.ftest('atan(0)', math.atan(0), 0)
303 self.ftest('atan(1)', math.atan(1), math.pi/4)
Christian Heimes53876d92008-04-19 00:31:39 +0000304 self.ftest('atan(inf)', math.atan(INF), math.pi/2)
Christian Heimesa342c012008-04-20 21:01:16 +0000305 self.ftest('atan(-inf)', math.atan(NINF), -math.pi/2)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000306 self.assertTrue(math.isnan(math.atan(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000307
308 def testAtanh(self):
309 self.assertRaises(TypeError, math.atan)
310 self.ftest('atanh(0)', math.atanh(0), 0)
311 self.ftest('atanh(0.5)', math.atanh(0.5), 0.54930614433405489)
312 self.ftest('atanh(-0.5)', math.atanh(-0.5), -0.54930614433405489)
313 self.assertRaises(ValueError, math.atanh, 1)
314 self.assertRaises(ValueError, math.atanh, -1)
315 self.assertRaises(ValueError, math.atanh, INF)
316 self.assertRaises(ValueError, math.atanh, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000317 self.assertTrue(math.isnan(math.atanh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000318
Thomas Wouters89f507f2006-12-13 04:49:30 +0000319 def testAtan2(self):
320 self.assertRaises(TypeError, math.atan2)
321 self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
322 self.ftest('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
323 self.ftest('atan2(0, 1)', math.atan2(0, 1), 0)
324 self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
325 self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000326
Christian Heimese57950f2008-04-21 13:08:03 +0000327 # math.atan2(0, x)
328 self.ftest('atan2(0., -inf)', math.atan2(0., NINF), math.pi)
329 self.ftest('atan2(0., -2.3)', math.atan2(0., -2.3), math.pi)
330 self.ftest('atan2(0., -0.)', math.atan2(0., -0.), math.pi)
331 self.assertEqual(math.atan2(0., 0.), 0.)
332 self.assertEqual(math.atan2(0., 2.3), 0.)
333 self.assertEqual(math.atan2(0., INF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000334 self.assertTrue(math.isnan(math.atan2(0., NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000335 # math.atan2(-0, x)
336 self.ftest('atan2(-0., -inf)', math.atan2(-0., NINF), -math.pi)
337 self.ftest('atan2(-0., -2.3)', math.atan2(-0., -2.3), -math.pi)
338 self.ftest('atan2(-0., -0.)', math.atan2(-0., -0.), -math.pi)
339 self.assertEqual(math.atan2(-0., 0.), -0.)
340 self.assertEqual(math.atan2(-0., 2.3), -0.)
341 self.assertEqual(math.atan2(-0., INF), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000342 self.assertTrue(math.isnan(math.atan2(-0., NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000343 # math.atan2(INF, x)
344 self.ftest('atan2(inf, -inf)', math.atan2(INF, NINF), math.pi*3/4)
345 self.ftest('atan2(inf, -2.3)', math.atan2(INF, -2.3), math.pi/2)
346 self.ftest('atan2(inf, -0.)', math.atan2(INF, -0.0), math.pi/2)
347 self.ftest('atan2(inf, 0.)', math.atan2(INF, 0.0), math.pi/2)
348 self.ftest('atan2(inf, 2.3)', math.atan2(INF, 2.3), math.pi/2)
349 self.ftest('atan2(inf, inf)', math.atan2(INF, INF), math.pi/4)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000350 self.assertTrue(math.isnan(math.atan2(INF, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000351 # math.atan2(NINF, x)
352 self.ftest('atan2(-inf, -inf)', math.atan2(NINF, NINF), -math.pi*3/4)
353 self.ftest('atan2(-inf, -2.3)', math.atan2(NINF, -2.3), -math.pi/2)
354 self.ftest('atan2(-inf, -0.)', math.atan2(NINF, -0.0), -math.pi/2)
355 self.ftest('atan2(-inf, 0.)', math.atan2(NINF, 0.0), -math.pi/2)
356 self.ftest('atan2(-inf, 2.3)', math.atan2(NINF, 2.3), -math.pi/2)
357 self.ftest('atan2(-inf, inf)', math.atan2(NINF, INF), -math.pi/4)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000358 self.assertTrue(math.isnan(math.atan2(NINF, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000359 # math.atan2(+finite, x)
360 self.ftest('atan2(2.3, -inf)', math.atan2(2.3, NINF), math.pi)
361 self.ftest('atan2(2.3, -0.)', math.atan2(2.3, -0.), math.pi/2)
362 self.ftest('atan2(2.3, 0.)', math.atan2(2.3, 0.), math.pi/2)
363 self.assertEqual(math.atan2(2.3, INF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000364 self.assertTrue(math.isnan(math.atan2(2.3, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000365 # math.atan2(-finite, x)
366 self.ftest('atan2(-2.3, -inf)', math.atan2(-2.3, NINF), -math.pi)
367 self.ftest('atan2(-2.3, -0.)', math.atan2(-2.3, -0.), -math.pi/2)
368 self.ftest('atan2(-2.3, 0.)', math.atan2(-2.3, 0.), -math.pi/2)
369 self.assertEqual(math.atan2(-2.3, INF), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000370 self.assertTrue(math.isnan(math.atan2(-2.3, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000371 # math.atan2(NAN, x)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000372 self.assertTrue(math.isnan(math.atan2(NAN, NINF)))
373 self.assertTrue(math.isnan(math.atan2(NAN, -2.3)))
374 self.assertTrue(math.isnan(math.atan2(NAN, -0.)))
375 self.assertTrue(math.isnan(math.atan2(NAN, 0.)))
376 self.assertTrue(math.isnan(math.atan2(NAN, 2.3)))
377 self.assertTrue(math.isnan(math.atan2(NAN, INF)))
378 self.assertTrue(math.isnan(math.atan2(NAN, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000379
Thomas Wouters89f507f2006-12-13 04:49:30 +0000380 def testCeil(self):
381 self.assertRaises(TypeError, math.ceil)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000382 self.assertEqual(int, type(math.ceil(0.5)))
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200383 self.assertEqual(math.ceil(0.5), 1)
384 self.assertEqual(math.ceil(1.0), 1)
385 self.assertEqual(math.ceil(1.5), 2)
386 self.assertEqual(math.ceil(-0.5), 0)
387 self.assertEqual(math.ceil(-1.0), -1)
388 self.assertEqual(math.ceil(-1.5), -1)
389 self.assertEqual(math.ceil(0.0), 0)
390 self.assertEqual(math.ceil(-0.0), 0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000391 #self.assertEqual(math.ceil(INF), INF)
392 #self.assertEqual(math.ceil(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000393 #self.assertTrue(math.isnan(math.ceil(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000394
Guido van Rossum13e05de2007-08-23 22:56:55 +0000395 class TestCeil:
396 def __ceil__(self):
397 return 42
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200398 class FloatCeil(float):
399 def __ceil__(self):
400 return 42
Guido van Rossum13e05de2007-08-23 22:56:55 +0000401 class TestNoCeil:
402 pass
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200403 self.assertEqual(math.ceil(TestCeil()), 42)
404 self.assertEqual(math.ceil(FloatCeil()), 42)
405 self.assertEqual(math.ceil(FloatLike(42.5)), 43)
Guido van Rossum13e05de2007-08-23 22:56:55 +0000406 self.assertRaises(TypeError, math.ceil, TestNoCeil())
407
408 t = TestNoCeil()
409 t.__ceil__ = lambda *args: args
410 self.assertRaises(TypeError, math.ceil, t)
411 self.assertRaises(TypeError, math.ceil, t, 0)
412
Mark Dickinson63566232009-09-18 21:04:19 +0000413 @requires_IEEE_754
414 def testCopysign(self):
Mark Dickinson06b59e02010-02-06 23:16:50 +0000415 self.assertEqual(math.copysign(1, 42), 1.0)
416 self.assertEqual(math.copysign(0., 42), 0.0)
417 self.assertEqual(math.copysign(1., -42), -1.0)
418 self.assertEqual(math.copysign(3, 0.), 3.0)
419 self.assertEqual(math.copysign(4., -0.), -4.0)
420
Mark Dickinson63566232009-09-18 21:04:19 +0000421 self.assertRaises(TypeError, math.copysign)
422 # copysign should let us distinguish signs of zeros
Ezio Melottib3aedd42010-11-20 19:04:17 +0000423 self.assertEqual(math.copysign(1., 0.), 1.)
424 self.assertEqual(math.copysign(1., -0.), -1.)
425 self.assertEqual(math.copysign(INF, 0.), INF)
426 self.assertEqual(math.copysign(INF, -0.), NINF)
427 self.assertEqual(math.copysign(NINF, 0.), INF)
428 self.assertEqual(math.copysign(NINF, -0.), NINF)
Mark Dickinson63566232009-09-18 21:04:19 +0000429 # and of infinities
Ezio Melottib3aedd42010-11-20 19:04:17 +0000430 self.assertEqual(math.copysign(1., INF), 1.)
431 self.assertEqual(math.copysign(1., NINF), -1.)
432 self.assertEqual(math.copysign(INF, INF), INF)
433 self.assertEqual(math.copysign(INF, NINF), NINF)
434 self.assertEqual(math.copysign(NINF, INF), INF)
435 self.assertEqual(math.copysign(NINF, NINF), NINF)
Mark Dickinson06b59e02010-02-06 23:16:50 +0000436 self.assertTrue(math.isnan(math.copysign(NAN, 1.)))
437 self.assertTrue(math.isnan(math.copysign(NAN, INF)))
438 self.assertTrue(math.isnan(math.copysign(NAN, NINF)))
439 self.assertTrue(math.isnan(math.copysign(NAN, NAN)))
Mark Dickinson63566232009-09-18 21:04:19 +0000440 # copysign(INF, NAN) may be INF or it may be NINF, since
441 # we don't know whether the sign bit of NAN is set on any
442 # given platform.
Mark Dickinson06b59e02010-02-06 23:16:50 +0000443 self.assertTrue(math.isinf(math.copysign(INF, NAN)))
Mark Dickinson63566232009-09-18 21:04:19 +0000444 # similarly, copysign(2., NAN) could be 2. or -2.
Ezio Melottib3aedd42010-11-20 19:04:17 +0000445 self.assertEqual(abs(math.copysign(2., NAN)), 2.)
Christian Heimes53876d92008-04-19 00:31:39 +0000446
Thomas Wouters89f507f2006-12-13 04:49:30 +0000447 def testCos(self):
448 self.assertRaises(TypeError, math.cos)
Victor Stinner0b2ab212020-01-13 12:44:35 +0100449 self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0, abs_tol=math.ulp(1))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000450 self.ftest('cos(0)', math.cos(0), 1)
Victor Stinner0b2ab212020-01-13 12:44:35 +0100451 self.ftest('cos(pi/2)', math.cos(math.pi/2), 0, abs_tol=math.ulp(1))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000452 self.ftest('cos(pi)', math.cos(math.pi), -1)
Christian Heimes53876d92008-04-19 00:31:39 +0000453 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000454 self.assertTrue(math.isnan(math.cos(INF)))
455 self.assertTrue(math.isnan(math.cos(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +0000456 except ValueError:
457 self.assertRaises(ValueError, math.cos, INF)
458 self.assertRaises(ValueError, math.cos, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000459 self.assertTrue(math.isnan(math.cos(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000460
Paul Monsonf3550692019-06-19 13:09:54 -0700461 @unittest.skipIf(sys.platform == 'win32' and platform.machine() in ('ARM', 'ARM64'),
462 "Windows UCRT is off by 2 ULP this test requires accuracy within 1 ULP")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000463 def testCosh(self):
464 self.assertRaises(TypeError, math.cosh)
465 self.ftest('cosh(0)', math.cosh(0), 1)
466 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 +0000467 self.assertEqual(math.cosh(INF), INF)
468 self.assertEqual(math.cosh(NINF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000469 self.assertTrue(math.isnan(math.cosh(NAN)))
Raymond Hettinger64108af2002-05-13 03:55:01 +0000470
Thomas Wouters89f507f2006-12-13 04:49:30 +0000471 def testDegrees(self):
472 self.assertRaises(TypeError, math.degrees)
473 self.ftest('degrees(pi)', math.degrees(math.pi), 180.0)
474 self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
475 self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100476 self.ftest('degrees(0)', math.degrees(0), 0)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000477
Thomas Wouters89f507f2006-12-13 04:49:30 +0000478 def testExp(self):
479 self.assertRaises(TypeError, math.exp)
480 self.ftest('exp(-1)', math.exp(-1), 1/math.e)
481 self.ftest('exp(0)', math.exp(0), 1)
482 self.ftest('exp(1)', math.exp(1), math.e)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000483 self.assertEqual(math.exp(INF), INF)
484 self.assertEqual(math.exp(NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000485 self.assertTrue(math.isnan(math.exp(NAN)))
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100486 self.assertRaises(OverflowError, math.exp, 1000000)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000487
Thomas Wouters89f507f2006-12-13 04:49:30 +0000488 def testFabs(self):
489 self.assertRaises(TypeError, math.fabs)
490 self.ftest('fabs(-1)', math.fabs(-1), 1)
491 self.ftest('fabs(0)', math.fabs(0), 0)
492 self.ftest('fabs(1)', math.fabs(1), 1)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000493
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000494 def testFactorial(self):
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000495 self.assertEqual(math.factorial(0), 1)
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000496 total = 1
497 for i in range(1, 1000):
498 total *= i
499 self.assertEqual(math.factorial(i), total)
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000500 self.assertEqual(math.factorial(i), py_factorial(i))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000501 self.assertRaises(ValueError, math.factorial, -1)
Mark Dickinson5990d282014-04-10 09:29:39 -0400502 self.assertRaises(ValueError, math.factorial, -10**100)
Mark Dickinson5990d282014-04-10 09:29:39 -0400503
Pablo Galindoe9ba3702018-09-03 22:20:06 +0100504 def testFactorialNonIntegers(self):
Serhiy Storchaka578c3952020-05-26 18:43:38 +0300505 self.assertRaises(TypeError, math.factorial, 5.0)
506 self.assertRaises(TypeError, math.factorial, 5.2)
507 self.assertRaises(TypeError, math.factorial, -1.0)
508 self.assertRaises(TypeError, math.factorial, -1e100)
Serhiy Storchaka231aad32019-06-17 16:57:27 +0300509 self.assertRaises(TypeError, math.factorial, decimal.Decimal('5'))
510 self.assertRaises(TypeError, math.factorial, decimal.Decimal('5.2'))
Pablo Galindoe9ba3702018-09-03 22:20:06 +0100511 self.assertRaises(TypeError, math.factorial, "5")
512
Mark Dickinson5990d282014-04-10 09:29:39 -0400513 # Other implementations may place different upper bounds.
514 @support.cpython_only
515 def testFactorialHugeInputs(self):
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +0300516 # Currently raises OverflowError for inputs that are too large
Mark Dickinson5990d282014-04-10 09:29:39 -0400517 # to fit into a C long.
518 self.assertRaises(OverflowError, math.factorial, 10**100)
Serhiy Storchaka578c3952020-05-26 18:43:38 +0300519 self.assertRaises(TypeError, math.factorial, 1e100)
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000520
Thomas Wouters89f507f2006-12-13 04:49:30 +0000521 def testFloor(self):
522 self.assertRaises(TypeError, math.floor)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000523 self.assertEqual(int, type(math.floor(0.5)))
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200524 self.assertEqual(math.floor(0.5), 0)
525 self.assertEqual(math.floor(1.0), 1)
526 self.assertEqual(math.floor(1.5), 1)
527 self.assertEqual(math.floor(-0.5), -1)
528 self.assertEqual(math.floor(-1.0), -1)
529 self.assertEqual(math.floor(-1.5), -2)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000530 #self.assertEqual(math.ceil(INF), INF)
531 #self.assertEqual(math.ceil(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000532 #self.assertTrue(math.isnan(math.floor(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000533
Guido van Rossum13e05de2007-08-23 22:56:55 +0000534 class TestFloor:
535 def __floor__(self):
536 return 42
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200537 class FloatFloor(float):
538 def __floor__(self):
539 return 42
Guido van Rossum13e05de2007-08-23 22:56:55 +0000540 class TestNoFloor:
541 pass
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200542 self.assertEqual(math.floor(TestFloor()), 42)
543 self.assertEqual(math.floor(FloatFloor()), 42)
544 self.assertEqual(math.floor(FloatLike(41.9)), 41)
Guido van Rossum13e05de2007-08-23 22:56:55 +0000545 self.assertRaises(TypeError, math.floor, TestNoFloor())
546
547 t = TestNoFloor()
548 t.__floor__ = lambda *args: args
549 self.assertRaises(TypeError, math.floor, t)
550 self.assertRaises(TypeError, math.floor, t, 0)
551
Thomas Wouters89f507f2006-12-13 04:49:30 +0000552 def testFmod(self):
553 self.assertRaises(TypeError, math.fmod)
Mark Dickinson5bc7a442011-05-03 21:13:40 +0100554 self.ftest('fmod(10, 1)', math.fmod(10, 1), 0.0)
555 self.ftest('fmod(10, 0.5)', math.fmod(10, 0.5), 0.0)
556 self.ftest('fmod(10, 1.5)', math.fmod(10, 1.5), 1.0)
557 self.ftest('fmod(-10, 1)', math.fmod(-10, 1), -0.0)
558 self.ftest('fmod(-10, 0.5)', math.fmod(-10, 0.5), -0.0)
559 self.ftest('fmod(-10, 1.5)', math.fmod(-10, 1.5), -1.0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000560 self.assertTrue(math.isnan(math.fmod(NAN, 1.)))
561 self.assertTrue(math.isnan(math.fmod(1., NAN)))
562 self.assertTrue(math.isnan(math.fmod(NAN, NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000563 self.assertRaises(ValueError, math.fmod, 1., 0.)
564 self.assertRaises(ValueError, math.fmod, INF, 1.)
565 self.assertRaises(ValueError, math.fmod, NINF, 1.)
566 self.assertRaises(ValueError, math.fmod, INF, 0.)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000567 self.assertEqual(math.fmod(3.0, INF), 3.0)
568 self.assertEqual(math.fmod(-3.0, INF), -3.0)
569 self.assertEqual(math.fmod(3.0, NINF), 3.0)
570 self.assertEqual(math.fmod(-3.0, NINF), -3.0)
571 self.assertEqual(math.fmod(0.0, 3.0), 0.0)
572 self.assertEqual(math.fmod(0.0, NINF), 0.0)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000573
Thomas Wouters89f507f2006-12-13 04:49:30 +0000574 def testFrexp(self):
575 self.assertRaises(TypeError, math.frexp)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000576
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000577 def testfrexp(name, result, expected):
578 (mant, exp), (emant, eexp) = result, expected
Thomas Wouters89f507f2006-12-13 04:49:30 +0000579 if abs(mant-emant) > eps or exp != eexp:
580 self.fail('%s returned %r, expected %r'%\
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000581 (name, result, expected))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000582
Thomas Wouters89f507f2006-12-13 04:49:30 +0000583 testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
584 testfrexp('frexp(0)', math.frexp(0), (0, 0))
585 testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
586 testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000587
Ezio Melottib3aedd42010-11-20 19:04:17 +0000588 self.assertEqual(math.frexp(INF)[0], INF)
589 self.assertEqual(math.frexp(NINF)[0], NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000590 self.assertTrue(math.isnan(math.frexp(NAN)[0]))
Christian Heimes53876d92008-04-19 00:31:39 +0000591
Mark Dickinson63566232009-09-18 21:04:19 +0000592 @requires_IEEE_754
Mark Dickinson5c567082009-04-24 16:39:07 +0000593 @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
594 "fsum is not exact on machines with double rounding")
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000595 def testFsum(self):
596 # math.fsum relies on exact rounding for correct operation.
597 # There's a known problem with IA32 floating-point that causes
598 # inexact rounding in some situations, and will cause the
599 # math.fsum tests below to fail; see issue #2937. On non IEEE
600 # 754 platforms, and on IEEE 754 platforms that exhibit the
601 # problem described in issue #2937, we simply skip the whole
602 # test.
603
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000604 # Python version of math.fsum, for comparison. Uses a
605 # different algorithm based on frexp, ldexp and integer
606 # arithmetic.
607 from sys import float_info
608 mant_dig = float_info.mant_dig
609 etiny = float_info.min_exp - mant_dig
610
611 def msum(iterable):
612 """Full precision summation. Compute sum(iterable) without any
613 intermediate accumulation of error. Based on the 'lsum' function
Andre Delfinoe8a20762020-09-26 21:47:25 -0300614 at http://code.activestate.com/recipes/393090/
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000615
616 """
617 tmant, texp = 0, 0
618 for x in iterable:
619 mant, exp = math.frexp(x)
620 mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig
621 if texp > exp:
622 tmant <<= texp-exp
623 texp = exp
624 else:
625 mant <<= exp-texp
626 tmant += mant
627 # Round tmant * 2**texp to a float. The original recipe
628 # used float(str(tmant)) * 2.0**texp for this, but that's
629 # a little unsafe because str -> float conversion can't be
630 # relied upon to do correct rounding on all platforms.
631 tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp)
632 if tail > 0:
633 h = 1 << (tail-1)
634 tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1)
635 texp += tail
636 return math.ldexp(tmant, texp)
637
638 test_values = [
639 ([], 0.0),
640 ([0.0], 0.0),
641 ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
642 ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
643 ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
644 ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
645 ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
646 ([1./n for n in range(1, 1001)],
647 float.fromhex('0x1.df11f45f4e61ap+2')),
648 ([(-1.)**n/n for n in range(1, 1001)],
649 float.fromhex('-0x1.62a2af1bd3624p-1')),
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000650 ([1e16, 1., 1e-16], 10000000000000002.0),
651 ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
652 # exercise code for resizing partials array
653 ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] +
654 [-2.**1022],
655 float.fromhex('0x1.5555555555555p+970')),
656 ]
657
Mark Dickinsonbba873e2019-12-09 08:36:34 -0600658 # Telescoping sum, with exact differences (due to Sterbenz)
659 terms = [1.7**i for i in range(1001)]
660 test_values.append((
661 [terms[i+1] - terms[i] for i in range(1000)] + [-terms[1000]],
662 -terms[0]
663 ))
664
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000665 for i, (vals, expected) in enumerate(test_values):
666 try:
667 actual = math.fsum(vals)
668 except OverflowError:
669 self.fail("test %d failed: got OverflowError, expected %r "
670 "for math.fsum(%.100r)" % (i, expected, vals))
671 except ValueError:
672 self.fail("test %d failed: got ValueError, expected %r "
673 "for math.fsum(%.100r)" % (i, expected, vals))
674 self.assertEqual(actual, expected)
675
676 from random import random, gauss, shuffle
677 for j in range(1000):
678 vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
679 s = 0
680 for i in range(200):
681 v = gauss(0, random()) ** 7 - s
682 s += v
683 vals.append(v)
684 shuffle(vals)
685
686 s = msum(vals)
687 self.assertEqual(msum(vals), math.fsum(vals))
688
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300689 def testGcd(self):
690 gcd = math.gcd
691 self.assertEqual(gcd(0, 0), 0)
692 self.assertEqual(gcd(1, 0), 1)
693 self.assertEqual(gcd(-1, 0), 1)
694 self.assertEqual(gcd(0, 1), 1)
695 self.assertEqual(gcd(0, -1), 1)
696 self.assertEqual(gcd(7, 1), 1)
697 self.assertEqual(gcd(7, -1), 1)
698 self.assertEqual(gcd(-23, 15), 1)
699 self.assertEqual(gcd(120, 84), 12)
700 self.assertEqual(gcd(84, -120), 12)
701 self.assertEqual(gcd(1216342683557601535506311712,
702 436522681849110124616458784), 32)
Serhiy Storchaka559e7f12020-02-23 13:21:29 +0200703
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300704 x = 434610456570399902378880679233098819019853229470286994367836600566
705 y = 1064502245825115327754847244914921553977
Serhiy Storchaka559e7f12020-02-23 13:21:29 +0200706 for c in (652560,
707 576559230871654959816130551884856912003141446781646602790216406874):
708 a = x * c
709 b = y * c
710 self.assertEqual(gcd(a, b), c)
711 self.assertEqual(gcd(b, a), c)
712 self.assertEqual(gcd(-a, b), c)
713 self.assertEqual(gcd(b, -a), c)
714 self.assertEqual(gcd(a, -b), c)
715 self.assertEqual(gcd(-b, a), c)
716 self.assertEqual(gcd(-a, -b), c)
717 self.assertEqual(gcd(-b, -a), c)
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300718
Serhiy Storchaka559e7f12020-02-23 13:21:29 +0200719 self.assertEqual(gcd(), 0)
720 self.assertEqual(gcd(120), 120)
721 self.assertEqual(gcd(-120), 120)
722 self.assertEqual(gcd(120, 84, 102), 6)
723 self.assertEqual(gcd(120, 1, 84), 1)
724
725 self.assertRaises(TypeError, gcd, 120.0)
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300726 self.assertRaises(TypeError, gcd, 120.0, 84)
727 self.assertRaises(TypeError, gcd, 120, 84.0)
Serhiy Storchaka559e7f12020-02-23 13:21:29 +0200728 self.assertRaises(TypeError, gcd, 120, 1, 84.0)
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300729 self.assertEqual(gcd(MyIndexable(120), MyIndexable(84)), 12)
730
Thomas Wouters89f507f2006-12-13 04:49:30 +0000731 def testHypot(self):
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700732 from decimal import Decimal
733 from fractions import Fraction
734
735 hypot = math.hypot
736
737 # Test different numbers of arguments (from zero to five)
738 # against a straightforward pure python implementation
739 args = math.e, math.pi, math.sqrt(2.0), math.gamma(3.5), math.sin(2.1)
740 for i in range(len(args)+1):
741 self.assertAlmostEqual(
742 hypot(*args[:i]),
743 math.sqrt(sum(s**2 for s in args[:i]))
744 )
745
746 # Test allowable types (those with __float__)
747 self.assertEqual(hypot(12.0, 5.0), 13.0)
748 self.assertEqual(hypot(12, 5), 13)
749 self.assertEqual(hypot(Decimal(12), Decimal(5)), 13)
750 self.assertEqual(hypot(Fraction(12, 32), Fraction(5, 32)), Fraction(13, 32))
751 self.assertEqual(hypot(bool(1), bool(0), bool(1), bool(1)), math.sqrt(3))
752
753 # Test corner cases
754 self.assertEqual(hypot(0.0, 0.0), 0.0) # Max input is zero
755 self.assertEqual(hypot(-10.5), 10.5) # Negative input
756 self.assertEqual(hypot(), 0.0) # Negative input
757 self.assertEqual(1.0,
758 math.copysign(1.0, hypot(-0.0)) # Convert negative zero to positive zero
759 )
Raymond Hettinger00414592018-08-12 12:15:23 -0700760 self.assertEqual( # Handling of moving max to the end
761 hypot(1.5, 1.5, 0.5),
762 hypot(1.5, 0.5, 1.5),
763 )
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700764
765 # Test handling of bad arguments
766 with self.assertRaises(TypeError): # Reject keyword args
767 hypot(x=1)
768 with self.assertRaises(TypeError): # Reject values without __float__
769 hypot(1.1, 'string', 2.2)
Raymond Hettinger808180c2019-01-28 13:59:56 -0800770 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
771 with self.assertRaises((ValueError, OverflowError)):
772 hypot(1, int_too_big_for_float)
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700773
774 # Any infinity gives positive infinity.
775 self.assertEqual(hypot(INF), INF)
776 self.assertEqual(hypot(0, INF), INF)
777 self.assertEqual(hypot(10, INF), INF)
778 self.assertEqual(hypot(-10, INF), INF)
779 self.assertEqual(hypot(NAN, INF), INF)
780 self.assertEqual(hypot(INF, NAN), INF)
781 self.assertEqual(hypot(NINF, NAN), INF)
782 self.assertEqual(hypot(NAN, NINF), INF)
783 self.assertEqual(hypot(-INF, INF), INF)
784 self.assertEqual(hypot(-INF, -INF), INF)
785 self.assertEqual(hypot(10, -INF), INF)
786
Raymond Hettinger00414592018-08-12 12:15:23 -0700787 # If no infinity, any NaN gives a NaN.
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700788 self.assertTrue(math.isnan(hypot(NAN)))
789 self.assertTrue(math.isnan(hypot(0, NAN)))
790 self.assertTrue(math.isnan(hypot(NAN, 10)))
791 self.assertTrue(math.isnan(hypot(10, NAN)))
792 self.assertTrue(math.isnan(hypot(NAN, NAN)))
793 self.assertTrue(math.isnan(hypot(NAN)))
794
795 # Verify scaling for extremely large values
796 fourthmax = FLOAT_MAX / 4.0
797 for n in range(32):
Raymond Hettingerfff3c282020-08-15 19:38:19 -0700798 self.assertTrue(math.isclose(hypot(*([fourthmax]*n)),
799 fourthmax * math.sqrt(n)))
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700800
801 # Verify scaling for extremely small values
802 for exp in range(32):
803 scale = FLOAT_MIN / 2.0 ** exp
804 self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000805
Raymond Hettingerbc6b7fa2020-09-20 21:47:56 -0700806 @requires_IEEE_754
807 @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
808 "hypot() loses accuracy on machines with double rounding")
809 def testHypotAccuracy(self):
810 # Verify improved accuracy in cases that were known to be inaccurate.
811 #
812 # The new algorithm's accuracy depends on IEEE 754 arithmetic
813 # guarantees, on having the usual ROUND HALF EVEN rounding mode, on
814 # the system not having double rounding due to extended precision,
815 # and on the compiler maintaining the specified order of operations.
816 #
817 # This test is known to succeed on most of our builds. If it fails
818 # some build, we either need to add another skipIf if the cause is
819 # identifiable; otherwise, we can remove this test entirely.
820
821 hypot = math.hypot
822 Decimal = decimal.Decimal
823 high_precision = decimal.Context(prec=500)
824
825 for hx, hy in [
826 # Cases with a 1 ulp error in Python 3.7 compiled with Clang
827 ('0x1.10e89518dca48p+29', '0x1.1970f7565b7efp+30'),
828 ('0x1.10106eb4b44a2p+29', '0x1.ef0596cdc97f8p+29'),
829 ('0x1.459c058e20bb7p+30', '0x1.993ca009b9178p+29'),
830 ('0x1.378371ae67c0cp+30', '0x1.fbe6619854b4cp+29'),
831 ('0x1.f4cd0574fb97ap+29', '0x1.50fe31669340ep+30'),
832 ('0x1.494b2cdd3d446p+29', '0x1.212a5367b4c7cp+29'),
833 ('0x1.f84e649f1e46dp+29', '0x1.1fa56bef8eec4p+30'),
834 ('0x1.2e817edd3d6fap+30', '0x1.eb0814f1e9602p+29'),
835 ('0x1.0d3a6e3d04245p+29', '0x1.32a62fea52352p+30'),
836 ('0x1.888e19611bfc5p+29', '0x1.52b8e70b24353p+29'),
837
838 # Cases with 2 ulp error in Python 3.8
839 ('0x1.538816d48a13fp+29', '0x1.7967c5ca43e16p+29'),
840 ('0x1.57b47b7234530p+29', '0x1.74e2c7040e772p+29'),
841 ('0x1.821b685e9b168p+30', '0x1.677dc1c1e3dc6p+29'),
842 ('0x1.9e8247f67097bp+29', '0x1.24bd2dc4f4baep+29'),
843 ('0x1.b73b59e0cb5f9p+29', '0x1.da899ab784a97p+28'),
844 ('0x1.94a8d2842a7cfp+30', '0x1.326a51d4d8d8ap+30'),
845 ('0x1.e930b9cd99035p+29', '0x1.5a1030e18dff9p+30'),
846 ('0x1.1592bbb0e4690p+29', '0x1.a9c337b33fb9ap+29'),
847 ('0x1.1243a50751fd4p+29', '0x1.a5a10175622d9p+29'),
848 ('0x1.57a8596e74722p+30', '0x1.42d1af9d04da9p+30'),
849
850 # Cases with 1 ulp error in version fff3c28052e6b0
851 ('0x1.ee7dbd9565899p+29', '0x1.7ab4d6fc6e4b4p+29'),
852 ('0x1.5c6bfbec5c4dcp+30', '0x1.02511184b4970p+30'),
853 ('0x1.59dcebba995cap+30', '0x1.50ca7e7c38854p+29'),
854 ('0x1.768cdd94cf5aap+29', '0x1.9cfdc5571d38ep+29'),
855 ('0x1.dcf137d60262ep+29', '0x1.1101621990b3ep+30'),
856 ('0x1.3a2d006e288b0p+30', '0x1.e9a240914326cp+29'),
857 ('0x1.62a32f7f53c61p+29', '0x1.47eb6cd72684fp+29'),
858 ('0x1.d3bcb60748ef2p+29', '0x1.3f13c4056312cp+30'),
859 ('0x1.282bdb82f17f3p+30', '0x1.640ba4c4eed3ap+30'),
860 ('0x1.89d8c423ea0c6p+29', '0x1.d35dcfe902bc3p+29'),
861 ]:
862 x = float.fromhex(hx)
863 y = float.fromhex(hy)
864 with self.subTest(hx=hx, hy=hy, x=x, y=y):
865 with decimal.localcontext(high_precision):
866 z = float((Decimal(x)**2 + Decimal(y)**2).sqrt())
867 self.assertEqual(hypot(x, y), z)
868
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700869 def testDist(self):
870 from decimal import Decimal as D
871 from fractions import Fraction as F
872
873 dist = math.dist
874 sqrt = math.sqrt
875
Raymond Hettinger808180c2019-01-28 13:59:56 -0800876 # Simple exact cases
877 self.assertEqual(dist((1.0, 2.0, 3.0), (4.0, 2.0, -1.0)), 5.0)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700878 self.assertEqual(dist((1, 2, 3), (4, 2, -1)), 5.0)
879
880 # Test different numbers of arguments (from zero to nine)
881 # against a straightforward pure python implementation
882 for i in range(9):
883 for j in range(5):
884 p = tuple(random.uniform(-5, 5) for k in range(i))
885 q = tuple(random.uniform(-5, 5) for k in range(i))
886 self.assertAlmostEqual(
887 dist(p, q),
888 sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
889 )
890
Raymond Hettinger6b5f1b42019-07-27 14:04:29 -0700891 # Test non-tuple inputs
892 self.assertEqual(dist([1.0, 2.0, 3.0], [4.0, 2.0, -1.0]), 5.0)
893 self.assertEqual(dist(iter([1.0, 2.0, 3.0]), iter([4.0, 2.0, -1.0])), 5.0)
894
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700895 # Test allowable types (those with __float__)
896 self.assertEqual(dist((14.0, 1.0), (2.0, -4.0)), 13.0)
897 self.assertEqual(dist((14, 1), (2, -4)), 13)
898 self.assertEqual(dist((D(14), D(1)), (D(2), D(-4))), D(13))
899 self.assertEqual(dist((F(14, 32), F(1, 32)), (F(2, 32), F(-4, 32))),
900 F(13, 32))
901 self.assertEqual(dist((True, True, False, True, False),
902 (True, False, True, True, False)),
903 sqrt(2.0))
904
905 # Test corner cases
906 self.assertEqual(dist((13.25, 12.5, -3.25),
907 (13.25, 12.5, -3.25)),
908 0.0) # Distance with self is zero
909 self.assertEqual(dist((), ()), 0.0) # Zero-dimensional case
910 self.assertEqual(1.0, # Convert negative zero to positive zero
911 math.copysign(1.0, dist((-0.0,), (0.0,)))
912 )
913 self.assertEqual(1.0, # Convert negative zero to positive zero
914 math.copysign(1.0, dist((0.0,), (-0.0,)))
915 )
Raymond Hettinger00414592018-08-12 12:15:23 -0700916 self.assertEqual( # Handling of moving max to the end
917 dist((1.5, 1.5, 0.5), (0, 0, 0)),
918 dist((1.5, 0.5, 1.5), (0, 0, 0))
919 )
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700920
921 # Verify tuple subclasses are allowed
Raymond Hettinger00414592018-08-12 12:15:23 -0700922 class T(tuple):
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700923 pass
924 self.assertEqual(dist(T((1, 2, 3)), ((4, 2, -1))), 5.0)
925
926 # Test handling of bad arguments
927 with self.assertRaises(TypeError): # Reject keyword args
928 dist(p=(1, 2, 3), q=(4, 5, 6))
929 with self.assertRaises(TypeError): # Too few args
930 dist((1, 2, 3))
931 with self.assertRaises(TypeError): # Too many args
932 dist((1, 2, 3), (4, 5, 6), (7, 8, 9))
933 with self.assertRaises(TypeError): # Scalars not allowed
934 dist(1, 2)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700935 with self.assertRaises(TypeError): # Reject values without __float__
936 dist((1.1, 'string', 2.2), (1, 2, 3))
937 with self.assertRaises(ValueError): # Check dimension agree
938 dist((1, 2, 3, 4), (5, 6, 7))
939 with self.assertRaises(ValueError): # Check dimension agree
940 dist((1, 2, 3), (4, 5, 6, 7))
Ammar Askarcb08a712019-01-12 01:23:41 -0500941 with self.assertRaises(TypeError): # Rejects invalid types
942 dist("abc", "xyz")
Raymond Hettinger808180c2019-01-28 13:59:56 -0800943 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
944 with self.assertRaises((ValueError, OverflowError)):
945 dist((1, int_too_big_for_float), (2, 3))
946 with self.assertRaises((ValueError, OverflowError)):
947 dist((2, 3), (1, int_too_big_for_float))
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700948
Raymond Hettinger00414592018-08-12 12:15:23 -0700949 # Verify that the one dimensional case is equivalent to abs()
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700950 for i in range(20):
951 p, q = random.random(), random.random()
952 self.assertEqual(dist((p,), (q,)), abs(p - q))
953
954 # Test special values
955 values = [NINF, -10.5, -0.0, 0.0, 10.5, INF, NAN]
956 for p in itertools.product(values, repeat=3):
957 for q in itertools.product(values, repeat=3):
958 diffs = [px - qx for px, qx in zip(p, q)]
959 if any(map(math.isinf, diffs)):
960 # Any infinite difference gives positive infinity.
961 self.assertEqual(dist(p, q), INF)
962 elif any(map(math.isnan, diffs)):
Raymond Hettinger00414592018-08-12 12:15:23 -0700963 # If no infinity, any NaN gives a NaN.
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700964 self.assertTrue(math.isnan(dist(p, q)))
965
966 # Verify scaling for extremely large values
967 fourthmax = FLOAT_MAX / 4.0
968 for n in range(32):
969 p = (fourthmax,) * n
970 q = (0.0,) * n
Raymond Hettingerfff3c282020-08-15 19:38:19 -0700971 self.assertTrue(math.isclose(dist(p, q), fourthmax * math.sqrt(n)))
972 self.assertTrue(math.isclose(dist(q, p), fourthmax * math.sqrt(n)))
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700973
974 # Verify scaling for extremely small values
975 for exp in range(32):
976 scale = FLOAT_MIN / 2.0 ** exp
977 p = (4*scale, 3*scale)
978 q = (0.0, 0.0)
979 self.assertEqual(math.dist(p, q), 5*scale)
980 self.assertEqual(math.dist(q, p), 5*scale)
981
Mark Dickinson73934b92019-05-18 12:29:50 +0100982 def testIsqrt(self):
983 # Test a variety of inputs, large and small.
984 test_values = (
985 list(range(1000))
986 + list(range(10**6 - 1000, 10**6 + 1000))
Mark Dickinson5c08ce92019-05-19 17:51:56 +0100987 + [2**e + i for e in range(60, 200) for i in range(-40, 40)]
Mark Dickinson73934b92019-05-18 12:29:50 +0100988 + [3**9999, 10**5001]
989 )
990
991 for value in test_values:
992 with self.subTest(value=value):
993 s = math.isqrt(value)
994 self.assertIs(type(s), int)
995 self.assertLessEqual(s*s, value)
996 self.assertLess(value, (s+1)*(s+1))
997
998 # Negative values
999 with self.assertRaises(ValueError):
1000 math.isqrt(-1)
1001
1002 # Integer-like things
1003 s = math.isqrt(True)
1004 self.assertIs(type(s), int)
1005 self.assertEqual(s, 1)
1006
1007 s = math.isqrt(False)
1008 self.assertIs(type(s), int)
1009 self.assertEqual(s, 0)
1010
1011 class IntegerLike(object):
1012 def __init__(self, value):
1013 self.value = value
1014
1015 def __index__(self):
1016 return self.value
1017
1018 s = math.isqrt(IntegerLike(1729))
1019 self.assertIs(type(s), int)
1020 self.assertEqual(s, 41)
1021
1022 with self.assertRaises(ValueError):
1023 math.isqrt(IntegerLike(-3))
1024
1025 # Non-integer-like things
1026 bad_values = [
1027 3.5, "a string", decimal.Decimal("3.5"), 3.5j,
1028 100.0, -4.0,
1029 ]
1030 for value in bad_values:
1031 with self.subTest(value=value):
1032 with self.assertRaises(TypeError):
1033 math.isqrt(value)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -07001034
ananthan-123f2ee21d2020-02-19 23:51:37 +05301035 def test_lcm(self):
1036 lcm = math.lcm
1037 self.assertEqual(lcm(0, 0), 0)
1038 self.assertEqual(lcm(1, 0), 0)
1039 self.assertEqual(lcm(-1, 0), 0)
1040 self.assertEqual(lcm(0, 1), 0)
1041 self.assertEqual(lcm(0, -1), 0)
1042 self.assertEqual(lcm(7, 1), 7)
1043 self.assertEqual(lcm(7, -1), 7)
1044 self.assertEqual(lcm(-23, 15), 345)
1045 self.assertEqual(lcm(120, 84), 840)
1046 self.assertEqual(lcm(84, -120), 840)
1047 self.assertEqual(lcm(1216342683557601535506311712,
1048 436522681849110124616458784),
1049 16592536571065866494401400422922201534178938447014944)
Serhiy Storchaka559e7f12020-02-23 13:21:29 +02001050
ananthan-123f2ee21d2020-02-19 23:51:37 +05301051 x = 43461045657039990237
1052 y = 10645022458251153277
ananthan-123f2ee21d2020-02-19 23:51:37 +05301053 for c in (652560,
1054 57655923087165495981):
1055 a = x * c
1056 b = y * c
1057 d = x * y * c
1058 self.assertEqual(lcm(a, b), d)
1059 self.assertEqual(lcm(b, a), d)
1060 self.assertEqual(lcm(-a, b), d)
1061 self.assertEqual(lcm(b, -a), d)
1062 self.assertEqual(lcm(a, -b), d)
1063 self.assertEqual(lcm(-b, a), d)
1064 self.assertEqual(lcm(-a, -b), d)
1065 self.assertEqual(lcm(-b, -a), d)
Serhiy Storchaka559e7f12020-02-23 13:21:29 +02001066
1067 self.assertEqual(lcm(), 1)
1068 self.assertEqual(lcm(120), 120)
1069 self.assertEqual(lcm(-120), 120)
1070 self.assertEqual(lcm(120, 84, 102), 14280)
1071 self.assertEqual(lcm(120, 0, 84), 0)
1072
1073 self.assertRaises(TypeError, lcm, 120.0)
ananthan-123f2ee21d2020-02-19 23:51:37 +05301074 self.assertRaises(TypeError, lcm, 120.0, 84)
1075 self.assertRaises(TypeError, lcm, 120, 84.0)
Serhiy Storchaka559e7f12020-02-23 13:21:29 +02001076 self.assertRaises(TypeError, lcm, 120, 0, 84.0)
1077 self.assertEqual(lcm(MyIndexable(120), MyIndexable(84)), 840)
ananthan-123f2ee21d2020-02-19 23:51:37 +05301078
Thomas Wouters89f507f2006-12-13 04:49:30 +00001079 def testLdexp(self):
1080 self.assertRaises(TypeError, math.ldexp)
1081 self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
1082 self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
1083 self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
1084 self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
Christian Heimes53876d92008-04-19 00:31:39 +00001085 self.assertRaises(OverflowError, math.ldexp, 1., 1000000)
1086 self.assertRaises(OverflowError, math.ldexp, -1., 1000000)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001087 self.assertEqual(math.ldexp(1., -1000000), 0.)
1088 self.assertEqual(math.ldexp(-1., -1000000), -0.)
1089 self.assertEqual(math.ldexp(INF, 30), INF)
1090 self.assertEqual(math.ldexp(NINF, -213), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001091 self.assertTrue(math.isnan(math.ldexp(NAN, 0)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001092
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001093 # large second argument
1094 for n in [10**5, 10**10, 10**20, 10**40]:
Ezio Melottib3aedd42010-11-20 19:04:17 +00001095 self.assertEqual(math.ldexp(INF, -n), INF)
1096 self.assertEqual(math.ldexp(NINF, -n), NINF)
1097 self.assertEqual(math.ldexp(1., -n), 0.)
1098 self.assertEqual(math.ldexp(-1., -n), -0.)
1099 self.assertEqual(math.ldexp(0., -n), 0.)
1100 self.assertEqual(math.ldexp(-0., -n), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001101 self.assertTrue(math.isnan(math.ldexp(NAN, -n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001102
1103 self.assertRaises(OverflowError, math.ldexp, 1., n)
1104 self.assertRaises(OverflowError, math.ldexp, -1., n)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001105 self.assertEqual(math.ldexp(0., n), 0.)
1106 self.assertEqual(math.ldexp(-0., n), -0.)
1107 self.assertEqual(math.ldexp(INF, n), INF)
1108 self.assertEqual(math.ldexp(NINF, n), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001109 self.assertTrue(math.isnan(math.ldexp(NAN, n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001110
Thomas Wouters89f507f2006-12-13 04:49:30 +00001111 def testLog(self):
1112 self.assertRaises(TypeError, math.log)
1113 self.ftest('log(1/e)', math.log(1/math.e), -1)
1114 self.ftest('log(1)', math.log(1), 0)
1115 self.ftest('log(e)', math.log(math.e), 1)
1116 self.ftest('log(32,2)', math.log(32,2), 5)
1117 self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
1118 self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001119 self.ftest('log(10**1000)', math.log(10**1000),
1120 2302.5850929940457)
1121 self.assertRaises(ValueError, math.log, -1.5)
1122 self.assertRaises(ValueError, math.log, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001123 self.assertRaises(ValueError, math.log, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001124 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001125 self.assertTrue(math.isnan(math.log(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001126
1127 def testLog1p(self):
1128 self.assertRaises(TypeError, math.log1p)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001129 for n in [2, 2**90, 2**300]:
1130 self.assertAlmostEqual(math.log1p(n), math.log1p(float(n)))
1131 self.assertRaises(ValueError, math.log1p, -1)
1132 self.assertEqual(math.log1p(INF), INF)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001133
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001134 @requires_IEEE_754
1135 def testLog2(self):
1136 self.assertRaises(TypeError, math.log2)
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001137
1138 # Check some integer values
1139 self.assertEqual(math.log2(1), 0.0)
1140 self.assertEqual(math.log2(2), 1.0)
1141 self.assertEqual(math.log2(4), 2.0)
1142
1143 # Large integer values
1144 self.assertEqual(math.log2(2**1023), 1023.0)
1145 self.assertEqual(math.log2(2**1024), 1024.0)
1146 self.assertEqual(math.log2(2**2000), 2000.0)
1147
1148 self.assertRaises(ValueError, math.log2, -1.5)
1149 self.assertRaises(ValueError, math.log2, NINF)
1150 self.assertTrue(math.isnan(math.log2(NAN)))
1151
Victor Stinnercd9dd372011-05-10 23:40:17 +02001152 @requires_IEEE_754
Victor Stinnerebbbdaf2011-06-01 13:19:07 +02001153 # log2() is not accurate enough on Mac OS X Tiger (10.4)
1154 @support.requires_mac_ver(10, 5)
Victor Stinnercd9dd372011-05-10 23:40:17 +02001155 def testLog2Exact(self):
1156 # Check that we get exact equality for log2 of powers of 2.
1157 actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)]
1158 expected = [float(n) for n in range(-1074, 1024)]
1159 self.assertEqual(actual, expected)
1160
Thomas Wouters89f507f2006-12-13 04:49:30 +00001161 def testLog10(self):
1162 self.assertRaises(TypeError, math.log10)
1163 self.ftest('log10(0.1)', math.log10(0.1), -1)
1164 self.ftest('log10(1)', math.log10(1), 0)
1165 self.ftest('log10(10)', math.log10(10), 1)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001166 self.ftest('log10(10**1000)', math.log10(10**1000), 1000.0)
1167 self.assertRaises(ValueError, math.log10, -1.5)
1168 self.assertRaises(ValueError, math.log10, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001169 self.assertRaises(ValueError, math.log10, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001170 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001171 self.assertTrue(math.isnan(math.log10(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001172
Thomas Wouters89f507f2006-12-13 04:49:30 +00001173 def testModf(self):
1174 self.assertRaises(TypeError, math.modf)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001175
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001176 def testmodf(name, result, expected):
1177 (v1, v2), (e1, e2) = result, expected
Thomas Wouters89f507f2006-12-13 04:49:30 +00001178 if abs(v1-e1) > eps or abs(v2-e2):
1179 self.fail('%s returned %r, expected %r'%\
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001180 (name, result, expected))
Raymond Hettinger64108af2002-05-13 03:55:01 +00001181
Thomas Wouters89f507f2006-12-13 04:49:30 +00001182 testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
1183 testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001184
Ezio Melottib3aedd42010-11-20 19:04:17 +00001185 self.assertEqual(math.modf(INF), (0.0, INF))
1186 self.assertEqual(math.modf(NINF), (-0.0, NINF))
Christian Heimes53876d92008-04-19 00:31:39 +00001187
1188 modf_nan = math.modf(NAN)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001189 self.assertTrue(math.isnan(modf_nan[0]))
1190 self.assertTrue(math.isnan(modf_nan[1]))
Christian Heimes53876d92008-04-19 00:31:39 +00001191
Thomas Wouters89f507f2006-12-13 04:49:30 +00001192 def testPow(self):
1193 self.assertRaises(TypeError, math.pow)
1194 self.ftest('pow(0,1)', math.pow(0,1), 0)
1195 self.ftest('pow(1,0)', math.pow(1,0), 1)
1196 self.ftest('pow(2,1)', math.pow(2,1), 2)
1197 self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
Christian Heimes53876d92008-04-19 00:31:39 +00001198 self.assertEqual(math.pow(INF, 1), INF)
1199 self.assertEqual(math.pow(NINF, 1), NINF)
1200 self.assertEqual((math.pow(1, INF)), 1.)
1201 self.assertEqual((math.pow(1, NINF)), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001202 self.assertTrue(math.isnan(math.pow(NAN, 1)))
1203 self.assertTrue(math.isnan(math.pow(2, NAN)))
1204 self.assertTrue(math.isnan(math.pow(0, NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001205 self.assertEqual(math.pow(1, NAN), 1)
Christian Heimesa342c012008-04-20 21:01:16 +00001206
1207 # pow(0., x)
1208 self.assertEqual(math.pow(0., INF), 0.)
1209 self.assertEqual(math.pow(0., 3.), 0.)
1210 self.assertEqual(math.pow(0., 2.3), 0.)
1211 self.assertEqual(math.pow(0., 2.), 0.)
1212 self.assertEqual(math.pow(0., 0.), 1.)
1213 self.assertEqual(math.pow(0., -0.), 1.)
1214 self.assertRaises(ValueError, math.pow, 0., -2.)
1215 self.assertRaises(ValueError, math.pow, 0., -2.3)
1216 self.assertRaises(ValueError, math.pow, 0., -3.)
1217 self.assertRaises(ValueError, math.pow, 0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001218 self.assertTrue(math.isnan(math.pow(0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001219
1220 # pow(INF, x)
1221 self.assertEqual(math.pow(INF, INF), INF)
1222 self.assertEqual(math.pow(INF, 3.), INF)
1223 self.assertEqual(math.pow(INF, 2.3), INF)
1224 self.assertEqual(math.pow(INF, 2.), INF)
1225 self.assertEqual(math.pow(INF, 0.), 1.)
1226 self.assertEqual(math.pow(INF, -0.), 1.)
1227 self.assertEqual(math.pow(INF, -2.), 0.)
1228 self.assertEqual(math.pow(INF, -2.3), 0.)
1229 self.assertEqual(math.pow(INF, -3.), 0.)
1230 self.assertEqual(math.pow(INF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001231 self.assertTrue(math.isnan(math.pow(INF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001232
1233 # pow(-0., x)
1234 self.assertEqual(math.pow(-0., INF), 0.)
1235 self.assertEqual(math.pow(-0., 3.), -0.)
1236 self.assertEqual(math.pow(-0., 2.3), 0.)
1237 self.assertEqual(math.pow(-0., 2.), 0.)
1238 self.assertEqual(math.pow(-0., 0.), 1.)
1239 self.assertEqual(math.pow(-0., -0.), 1.)
1240 self.assertRaises(ValueError, math.pow, -0., -2.)
1241 self.assertRaises(ValueError, math.pow, -0., -2.3)
1242 self.assertRaises(ValueError, math.pow, -0., -3.)
1243 self.assertRaises(ValueError, math.pow, -0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001244 self.assertTrue(math.isnan(math.pow(-0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001245
1246 # pow(NINF, x)
1247 self.assertEqual(math.pow(NINF, INF), INF)
1248 self.assertEqual(math.pow(NINF, 3.), NINF)
1249 self.assertEqual(math.pow(NINF, 2.3), INF)
1250 self.assertEqual(math.pow(NINF, 2.), INF)
1251 self.assertEqual(math.pow(NINF, 0.), 1.)
1252 self.assertEqual(math.pow(NINF, -0.), 1.)
1253 self.assertEqual(math.pow(NINF, -2.), 0.)
1254 self.assertEqual(math.pow(NINF, -2.3), 0.)
1255 self.assertEqual(math.pow(NINF, -3.), -0.)
1256 self.assertEqual(math.pow(NINF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001257 self.assertTrue(math.isnan(math.pow(NINF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001258
1259 # pow(-1, x)
1260 self.assertEqual(math.pow(-1., INF), 1.)
1261 self.assertEqual(math.pow(-1., 3.), -1.)
1262 self.assertRaises(ValueError, math.pow, -1., 2.3)
1263 self.assertEqual(math.pow(-1., 2.), 1.)
1264 self.assertEqual(math.pow(-1., 0.), 1.)
1265 self.assertEqual(math.pow(-1., -0.), 1.)
1266 self.assertEqual(math.pow(-1., -2.), 1.)
1267 self.assertRaises(ValueError, math.pow, -1., -2.3)
1268 self.assertEqual(math.pow(-1., -3.), -1.)
1269 self.assertEqual(math.pow(-1., NINF), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001270 self.assertTrue(math.isnan(math.pow(-1., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001271
1272 # pow(1, x)
1273 self.assertEqual(math.pow(1., INF), 1.)
1274 self.assertEqual(math.pow(1., 3.), 1.)
1275 self.assertEqual(math.pow(1., 2.3), 1.)
1276 self.assertEqual(math.pow(1., 2.), 1.)
1277 self.assertEqual(math.pow(1., 0.), 1.)
1278 self.assertEqual(math.pow(1., -0.), 1.)
1279 self.assertEqual(math.pow(1., -2.), 1.)
1280 self.assertEqual(math.pow(1., -2.3), 1.)
1281 self.assertEqual(math.pow(1., -3.), 1.)
1282 self.assertEqual(math.pow(1., NINF), 1.)
1283 self.assertEqual(math.pow(1., NAN), 1.)
1284
1285 # pow(x, 0) should be 1 for any x
1286 self.assertEqual(math.pow(2.3, 0.), 1.)
1287 self.assertEqual(math.pow(-2.3, 0.), 1.)
1288 self.assertEqual(math.pow(NAN, 0.), 1.)
1289 self.assertEqual(math.pow(2.3, -0.), 1.)
1290 self.assertEqual(math.pow(-2.3, -0.), 1.)
1291 self.assertEqual(math.pow(NAN, -0.), 1.)
1292
1293 # pow(x, y) is invalid if x is negative and y is not integral
1294 self.assertRaises(ValueError, math.pow, -1., 2.3)
1295 self.assertRaises(ValueError, math.pow, -15., -3.1)
1296
1297 # pow(x, NINF)
1298 self.assertEqual(math.pow(1.9, NINF), 0.)
1299 self.assertEqual(math.pow(1.1, NINF), 0.)
1300 self.assertEqual(math.pow(0.9, NINF), INF)
1301 self.assertEqual(math.pow(0.1, NINF), INF)
1302 self.assertEqual(math.pow(-0.1, NINF), INF)
1303 self.assertEqual(math.pow(-0.9, NINF), INF)
1304 self.assertEqual(math.pow(-1.1, NINF), 0.)
1305 self.assertEqual(math.pow(-1.9, NINF), 0.)
1306
1307 # pow(x, INF)
1308 self.assertEqual(math.pow(1.9, INF), INF)
1309 self.assertEqual(math.pow(1.1, INF), INF)
1310 self.assertEqual(math.pow(0.9, INF), 0.)
1311 self.assertEqual(math.pow(0.1, INF), 0.)
1312 self.assertEqual(math.pow(-0.1, INF), 0.)
1313 self.assertEqual(math.pow(-0.9, INF), 0.)
1314 self.assertEqual(math.pow(-1.1, INF), INF)
1315 self.assertEqual(math.pow(-1.9, INF), INF)
1316
1317 # pow(x, y) should work for x negative, y an integer
1318 self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
1319 self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
1320 self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
1321 self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
1322 self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
1323 self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
1324 self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
1325 self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
1326 self.assertRaises(ValueError, math.pow, -2.0, -0.5)
1327 self.assertRaises(ValueError, math.pow, -2.0, 0.5)
1328
1329 # the following tests have been commented out since they don't
1330 # really belong here: the implementation of ** for floats is
Ezio Melotti13925002011-03-16 11:05:33 +02001331 # independent of the implementation of math.pow
Christian Heimesa342c012008-04-20 21:01:16 +00001332 #self.assertEqual(1**NAN, 1)
1333 #self.assertEqual(1**INF, 1)
1334 #self.assertEqual(1**NINF, 1)
1335 #self.assertEqual(1**0, 1)
1336 #self.assertEqual(1.**NAN, 1)
1337 #self.assertEqual(1.**INF, 1)
1338 #self.assertEqual(1.**NINF, 1)
1339 #self.assertEqual(1.**0, 1)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001340
Thomas Wouters89f507f2006-12-13 04:49:30 +00001341 def testRadians(self):
1342 self.assertRaises(TypeError, math.radians)
1343 self.ftest('radians(180)', math.radians(180), math.pi)
1344 self.ftest('radians(90)', math.radians(90), math.pi/2)
1345 self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001346 self.ftest('radians(0)', math.radians(0), 0)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001347
Mark Dickinsona0ce3752017-04-05 18:34:27 +01001348 @requires_IEEE_754
1349 def testRemainder(self):
1350 from fractions import Fraction
1351
1352 def validate_spec(x, y, r):
1353 """
1354 Check that r matches remainder(x, y) according to the IEEE 754
1355 specification. Assumes that x, y and r are finite and y is nonzero.
1356 """
1357 fx, fy, fr = Fraction(x), Fraction(y), Fraction(r)
1358 # r should not exceed y/2 in absolute value
1359 self.assertLessEqual(abs(fr), abs(fy/2))
1360 # x - r should be an exact integer multiple of y
1361 n = (fx - fr) / fy
1362 self.assertEqual(n, int(n))
1363 if abs(fr) == abs(fy/2):
1364 # If |r| == |y/2|, n should be even.
1365 self.assertEqual(n/2, int(n/2))
1366
1367 # triples (x, y, remainder(x, y)) in hexadecimal form.
1368 testcases = [
1369 # Remainders modulo 1, showing the ties-to-even behaviour.
1370 '-4.0 1 -0.0',
1371 '-3.8 1 0.8',
1372 '-3.0 1 -0.0',
1373 '-2.8 1 -0.8',
1374 '-2.0 1 -0.0',
1375 '-1.8 1 0.8',
1376 '-1.0 1 -0.0',
1377 '-0.8 1 -0.8',
1378 '-0.0 1 -0.0',
1379 ' 0.0 1 0.0',
1380 ' 0.8 1 0.8',
1381 ' 1.0 1 0.0',
1382 ' 1.8 1 -0.8',
1383 ' 2.0 1 0.0',
1384 ' 2.8 1 0.8',
1385 ' 3.0 1 0.0',
1386 ' 3.8 1 -0.8',
1387 ' 4.0 1 0.0',
1388
1389 # Reductions modulo 2*pi
1390 '0x0.0p+0 0x1.921fb54442d18p+2 0x0.0p+0',
1391 '0x1.921fb54442d18p+0 0x1.921fb54442d18p+2 0x1.921fb54442d18p+0',
1392 '0x1.921fb54442d17p+1 0x1.921fb54442d18p+2 0x1.921fb54442d17p+1',
1393 '0x1.921fb54442d18p+1 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1394 '0x1.921fb54442d19p+1 0x1.921fb54442d18p+2 -0x1.921fb54442d17p+1',
1395 '0x1.921fb54442d17p+2 0x1.921fb54442d18p+2 -0x0.0000000000001p+2',
1396 '0x1.921fb54442d18p+2 0x1.921fb54442d18p+2 0x0p0',
1397 '0x1.921fb54442d19p+2 0x1.921fb54442d18p+2 0x0.0000000000001p+2',
1398 '0x1.2d97c7f3321d1p+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1399 '0x1.2d97c7f3321d2p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d18p+1',
1400 '0x1.2d97c7f3321d3p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1401 '0x1.921fb54442d17p+3 0x1.921fb54442d18p+2 -0x0.0000000000001p+3',
1402 '0x1.921fb54442d18p+3 0x1.921fb54442d18p+2 0x0p0',
1403 '0x1.921fb54442d19p+3 0x1.921fb54442d18p+2 0x0.0000000000001p+3',
1404 '0x1.f6a7a2955385dp+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1405 '0x1.f6a7a2955385ep+3 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1406 '0x1.f6a7a2955385fp+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1407 '0x1.1475cc9eedf00p+5 0x1.921fb54442d18p+2 0x1.921fb54442d10p+1',
1408 '0x1.1475cc9eedf01p+5 0x1.921fb54442d18p+2 -0x1.921fb54442d10p+1',
1409
1410 # Symmetry with respect to signs.
1411 ' 1 0.c 0.4',
1412 '-1 0.c -0.4',
1413 ' 1 -0.c 0.4',
1414 '-1 -0.c -0.4',
1415 ' 1.4 0.c -0.4',
1416 '-1.4 0.c 0.4',
1417 ' 1.4 -0.c -0.4',
1418 '-1.4 -0.c 0.4',
1419
1420 # Huge modulus, to check that the underlying algorithm doesn't
1421 # rely on 2.0 * modulus being representable.
1422 '0x1.dp+1023 0x1.4p+1023 0x0.9p+1023',
1423 '0x1.ep+1023 0x1.4p+1023 -0x0.ap+1023',
1424 '0x1.fp+1023 0x1.4p+1023 -0x0.9p+1023',
1425 ]
1426
1427 for case in testcases:
1428 with self.subTest(case=case):
1429 x_hex, y_hex, expected_hex = case.split()
1430 x = float.fromhex(x_hex)
1431 y = float.fromhex(y_hex)
1432 expected = float.fromhex(expected_hex)
1433 validate_spec(x, y, expected)
1434 actual = math.remainder(x, y)
1435 # Cheap way of checking that the floats are
1436 # as identical as we need them to be.
1437 self.assertEqual(actual.hex(), expected.hex())
1438
1439 # Test tiny subnormal modulus: there's potential for
1440 # getting the implementation wrong here (for example,
1441 # by assuming that modulus/2 is exactly representable).
1442 tiny = float.fromhex('1p-1074') # min +ve subnormal
1443 for n in range(-25, 25):
1444 if n == 0:
1445 continue
1446 y = n * tiny
1447 for m in range(100):
1448 x = m * tiny
1449 actual = math.remainder(x, y)
1450 validate_spec(x, y, actual)
1451 actual = math.remainder(-x, y)
1452 validate_spec(-x, y, actual)
1453
1454 # Special values.
1455 # NaNs should propagate as usual.
1456 for value in [NAN, 0.0, -0.0, 2.0, -2.3, NINF, INF]:
1457 self.assertIsNaN(math.remainder(NAN, value))
1458 self.assertIsNaN(math.remainder(value, NAN))
1459
1460 # remainder(x, inf) is x, for non-nan non-infinite x.
1461 for value in [-2.3, -0.0, 0.0, 2.3]:
1462 self.assertEqual(math.remainder(value, INF), value)
1463 self.assertEqual(math.remainder(value, NINF), value)
1464
1465 # remainder(x, 0) and remainder(infinity, x) for non-NaN x are invalid
1466 # operations according to IEEE 754-2008 7.2(f), and should raise.
1467 for value in [NINF, -2.3, -0.0, 0.0, 2.3, INF]:
1468 with self.assertRaises(ValueError):
1469 math.remainder(INF, value)
1470 with self.assertRaises(ValueError):
1471 math.remainder(NINF, value)
1472 with self.assertRaises(ValueError):
1473 math.remainder(value, 0.0)
1474 with self.assertRaises(ValueError):
1475 math.remainder(value, -0.0)
1476
Thomas Wouters89f507f2006-12-13 04:49:30 +00001477 def testSin(self):
1478 self.assertRaises(TypeError, math.sin)
1479 self.ftest('sin(0)', math.sin(0), 0)
1480 self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
1481 self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001482 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001483 self.assertTrue(math.isnan(math.sin(INF)))
1484 self.assertTrue(math.isnan(math.sin(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001485 except ValueError:
1486 self.assertRaises(ValueError, math.sin, INF)
1487 self.assertRaises(ValueError, math.sin, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001488 self.assertTrue(math.isnan(math.sin(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001489
Thomas Wouters89f507f2006-12-13 04:49:30 +00001490 def testSinh(self):
1491 self.assertRaises(TypeError, math.sinh)
1492 self.ftest('sinh(0)', math.sinh(0), 0)
1493 self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
1494 self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001495 self.assertEqual(math.sinh(INF), INF)
1496 self.assertEqual(math.sinh(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001497 self.assertTrue(math.isnan(math.sinh(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001498
Thomas Wouters89f507f2006-12-13 04:49:30 +00001499 def testSqrt(self):
1500 self.assertRaises(TypeError, math.sqrt)
1501 self.ftest('sqrt(0)', math.sqrt(0), 0)
1502 self.ftest('sqrt(1)', math.sqrt(1), 1)
1503 self.ftest('sqrt(4)', math.sqrt(4), 2)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001504 self.assertEqual(math.sqrt(INF), INF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001505 self.assertRaises(ValueError, math.sqrt, -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001506 self.assertRaises(ValueError, math.sqrt, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001507 self.assertTrue(math.isnan(math.sqrt(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001508
Thomas Wouters89f507f2006-12-13 04:49:30 +00001509 def testTan(self):
1510 self.assertRaises(TypeError, math.tan)
1511 self.ftest('tan(0)', math.tan(0), 0)
1512 self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
1513 self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001514 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001515 self.assertTrue(math.isnan(math.tan(INF)))
1516 self.assertTrue(math.isnan(math.tan(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001517 except:
1518 self.assertRaises(ValueError, math.tan, INF)
1519 self.assertRaises(ValueError, math.tan, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001520 self.assertTrue(math.isnan(math.tan(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001521
Thomas Wouters89f507f2006-12-13 04:49:30 +00001522 def testTanh(self):
1523 self.assertRaises(TypeError, math.tanh)
1524 self.ftest('tanh(0)', math.tanh(0), 0)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001525 self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0,
Victor Stinner0b2ab212020-01-13 12:44:35 +01001526 abs_tol=math.ulp(1))
Christian Heimes53876d92008-04-19 00:31:39 +00001527 self.ftest('tanh(inf)', math.tanh(INF), 1)
1528 self.ftest('tanh(-inf)', math.tanh(NINF), -1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001529 self.assertTrue(math.isnan(math.tanh(NAN)))
Victor Stinnerbe3da382010-11-07 14:14:27 +00001530
1531 @requires_IEEE_754
Victor Stinnerbe3da382010-11-07 14:14:27 +00001532 def testTanhSign(self):
Christian Heimese57950f2008-04-21 13:08:03 +00001533 # check that tanh(-0.) == -0. on IEEE 754 systems
Victor Stinnerbe3da382010-11-07 14:14:27 +00001534 self.assertEqual(math.tanh(-0.), -0.)
1535 self.assertEqual(math.copysign(1., math.tanh(-0.)),
1536 math.copysign(1., -0.))
Tim Peters1d120612000-10-12 06:10:25 +00001537
Christian Heimes400adb02008-02-01 08:12:03 +00001538 def test_trunc(self):
1539 self.assertEqual(math.trunc(1), 1)
1540 self.assertEqual(math.trunc(-1), -1)
1541 self.assertEqual(type(math.trunc(1)), int)
1542 self.assertEqual(type(math.trunc(1.5)), int)
1543 self.assertEqual(math.trunc(1.5), 1)
1544 self.assertEqual(math.trunc(-1.5), -1)
1545 self.assertEqual(math.trunc(1.999999), 1)
1546 self.assertEqual(math.trunc(-1.999999), -1)
1547 self.assertEqual(math.trunc(-0.999999), -0)
1548 self.assertEqual(math.trunc(-100.999), -100)
1549
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001550 class TestTrunc:
Christian Heimes400adb02008-02-01 08:12:03 +00001551 def __trunc__(self):
1552 return 23
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001553 class FloatTrunc(float):
1554 def __trunc__(self):
1555 return 23
1556 class TestNoTrunc:
Christian Heimes400adb02008-02-01 08:12:03 +00001557 pass
1558
1559 self.assertEqual(math.trunc(TestTrunc()), 23)
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001560 self.assertEqual(math.trunc(FloatTrunc()), 23)
Christian Heimes400adb02008-02-01 08:12:03 +00001561
1562 self.assertRaises(TypeError, math.trunc)
1563 self.assertRaises(TypeError, math.trunc, 1, 2)
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001564 self.assertRaises(TypeError, math.trunc, FloatLike(23.5))
Christian Heimes400adb02008-02-01 08:12:03 +00001565 self.assertRaises(TypeError, math.trunc, TestNoTrunc())
1566
Mark Dickinson8e0c9962010-07-11 17:38:24 +00001567 def testIsfinite(self):
1568 self.assertTrue(math.isfinite(0.0))
1569 self.assertTrue(math.isfinite(-0.0))
1570 self.assertTrue(math.isfinite(1.0))
1571 self.assertTrue(math.isfinite(-1.0))
1572 self.assertFalse(math.isfinite(float("nan")))
1573 self.assertFalse(math.isfinite(float("inf")))
1574 self.assertFalse(math.isfinite(float("-inf")))
1575
Christian Heimes072c0f12008-01-03 23:01:04 +00001576 def testIsnan(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001577 self.assertTrue(math.isnan(float("nan")))
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001578 self.assertTrue(math.isnan(float("-nan")))
1579 self.assertTrue(math.isnan(float("inf") * 0.))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001580 self.assertFalse(math.isnan(float("inf")))
1581 self.assertFalse(math.isnan(0.))
1582 self.assertFalse(math.isnan(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001583
1584 def testIsinf(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001585 self.assertTrue(math.isinf(float("inf")))
1586 self.assertTrue(math.isinf(float("-inf")))
1587 self.assertTrue(math.isinf(1E400))
1588 self.assertTrue(math.isinf(-1E400))
1589 self.assertFalse(math.isinf(float("nan")))
1590 self.assertFalse(math.isinf(0.))
1591 self.assertFalse(math.isinf(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001592
Mark Dickinsona5d0c7c2015-01-11 11:55:29 +00001593 @requires_IEEE_754
1594 def test_nan_constant(self):
1595 self.assertTrue(math.isnan(math.nan))
1596
1597 @requires_IEEE_754
1598 def test_inf_constant(self):
1599 self.assertTrue(math.isinf(math.inf))
1600 self.assertGreater(math.inf, 0.0)
1601 self.assertEqual(math.inf, float("inf"))
1602 self.assertEqual(-math.inf, float("-inf"))
1603
Thomas Wouters89f507f2006-12-13 04:49:30 +00001604 # RED_FLAG 16-Oct-2000 Tim
1605 # While 2.0 is more consistent about exceptions than previous releases, it
1606 # still fails this part of the test on some platforms. For now, we only
1607 # *run* test_exceptions() in verbose mode, so that this isn't normally
1608 # tested.
Serhiy Storchaka43767632013-11-03 21:31:38 +02001609 @unittest.skipUnless(verbose, 'requires verbose mode')
1610 def test_exceptions(self):
1611 try:
1612 x = math.exp(-1000000000)
1613 except:
1614 # mathmodule.c is failing to weed out underflows from libm, or
1615 # we've got an fp format with huge dynamic range
1616 self.fail("underflowing exp() should not have raised "
1617 "an exception")
1618 if x != 0:
1619 self.fail("underflowing exp() should have returned 0")
Tim Peters98c81842000-10-16 17:35:13 +00001620
Serhiy Storchaka43767632013-11-03 21:31:38 +02001621 # If this fails, probably using a strict IEEE-754 conforming libm, and x
1622 # is +Inf afterwards. But Python wants overflows detected by default.
1623 try:
1624 x = math.exp(1000000000)
1625 except OverflowError:
1626 pass
1627 else:
1628 self.fail("overflowing exp() didn't trigger OverflowError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001629
Serhiy Storchaka43767632013-11-03 21:31:38 +02001630 # If this fails, it could be a puzzle. One odd possibility is that
1631 # mathmodule.c's macros are getting confused while comparing
1632 # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
1633 # as a result (and so raising OverflowError instead).
1634 try:
1635 x = math.sqrt(-1.0)
1636 except ValueError:
1637 pass
1638 else:
1639 self.fail("sqrt(-1) didn't raise ValueError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001640
Mark Dickinson63566232009-09-18 21:04:19 +00001641 @requires_IEEE_754
Christian Heimes53876d92008-04-19 00:31:39 +00001642 def test_testfile(self):
Mark Dickinson85746542016-09-04 09:58:51 +01001643 # Some tests need to be skipped on ancient OS X versions.
1644 # See issue #27953.
1645 SKIP_ON_TIGER = {'tan0064'}
1646
1647 osx_version = None
1648 if sys.platform == 'darwin':
1649 version_txt = platform.mac_ver()[0]
1650 try:
1651 osx_version = tuple(map(int, version_txt.split('.')))
1652 except ValueError:
1653 pass
1654
Mark Dickinson96f774d2016-09-03 19:30:22 +01001655 fail_fmt = "{}: {}({!r}): {}"
1656
1657 failures = []
Christian Heimes53876d92008-04-19 00:31:39 +00001658 for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001659 # Skip if either the input or result is complex
1660 if ai != 0.0 or ei != 0.0:
Christian Heimes53876d92008-04-19 00:31:39 +00001661 continue
1662 if fn in ['rect', 'polar']:
1663 # no real versions of rect, polar
1664 continue
Mark Dickinson85746542016-09-04 09:58:51 +01001665 # Skip certain tests on OS X 10.4.
1666 if osx_version is not None and osx_version < (10, 5):
1667 if id in SKIP_ON_TIGER:
1668 continue
Mark Dickinson96f774d2016-09-03 19:30:22 +01001669
Christian Heimes53876d92008-04-19 00:31:39 +00001670 func = getattr(math, fn)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001671
1672 if 'invalid' in flags or 'divide-by-zero' in flags:
1673 er = 'ValueError'
1674 elif 'overflow' in flags:
1675 er = 'OverflowError'
1676
Christian Heimesa342c012008-04-20 21:01:16 +00001677 try:
1678 result = func(ar)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001679 except ValueError:
1680 result = 'ValueError'
Benjamin Peterson2b7411d2008-05-26 17:36:47 +00001681 except OverflowError:
Mark Dickinson96f774d2016-09-03 19:30:22 +01001682 result = 'OverflowError'
1683
1684 # Default tolerances
1685 ulp_tol, abs_tol = 5, 0.0
1686
1687 failure = result_check(er, result, ulp_tol, abs_tol)
1688 if failure is None:
1689 continue
1690
1691 msg = fail_fmt.format(id, fn, ar, failure)
1692 failures.append(msg)
1693
1694 if failures:
1695 self.fail('Failures in test_testfile:\n ' +
1696 '\n '.join(failures))
Thomas Wouters89f507f2006-12-13 04:49:30 +00001697
Victor Stinnerbe3da382010-11-07 14:14:27 +00001698 @requires_IEEE_754
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001699 def test_mtestfile(self):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001700 fail_fmt = "{}: {}({!r}): {}"
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001701
1702 failures = []
1703 for id, fn, arg, expected, flags in parse_mtestfile(math_testcases):
1704 func = getattr(math, fn)
1705
1706 if 'invalid' in flags or 'divide-by-zero' in flags:
1707 expected = 'ValueError'
1708 elif 'overflow' in flags:
1709 expected = 'OverflowError'
1710
1711 try:
1712 got = func(arg)
1713 except ValueError:
1714 got = 'ValueError'
1715 except OverflowError:
1716 got = 'OverflowError'
1717
Mark Dickinson96f774d2016-09-03 19:30:22 +01001718 # Default tolerances
1719 ulp_tol, abs_tol = 5, 0.0
Mark Dickinsonbcdf9da2010-06-13 10:52:38 +00001720
Mark Dickinson96f774d2016-09-03 19:30:22 +01001721 # Exceptions to the defaults
1722 if fn == 'gamma':
1723 # Experimental results on one platform gave
1724 # an accuracy of <= 10 ulps across the entire float
1725 # domain. We weaken that to require 20 ulp accuracy.
1726 ulp_tol = 20
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001727
Mark Dickinson96f774d2016-09-03 19:30:22 +01001728 elif fn == 'lgamma':
1729 # we use a weaker accuracy test for lgamma;
1730 # lgamma only achieves an absolute error of
1731 # a few multiples of the machine accuracy, in
1732 # general.
1733 abs_tol = 1e-15
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001734
Mark Dickinson96f774d2016-09-03 19:30:22 +01001735 elif fn == 'erfc' and arg >= 0.0:
1736 # erfc has less-than-ideal accuracy for large
1737 # arguments (x ~ 25 or so), mainly due to the
1738 # error involved in computing exp(-x*x).
1739 #
1740 # Observed between CPython and mpmath at 25 dp:
1741 # x < 0 : err <= 2 ulp
1742 # 0 <= x < 1 : err <= 10 ulp
1743 # 1 <= x < 10 : err <= 100 ulp
1744 # 10 <= x < 20 : err <= 300 ulp
1745 # 20 <= x : < 600 ulp
1746 #
1747 if arg < 1.0:
1748 ulp_tol = 10
1749 elif arg < 10.0:
1750 ulp_tol = 100
1751 else:
1752 ulp_tol = 1000
1753
1754 failure = result_check(expected, got, ulp_tol, abs_tol)
1755 if failure is None:
1756 continue
1757
1758 msg = fail_fmt.format(id, fn, arg, failure)
1759 failures.append(msg)
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001760
1761 if failures:
1762 self.fail('Failures in test_mtestfile:\n ' +
1763 '\n '.join(failures))
1764
Pablo Galindo04114112019-03-09 19:18:08 +00001765 def test_prod(self):
1766 prod = math.prod
1767 self.assertEqual(prod([]), 1)
1768 self.assertEqual(prod([], start=5), 5)
1769 self.assertEqual(prod(list(range(2,8))), 5040)
1770 self.assertEqual(prod(iter(list(range(2,8)))), 5040)
1771 self.assertEqual(prod(range(1, 10), start=10), 3628800)
1772
1773 self.assertEqual(prod([1, 2, 3, 4, 5]), 120)
1774 self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0)
1775 self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0)
1776 self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0)
1777
1778 # Test overflow in fast-path for integers
1779 self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32)
1780 # Test overflow in fast-path for floats
1781 self.assertEqual(prod([1.0, 1.0, 2**32, 1, 1]), float(2**32))
1782
1783 self.assertRaises(TypeError, prod)
1784 self.assertRaises(TypeError, prod, 42)
1785 self.assertRaises(TypeError, prod, ['a', 'b', 'c'])
1786 self.assertRaises(TypeError, prod, ['a', 'b', 'c'], '')
1787 self.assertRaises(TypeError, prod, [b'a', b'c'], b'')
1788 values = [bytearray(b'a'), bytearray(b'b')]
1789 self.assertRaises(TypeError, prod, values, bytearray(b''))
1790 self.assertRaises(TypeError, prod, [[1], [2], [3]])
1791 self.assertRaises(TypeError, prod, [{2:3}])
1792 self.assertRaises(TypeError, prod, [{2:3}]*2, {2:3})
1793 self.assertRaises(TypeError, prod, [[1], [2], [3]], [])
1794 with self.assertRaises(TypeError):
1795 prod([10, 20], [30, 40]) # start is a keyword-only argument
1796
1797 self.assertEqual(prod([0, 1, 2, 3]), 0)
1798 self.assertEqual(prod([1, 0, 2, 3]), 0)
1799 self.assertEqual(prod([1, 2, 3, 0]), 0)
1800
1801 def _naive_prod(iterable, start=1):
1802 for elem in iterable:
1803 start *= elem
1804 return start
1805
1806 # Big integers
1807
1808 iterable = range(1, 10000)
1809 self.assertEqual(prod(iterable), _naive_prod(iterable))
1810 iterable = range(-10000, -1)
1811 self.assertEqual(prod(iterable), _naive_prod(iterable))
1812 iterable = range(-1000, 1000)
1813 self.assertEqual(prod(iterable), 0)
1814
1815 # Big floats
1816
1817 iterable = [float(x) for x in range(1, 1000)]
1818 self.assertEqual(prod(iterable), _naive_prod(iterable))
1819 iterable = [float(x) for x in range(-1000, -1)]
1820 self.assertEqual(prod(iterable), _naive_prod(iterable))
1821 iterable = [float(x) for x in range(-1000, 1000)]
1822 self.assertIsNaN(prod(iterable))
1823
1824 # Float tests
1825
1826 self.assertIsNaN(prod([1, 2, 3, float("nan"), 2, 3]))
1827 self.assertIsNaN(prod([1, 0, float("nan"), 2, 3]))
1828 self.assertIsNaN(prod([1, float("nan"), 0, 3]))
1829 self.assertIsNaN(prod([1, float("inf"), float("nan"),3]))
1830 self.assertIsNaN(prod([1, float("-inf"), float("nan"),3]))
1831 self.assertIsNaN(prod([1, float("nan"), float("inf"),3]))
1832 self.assertIsNaN(prod([1, float("nan"), float("-inf"),3]))
1833
1834 self.assertEqual(prod([1, 2, 3, float('inf'),-3,4]), float('-inf'))
1835 self.assertEqual(prod([1, 2, 3, float('-inf'),-3,4]), float('inf'))
1836
1837 self.assertIsNaN(prod([1,2,0,float('inf'), -3, 4]))
1838 self.assertIsNaN(prod([1,2,0,float('-inf'), -3, 4]))
1839 self.assertIsNaN(prod([1, 2, 3, float('inf'), -3, 0, 3]))
1840 self.assertIsNaN(prod([1, 2, 3, float('-inf'), -3, 0, 2]))
1841
1842 # Type preservation
1843
1844 self.assertEqual(type(prod([1, 2, 3, 4, 5, 6])), int)
1845 self.assertEqual(type(prod([1, 2.0, 3, 4, 5, 6])), float)
1846 self.assertEqual(type(prod(range(1, 10000))), int)
1847 self.assertEqual(type(prod(range(1, 10000), start=1.0)), float)
1848 self.assertEqual(type(prod([1, decimal.Decimal(2.0), 3, 4, 5, 6])),
1849 decimal.Decimal)
1850
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001851 def testPerm(self):
1852 perm = math.perm
1853 factorial = math.factorial
Min ho Kim96e12d52019-07-22 06:12:33 +10001854 # Test if factorial definition is satisfied
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001855 for n in range(100):
1856 for k in range(n + 1):
1857 self.assertEqual(perm(n, k),
1858 factorial(n) // factorial(n - k))
1859
1860 # Test for Pascal's identity
1861 for n in range(1, 100):
1862 for k in range(1, n):
1863 self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k))
1864
1865 # Test corner cases
1866 for n in range(1, 100):
1867 self.assertEqual(perm(n, 0), 1)
1868 self.assertEqual(perm(n, 1), n)
1869 self.assertEqual(perm(n, n), factorial(n))
1870
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001871 # Test one argument form
1872 for n in range(20):
1873 self.assertEqual(perm(n), factorial(n))
1874 self.assertEqual(perm(n, None), factorial(n))
1875
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001876 # Raises TypeError if any argument is non-integer or argument count is
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001877 # not 1 or 2
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001878 self.assertRaises(TypeError, perm, 10, 1.0)
1879 self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
1880 self.assertRaises(TypeError, perm, 10, "1")
1881 self.assertRaises(TypeError, perm, 10.0, 1)
1882 self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
1883 self.assertRaises(TypeError, perm, "10", 1)
1884
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001885 self.assertRaises(TypeError, perm)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001886 self.assertRaises(TypeError, perm, 10, 1, 3)
1887 self.assertRaises(TypeError, perm)
1888
1889 # Raises Value error if not k or n are negative numbers
1890 self.assertRaises(ValueError, perm, -1, 1)
1891 self.assertRaises(ValueError, perm, -2**1000, 1)
1892 self.assertRaises(ValueError, perm, 1, -1)
1893 self.assertRaises(ValueError, perm, 1, -2**1000)
1894
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07001895 # Returns zero if k is greater than n
1896 self.assertEqual(perm(1, 2), 0)
1897 self.assertEqual(perm(1, 2**1000), 0)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001898
1899 n = 2**1000
1900 self.assertEqual(perm(n, 0), 1)
1901 self.assertEqual(perm(n, 1), n)
1902 self.assertEqual(perm(n, 2), n * (n-1))
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +03001903 if support.check_impl_detail(cpython=True):
1904 self.assertRaises(OverflowError, perm, n, n)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001905
1906 for n, k in (True, True), (True, False), (False, False):
1907 self.assertEqual(perm(n, k), 1)
1908 self.assertIs(type(perm(n, k)), int)
1909 self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20)
1910 self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20)
1911 for k in range(3):
1912 self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int)
1913 self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int)
1914
Yash Aggarwal4a686502019-06-01 12:51:27 +05301915 def testComb(self):
1916 comb = math.comb
1917 factorial = math.factorial
Min ho Kim96e12d52019-07-22 06:12:33 +10001918 # Test if factorial definition is satisfied
Yash Aggarwal4a686502019-06-01 12:51:27 +05301919 for n in range(100):
1920 for k in range(n + 1):
1921 self.assertEqual(comb(n, k), factorial(n)
1922 // (factorial(k) * factorial(n - k)))
1923
1924 # Test for Pascal's identity
1925 for n in range(1, 100):
1926 for k in range(1, n):
1927 self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k))
1928
1929 # Test corner cases
1930 for n in range(100):
1931 self.assertEqual(comb(n, 0), 1)
1932 self.assertEqual(comb(n, n), 1)
1933
1934 for n in range(1, 100):
1935 self.assertEqual(comb(n, 1), n)
1936 self.assertEqual(comb(n, n - 1), n)
1937
1938 # Test Symmetry
1939 for n in range(100):
1940 for k in range(n // 2):
1941 self.assertEqual(comb(n, k), comb(n, n - k))
1942
1943 # Raises TypeError if any argument is non-integer or argument count is
1944 # not 2
1945 self.assertRaises(TypeError, comb, 10, 1.0)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001946 self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0))
Yash Aggarwal4a686502019-06-01 12:51:27 +05301947 self.assertRaises(TypeError, comb, 10, "1")
Yash Aggarwal4a686502019-06-01 12:51:27 +05301948 self.assertRaises(TypeError, comb, 10.0, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001949 self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1)
1950 self.assertRaises(TypeError, comb, "10", 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301951
1952 self.assertRaises(TypeError, comb, 10)
1953 self.assertRaises(TypeError, comb, 10, 1, 3)
1954 self.assertRaises(TypeError, comb)
1955
1956 # Raises Value error if not k or n are negative numbers
1957 self.assertRaises(ValueError, comb, -1, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001958 self.assertRaises(ValueError, comb, -2**1000, 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301959 self.assertRaises(ValueError, comb, 1, -1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001960 self.assertRaises(ValueError, comb, 1, -2**1000)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301961
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07001962 # Returns zero if k is greater than n
1963 self.assertEqual(comb(1, 2), 0)
1964 self.assertEqual(comb(1, 2**1000), 0)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301965
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001966 n = 2**1000
1967 self.assertEqual(comb(n, 0), 1)
1968 self.assertEqual(comb(n, 1), n)
1969 self.assertEqual(comb(n, 2), n * (n-1) // 2)
1970 self.assertEqual(comb(n, n), 1)
1971 self.assertEqual(comb(n, n-1), n)
1972 self.assertEqual(comb(n, n-2), n * (n-1) // 2)
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +03001973 if support.check_impl_detail(cpython=True):
1974 self.assertRaises(OverflowError, comb, n, n//2)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301975
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001976 for n, k in (True, True), (True, False), (False, False):
1977 self.assertEqual(comb(n, k), 1)
1978 self.assertIs(type(comb(n, k)), int)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001979 self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001980 self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001981 for k in range(3):
1982 self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int)
1983 self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301984
Victor Stinner59e2d262020-01-21 12:48:16 +01001985 @requires_IEEE_754
1986 def test_nextafter(self):
1987 # around 2^52 and 2^63
1988 self.assertEqual(math.nextafter(4503599627370496.0, -INF),
1989 4503599627370495.5)
1990 self.assertEqual(math.nextafter(4503599627370496.0, INF),
1991 4503599627370497.0)
1992 self.assertEqual(math.nextafter(9223372036854775808.0, 0.0),
1993 9223372036854774784.0)
1994 self.assertEqual(math.nextafter(-9223372036854775808.0, 0.0),
1995 -9223372036854774784.0)
1996
1997 # around 1.0
1998 self.assertEqual(math.nextafter(1.0, -INF),
1999 float.fromhex('0x1.fffffffffffffp-1'))
2000 self.assertEqual(math.nextafter(1.0, INF),
2001 float.fromhex('0x1.0000000000001p+0'))
2002
2003 # x == y: y is returned
2004 self.assertEqual(math.nextafter(2.0, 2.0), 2.0)
2005 self.assertEqualSign(math.nextafter(-0.0, +0.0), +0.0)
2006 self.assertEqualSign(math.nextafter(+0.0, -0.0), -0.0)
2007
2008 # around 0.0
2009 smallest_subnormal = sys.float_info.min * sys.float_info.epsilon
2010 self.assertEqual(math.nextafter(+0.0, INF), smallest_subnormal)
2011 self.assertEqual(math.nextafter(-0.0, INF), smallest_subnormal)
2012 self.assertEqual(math.nextafter(+0.0, -INF), -smallest_subnormal)
2013 self.assertEqual(math.nextafter(-0.0, -INF), -smallest_subnormal)
2014 self.assertEqualSign(math.nextafter(smallest_subnormal, +0.0), +0.0)
2015 self.assertEqualSign(math.nextafter(-smallest_subnormal, +0.0), -0.0)
2016 self.assertEqualSign(math.nextafter(smallest_subnormal, -0.0), +0.0)
2017 self.assertEqualSign(math.nextafter(-smallest_subnormal, -0.0), -0.0)
2018
2019 # around infinity
2020 largest_normal = sys.float_info.max
2021 self.assertEqual(math.nextafter(INF, 0.0), largest_normal)
2022 self.assertEqual(math.nextafter(-INF, 0.0), -largest_normal)
2023 self.assertEqual(math.nextafter(largest_normal, INF), INF)
2024 self.assertEqual(math.nextafter(-largest_normal, -INF), -INF)
2025
2026 # NaN
2027 self.assertIsNaN(math.nextafter(NAN, 1.0))
2028 self.assertIsNaN(math.nextafter(1.0, NAN))
2029 self.assertIsNaN(math.nextafter(NAN, NAN))
2030
2031 @requires_IEEE_754
2032 def test_ulp(self):
2033 self.assertEqual(math.ulp(1.0), sys.float_info.epsilon)
2034 # use int ** int rather than float ** int to not rely on pow() accuracy
2035 self.assertEqual(math.ulp(2 ** 52), 1.0)
2036 self.assertEqual(math.ulp(2 ** 53), 2.0)
2037 self.assertEqual(math.ulp(2 ** 64), 4096.0)
2038
2039 # min and max
2040 self.assertEqual(math.ulp(0.0),
2041 sys.float_info.min * sys.float_info.epsilon)
2042 self.assertEqual(math.ulp(FLOAT_MAX),
2043 FLOAT_MAX - math.nextafter(FLOAT_MAX, -INF))
2044
2045 # special cases
2046 self.assertEqual(math.ulp(INF), INF)
2047 self.assertIsNaN(math.ulp(math.nan))
2048
2049 # negative number: ulp(-x) == ulp(x)
2050 for x in (0.0, 1.0, 2 ** 52, 2 ** 64, INF):
2051 with self.subTest(x=x):
2052 self.assertEqual(math.ulp(-x), math.ulp(x))
2053
Zackery Spytz5208b4b2020-03-14 04:45:32 -06002054 def test_issue39871(self):
2055 # A SystemError should not be raised if the first arg to atan2(),
2056 # copysign(), or remainder() cannot be converted to a float.
2057 class F:
2058 def __float__(self):
2059 self.converted = True
2060 1/0
2061 for func in math.atan2, math.copysign, math.remainder:
2062 y = F()
2063 with self.assertRaises(TypeError):
2064 func("not a number", y)
2065
2066 # There should not have been any attempt to convert the second
2067 # argument to a float.
2068 self.assertFalse(getattr(y, "converted", False))
2069
Victor Stinner59e2d262020-01-21 12:48:16 +01002070 # Custom assertions.
2071
2072 def assertIsNaN(self, value):
2073 if not math.isnan(value):
2074 self.fail("Expected a NaN, got {!r}.".format(value))
2075
2076 def assertEqualSign(self, x, y):
2077 """Similar to assertEqual(), but compare also the sign with copysign().
2078
2079 Function useful to compare signed zeros.
2080 """
2081 self.assertEqual(x, y)
2082 self.assertEqual(math.copysign(1.0, x), math.copysign(1.0, y))
2083
2084
2085class IsCloseTests(unittest.TestCase):
2086 isclose = math.isclose # subclasses should override this
2087
2088 def assertIsClose(self, a, b, *args, **kwargs):
2089 self.assertTrue(self.isclose(a, b, *args, **kwargs),
2090 msg="%s and %s should be close!" % (a, b))
2091
2092 def assertIsNotClose(self, a, b, *args, **kwargs):
2093 self.assertFalse(self.isclose(a, b, *args, **kwargs),
2094 msg="%s and %s should not be close!" % (a, b))
2095
2096 def assertAllClose(self, examples, *args, **kwargs):
2097 for a, b in examples:
2098 self.assertIsClose(a, b, *args, **kwargs)
2099
2100 def assertAllNotClose(self, examples, *args, **kwargs):
2101 for a, b in examples:
2102 self.assertIsNotClose(a, b, *args, **kwargs)
2103
2104 def test_negative_tolerances(self):
2105 # ValueError should be raised if either tolerance is less than zero
2106 with self.assertRaises(ValueError):
2107 self.assertIsClose(1, 1, rel_tol=-1e-100)
2108 with self.assertRaises(ValueError):
2109 self.assertIsClose(1, 1, rel_tol=1e-100, abs_tol=-1e10)
2110
2111 def test_identical(self):
2112 # identical values must test as close
2113 identical_examples = [(2.0, 2.0),
2114 (0.1e200, 0.1e200),
2115 (1.123e-300, 1.123e-300),
2116 (12345, 12345.0),
2117 (0.0, -0.0),
2118 (345678, 345678)]
2119 self.assertAllClose(identical_examples, rel_tol=0.0, abs_tol=0.0)
2120
2121 def test_eight_decimal_places(self):
2122 # examples that are close to 1e-8, but not 1e-9
2123 eight_decimal_places_examples = [(1e8, 1e8 + 1),
2124 (-1e-8, -1.000000009e-8),
2125 (1.12345678, 1.12345679)]
2126 self.assertAllClose(eight_decimal_places_examples, rel_tol=1e-8)
2127 self.assertAllNotClose(eight_decimal_places_examples, rel_tol=1e-9)
2128
2129 def test_near_zero(self):
2130 # values close to zero
2131 near_zero_examples = [(1e-9, 0.0),
2132 (-1e-9, 0.0),
2133 (-1e-150, 0.0)]
2134 # these should not be close to any rel_tol
2135 self.assertAllNotClose(near_zero_examples, rel_tol=0.9)
2136 # these should be close to abs_tol=1e-8
2137 self.assertAllClose(near_zero_examples, abs_tol=1e-8)
2138
2139 def test_identical_infinite(self):
2140 # these are close regardless of tolerance -- i.e. they are equal
2141 self.assertIsClose(INF, INF)
2142 self.assertIsClose(INF, INF, abs_tol=0.0)
2143 self.assertIsClose(NINF, NINF)
2144 self.assertIsClose(NINF, NINF, abs_tol=0.0)
2145
2146 def test_inf_ninf_nan(self):
2147 # these should never be close (following IEEE 754 rules for equality)
2148 not_close_examples = [(NAN, NAN),
2149 (NAN, 1e-100),
2150 (1e-100, NAN),
2151 (INF, NAN),
2152 (NAN, INF),
2153 (INF, NINF),
2154 (INF, 1.0),
2155 (1.0, INF),
2156 (INF, 1e308),
2157 (1e308, INF)]
2158 # use largest reasonable tolerance
2159 self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999)
2160
2161 def test_zero_tolerance(self):
2162 # test with zero tolerance
2163 zero_tolerance_close_examples = [(1.0, 1.0),
2164 (-3.4, -3.4),
2165 (-1e-300, -1e-300)]
2166 self.assertAllClose(zero_tolerance_close_examples, rel_tol=0.0)
2167
2168 zero_tolerance_not_close_examples = [(1.0, 1.000000000000001),
2169 (0.99999999999999, 1.0),
2170 (1.0e200, .999999999999999e200)]
2171 self.assertAllNotClose(zero_tolerance_not_close_examples, rel_tol=0.0)
2172
2173 def test_asymmetry(self):
2174 # test the asymmetry example from PEP 485
2175 self.assertAllClose([(9, 10), (10, 9)], rel_tol=0.1)
2176
2177 def test_integers(self):
2178 # test with integer values
2179 integer_examples = [(100000001, 100000000),
2180 (123456789, 123456788)]
2181
2182 self.assertAllClose(integer_examples, rel_tol=1e-8)
2183 self.assertAllNotClose(integer_examples, rel_tol=1e-9)
2184
2185 def test_decimals(self):
2186 # test with Decimal values
2187 from decimal import Decimal
2188
2189 decimal_examples = [(Decimal('1.00000001'), Decimal('1.0')),
2190 (Decimal('1.00000001e-20'), Decimal('1.0e-20')),
2191 (Decimal('1.00000001e-100'), Decimal('1.0e-100')),
2192 (Decimal('1.00000001e20'), Decimal('1.0e20'))]
2193 self.assertAllClose(decimal_examples, rel_tol=1e-8)
2194 self.assertAllNotClose(decimal_examples, rel_tol=1e-9)
2195
2196 def test_fractions(self):
2197 # test with Fraction values
2198 from fractions import Fraction
2199
2200 fraction_examples = [
2201 (Fraction(1, 100000000) + 1, Fraction(1)),
2202 (Fraction(100000001), Fraction(100000000)),
2203 (Fraction(10**8 + 1, 10**28), Fraction(1, 10**20))]
2204 self.assertAllClose(fraction_examples, rel_tol=1e-8)
2205 self.assertAllNotClose(fraction_examples, rel_tol=1e-9)
2206
Pablo Galindo42079072019-02-10 19:56:58 +00002207
Thomas Wouters89f507f2006-12-13 04:49:30 +00002208def test_main():
Christian Heimes53876d92008-04-19 00:31:39 +00002209 from doctest import DocFileSuite
2210 suite = unittest.TestSuite()
2211 suite.addTest(unittest.makeSuite(MathTests))
Tal Einatd5519ed2015-05-31 22:05:00 +03002212 suite.addTest(unittest.makeSuite(IsCloseTests))
Christian Heimes53876d92008-04-19 00:31:39 +00002213 suite.addTest(DocFileSuite("ieee754.txt"))
2214 run_unittest(suite)
Thomas Wouters89f507f2006-12-13 04:49:30 +00002215
2216if __name__ == '__main__':
2217 test_main()