blob: bbaa533c8489eb71d02e11ee4906a1142c3a158d [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 """
133 with open(fname) as fp:
134 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 """
156 with open(fname) as fp:
157 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
614 at http://code.activestate.com/recipes/393090/
615
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 Hettinger457d4e92020-09-13 23:33:41 -0700806 def testHypotAccuracy(self):
807 # Verify improved accuracy in cases that were known to be inaccurate.
808
809 hypot = math.hypot
810 Decimal = decimal.Decimal
811 high_precision = decimal.Context(prec=500)
812
813 for hx, hy in [
814 # Cases with a 1 ulp error in Python 3.7 compiled with Clang
815 ('0x1.10e89518dca48p+29', '0x1.1970f7565b7efp+30'),
816 ('0x1.10106eb4b44a2p+29', '0x1.ef0596cdc97f8p+29'),
817 ('0x1.459c058e20bb7p+30', '0x1.993ca009b9178p+29'),
818 ('0x1.378371ae67c0cp+30', '0x1.fbe6619854b4cp+29'),
819 ('0x1.f4cd0574fb97ap+29', '0x1.50fe31669340ep+30'),
820 ('0x1.494b2cdd3d446p+29', '0x1.212a5367b4c7cp+29'),
821 ('0x1.f84e649f1e46dp+29', '0x1.1fa56bef8eec4p+30'),
822 ('0x1.2e817edd3d6fap+30', '0x1.eb0814f1e9602p+29'),
823 ('0x1.0d3a6e3d04245p+29', '0x1.32a62fea52352p+30'),
824 ('0x1.888e19611bfc5p+29', '0x1.52b8e70b24353p+29'),
825
826 # Cases with 2 ulp error in Python 3.8
827 ('0x1.538816d48a13fp+29', '0x1.7967c5ca43e16p+29'),
828 ('0x1.57b47b7234530p+29', '0x1.74e2c7040e772p+29'),
829 ('0x1.821b685e9b168p+30', '0x1.677dc1c1e3dc6p+29'),
830 ('0x1.9e8247f67097bp+29', '0x1.24bd2dc4f4baep+29'),
831 ('0x1.b73b59e0cb5f9p+29', '0x1.da899ab784a97p+28'),
832 ('0x1.94a8d2842a7cfp+30', '0x1.326a51d4d8d8ap+30'),
833 ('0x1.e930b9cd99035p+29', '0x1.5a1030e18dff9p+30'),
834 ('0x1.1592bbb0e4690p+29', '0x1.a9c337b33fb9ap+29'),
835 ('0x1.1243a50751fd4p+29', '0x1.a5a10175622d9p+29'),
836 ('0x1.57a8596e74722p+30', '0x1.42d1af9d04da9p+30'),
837
838 # Cases with 1 ulp error in version fff3c28052e6b0750d6218e00acacd2fded4991a
839 ('0x1.ee7dbd9565899p+29', '0x1.7ab4d6fc6e4b4p+29'),
840 ('0x1.5c6bfbec5c4dcp+30', '0x1.02511184b4970p+30'),
841 ('0x1.59dcebba995cap+30', '0x1.50ca7e7c38854p+29'),
842 ('0x1.768cdd94cf5aap+29', '0x1.9cfdc5571d38ep+29'),
843 ('0x1.dcf137d60262ep+29', '0x1.1101621990b3ep+30'),
844 ('0x1.3a2d006e288b0p+30', '0x1.e9a240914326cp+29'),
845 ('0x1.62a32f7f53c61p+29', '0x1.47eb6cd72684fp+29'),
846 ('0x1.d3bcb60748ef2p+29', '0x1.3f13c4056312cp+30'),
847 ('0x1.282bdb82f17f3p+30', '0x1.640ba4c4eed3ap+30'),
848 ('0x1.89d8c423ea0c6p+29', '0x1.d35dcfe902bc3p+29'),
849 ]:
850 with self.subTest(hx=hx, hy=hy):
851 x = float.fromhex(hx)
852 y = float.fromhex(hy)
853 with decimal.localcontext(high_precision):
854 z = float((Decimal(x)**2 + Decimal(y)**2).sqrt())
855 self.assertEqual(hypot(x, y), z)
856
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700857 def testDist(self):
858 from decimal import Decimal as D
859 from fractions import Fraction as F
860
861 dist = math.dist
862 sqrt = math.sqrt
863
Raymond Hettinger808180c2019-01-28 13:59:56 -0800864 # Simple exact cases
865 self.assertEqual(dist((1.0, 2.0, 3.0), (4.0, 2.0, -1.0)), 5.0)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700866 self.assertEqual(dist((1, 2, 3), (4, 2, -1)), 5.0)
867
868 # Test different numbers of arguments (from zero to nine)
869 # against a straightforward pure python implementation
870 for i in range(9):
871 for j in range(5):
872 p = tuple(random.uniform(-5, 5) for k in range(i))
873 q = tuple(random.uniform(-5, 5) for k in range(i))
874 self.assertAlmostEqual(
875 dist(p, q),
876 sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
877 )
878
Raymond Hettinger6b5f1b42019-07-27 14:04:29 -0700879 # Test non-tuple inputs
880 self.assertEqual(dist([1.0, 2.0, 3.0], [4.0, 2.0, -1.0]), 5.0)
881 self.assertEqual(dist(iter([1.0, 2.0, 3.0]), iter([4.0, 2.0, -1.0])), 5.0)
882
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700883 # Test allowable types (those with __float__)
884 self.assertEqual(dist((14.0, 1.0), (2.0, -4.0)), 13.0)
885 self.assertEqual(dist((14, 1), (2, -4)), 13)
886 self.assertEqual(dist((D(14), D(1)), (D(2), D(-4))), D(13))
887 self.assertEqual(dist((F(14, 32), F(1, 32)), (F(2, 32), F(-4, 32))),
888 F(13, 32))
889 self.assertEqual(dist((True, True, False, True, False),
890 (True, False, True, True, False)),
891 sqrt(2.0))
892
893 # Test corner cases
894 self.assertEqual(dist((13.25, 12.5, -3.25),
895 (13.25, 12.5, -3.25)),
896 0.0) # Distance with self is zero
897 self.assertEqual(dist((), ()), 0.0) # Zero-dimensional case
898 self.assertEqual(1.0, # Convert negative zero to positive zero
899 math.copysign(1.0, dist((-0.0,), (0.0,)))
900 )
901 self.assertEqual(1.0, # Convert negative zero to positive zero
902 math.copysign(1.0, dist((0.0,), (-0.0,)))
903 )
Raymond Hettinger00414592018-08-12 12:15:23 -0700904 self.assertEqual( # Handling of moving max to the end
905 dist((1.5, 1.5, 0.5), (0, 0, 0)),
906 dist((1.5, 0.5, 1.5), (0, 0, 0))
907 )
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700908
909 # Verify tuple subclasses are allowed
Raymond Hettinger00414592018-08-12 12:15:23 -0700910 class T(tuple):
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700911 pass
912 self.assertEqual(dist(T((1, 2, 3)), ((4, 2, -1))), 5.0)
913
914 # Test handling of bad arguments
915 with self.assertRaises(TypeError): # Reject keyword args
916 dist(p=(1, 2, 3), q=(4, 5, 6))
917 with self.assertRaises(TypeError): # Too few args
918 dist((1, 2, 3))
919 with self.assertRaises(TypeError): # Too many args
920 dist((1, 2, 3), (4, 5, 6), (7, 8, 9))
921 with self.assertRaises(TypeError): # Scalars not allowed
922 dist(1, 2)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700923 with self.assertRaises(TypeError): # Reject values without __float__
924 dist((1.1, 'string', 2.2), (1, 2, 3))
925 with self.assertRaises(ValueError): # Check dimension agree
926 dist((1, 2, 3, 4), (5, 6, 7))
927 with self.assertRaises(ValueError): # Check dimension agree
928 dist((1, 2, 3), (4, 5, 6, 7))
Ammar Askarcb08a712019-01-12 01:23:41 -0500929 with self.assertRaises(TypeError): # Rejects invalid types
930 dist("abc", "xyz")
Raymond Hettinger808180c2019-01-28 13:59:56 -0800931 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
932 with self.assertRaises((ValueError, OverflowError)):
933 dist((1, int_too_big_for_float), (2, 3))
934 with self.assertRaises((ValueError, OverflowError)):
935 dist((2, 3), (1, int_too_big_for_float))
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700936
Raymond Hettinger00414592018-08-12 12:15:23 -0700937 # Verify that the one dimensional case is equivalent to abs()
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700938 for i in range(20):
939 p, q = random.random(), random.random()
940 self.assertEqual(dist((p,), (q,)), abs(p - q))
941
942 # Test special values
943 values = [NINF, -10.5, -0.0, 0.0, 10.5, INF, NAN]
944 for p in itertools.product(values, repeat=3):
945 for q in itertools.product(values, repeat=3):
946 diffs = [px - qx for px, qx in zip(p, q)]
947 if any(map(math.isinf, diffs)):
948 # Any infinite difference gives positive infinity.
949 self.assertEqual(dist(p, q), INF)
950 elif any(map(math.isnan, diffs)):
Raymond Hettinger00414592018-08-12 12:15:23 -0700951 # If no infinity, any NaN gives a NaN.
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700952 self.assertTrue(math.isnan(dist(p, q)))
953
954 # Verify scaling for extremely large values
955 fourthmax = FLOAT_MAX / 4.0
956 for n in range(32):
957 p = (fourthmax,) * n
958 q = (0.0,) * n
Raymond Hettingerfff3c282020-08-15 19:38:19 -0700959 self.assertTrue(math.isclose(dist(p, q), fourthmax * math.sqrt(n)))
960 self.assertTrue(math.isclose(dist(q, p), fourthmax * math.sqrt(n)))
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700961
962 # Verify scaling for extremely small values
963 for exp in range(32):
964 scale = FLOAT_MIN / 2.0 ** exp
965 p = (4*scale, 3*scale)
966 q = (0.0, 0.0)
967 self.assertEqual(math.dist(p, q), 5*scale)
968 self.assertEqual(math.dist(q, p), 5*scale)
969
Mark Dickinson73934b92019-05-18 12:29:50 +0100970 def testIsqrt(self):
971 # Test a variety of inputs, large and small.
972 test_values = (
973 list(range(1000))
974 + list(range(10**6 - 1000, 10**6 + 1000))
Mark Dickinson5c08ce92019-05-19 17:51:56 +0100975 + [2**e + i for e in range(60, 200) for i in range(-40, 40)]
Mark Dickinson73934b92019-05-18 12:29:50 +0100976 + [3**9999, 10**5001]
977 )
978
979 for value in test_values:
980 with self.subTest(value=value):
981 s = math.isqrt(value)
982 self.assertIs(type(s), int)
983 self.assertLessEqual(s*s, value)
984 self.assertLess(value, (s+1)*(s+1))
985
986 # Negative values
987 with self.assertRaises(ValueError):
988 math.isqrt(-1)
989
990 # Integer-like things
991 s = math.isqrt(True)
992 self.assertIs(type(s), int)
993 self.assertEqual(s, 1)
994
995 s = math.isqrt(False)
996 self.assertIs(type(s), int)
997 self.assertEqual(s, 0)
998
999 class IntegerLike(object):
1000 def __init__(self, value):
1001 self.value = value
1002
1003 def __index__(self):
1004 return self.value
1005
1006 s = math.isqrt(IntegerLike(1729))
1007 self.assertIs(type(s), int)
1008 self.assertEqual(s, 41)
1009
1010 with self.assertRaises(ValueError):
1011 math.isqrt(IntegerLike(-3))
1012
1013 # Non-integer-like things
1014 bad_values = [
1015 3.5, "a string", decimal.Decimal("3.5"), 3.5j,
1016 100.0, -4.0,
1017 ]
1018 for value in bad_values:
1019 with self.subTest(value=value):
1020 with self.assertRaises(TypeError):
1021 math.isqrt(value)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -07001022
ananthan-123f2ee21d2020-02-19 23:51:37 +05301023 def test_lcm(self):
1024 lcm = math.lcm
1025 self.assertEqual(lcm(0, 0), 0)
1026 self.assertEqual(lcm(1, 0), 0)
1027 self.assertEqual(lcm(-1, 0), 0)
1028 self.assertEqual(lcm(0, 1), 0)
1029 self.assertEqual(lcm(0, -1), 0)
1030 self.assertEqual(lcm(7, 1), 7)
1031 self.assertEqual(lcm(7, -1), 7)
1032 self.assertEqual(lcm(-23, 15), 345)
1033 self.assertEqual(lcm(120, 84), 840)
1034 self.assertEqual(lcm(84, -120), 840)
1035 self.assertEqual(lcm(1216342683557601535506311712,
1036 436522681849110124616458784),
1037 16592536571065866494401400422922201534178938447014944)
Serhiy Storchaka559e7f12020-02-23 13:21:29 +02001038
ananthan-123f2ee21d2020-02-19 23:51:37 +05301039 x = 43461045657039990237
1040 y = 10645022458251153277
ananthan-123f2ee21d2020-02-19 23:51:37 +05301041 for c in (652560,
1042 57655923087165495981):
1043 a = x * c
1044 b = y * c
1045 d = x * y * c
1046 self.assertEqual(lcm(a, b), d)
1047 self.assertEqual(lcm(b, a), d)
1048 self.assertEqual(lcm(-a, b), d)
1049 self.assertEqual(lcm(b, -a), d)
1050 self.assertEqual(lcm(a, -b), d)
1051 self.assertEqual(lcm(-b, a), d)
1052 self.assertEqual(lcm(-a, -b), d)
1053 self.assertEqual(lcm(-b, -a), d)
Serhiy Storchaka559e7f12020-02-23 13:21:29 +02001054
1055 self.assertEqual(lcm(), 1)
1056 self.assertEqual(lcm(120), 120)
1057 self.assertEqual(lcm(-120), 120)
1058 self.assertEqual(lcm(120, 84, 102), 14280)
1059 self.assertEqual(lcm(120, 0, 84), 0)
1060
1061 self.assertRaises(TypeError, lcm, 120.0)
ananthan-123f2ee21d2020-02-19 23:51:37 +05301062 self.assertRaises(TypeError, lcm, 120.0, 84)
1063 self.assertRaises(TypeError, lcm, 120, 84.0)
Serhiy Storchaka559e7f12020-02-23 13:21:29 +02001064 self.assertRaises(TypeError, lcm, 120, 0, 84.0)
1065 self.assertEqual(lcm(MyIndexable(120), MyIndexable(84)), 840)
ananthan-123f2ee21d2020-02-19 23:51:37 +05301066
Thomas Wouters89f507f2006-12-13 04:49:30 +00001067 def testLdexp(self):
1068 self.assertRaises(TypeError, math.ldexp)
1069 self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
1070 self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
1071 self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
1072 self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
Christian Heimes53876d92008-04-19 00:31:39 +00001073 self.assertRaises(OverflowError, math.ldexp, 1., 1000000)
1074 self.assertRaises(OverflowError, math.ldexp, -1., 1000000)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001075 self.assertEqual(math.ldexp(1., -1000000), 0.)
1076 self.assertEqual(math.ldexp(-1., -1000000), -0.)
1077 self.assertEqual(math.ldexp(INF, 30), INF)
1078 self.assertEqual(math.ldexp(NINF, -213), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001079 self.assertTrue(math.isnan(math.ldexp(NAN, 0)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001080
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001081 # large second argument
1082 for n in [10**5, 10**10, 10**20, 10**40]:
Ezio Melottib3aedd42010-11-20 19:04:17 +00001083 self.assertEqual(math.ldexp(INF, -n), INF)
1084 self.assertEqual(math.ldexp(NINF, -n), NINF)
1085 self.assertEqual(math.ldexp(1., -n), 0.)
1086 self.assertEqual(math.ldexp(-1., -n), -0.)
1087 self.assertEqual(math.ldexp(0., -n), 0.)
1088 self.assertEqual(math.ldexp(-0., -n), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001089 self.assertTrue(math.isnan(math.ldexp(NAN, -n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001090
1091 self.assertRaises(OverflowError, math.ldexp, 1., n)
1092 self.assertRaises(OverflowError, math.ldexp, -1., n)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001093 self.assertEqual(math.ldexp(0., n), 0.)
1094 self.assertEqual(math.ldexp(-0., n), -0.)
1095 self.assertEqual(math.ldexp(INF, n), INF)
1096 self.assertEqual(math.ldexp(NINF, n), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001097 self.assertTrue(math.isnan(math.ldexp(NAN, n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001098
Thomas Wouters89f507f2006-12-13 04:49:30 +00001099 def testLog(self):
1100 self.assertRaises(TypeError, math.log)
1101 self.ftest('log(1/e)', math.log(1/math.e), -1)
1102 self.ftest('log(1)', math.log(1), 0)
1103 self.ftest('log(e)', math.log(math.e), 1)
1104 self.ftest('log(32,2)', math.log(32,2), 5)
1105 self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
1106 self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001107 self.ftest('log(10**1000)', math.log(10**1000),
1108 2302.5850929940457)
1109 self.assertRaises(ValueError, math.log, -1.5)
1110 self.assertRaises(ValueError, math.log, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001111 self.assertRaises(ValueError, math.log, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001112 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001113 self.assertTrue(math.isnan(math.log(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001114
1115 def testLog1p(self):
1116 self.assertRaises(TypeError, math.log1p)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001117 for n in [2, 2**90, 2**300]:
1118 self.assertAlmostEqual(math.log1p(n), math.log1p(float(n)))
1119 self.assertRaises(ValueError, math.log1p, -1)
1120 self.assertEqual(math.log1p(INF), INF)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001121
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001122 @requires_IEEE_754
1123 def testLog2(self):
1124 self.assertRaises(TypeError, math.log2)
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001125
1126 # Check some integer values
1127 self.assertEqual(math.log2(1), 0.0)
1128 self.assertEqual(math.log2(2), 1.0)
1129 self.assertEqual(math.log2(4), 2.0)
1130
1131 # Large integer values
1132 self.assertEqual(math.log2(2**1023), 1023.0)
1133 self.assertEqual(math.log2(2**1024), 1024.0)
1134 self.assertEqual(math.log2(2**2000), 2000.0)
1135
1136 self.assertRaises(ValueError, math.log2, -1.5)
1137 self.assertRaises(ValueError, math.log2, NINF)
1138 self.assertTrue(math.isnan(math.log2(NAN)))
1139
Victor Stinnercd9dd372011-05-10 23:40:17 +02001140 @requires_IEEE_754
Victor Stinnerebbbdaf2011-06-01 13:19:07 +02001141 # log2() is not accurate enough on Mac OS X Tiger (10.4)
1142 @support.requires_mac_ver(10, 5)
Victor Stinnercd9dd372011-05-10 23:40:17 +02001143 def testLog2Exact(self):
1144 # Check that we get exact equality for log2 of powers of 2.
1145 actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)]
1146 expected = [float(n) for n in range(-1074, 1024)]
1147 self.assertEqual(actual, expected)
1148
Thomas Wouters89f507f2006-12-13 04:49:30 +00001149 def testLog10(self):
1150 self.assertRaises(TypeError, math.log10)
1151 self.ftest('log10(0.1)', math.log10(0.1), -1)
1152 self.ftest('log10(1)', math.log10(1), 0)
1153 self.ftest('log10(10)', math.log10(10), 1)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001154 self.ftest('log10(10**1000)', math.log10(10**1000), 1000.0)
1155 self.assertRaises(ValueError, math.log10, -1.5)
1156 self.assertRaises(ValueError, math.log10, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001157 self.assertRaises(ValueError, math.log10, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001158 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001159 self.assertTrue(math.isnan(math.log10(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001160
Thomas Wouters89f507f2006-12-13 04:49:30 +00001161 def testModf(self):
1162 self.assertRaises(TypeError, math.modf)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001163
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001164 def testmodf(name, result, expected):
1165 (v1, v2), (e1, e2) = result, expected
Thomas Wouters89f507f2006-12-13 04:49:30 +00001166 if abs(v1-e1) > eps or abs(v2-e2):
1167 self.fail('%s returned %r, expected %r'%\
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001168 (name, result, expected))
Raymond Hettinger64108af2002-05-13 03:55:01 +00001169
Thomas Wouters89f507f2006-12-13 04:49:30 +00001170 testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
1171 testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001172
Ezio Melottib3aedd42010-11-20 19:04:17 +00001173 self.assertEqual(math.modf(INF), (0.0, INF))
1174 self.assertEqual(math.modf(NINF), (-0.0, NINF))
Christian Heimes53876d92008-04-19 00:31:39 +00001175
1176 modf_nan = math.modf(NAN)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001177 self.assertTrue(math.isnan(modf_nan[0]))
1178 self.assertTrue(math.isnan(modf_nan[1]))
Christian Heimes53876d92008-04-19 00:31:39 +00001179
Thomas Wouters89f507f2006-12-13 04:49:30 +00001180 def testPow(self):
1181 self.assertRaises(TypeError, math.pow)
1182 self.ftest('pow(0,1)', math.pow(0,1), 0)
1183 self.ftest('pow(1,0)', math.pow(1,0), 1)
1184 self.ftest('pow(2,1)', math.pow(2,1), 2)
1185 self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
Christian Heimes53876d92008-04-19 00:31:39 +00001186 self.assertEqual(math.pow(INF, 1), INF)
1187 self.assertEqual(math.pow(NINF, 1), NINF)
1188 self.assertEqual((math.pow(1, INF)), 1.)
1189 self.assertEqual((math.pow(1, NINF)), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001190 self.assertTrue(math.isnan(math.pow(NAN, 1)))
1191 self.assertTrue(math.isnan(math.pow(2, NAN)))
1192 self.assertTrue(math.isnan(math.pow(0, NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001193 self.assertEqual(math.pow(1, NAN), 1)
Christian Heimesa342c012008-04-20 21:01:16 +00001194
1195 # pow(0., x)
1196 self.assertEqual(math.pow(0., INF), 0.)
1197 self.assertEqual(math.pow(0., 3.), 0.)
1198 self.assertEqual(math.pow(0., 2.3), 0.)
1199 self.assertEqual(math.pow(0., 2.), 0.)
1200 self.assertEqual(math.pow(0., 0.), 1.)
1201 self.assertEqual(math.pow(0., -0.), 1.)
1202 self.assertRaises(ValueError, math.pow, 0., -2.)
1203 self.assertRaises(ValueError, math.pow, 0., -2.3)
1204 self.assertRaises(ValueError, math.pow, 0., -3.)
1205 self.assertRaises(ValueError, math.pow, 0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001206 self.assertTrue(math.isnan(math.pow(0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001207
1208 # pow(INF, x)
1209 self.assertEqual(math.pow(INF, INF), INF)
1210 self.assertEqual(math.pow(INF, 3.), INF)
1211 self.assertEqual(math.pow(INF, 2.3), INF)
1212 self.assertEqual(math.pow(INF, 2.), INF)
1213 self.assertEqual(math.pow(INF, 0.), 1.)
1214 self.assertEqual(math.pow(INF, -0.), 1.)
1215 self.assertEqual(math.pow(INF, -2.), 0.)
1216 self.assertEqual(math.pow(INF, -2.3), 0.)
1217 self.assertEqual(math.pow(INF, -3.), 0.)
1218 self.assertEqual(math.pow(INF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001219 self.assertTrue(math.isnan(math.pow(INF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001220
1221 # pow(-0., x)
1222 self.assertEqual(math.pow(-0., INF), 0.)
1223 self.assertEqual(math.pow(-0., 3.), -0.)
1224 self.assertEqual(math.pow(-0., 2.3), 0.)
1225 self.assertEqual(math.pow(-0., 2.), 0.)
1226 self.assertEqual(math.pow(-0., 0.), 1.)
1227 self.assertEqual(math.pow(-0., -0.), 1.)
1228 self.assertRaises(ValueError, math.pow, -0., -2.)
1229 self.assertRaises(ValueError, math.pow, -0., -2.3)
1230 self.assertRaises(ValueError, math.pow, -0., -3.)
1231 self.assertRaises(ValueError, math.pow, -0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001232 self.assertTrue(math.isnan(math.pow(-0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001233
1234 # pow(NINF, x)
1235 self.assertEqual(math.pow(NINF, INF), INF)
1236 self.assertEqual(math.pow(NINF, 3.), NINF)
1237 self.assertEqual(math.pow(NINF, 2.3), INF)
1238 self.assertEqual(math.pow(NINF, 2.), INF)
1239 self.assertEqual(math.pow(NINF, 0.), 1.)
1240 self.assertEqual(math.pow(NINF, -0.), 1.)
1241 self.assertEqual(math.pow(NINF, -2.), 0.)
1242 self.assertEqual(math.pow(NINF, -2.3), 0.)
1243 self.assertEqual(math.pow(NINF, -3.), -0.)
1244 self.assertEqual(math.pow(NINF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001245 self.assertTrue(math.isnan(math.pow(NINF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001246
1247 # pow(-1, x)
1248 self.assertEqual(math.pow(-1., INF), 1.)
1249 self.assertEqual(math.pow(-1., 3.), -1.)
1250 self.assertRaises(ValueError, math.pow, -1., 2.3)
1251 self.assertEqual(math.pow(-1., 2.), 1.)
1252 self.assertEqual(math.pow(-1., 0.), 1.)
1253 self.assertEqual(math.pow(-1., -0.), 1.)
1254 self.assertEqual(math.pow(-1., -2.), 1.)
1255 self.assertRaises(ValueError, math.pow, -1., -2.3)
1256 self.assertEqual(math.pow(-1., -3.), -1.)
1257 self.assertEqual(math.pow(-1., NINF), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001258 self.assertTrue(math.isnan(math.pow(-1., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001259
1260 # pow(1, x)
1261 self.assertEqual(math.pow(1., INF), 1.)
1262 self.assertEqual(math.pow(1., 3.), 1.)
1263 self.assertEqual(math.pow(1., 2.3), 1.)
1264 self.assertEqual(math.pow(1., 2.), 1.)
1265 self.assertEqual(math.pow(1., 0.), 1.)
1266 self.assertEqual(math.pow(1., -0.), 1.)
1267 self.assertEqual(math.pow(1., -2.), 1.)
1268 self.assertEqual(math.pow(1., -2.3), 1.)
1269 self.assertEqual(math.pow(1., -3.), 1.)
1270 self.assertEqual(math.pow(1., NINF), 1.)
1271 self.assertEqual(math.pow(1., NAN), 1.)
1272
1273 # pow(x, 0) should be 1 for any x
1274 self.assertEqual(math.pow(2.3, 0.), 1.)
1275 self.assertEqual(math.pow(-2.3, 0.), 1.)
1276 self.assertEqual(math.pow(NAN, 0.), 1.)
1277 self.assertEqual(math.pow(2.3, -0.), 1.)
1278 self.assertEqual(math.pow(-2.3, -0.), 1.)
1279 self.assertEqual(math.pow(NAN, -0.), 1.)
1280
1281 # pow(x, y) is invalid if x is negative and y is not integral
1282 self.assertRaises(ValueError, math.pow, -1., 2.3)
1283 self.assertRaises(ValueError, math.pow, -15., -3.1)
1284
1285 # pow(x, NINF)
1286 self.assertEqual(math.pow(1.9, NINF), 0.)
1287 self.assertEqual(math.pow(1.1, NINF), 0.)
1288 self.assertEqual(math.pow(0.9, NINF), INF)
1289 self.assertEqual(math.pow(0.1, NINF), INF)
1290 self.assertEqual(math.pow(-0.1, NINF), INF)
1291 self.assertEqual(math.pow(-0.9, NINF), INF)
1292 self.assertEqual(math.pow(-1.1, NINF), 0.)
1293 self.assertEqual(math.pow(-1.9, NINF), 0.)
1294
1295 # pow(x, INF)
1296 self.assertEqual(math.pow(1.9, INF), INF)
1297 self.assertEqual(math.pow(1.1, INF), INF)
1298 self.assertEqual(math.pow(0.9, INF), 0.)
1299 self.assertEqual(math.pow(0.1, INF), 0.)
1300 self.assertEqual(math.pow(-0.1, INF), 0.)
1301 self.assertEqual(math.pow(-0.9, INF), 0.)
1302 self.assertEqual(math.pow(-1.1, INF), INF)
1303 self.assertEqual(math.pow(-1.9, INF), INF)
1304
1305 # pow(x, y) should work for x negative, y an integer
1306 self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
1307 self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
1308 self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
1309 self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
1310 self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
1311 self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
1312 self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
1313 self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
1314 self.assertRaises(ValueError, math.pow, -2.0, -0.5)
1315 self.assertRaises(ValueError, math.pow, -2.0, 0.5)
1316
1317 # the following tests have been commented out since they don't
1318 # really belong here: the implementation of ** for floats is
Ezio Melotti13925002011-03-16 11:05:33 +02001319 # independent of the implementation of math.pow
Christian Heimesa342c012008-04-20 21:01:16 +00001320 #self.assertEqual(1**NAN, 1)
1321 #self.assertEqual(1**INF, 1)
1322 #self.assertEqual(1**NINF, 1)
1323 #self.assertEqual(1**0, 1)
1324 #self.assertEqual(1.**NAN, 1)
1325 #self.assertEqual(1.**INF, 1)
1326 #self.assertEqual(1.**NINF, 1)
1327 #self.assertEqual(1.**0, 1)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001328
Thomas Wouters89f507f2006-12-13 04:49:30 +00001329 def testRadians(self):
1330 self.assertRaises(TypeError, math.radians)
1331 self.ftest('radians(180)', math.radians(180), math.pi)
1332 self.ftest('radians(90)', math.radians(90), math.pi/2)
1333 self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001334 self.ftest('radians(0)', math.radians(0), 0)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001335
Mark Dickinsona0ce3752017-04-05 18:34:27 +01001336 @requires_IEEE_754
1337 def testRemainder(self):
1338 from fractions import Fraction
1339
1340 def validate_spec(x, y, r):
1341 """
1342 Check that r matches remainder(x, y) according to the IEEE 754
1343 specification. Assumes that x, y and r are finite and y is nonzero.
1344 """
1345 fx, fy, fr = Fraction(x), Fraction(y), Fraction(r)
1346 # r should not exceed y/2 in absolute value
1347 self.assertLessEqual(abs(fr), abs(fy/2))
1348 # x - r should be an exact integer multiple of y
1349 n = (fx - fr) / fy
1350 self.assertEqual(n, int(n))
1351 if abs(fr) == abs(fy/2):
1352 # If |r| == |y/2|, n should be even.
1353 self.assertEqual(n/2, int(n/2))
1354
1355 # triples (x, y, remainder(x, y)) in hexadecimal form.
1356 testcases = [
1357 # Remainders modulo 1, showing the ties-to-even behaviour.
1358 '-4.0 1 -0.0',
1359 '-3.8 1 0.8',
1360 '-3.0 1 -0.0',
1361 '-2.8 1 -0.8',
1362 '-2.0 1 -0.0',
1363 '-1.8 1 0.8',
1364 '-1.0 1 -0.0',
1365 '-0.8 1 -0.8',
1366 '-0.0 1 -0.0',
1367 ' 0.0 1 0.0',
1368 ' 0.8 1 0.8',
1369 ' 1.0 1 0.0',
1370 ' 1.8 1 -0.8',
1371 ' 2.0 1 0.0',
1372 ' 2.8 1 0.8',
1373 ' 3.0 1 0.0',
1374 ' 3.8 1 -0.8',
1375 ' 4.0 1 0.0',
1376
1377 # Reductions modulo 2*pi
1378 '0x0.0p+0 0x1.921fb54442d18p+2 0x0.0p+0',
1379 '0x1.921fb54442d18p+0 0x1.921fb54442d18p+2 0x1.921fb54442d18p+0',
1380 '0x1.921fb54442d17p+1 0x1.921fb54442d18p+2 0x1.921fb54442d17p+1',
1381 '0x1.921fb54442d18p+1 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1382 '0x1.921fb54442d19p+1 0x1.921fb54442d18p+2 -0x1.921fb54442d17p+1',
1383 '0x1.921fb54442d17p+2 0x1.921fb54442d18p+2 -0x0.0000000000001p+2',
1384 '0x1.921fb54442d18p+2 0x1.921fb54442d18p+2 0x0p0',
1385 '0x1.921fb54442d19p+2 0x1.921fb54442d18p+2 0x0.0000000000001p+2',
1386 '0x1.2d97c7f3321d1p+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1387 '0x1.2d97c7f3321d2p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d18p+1',
1388 '0x1.2d97c7f3321d3p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1389 '0x1.921fb54442d17p+3 0x1.921fb54442d18p+2 -0x0.0000000000001p+3',
1390 '0x1.921fb54442d18p+3 0x1.921fb54442d18p+2 0x0p0',
1391 '0x1.921fb54442d19p+3 0x1.921fb54442d18p+2 0x0.0000000000001p+3',
1392 '0x1.f6a7a2955385dp+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1393 '0x1.f6a7a2955385ep+3 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1394 '0x1.f6a7a2955385fp+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1395 '0x1.1475cc9eedf00p+5 0x1.921fb54442d18p+2 0x1.921fb54442d10p+1',
1396 '0x1.1475cc9eedf01p+5 0x1.921fb54442d18p+2 -0x1.921fb54442d10p+1',
1397
1398 # Symmetry with respect to signs.
1399 ' 1 0.c 0.4',
1400 '-1 0.c -0.4',
1401 ' 1 -0.c 0.4',
1402 '-1 -0.c -0.4',
1403 ' 1.4 0.c -0.4',
1404 '-1.4 0.c 0.4',
1405 ' 1.4 -0.c -0.4',
1406 '-1.4 -0.c 0.4',
1407
1408 # Huge modulus, to check that the underlying algorithm doesn't
1409 # rely on 2.0 * modulus being representable.
1410 '0x1.dp+1023 0x1.4p+1023 0x0.9p+1023',
1411 '0x1.ep+1023 0x1.4p+1023 -0x0.ap+1023',
1412 '0x1.fp+1023 0x1.4p+1023 -0x0.9p+1023',
1413 ]
1414
1415 for case in testcases:
1416 with self.subTest(case=case):
1417 x_hex, y_hex, expected_hex = case.split()
1418 x = float.fromhex(x_hex)
1419 y = float.fromhex(y_hex)
1420 expected = float.fromhex(expected_hex)
1421 validate_spec(x, y, expected)
1422 actual = math.remainder(x, y)
1423 # Cheap way of checking that the floats are
1424 # as identical as we need them to be.
1425 self.assertEqual(actual.hex(), expected.hex())
1426
1427 # Test tiny subnormal modulus: there's potential for
1428 # getting the implementation wrong here (for example,
1429 # by assuming that modulus/2 is exactly representable).
1430 tiny = float.fromhex('1p-1074') # min +ve subnormal
1431 for n in range(-25, 25):
1432 if n == 0:
1433 continue
1434 y = n * tiny
1435 for m in range(100):
1436 x = m * tiny
1437 actual = math.remainder(x, y)
1438 validate_spec(x, y, actual)
1439 actual = math.remainder(-x, y)
1440 validate_spec(-x, y, actual)
1441
1442 # Special values.
1443 # NaNs should propagate as usual.
1444 for value in [NAN, 0.0, -0.0, 2.0, -2.3, NINF, INF]:
1445 self.assertIsNaN(math.remainder(NAN, value))
1446 self.assertIsNaN(math.remainder(value, NAN))
1447
1448 # remainder(x, inf) is x, for non-nan non-infinite x.
1449 for value in [-2.3, -0.0, 0.0, 2.3]:
1450 self.assertEqual(math.remainder(value, INF), value)
1451 self.assertEqual(math.remainder(value, NINF), value)
1452
1453 # remainder(x, 0) and remainder(infinity, x) for non-NaN x are invalid
1454 # operations according to IEEE 754-2008 7.2(f), and should raise.
1455 for value in [NINF, -2.3, -0.0, 0.0, 2.3, INF]:
1456 with self.assertRaises(ValueError):
1457 math.remainder(INF, value)
1458 with self.assertRaises(ValueError):
1459 math.remainder(NINF, value)
1460 with self.assertRaises(ValueError):
1461 math.remainder(value, 0.0)
1462 with self.assertRaises(ValueError):
1463 math.remainder(value, -0.0)
1464
Thomas Wouters89f507f2006-12-13 04:49:30 +00001465 def testSin(self):
1466 self.assertRaises(TypeError, math.sin)
1467 self.ftest('sin(0)', math.sin(0), 0)
1468 self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
1469 self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001470 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001471 self.assertTrue(math.isnan(math.sin(INF)))
1472 self.assertTrue(math.isnan(math.sin(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001473 except ValueError:
1474 self.assertRaises(ValueError, math.sin, INF)
1475 self.assertRaises(ValueError, math.sin, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001476 self.assertTrue(math.isnan(math.sin(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001477
Thomas Wouters89f507f2006-12-13 04:49:30 +00001478 def testSinh(self):
1479 self.assertRaises(TypeError, math.sinh)
1480 self.ftest('sinh(0)', math.sinh(0), 0)
1481 self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
1482 self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001483 self.assertEqual(math.sinh(INF), INF)
1484 self.assertEqual(math.sinh(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001485 self.assertTrue(math.isnan(math.sinh(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001486
Thomas Wouters89f507f2006-12-13 04:49:30 +00001487 def testSqrt(self):
1488 self.assertRaises(TypeError, math.sqrt)
1489 self.ftest('sqrt(0)', math.sqrt(0), 0)
1490 self.ftest('sqrt(1)', math.sqrt(1), 1)
1491 self.ftest('sqrt(4)', math.sqrt(4), 2)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001492 self.assertEqual(math.sqrt(INF), INF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001493 self.assertRaises(ValueError, math.sqrt, -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001494 self.assertRaises(ValueError, math.sqrt, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001495 self.assertTrue(math.isnan(math.sqrt(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001496
Thomas Wouters89f507f2006-12-13 04:49:30 +00001497 def testTan(self):
1498 self.assertRaises(TypeError, math.tan)
1499 self.ftest('tan(0)', math.tan(0), 0)
1500 self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
1501 self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001502 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001503 self.assertTrue(math.isnan(math.tan(INF)))
1504 self.assertTrue(math.isnan(math.tan(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001505 except:
1506 self.assertRaises(ValueError, math.tan, INF)
1507 self.assertRaises(ValueError, math.tan, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001508 self.assertTrue(math.isnan(math.tan(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001509
Thomas Wouters89f507f2006-12-13 04:49:30 +00001510 def testTanh(self):
1511 self.assertRaises(TypeError, math.tanh)
1512 self.ftest('tanh(0)', math.tanh(0), 0)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001513 self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0,
Victor Stinner0b2ab212020-01-13 12:44:35 +01001514 abs_tol=math.ulp(1))
Christian Heimes53876d92008-04-19 00:31:39 +00001515 self.ftest('tanh(inf)', math.tanh(INF), 1)
1516 self.ftest('tanh(-inf)', math.tanh(NINF), -1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001517 self.assertTrue(math.isnan(math.tanh(NAN)))
Victor Stinnerbe3da382010-11-07 14:14:27 +00001518
1519 @requires_IEEE_754
Victor Stinnerbe3da382010-11-07 14:14:27 +00001520 def testTanhSign(self):
Christian Heimese57950f2008-04-21 13:08:03 +00001521 # check that tanh(-0.) == -0. on IEEE 754 systems
Victor Stinnerbe3da382010-11-07 14:14:27 +00001522 self.assertEqual(math.tanh(-0.), -0.)
1523 self.assertEqual(math.copysign(1., math.tanh(-0.)),
1524 math.copysign(1., -0.))
Tim Peters1d120612000-10-12 06:10:25 +00001525
Christian Heimes400adb02008-02-01 08:12:03 +00001526 def test_trunc(self):
1527 self.assertEqual(math.trunc(1), 1)
1528 self.assertEqual(math.trunc(-1), -1)
1529 self.assertEqual(type(math.trunc(1)), int)
1530 self.assertEqual(type(math.trunc(1.5)), int)
1531 self.assertEqual(math.trunc(1.5), 1)
1532 self.assertEqual(math.trunc(-1.5), -1)
1533 self.assertEqual(math.trunc(1.999999), 1)
1534 self.assertEqual(math.trunc(-1.999999), -1)
1535 self.assertEqual(math.trunc(-0.999999), -0)
1536 self.assertEqual(math.trunc(-100.999), -100)
1537
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001538 class TestTrunc:
Christian Heimes400adb02008-02-01 08:12:03 +00001539 def __trunc__(self):
1540 return 23
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001541 class FloatTrunc(float):
1542 def __trunc__(self):
1543 return 23
1544 class TestNoTrunc:
Christian Heimes400adb02008-02-01 08:12:03 +00001545 pass
1546
1547 self.assertEqual(math.trunc(TestTrunc()), 23)
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001548 self.assertEqual(math.trunc(FloatTrunc()), 23)
Christian Heimes400adb02008-02-01 08:12:03 +00001549
1550 self.assertRaises(TypeError, math.trunc)
1551 self.assertRaises(TypeError, math.trunc, 1, 2)
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001552 self.assertRaises(TypeError, math.trunc, FloatLike(23.5))
Christian Heimes400adb02008-02-01 08:12:03 +00001553 self.assertRaises(TypeError, math.trunc, TestNoTrunc())
1554
Mark Dickinson8e0c9962010-07-11 17:38:24 +00001555 def testIsfinite(self):
1556 self.assertTrue(math.isfinite(0.0))
1557 self.assertTrue(math.isfinite(-0.0))
1558 self.assertTrue(math.isfinite(1.0))
1559 self.assertTrue(math.isfinite(-1.0))
1560 self.assertFalse(math.isfinite(float("nan")))
1561 self.assertFalse(math.isfinite(float("inf")))
1562 self.assertFalse(math.isfinite(float("-inf")))
1563
Christian Heimes072c0f12008-01-03 23:01:04 +00001564 def testIsnan(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001565 self.assertTrue(math.isnan(float("nan")))
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001566 self.assertTrue(math.isnan(float("-nan")))
1567 self.assertTrue(math.isnan(float("inf") * 0.))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001568 self.assertFalse(math.isnan(float("inf")))
1569 self.assertFalse(math.isnan(0.))
1570 self.assertFalse(math.isnan(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001571
1572 def testIsinf(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001573 self.assertTrue(math.isinf(float("inf")))
1574 self.assertTrue(math.isinf(float("-inf")))
1575 self.assertTrue(math.isinf(1E400))
1576 self.assertTrue(math.isinf(-1E400))
1577 self.assertFalse(math.isinf(float("nan")))
1578 self.assertFalse(math.isinf(0.))
1579 self.assertFalse(math.isinf(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001580
Mark Dickinsona5d0c7c2015-01-11 11:55:29 +00001581 @requires_IEEE_754
1582 def test_nan_constant(self):
1583 self.assertTrue(math.isnan(math.nan))
1584
1585 @requires_IEEE_754
1586 def test_inf_constant(self):
1587 self.assertTrue(math.isinf(math.inf))
1588 self.assertGreater(math.inf, 0.0)
1589 self.assertEqual(math.inf, float("inf"))
1590 self.assertEqual(-math.inf, float("-inf"))
1591
Thomas Wouters89f507f2006-12-13 04:49:30 +00001592 # RED_FLAG 16-Oct-2000 Tim
1593 # While 2.0 is more consistent about exceptions than previous releases, it
1594 # still fails this part of the test on some platforms. For now, we only
1595 # *run* test_exceptions() in verbose mode, so that this isn't normally
1596 # tested.
Serhiy Storchaka43767632013-11-03 21:31:38 +02001597 @unittest.skipUnless(verbose, 'requires verbose mode')
1598 def test_exceptions(self):
1599 try:
1600 x = math.exp(-1000000000)
1601 except:
1602 # mathmodule.c is failing to weed out underflows from libm, or
1603 # we've got an fp format with huge dynamic range
1604 self.fail("underflowing exp() should not have raised "
1605 "an exception")
1606 if x != 0:
1607 self.fail("underflowing exp() should have returned 0")
Tim Peters98c81842000-10-16 17:35:13 +00001608
Serhiy Storchaka43767632013-11-03 21:31:38 +02001609 # If this fails, probably using a strict IEEE-754 conforming libm, and x
1610 # is +Inf afterwards. But Python wants overflows detected by default.
1611 try:
1612 x = math.exp(1000000000)
1613 except OverflowError:
1614 pass
1615 else:
1616 self.fail("overflowing exp() didn't trigger OverflowError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001617
Serhiy Storchaka43767632013-11-03 21:31:38 +02001618 # If this fails, it could be a puzzle. One odd possibility is that
1619 # mathmodule.c's macros are getting confused while comparing
1620 # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
1621 # as a result (and so raising OverflowError instead).
1622 try:
1623 x = math.sqrt(-1.0)
1624 except ValueError:
1625 pass
1626 else:
1627 self.fail("sqrt(-1) didn't raise ValueError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001628
Mark Dickinson63566232009-09-18 21:04:19 +00001629 @requires_IEEE_754
Christian Heimes53876d92008-04-19 00:31:39 +00001630 def test_testfile(self):
Mark Dickinson85746542016-09-04 09:58:51 +01001631 # Some tests need to be skipped on ancient OS X versions.
1632 # See issue #27953.
1633 SKIP_ON_TIGER = {'tan0064'}
1634
1635 osx_version = None
1636 if sys.platform == 'darwin':
1637 version_txt = platform.mac_ver()[0]
1638 try:
1639 osx_version = tuple(map(int, version_txt.split('.')))
1640 except ValueError:
1641 pass
1642
Mark Dickinson96f774d2016-09-03 19:30:22 +01001643 fail_fmt = "{}: {}({!r}): {}"
1644
1645 failures = []
Christian Heimes53876d92008-04-19 00:31:39 +00001646 for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001647 # Skip if either the input or result is complex
1648 if ai != 0.0 or ei != 0.0:
Christian Heimes53876d92008-04-19 00:31:39 +00001649 continue
1650 if fn in ['rect', 'polar']:
1651 # no real versions of rect, polar
1652 continue
Mark Dickinson85746542016-09-04 09:58:51 +01001653 # Skip certain tests on OS X 10.4.
1654 if osx_version is not None and osx_version < (10, 5):
1655 if id in SKIP_ON_TIGER:
1656 continue
Mark Dickinson96f774d2016-09-03 19:30:22 +01001657
Christian Heimes53876d92008-04-19 00:31:39 +00001658 func = getattr(math, fn)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001659
1660 if 'invalid' in flags or 'divide-by-zero' in flags:
1661 er = 'ValueError'
1662 elif 'overflow' in flags:
1663 er = 'OverflowError'
1664
Christian Heimesa342c012008-04-20 21:01:16 +00001665 try:
1666 result = func(ar)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001667 except ValueError:
1668 result = 'ValueError'
Benjamin Peterson2b7411d2008-05-26 17:36:47 +00001669 except OverflowError:
Mark Dickinson96f774d2016-09-03 19:30:22 +01001670 result = 'OverflowError'
1671
1672 # Default tolerances
1673 ulp_tol, abs_tol = 5, 0.0
1674
1675 failure = result_check(er, result, ulp_tol, abs_tol)
1676 if failure is None:
1677 continue
1678
1679 msg = fail_fmt.format(id, fn, ar, failure)
1680 failures.append(msg)
1681
1682 if failures:
1683 self.fail('Failures in test_testfile:\n ' +
1684 '\n '.join(failures))
Thomas Wouters89f507f2006-12-13 04:49:30 +00001685
Victor Stinnerbe3da382010-11-07 14:14:27 +00001686 @requires_IEEE_754
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001687 def test_mtestfile(self):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001688 fail_fmt = "{}: {}({!r}): {}"
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001689
1690 failures = []
1691 for id, fn, arg, expected, flags in parse_mtestfile(math_testcases):
1692 func = getattr(math, fn)
1693
1694 if 'invalid' in flags or 'divide-by-zero' in flags:
1695 expected = 'ValueError'
1696 elif 'overflow' in flags:
1697 expected = 'OverflowError'
1698
1699 try:
1700 got = func(arg)
1701 except ValueError:
1702 got = 'ValueError'
1703 except OverflowError:
1704 got = 'OverflowError'
1705
Mark Dickinson96f774d2016-09-03 19:30:22 +01001706 # Default tolerances
1707 ulp_tol, abs_tol = 5, 0.0
Mark Dickinsonbcdf9da2010-06-13 10:52:38 +00001708
Mark Dickinson96f774d2016-09-03 19:30:22 +01001709 # Exceptions to the defaults
1710 if fn == 'gamma':
1711 # Experimental results on one platform gave
1712 # an accuracy of <= 10 ulps across the entire float
1713 # domain. We weaken that to require 20 ulp accuracy.
1714 ulp_tol = 20
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001715
Mark Dickinson96f774d2016-09-03 19:30:22 +01001716 elif fn == 'lgamma':
1717 # we use a weaker accuracy test for lgamma;
1718 # lgamma only achieves an absolute error of
1719 # a few multiples of the machine accuracy, in
1720 # general.
1721 abs_tol = 1e-15
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001722
Mark Dickinson96f774d2016-09-03 19:30:22 +01001723 elif fn == 'erfc' and arg >= 0.0:
1724 # erfc has less-than-ideal accuracy for large
1725 # arguments (x ~ 25 or so), mainly due to the
1726 # error involved in computing exp(-x*x).
1727 #
1728 # Observed between CPython and mpmath at 25 dp:
1729 # x < 0 : err <= 2 ulp
1730 # 0 <= x < 1 : err <= 10 ulp
1731 # 1 <= x < 10 : err <= 100 ulp
1732 # 10 <= x < 20 : err <= 300 ulp
1733 # 20 <= x : < 600 ulp
1734 #
1735 if arg < 1.0:
1736 ulp_tol = 10
1737 elif arg < 10.0:
1738 ulp_tol = 100
1739 else:
1740 ulp_tol = 1000
1741
1742 failure = result_check(expected, got, ulp_tol, abs_tol)
1743 if failure is None:
1744 continue
1745
1746 msg = fail_fmt.format(id, fn, arg, failure)
1747 failures.append(msg)
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001748
1749 if failures:
1750 self.fail('Failures in test_mtestfile:\n ' +
1751 '\n '.join(failures))
1752
Pablo Galindo04114112019-03-09 19:18:08 +00001753 def test_prod(self):
1754 prod = math.prod
1755 self.assertEqual(prod([]), 1)
1756 self.assertEqual(prod([], start=5), 5)
1757 self.assertEqual(prod(list(range(2,8))), 5040)
1758 self.assertEqual(prod(iter(list(range(2,8)))), 5040)
1759 self.assertEqual(prod(range(1, 10), start=10), 3628800)
1760
1761 self.assertEqual(prod([1, 2, 3, 4, 5]), 120)
1762 self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0)
1763 self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0)
1764 self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0)
1765
1766 # Test overflow in fast-path for integers
1767 self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32)
1768 # Test overflow in fast-path for floats
1769 self.assertEqual(prod([1.0, 1.0, 2**32, 1, 1]), float(2**32))
1770
1771 self.assertRaises(TypeError, prod)
1772 self.assertRaises(TypeError, prod, 42)
1773 self.assertRaises(TypeError, prod, ['a', 'b', 'c'])
1774 self.assertRaises(TypeError, prod, ['a', 'b', 'c'], '')
1775 self.assertRaises(TypeError, prod, [b'a', b'c'], b'')
1776 values = [bytearray(b'a'), bytearray(b'b')]
1777 self.assertRaises(TypeError, prod, values, bytearray(b''))
1778 self.assertRaises(TypeError, prod, [[1], [2], [3]])
1779 self.assertRaises(TypeError, prod, [{2:3}])
1780 self.assertRaises(TypeError, prod, [{2:3}]*2, {2:3})
1781 self.assertRaises(TypeError, prod, [[1], [2], [3]], [])
1782 with self.assertRaises(TypeError):
1783 prod([10, 20], [30, 40]) # start is a keyword-only argument
1784
1785 self.assertEqual(prod([0, 1, 2, 3]), 0)
1786 self.assertEqual(prod([1, 0, 2, 3]), 0)
1787 self.assertEqual(prod([1, 2, 3, 0]), 0)
1788
1789 def _naive_prod(iterable, start=1):
1790 for elem in iterable:
1791 start *= elem
1792 return start
1793
1794 # Big integers
1795
1796 iterable = range(1, 10000)
1797 self.assertEqual(prod(iterable), _naive_prod(iterable))
1798 iterable = range(-10000, -1)
1799 self.assertEqual(prod(iterable), _naive_prod(iterable))
1800 iterable = range(-1000, 1000)
1801 self.assertEqual(prod(iterable), 0)
1802
1803 # Big floats
1804
1805 iterable = [float(x) for x in range(1, 1000)]
1806 self.assertEqual(prod(iterable), _naive_prod(iterable))
1807 iterable = [float(x) for x in range(-1000, -1)]
1808 self.assertEqual(prod(iterable), _naive_prod(iterable))
1809 iterable = [float(x) for x in range(-1000, 1000)]
1810 self.assertIsNaN(prod(iterable))
1811
1812 # Float tests
1813
1814 self.assertIsNaN(prod([1, 2, 3, float("nan"), 2, 3]))
1815 self.assertIsNaN(prod([1, 0, float("nan"), 2, 3]))
1816 self.assertIsNaN(prod([1, float("nan"), 0, 3]))
1817 self.assertIsNaN(prod([1, float("inf"), float("nan"),3]))
1818 self.assertIsNaN(prod([1, float("-inf"), float("nan"),3]))
1819 self.assertIsNaN(prod([1, float("nan"), float("inf"),3]))
1820 self.assertIsNaN(prod([1, float("nan"), float("-inf"),3]))
1821
1822 self.assertEqual(prod([1, 2, 3, float('inf'),-3,4]), float('-inf'))
1823 self.assertEqual(prod([1, 2, 3, float('-inf'),-3,4]), float('inf'))
1824
1825 self.assertIsNaN(prod([1,2,0,float('inf'), -3, 4]))
1826 self.assertIsNaN(prod([1,2,0,float('-inf'), -3, 4]))
1827 self.assertIsNaN(prod([1, 2, 3, float('inf'), -3, 0, 3]))
1828 self.assertIsNaN(prod([1, 2, 3, float('-inf'), -3, 0, 2]))
1829
1830 # Type preservation
1831
1832 self.assertEqual(type(prod([1, 2, 3, 4, 5, 6])), int)
1833 self.assertEqual(type(prod([1, 2.0, 3, 4, 5, 6])), float)
1834 self.assertEqual(type(prod(range(1, 10000))), int)
1835 self.assertEqual(type(prod(range(1, 10000), start=1.0)), float)
1836 self.assertEqual(type(prod([1, decimal.Decimal(2.0), 3, 4, 5, 6])),
1837 decimal.Decimal)
1838
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001839 def testPerm(self):
1840 perm = math.perm
1841 factorial = math.factorial
Min ho Kim96e12d52019-07-22 06:12:33 +10001842 # Test if factorial definition is satisfied
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001843 for n in range(100):
1844 for k in range(n + 1):
1845 self.assertEqual(perm(n, k),
1846 factorial(n) // factorial(n - k))
1847
1848 # Test for Pascal's identity
1849 for n in range(1, 100):
1850 for k in range(1, n):
1851 self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k))
1852
1853 # Test corner cases
1854 for n in range(1, 100):
1855 self.assertEqual(perm(n, 0), 1)
1856 self.assertEqual(perm(n, 1), n)
1857 self.assertEqual(perm(n, n), factorial(n))
1858
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001859 # Test one argument form
1860 for n in range(20):
1861 self.assertEqual(perm(n), factorial(n))
1862 self.assertEqual(perm(n, None), factorial(n))
1863
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001864 # Raises TypeError if any argument is non-integer or argument count is
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001865 # not 1 or 2
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001866 self.assertRaises(TypeError, perm, 10, 1.0)
1867 self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
1868 self.assertRaises(TypeError, perm, 10, "1")
1869 self.assertRaises(TypeError, perm, 10.0, 1)
1870 self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
1871 self.assertRaises(TypeError, perm, "10", 1)
1872
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001873 self.assertRaises(TypeError, perm)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001874 self.assertRaises(TypeError, perm, 10, 1, 3)
1875 self.assertRaises(TypeError, perm)
1876
1877 # Raises Value error if not k or n are negative numbers
1878 self.assertRaises(ValueError, perm, -1, 1)
1879 self.assertRaises(ValueError, perm, -2**1000, 1)
1880 self.assertRaises(ValueError, perm, 1, -1)
1881 self.assertRaises(ValueError, perm, 1, -2**1000)
1882
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07001883 # Returns zero if k is greater than n
1884 self.assertEqual(perm(1, 2), 0)
1885 self.assertEqual(perm(1, 2**1000), 0)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001886
1887 n = 2**1000
1888 self.assertEqual(perm(n, 0), 1)
1889 self.assertEqual(perm(n, 1), n)
1890 self.assertEqual(perm(n, 2), n * (n-1))
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +03001891 if support.check_impl_detail(cpython=True):
1892 self.assertRaises(OverflowError, perm, n, n)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001893
1894 for n, k in (True, True), (True, False), (False, False):
1895 self.assertEqual(perm(n, k), 1)
1896 self.assertIs(type(perm(n, k)), int)
1897 self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20)
1898 self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20)
1899 for k in range(3):
1900 self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int)
1901 self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int)
1902
Yash Aggarwal4a686502019-06-01 12:51:27 +05301903 def testComb(self):
1904 comb = math.comb
1905 factorial = math.factorial
Min ho Kim96e12d52019-07-22 06:12:33 +10001906 # Test if factorial definition is satisfied
Yash Aggarwal4a686502019-06-01 12:51:27 +05301907 for n in range(100):
1908 for k in range(n + 1):
1909 self.assertEqual(comb(n, k), factorial(n)
1910 // (factorial(k) * factorial(n - k)))
1911
1912 # Test for Pascal's identity
1913 for n in range(1, 100):
1914 for k in range(1, n):
1915 self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k))
1916
1917 # Test corner cases
1918 for n in range(100):
1919 self.assertEqual(comb(n, 0), 1)
1920 self.assertEqual(comb(n, n), 1)
1921
1922 for n in range(1, 100):
1923 self.assertEqual(comb(n, 1), n)
1924 self.assertEqual(comb(n, n - 1), n)
1925
1926 # Test Symmetry
1927 for n in range(100):
1928 for k in range(n // 2):
1929 self.assertEqual(comb(n, k), comb(n, n - k))
1930
1931 # Raises TypeError if any argument is non-integer or argument count is
1932 # not 2
1933 self.assertRaises(TypeError, comb, 10, 1.0)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001934 self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0))
Yash Aggarwal4a686502019-06-01 12:51:27 +05301935 self.assertRaises(TypeError, comb, 10, "1")
Yash Aggarwal4a686502019-06-01 12:51:27 +05301936 self.assertRaises(TypeError, comb, 10.0, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001937 self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1)
1938 self.assertRaises(TypeError, comb, "10", 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301939
1940 self.assertRaises(TypeError, comb, 10)
1941 self.assertRaises(TypeError, comb, 10, 1, 3)
1942 self.assertRaises(TypeError, comb)
1943
1944 # Raises Value error if not k or n are negative numbers
1945 self.assertRaises(ValueError, comb, -1, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001946 self.assertRaises(ValueError, comb, -2**1000, 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301947 self.assertRaises(ValueError, comb, 1, -1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001948 self.assertRaises(ValueError, comb, 1, -2**1000)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301949
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07001950 # Returns zero if k is greater than n
1951 self.assertEqual(comb(1, 2), 0)
1952 self.assertEqual(comb(1, 2**1000), 0)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301953
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001954 n = 2**1000
1955 self.assertEqual(comb(n, 0), 1)
1956 self.assertEqual(comb(n, 1), n)
1957 self.assertEqual(comb(n, 2), n * (n-1) // 2)
1958 self.assertEqual(comb(n, n), 1)
1959 self.assertEqual(comb(n, n-1), n)
1960 self.assertEqual(comb(n, n-2), n * (n-1) // 2)
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +03001961 if support.check_impl_detail(cpython=True):
1962 self.assertRaises(OverflowError, comb, n, n//2)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301963
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001964 for n, k in (True, True), (True, False), (False, False):
1965 self.assertEqual(comb(n, k), 1)
1966 self.assertIs(type(comb(n, k)), int)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001967 self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001968 self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001969 for k in range(3):
1970 self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int)
1971 self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301972
Victor Stinner59e2d262020-01-21 12:48:16 +01001973 @requires_IEEE_754
1974 def test_nextafter(self):
1975 # around 2^52 and 2^63
1976 self.assertEqual(math.nextafter(4503599627370496.0, -INF),
1977 4503599627370495.5)
1978 self.assertEqual(math.nextafter(4503599627370496.0, INF),
1979 4503599627370497.0)
1980 self.assertEqual(math.nextafter(9223372036854775808.0, 0.0),
1981 9223372036854774784.0)
1982 self.assertEqual(math.nextafter(-9223372036854775808.0, 0.0),
1983 -9223372036854774784.0)
1984
1985 # around 1.0
1986 self.assertEqual(math.nextafter(1.0, -INF),
1987 float.fromhex('0x1.fffffffffffffp-1'))
1988 self.assertEqual(math.nextafter(1.0, INF),
1989 float.fromhex('0x1.0000000000001p+0'))
1990
1991 # x == y: y is returned
1992 self.assertEqual(math.nextafter(2.0, 2.0), 2.0)
1993 self.assertEqualSign(math.nextafter(-0.0, +0.0), +0.0)
1994 self.assertEqualSign(math.nextafter(+0.0, -0.0), -0.0)
1995
1996 # around 0.0
1997 smallest_subnormal = sys.float_info.min * sys.float_info.epsilon
1998 self.assertEqual(math.nextafter(+0.0, INF), smallest_subnormal)
1999 self.assertEqual(math.nextafter(-0.0, INF), smallest_subnormal)
2000 self.assertEqual(math.nextafter(+0.0, -INF), -smallest_subnormal)
2001 self.assertEqual(math.nextafter(-0.0, -INF), -smallest_subnormal)
2002 self.assertEqualSign(math.nextafter(smallest_subnormal, +0.0), +0.0)
2003 self.assertEqualSign(math.nextafter(-smallest_subnormal, +0.0), -0.0)
2004 self.assertEqualSign(math.nextafter(smallest_subnormal, -0.0), +0.0)
2005 self.assertEqualSign(math.nextafter(-smallest_subnormal, -0.0), -0.0)
2006
2007 # around infinity
2008 largest_normal = sys.float_info.max
2009 self.assertEqual(math.nextafter(INF, 0.0), largest_normal)
2010 self.assertEqual(math.nextafter(-INF, 0.0), -largest_normal)
2011 self.assertEqual(math.nextafter(largest_normal, INF), INF)
2012 self.assertEqual(math.nextafter(-largest_normal, -INF), -INF)
2013
2014 # NaN
2015 self.assertIsNaN(math.nextafter(NAN, 1.0))
2016 self.assertIsNaN(math.nextafter(1.0, NAN))
2017 self.assertIsNaN(math.nextafter(NAN, NAN))
2018
2019 @requires_IEEE_754
2020 def test_ulp(self):
2021 self.assertEqual(math.ulp(1.0), sys.float_info.epsilon)
2022 # use int ** int rather than float ** int to not rely on pow() accuracy
2023 self.assertEqual(math.ulp(2 ** 52), 1.0)
2024 self.assertEqual(math.ulp(2 ** 53), 2.0)
2025 self.assertEqual(math.ulp(2 ** 64), 4096.0)
2026
2027 # min and max
2028 self.assertEqual(math.ulp(0.0),
2029 sys.float_info.min * sys.float_info.epsilon)
2030 self.assertEqual(math.ulp(FLOAT_MAX),
2031 FLOAT_MAX - math.nextafter(FLOAT_MAX, -INF))
2032
2033 # special cases
2034 self.assertEqual(math.ulp(INF), INF)
2035 self.assertIsNaN(math.ulp(math.nan))
2036
2037 # negative number: ulp(-x) == ulp(x)
2038 for x in (0.0, 1.0, 2 ** 52, 2 ** 64, INF):
2039 with self.subTest(x=x):
2040 self.assertEqual(math.ulp(-x), math.ulp(x))
2041
Zackery Spytz5208b4b2020-03-14 04:45:32 -06002042 def test_issue39871(self):
2043 # A SystemError should not be raised if the first arg to atan2(),
2044 # copysign(), or remainder() cannot be converted to a float.
2045 class F:
2046 def __float__(self):
2047 self.converted = True
2048 1/0
2049 for func in math.atan2, math.copysign, math.remainder:
2050 y = F()
2051 with self.assertRaises(TypeError):
2052 func("not a number", y)
2053
2054 # There should not have been any attempt to convert the second
2055 # argument to a float.
2056 self.assertFalse(getattr(y, "converted", False))
2057
Victor Stinner59e2d262020-01-21 12:48:16 +01002058 # Custom assertions.
2059
2060 def assertIsNaN(self, value):
2061 if not math.isnan(value):
2062 self.fail("Expected a NaN, got {!r}.".format(value))
2063
2064 def assertEqualSign(self, x, y):
2065 """Similar to assertEqual(), but compare also the sign with copysign().
2066
2067 Function useful to compare signed zeros.
2068 """
2069 self.assertEqual(x, y)
2070 self.assertEqual(math.copysign(1.0, x), math.copysign(1.0, y))
2071
2072
2073class IsCloseTests(unittest.TestCase):
2074 isclose = math.isclose # subclasses should override this
2075
2076 def assertIsClose(self, a, b, *args, **kwargs):
2077 self.assertTrue(self.isclose(a, b, *args, **kwargs),
2078 msg="%s and %s should be close!" % (a, b))
2079
2080 def assertIsNotClose(self, a, b, *args, **kwargs):
2081 self.assertFalse(self.isclose(a, b, *args, **kwargs),
2082 msg="%s and %s should not be close!" % (a, b))
2083
2084 def assertAllClose(self, examples, *args, **kwargs):
2085 for a, b in examples:
2086 self.assertIsClose(a, b, *args, **kwargs)
2087
2088 def assertAllNotClose(self, examples, *args, **kwargs):
2089 for a, b in examples:
2090 self.assertIsNotClose(a, b, *args, **kwargs)
2091
2092 def test_negative_tolerances(self):
2093 # ValueError should be raised if either tolerance is less than zero
2094 with self.assertRaises(ValueError):
2095 self.assertIsClose(1, 1, rel_tol=-1e-100)
2096 with self.assertRaises(ValueError):
2097 self.assertIsClose(1, 1, rel_tol=1e-100, abs_tol=-1e10)
2098
2099 def test_identical(self):
2100 # identical values must test as close
2101 identical_examples = [(2.0, 2.0),
2102 (0.1e200, 0.1e200),
2103 (1.123e-300, 1.123e-300),
2104 (12345, 12345.0),
2105 (0.0, -0.0),
2106 (345678, 345678)]
2107 self.assertAllClose(identical_examples, rel_tol=0.0, abs_tol=0.0)
2108
2109 def test_eight_decimal_places(self):
2110 # examples that are close to 1e-8, but not 1e-9
2111 eight_decimal_places_examples = [(1e8, 1e8 + 1),
2112 (-1e-8, -1.000000009e-8),
2113 (1.12345678, 1.12345679)]
2114 self.assertAllClose(eight_decimal_places_examples, rel_tol=1e-8)
2115 self.assertAllNotClose(eight_decimal_places_examples, rel_tol=1e-9)
2116
2117 def test_near_zero(self):
2118 # values close to zero
2119 near_zero_examples = [(1e-9, 0.0),
2120 (-1e-9, 0.0),
2121 (-1e-150, 0.0)]
2122 # these should not be close to any rel_tol
2123 self.assertAllNotClose(near_zero_examples, rel_tol=0.9)
2124 # these should be close to abs_tol=1e-8
2125 self.assertAllClose(near_zero_examples, abs_tol=1e-8)
2126
2127 def test_identical_infinite(self):
2128 # these are close regardless of tolerance -- i.e. they are equal
2129 self.assertIsClose(INF, INF)
2130 self.assertIsClose(INF, INF, abs_tol=0.0)
2131 self.assertIsClose(NINF, NINF)
2132 self.assertIsClose(NINF, NINF, abs_tol=0.0)
2133
2134 def test_inf_ninf_nan(self):
2135 # these should never be close (following IEEE 754 rules for equality)
2136 not_close_examples = [(NAN, NAN),
2137 (NAN, 1e-100),
2138 (1e-100, NAN),
2139 (INF, NAN),
2140 (NAN, INF),
2141 (INF, NINF),
2142 (INF, 1.0),
2143 (1.0, INF),
2144 (INF, 1e308),
2145 (1e308, INF)]
2146 # use largest reasonable tolerance
2147 self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999)
2148
2149 def test_zero_tolerance(self):
2150 # test with zero tolerance
2151 zero_tolerance_close_examples = [(1.0, 1.0),
2152 (-3.4, -3.4),
2153 (-1e-300, -1e-300)]
2154 self.assertAllClose(zero_tolerance_close_examples, rel_tol=0.0)
2155
2156 zero_tolerance_not_close_examples = [(1.0, 1.000000000000001),
2157 (0.99999999999999, 1.0),
2158 (1.0e200, .999999999999999e200)]
2159 self.assertAllNotClose(zero_tolerance_not_close_examples, rel_tol=0.0)
2160
2161 def test_asymmetry(self):
2162 # test the asymmetry example from PEP 485
2163 self.assertAllClose([(9, 10), (10, 9)], rel_tol=0.1)
2164
2165 def test_integers(self):
2166 # test with integer values
2167 integer_examples = [(100000001, 100000000),
2168 (123456789, 123456788)]
2169
2170 self.assertAllClose(integer_examples, rel_tol=1e-8)
2171 self.assertAllNotClose(integer_examples, rel_tol=1e-9)
2172
2173 def test_decimals(self):
2174 # test with Decimal values
2175 from decimal import Decimal
2176
2177 decimal_examples = [(Decimal('1.00000001'), Decimal('1.0')),
2178 (Decimal('1.00000001e-20'), Decimal('1.0e-20')),
2179 (Decimal('1.00000001e-100'), Decimal('1.0e-100')),
2180 (Decimal('1.00000001e20'), Decimal('1.0e20'))]
2181 self.assertAllClose(decimal_examples, rel_tol=1e-8)
2182 self.assertAllNotClose(decimal_examples, rel_tol=1e-9)
2183
2184 def test_fractions(self):
2185 # test with Fraction values
2186 from fractions import Fraction
2187
2188 fraction_examples = [
2189 (Fraction(1, 100000000) + 1, Fraction(1)),
2190 (Fraction(100000001), Fraction(100000000)),
2191 (Fraction(10**8 + 1, 10**28), Fraction(1, 10**20))]
2192 self.assertAllClose(fraction_examples, rel_tol=1e-8)
2193 self.assertAllNotClose(fraction_examples, rel_tol=1e-9)
2194
Pablo Galindo42079072019-02-10 19:56:58 +00002195
Thomas Wouters89f507f2006-12-13 04:49:30 +00002196def test_main():
Christian Heimes53876d92008-04-19 00:31:39 +00002197 from doctest import DocFileSuite
2198 suite = unittest.TestSuite()
2199 suite.addTest(unittest.makeSuite(MathTests))
Tal Einatd5519ed2015-05-31 22:05:00 +03002200 suite.addTest(unittest.makeSuite(IsCloseTests))
Christian Heimes53876d92008-04-19 00:31:39 +00002201 suite.addTest(DocFileSuite("ieee754.txt"))
2202 run_unittest(suite)
Thomas Wouters89f507f2006-12-13 04:49:30 +00002203
2204if __name__ == '__main__':
2205 test_main()