blob: 4b848a5e7e5f85107c9a42c2415182475407b7e9 [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 Storchaka231aad32019-06-17 16:57:27 +0300505 with self.assertWarns(DeprecationWarning):
506 self.assertEqual(math.factorial(5.0), 120)
507 with self.assertWarns(DeprecationWarning):
508 self.assertRaises(ValueError, math.factorial, 5.2)
509 with self.assertWarns(DeprecationWarning):
510 self.assertRaises(ValueError, math.factorial, -1.0)
511 with self.assertWarns(DeprecationWarning):
512 self.assertRaises(ValueError, math.factorial, -1e100)
513 self.assertRaises(TypeError, math.factorial, decimal.Decimal('5'))
514 self.assertRaises(TypeError, math.factorial, decimal.Decimal('5.2'))
Pablo Galindoe9ba3702018-09-03 22:20:06 +0100515 self.assertRaises(TypeError, math.factorial, "5")
516
Mark Dickinson5990d282014-04-10 09:29:39 -0400517 # Other implementations may place different upper bounds.
518 @support.cpython_only
519 def testFactorialHugeInputs(self):
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +0300520 # Currently raises OverflowError for inputs that are too large
Mark Dickinson5990d282014-04-10 09:29:39 -0400521 # to fit into a C long.
522 self.assertRaises(OverflowError, math.factorial, 10**100)
Serhiy Storchaka231aad32019-06-17 16:57:27 +0300523 with self.assertWarns(DeprecationWarning):
524 self.assertRaises(OverflowError, math.factorial, 1e100)
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000525
Thomas Wouters89f507f2006-12-13 04:49:30 +0000526 def testFloor(self):
527 self.assertRaises(TypeError, math.floor)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000528 self.assertEqual(int, type(math.floor(0.5)))
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200529 self.assertEqual(math.floor(0.5), 0)
530 self.assertEqual(math.floor(1.0), 1)
531 self.assertEqual(math.floor(1.5), 1)
532 self.assertEqual(math.floor(-0.5), -1)
533 self.assertEqual(math.floor(-1.0), -1)
534 self.assertEqual(math.floor(-1.5), -2)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000535 #self.assertEqual(math.ceil(INF), INF)
536 #self.assertEqual(math.ceil(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000537 #self.assertTrue(math.isnan(math.floor(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000538
Guido van Rossum13e05de2007-08-23 22:56:55 +0000539 class TestFloor:
540 def __floor__(self):
541 return 42
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200542 class FloatFloor(float):
543 def __floor__(self):
544 return 42
Guido van Rossum13e05de2007-08-23 22:56:55 +0000545 class TestNoFloor:
546 pass
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200547 self.assertEqual(math.floor(TestFloor()), 42)
548 self.assertEqual(math.floor(FloatFloor()), 42)
549 self.assertEqual(math.floor(FloatLike(41.9)), 41)
Guido van Rossum13e05de2007-08-23 22:56:55 +0000550 self.assertRaises(TypeError, math.floor, TestNoFloor())
551
552 t = TestNoFloor()
553 t.__floor__ = lambda *args: args
554 self.assertRaises(TypeError, math.floor, t)
555 self.assertRaises(TypeError, math.floor, t, 0)
556
Thomas Wouters89f507f2006-12-13 04:49:30 +0000557 def testFmod(self):
558 self.assertRaises(TypeError, math.fmod)
Mark Dickinson5bc7a442011-05-03 21:13:40 +0100559 self.ftest('fmod(10, 1)', math.fmod(10, 1), 0.0)
560 self.ftest('fmod(10, 0.5)', math.fmod(10, 0.5), 0.0)
561 self.ftest('fmod(10, 1.5)', math.fmod(10, 1.5), 1.0)
562 self.ftest('fmod(-10, 1)', math.fmod(-10, 1), -0.0)
563 self.ftest('fmod(-10, 0.5)', math.fmod(-10, 0.5), -0.0)
564 self.ftest('fmod(-10, 1.5)', math.fmod(-10, 1.5), -1.0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000565 self.assertTrue(math.isnan(math.fmod(NAN, 1.)))
566 self.assertTrue(math.isnan(math.fmod(1., NAN)))
567 self.assertTrue(math.isnan(math.fmod(NAN, NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000568 self.assertRaises(ValueError, math.fmod, 1., 0.)
569 self.assertRaises(ValueError, math.fmod, INF, 1.)
570 self.assertRaises(ValueError, math.fmod, NINF, 1.)
571 self.assertRaises(ValueError, math.fmod, INF, 0.)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000572 self.assertEqual(math.fmod(3.0, INF), 3.0)
573 self.assertEqual(math.fmod(-3.0, INF), -3.0)
574 self.assertEqual(math.fmod(3.0, NINF), 3.0)
575 self.assertEqual(math.fmod(-3.0, NINF), -3.0)
576 self.assertEqual(math.fmod(0.0, 3.0), 0.0)
577 self.assertEqual(math.fmod(0.0, NINF), 0.0)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000578
Thomas Wouters89f507f2006-12-13 04:49:30 +0000579 def testFrexp(self):
580 self.assertRaises(TypeError, math.frexp)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000581
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000582 def testfrexp(name, result, expected):
583 (mant, exp), (emant, eexp) = result, expected
Thomas Wouters89f507f2006-12-13 04:49:30 +0000584 if abs(mant-emant) > eps or exp != eexp:
585 self.fail('%s returned %r, expected %r'%\
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000586 (name, result, expected))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000587
Thomas Wouters89f507f2006-12-13 04:49:30 +0000588 testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
589 testfrexp('frexp(0)', math.frexp(0), (0, 0))
590 testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
591 testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000592
Ezio Melottib3aedd42010-11-20 19:04:17 +0000593 self.assertEqual(math.frexp(INF)[0], INF)
594 self.assertEqual(math.frexp(NINF)[0], NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000595 self.assertTrue(math.isnan(math.frexp(NAN)[0]))
Christian Heimes53876d92008-04-19 00:31:39 +0000596
Mark Dickinson63566232009-09-18 21:04:19 +0000597 @requires_IEEE_754
Mark Dickinson5c567082009-04-24 16:39:07 +0000598 @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
599 "fsum is not exact on machines with double rounding")
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000600 def testFsum(self):
601 # math.fsum relies on exact rounding for correct operation.
602 # There's a known problem with IA32 floating-point that causes
603 # inexact rounding in some situations, and will cause the
604 # math.fsum tests below to fail; see issue #2937. On non IEEE
605 # 754 platforms, and on IEEE 754 platforms that exhibit the
606 # problem described in issue #2937, we simply skip the whole
607 # test.
608
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000609 # Python version of math.fsum, for comparison. Uses a
610 # different algorithm based on frexp, ldexp and integer
611 # arithmetic.
612 from sys import float_info
613 mant_dig = float_info.mant_dig
614 etiny = float_info.min_exp - mant_dig
615
616 def msum(iterable):
617 """Full precision summation. Compute sum(iterable) without any
618 intermediate accumulation of error. Based on the 'lsum' function
619 at http://code.activestate.com/recipes/393090/
620
621 """
622 tmant, texp = 0, 0
623 for x in iterable:
624 mant, exp = math.frexp(x)
625 mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig
626 if texp > exp:
627 tmant <<= texp-exp
628 texp = exp
629 else:
630 mant <<= exp-texp
631 tmant += mant
632 # Round tmant * 2**texp to a float. The original recipe
633 # used float(str(tmant)) * 2.0**texp for this, but that's
634 # a little unsafe because str -> float conversion can't be
635 # relied upon to do correct rounding on all platforms.
636 tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp)
637 if tail > 0:
638 h = 1 << (tail-1)
639 tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1)
640 texp += tail
641 return math.ldexp(tmant, texp)
642
643 test_values = [
644 ([], 0.0),
645 ([0.0], 0.0),
646 ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
647 ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
648 ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
649 ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
650 ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
651 ([1./n for n in range(1, 1001)],
652 float.fromhex('0x1.df11f45f4e61ap+2')),
653 ([(-1.)**n/n for n in range(1, 1001)],
654 float.fromhex('-0x1.62a2af1bd3624p-1')),
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000655 ([1e16, 1., 1e-16], 10000000000000002.0),
656 ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
657 # exercise code for resizing partials array
658 ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] +
659 [-2.**1022],
660 float.fromhex('0x1.5555555555555p+970')),
661 ]
662
Mark Dickinsonbba873e2019-12-09 08:36:34 -0600663 # Telescoping sum, with exact differences (due to Sterbenz)
664 terms = [1.7**i for i in range(1001)]
665 test_values.append((
666 [terms[i+1] - terms[i] for i in range(1000)] + [-terms[1000]],
667 -terms[0]
668 ))
669
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000670 for i, (vals, expected) in enumerate(test_values):
671 try:
672 actual = math.fsum(vals)
673 except OverflowError:
674 self.fail("test %d failed: got OverflowError, expected %r "
675 "for math.fsum(%.100r)" % (i, expected, vals))
676 except ValueError:
677 self.fail("test %d failed: got ValueError, expected %r "
678 "for math.fsum(%.100r)" % (i, expected, vals))
679 self.assertEqual(actual, expected)
680
681 from random import random, gauss, shuffle
682 for j in range(1000):
683 vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
684 s = 0
685 for i in range(200):
686 v = gauss(0, random()) ** 7 - s
687 s += v
688 vals.append(v)
689 shuffle(vals)
690
691 s = msum(vals)
692 self.assertEqual(msum(vals), math.fsum(vals))
693
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300694 def testGcd(self):
695 gcd = math.gcd
696 self.assertEqual(gcd(0, 0), 0)
697 self.assertEqual(gcd(1, 0), 1)
698 self.assertEqual(gcd(-1, 0), 1)
699 self.assertEqual(gcd(0, 1), 1)
700 self.assertEqual(gcd(0, -1), 1)
701 self.assertEqual(gcd(7, 1), 1)
702 self.assertEqual(gcd(7, -1), 1)
703 self.assertEqual(gcd(-23, 15), 1)
704 self.assertEqual(gcd(120, 84), 12)
705 self.assertEqual(gcd(84, -120), 12)
706 self.assertEqual(gcd(1216342683557601535506311712,
707 436522681849110124616458784), 32)
Serhiy Storchaka559e7f12020-02-23 13:21:29 +0200708
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300709 x = 434610456570399902378880679233098819019853229470286994367836600566
710 y = 1064502245825115327754847244914921553977
Serhiy Storchaka559e7f12020-02-23 13:21:29 +0200711 for c in (652560,
712 576559230871654959816130551884856912003141446781646602790216406874):
713 a = x * c
714 b = y * c
715 self.assertEqual(gcd(a, b), c)
716 self.assertEqual(gcd(b, a), c)
717 self.assertEqual(gcd(-a, b), c)
718 self.assertEqual(gcd(b, -a), c)
719 self.assertEqual(gcd(a, -b), c)
720 self.assertEqual(gcd(-b, a), c)
721 self.assertEqual(gcd(-a, -b), c)
722 self.assertEqual(gcd(-b, -a), c)
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300723
Serhiy Storchaka559e7f12020-02-23 13:21:29 +0200724 self.assertEqual(gcd(), 0)
725 self.assertEqual(gcd(120), 120)
726 self.assertEqual(gcd(-120), 120)
727 self.assertEqual(gcd(120, 84, 102), 6)
728 self.assertEqual(gcd(120, 1, 84), 1)
729
730 self.assertRaises(TypeError, gcd, 120.0)
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300731 self.assertRaises(TypeError, gcd, 120.0, 84)
732 self.assertRaises(TypeError, gcd, 120, 84.0)
Serhiy Storchaka559e7f12020-02-23 13:21:29 +0200733 self.assertRaises(TypeError, gcd, 120, 1, 84.0)
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300734 self.assertEqual(gcd(MyIndexable(120), MyIndexable(84)), 12)
735
Thomas Wouters89f507f2006-12-13 04:49:30 +0000736 def testHypot(self):
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700737 from decimal import Decimal
738 from fractions import Fraction
739
740 hypot = math.hypot
741
742 # Test different numbers of arguments (from zero to five)
743 # against a straightforward pure python implementation
744 args = math.e, math.pi, math.sqrt(2.0), math.gamma(3.5), math.sin(2.1)
745 for i in range(len(args)+1):
746 self.assertAlmostEqual(
747 hypot(*args[:i]),
748 math.sqrt(sum(s**2 for s in args[:i]))
749 )
750
751 # Test allowable types (those with __float__)
752 self.assertEqual(hypot(12.0, 5.0), 13.0)
753 self.assertEqual(hypot(12, 5), 13)
754 self.assertEqual(hypot(Decimal(12), Decimal(5)), 13)
755 self.assertEqual(hypot(Fraction(12, 32), Fraction(5, 32)), Fraction(13, 32))
756 self.assertEqual(hypot(bool(1), bool(0), bool(1), bool(1)), math.sqrt(3))
757
758 # Test corner cases
759 self.assertEqual(hypot(0.0, 0.0), 0.0) # Max input is zero
760 self.assertEqual(hypot(-10.5), 10.5) # Negative input
761 self.assertEqual(hypot(), 0.0) # Negative input
762 self.assertEqual(1.0,
763 math.copysign(1.0, hypot(-0.0)) # Convert negative zero to positive zero
764 )
Raymond Hettinger00414592018-08-12 12:15:23 -0700765 self.assertEqual( # Handling of moving max to the end
766 hypot(1.5, 1.5, 0.5),
767 hypot(1.5, 0.5, 1.5),
768 )
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700769
770 # Test handling of bad arguments
771 with self.assertRaises(TypeError): # Reject keyword args
772 hypot(x=1)
773 with self.assertRaises(TypeError): # Reject values without __float__
774 hypot(1.1, 'string', 2.2)
Raymond Hettinger808180c2019-01-28 13:59:56 -0800775 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
776 with self.assertRaises((ValueError, OverflowError)):
777 hypot(1, int_too_big_for_float)
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700778
779 # Any infinity gives positive infinity.
780 self.assertEqual(hypot(INF), INF)
781 self.assertEqual(hypot(0, INF), INF)
782 self.assertEqual(hypot(10, INF), INF)
783 self.assertEqual(hypot(-10, INF), INF)
784 self.assertEqual(hypot(NAN, INF), INF)
785 self.assertEqual(hypot(INF, NAN), INF)
786 self.assertEqual(hypot(NINF, NAN), INF)
787 self.assertEqual(hypot(NAN, NINF), INF)
788 self.assertEqual(hypot(-INF, INF), INF)
789 self.assertEqual(hypot(-INF, -INF), INF)
790 self.assertEqual(hypot(10, -INF), INF)
791
Raymond Hettinger00414592018-08-12 12:15:23 -0700792 # If no infinity, any NaN gives a NaN.
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700793 self.assertTrue(math.isnan(hypot(NAN)))
794 self.assertTrue(math.isnan(hypot(0, NAN)))
795 self.assertTrue(math.isnan(hypot(NAN, 10)))
796 self.assertTrue(math.isnan(hypot(10, NAN)))
797 self.assertTrue(math.isnan(hypot(NAN, NAN)))
798 self.assertTrue(math.isnan(hypot(NAN)))
799
800 # Verify scaling for extremely large values
801 fourthmax = FLOAT_MAX / 4.0
802 for n in range(32):
803 self.assertEqual(hypot(*([fourthmax]*n)), fourthmax * math.sqrt(n))
804
805 # Verify scaling for extremely small values
806 for exp in range(32):
807 scale = FLOAT_MIN / 2.0 ** exp
808 self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000809
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700810 def testDist(self):
811 from decimal import Decimal as D
812 from fractions import Fraction as F
813
814 dist = math.dist
815 sqrt = math.sqrt
816
Raymond Hettinger808180c2019-01-28 13:59:56 -0800817 # Simple exact cases
818 self.assertEqual(dist((1.0, 2.0, 3.0), (4.0, 2.0, -1.0)), 5.0)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700819 self.assertEqual(dist((1, 2, 3), (4, 2, -1)), 5.0)
820
821 # Test different numbers of arguments (from zero to nine)
822 # against a straightforward pure python implementation
823 for i in range(9):
824 for j in range(5):
825 p = tuple(random.uniform(-5, 5) for k in range(i))
826 q = tuple(random.uniform(-5, 5) for k in range(i))
827 self.assertAlmostEqual(
828 dist(p, q),
829 sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
830 )
831
Raymond Hettinger6b5f1b42019-07-27 14:04:29 -0700832 # Test non-tuple inputs
833 self.assertEqual(dist([1.0, 2.0, 3.0], [4.0, 2.0, -1.0]), 5.0)
834 self.assertEqual(dist(iter([1.0, 2.0, 3.0]), iter([4.0, 2.0, -1.0])), 5.0)
835
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700836 # Test allowable types (those with __float__)
837 self.assertEqual(dist((14.0, 1.0), (2.0, -4.0)), 13.0)
838 self.assertEqual(dist((14, 1), (2, -4)), 13)
839 self.assertEqual(dist((D(14), D(1)), (D(2), D(-4))), D(13))
840 self.assertEqual(dist((F(14, 32), F(1, 32)), (F(2, 32), F(-4, 32))),
841 F(13, 32))
842 self.assertEqual(dist((True, True, False, True, False),
843 (True, False, True, True, False)),
844 sqrt(2.0))
845
846 # Test corner cases
847 self.assertEqual(dist((13.25, 12.5, -3.25),
848 (13.25, 12.5, -3.25)),
849 0.0) # Distance with self is zero
850 self.assertEqual(dist((), ()), 0.0) # Zero-dimensional case
851 self.assertEqual(1.0, # Convert negative zero to positive zero
852 math.copysign(1.0, dist((-0.0,), (0.0,)))
853 )
854 self.assertEqual(1.0, # Convert negative zero to positive zero
855 math.copysign(1.0, dist((0.0,), (-0.0,)))
856 )
Raymond Hettinger00414592018-08-12 12:15:23 -0700857 self.assertEqual( # Handling of moving max to the end
858 dist((1.5, 1.5, 0.5), (0, 0, 0)),
859 dist((1.5, 0.5, 1.5), (0, 0, 0))
860 )
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700861
862 # Verify tuple subclasses are allowed
Raymond Hettinger00414592018-08-12 12:15:23 -0700863 class T(tuple):
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700864 pass
865 self.assertEqual(dist(T((1, 2, 3)), ((4, 2, -1))), 5.0)
866
867 # Test handling of bad arguments
868 with self.assertRaises(TypeError): # Reject keyword args
869 dist(p=(1, 2, 3), q=(4, 5, 6))
870 with self.assertRaises(TypeError): # Too few args
871 dist((1, 2, 3))
872 with self.assertRaises(TypeError): # Too many args
873 dist((1, 2, 3), (4, 5, 6), (7, 8, 9))
874 with self.assertRaises(TypeError): # Scalars not allowed
875 dist(1, 2)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700876 with self.assertRaises(TypeError): # Reject values without __float__
877 dist((1.1, 'string', 2.2), (1, 2, 3))
878 with self.assertRaises(ValueError): # Check dimension agree
879 dist((1, 2, 3, 4), (5, 6, 7))
880 with self.assertRaises(ValueError): # Check dimension agree
881 dist((1, 2, 3), (4, 5, 6, 7))
Ammar Askarcb08a712019-01-12 01:23:41 -0500882 with self.assertRaises(TypeError): # Rejects invalid types
883 dist("abc", "xyz")
Raymond Hettinger808180c2019-01-28 13:59:56 -0800884 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
885 with self.assertRaises((ValueError, OverflowError)):
886 dist((1, int_too_big_for_float), (2, 3))
887 with self.assertRaises((ValueError, OverflowError)):
888 dist((2, 3), (1, int_too_big_for_float))
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700889
Raymond Hettinger00414592018-08-12 12:15:23 -0700890 # Verify that the one dimensional case is equivalent to abs()
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700891 for i in range(20):
892 p, q = random.random(), random.random()
893 self.assertEqual(dist((p,), (q,)), abs(p - q))
894
895 # Test special values
896 values = [NINF, -10.5, -0.0, 0.0, 10.5, INF, NAN]
897 for p in itertools.product(values, repeat=3):
898 for q in itertools.product(values, repeat=3):
899 diffs = [px - qx for px, qx in zip(p, q)]
900 if any(map(math.isinf, diffs)):
901 # Any infinite difference gives positive infinity.
902 self.assertEqual(dist(p, q), INF)
903 elif any(map(math.isnan, diffs)):
Raymond Hettinger00414592018-08-12 12:15:23 -0700904 # If no infinity, any NaN gives a NaN.
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700905 self.assertTrue(math.isnan(dist(p, q)))
906
907 # Verify scaling for extremely large values
908 fourthmax = FLOAT_MAX / 4.0
909 for n in range(32):
910 p = (fourthmax,) * n
911 q = (0.0,) * n
912 self.assertEqual(dist(p, q), fourthmax * math.sqrt(n))
913 self.assertEqual(dist(q, p), fourthmax * math.sqrt(n))
914
915 # Verify scaling for extremely small values
916 for exp in range(32):
917 scale = FLOAT_MIN / 2.0 ** exp
918 p = (4*scale, 3*scale)
919 q = (0.0, 0.0)
920 self.assertEqual(math.dist(p, q), 5*scale)
921 self.assertEqual(math.dist(q, p), 5*scale)
922
Mark Dickinson73934b92019-05-18 12:29:50 +0100923 def testIsqrt(self):
924 # Test a variety of inputs, large and small.
925 test_values = (
926 list(range(1000))
927 + list(range(10**6 - 1000, 10**6 + 1000))
Mark Dickinson5c08ce92019-05-19 17:51:56 +0100928 + [2**e + i for e in range(60, 200) for i in range(-40, 40)]
Mark Dickinson73934b92019-05-18 12:29:50 +0100929 + [3**9999, 10**5001]
930 )
931
932 for value in test_values:
933 with self.subTest(value=value):
934 s = math.isqrt(value)
935 self.assertIs(type(s), int)
936 self.assertLessEqual(s*s, value)
937 self.assertLess(value, (s+1)*(s+1))
938
939 # Negative values
940 with self.assertRaises(ValueError):
941 math.isqrt(-1)
942
943 # Integer-like things
944 s = math.isqrt(True)
945 self.assertIs(type(s), int)
946 self.assertEqual(s, 1)
947
948 s = math.isqrt(False)
949 self.assertIs(type(s), int)
950 self.assertEqual(s, 0)
951
952 class IntegerLike(object):
953 def __init__(self, value):
954 self.value = value
955
956 def __index__(self):
957 return self.value
958
959 s = math.isqrt(IntegerLike(1729))
960 self.assertIs(type(s), int)
961 self.assertEqual(s, 41)
962
963 with self.assertRaises(ValueError):
964 math.isqrt(IntegerLike(-3))
965
966 # Non-integer-like things
967 bad_values = [
968 3.5, "a string", decimal.Decimal("3.5"), 3.5j,
969 100.0, -4.0,
970 ]
971 for value in bad_values:
972 with self.subTest(value=value):
973 with self.assertRaises(TypeError):
974 math.isqrt(value)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700975
ananthan-123f2ee21d2020-02-19 23:51:37 +0530976 def test_lcm(self):
977 lcm = math.lcm
978 self.assertEqual(lcm(0, 0), 0)
979 self.assertEqual(lcm(1, 0), 0)
980 self.assertEqual(lcm(-1, 0), 0)
981 self.assertEqual(lcm(0, 1), 0)
982 self.assertEqual(lcm(0, -1), 0)
983 self.assertEqual(lcm(7, 1), 7)
984 self.assertEqual(lcm(7, -1), 7)
985 self.assertEqual(lcm(-23, 15), 345)
986 self.assertEqual(lcm(120, 84), 840)
987 self.assertEqual(lcm(84, -120), 840)
988 self.assertEqual(lcm(1216342683557601535506311712,
989 436522681849110124616458784),
990 16592536571065866494401400422922201534178938447014944)
Serhiy Storchaka559e7f12020-02-23 13:21:29 +0200991
ananthan-123f2ee21d2020-02-19 23:51:37 +0530992 x = 43461045657039990237
993 y = 10645022458251153277
ananthan-123f2ee21d2020-02-19 23:51:37 +0530994 for c in (652560,
995 57655923087165495981):
996 a = x * c
997 b = y * c
998 d = x * y * c
999 self.assertEqual(lcm(a, b), d)
1000 self.assertEqual(lcm(b, a), d)
1001 self.assertEqual(lcm(-a, b), d)
1002 self.assertEqual(lcm(b, -a), d)
1003 self.assertEqual(lcm(a, -b), d)
1004 self.assertEqual(lcm(-b, a), d)
1005 self.assertEqual(lcm(-a, -b), d)
1006 self.assertEqual(lcm(-b, -a), d)
Serhiy Storchaka559e7f12020-02-23 13:21:29 +02001007
1008 self.assertEqual(lcm(), 1)
1009 self.assertEqual(lcm(120), 120)
1010 self.assertEqual(lcm(-120), 120)
1011 self.assertEqual(lcm(120, 84, 102), 14280)
1012 self.assertEqual(lcm(120, 0, 84), 0)
1013
1014 self.assertRaises(TypeError, lcm, 120.0)
ananthan-123f2ee21d2020-02-19 23:51:37 +05301015 self.assertRaises(TypeError, lcm, 120.0, 84)
1016 self.assertRaises(TypeError, lcm, 120, 84.0)
Serhiy Storchaka559e7f12020-02-23 13:21:29 +02001017 self.assertRaises(TypeError, lcm, 120, 0, 84.0)
1018 self.assertEqual(lcm(MyIndexable(120), MyIndexable(84)), 840)
ananthan-123f2ee21d2020-02-19 23:51:37 +05301019
Thomas Wouters89f507f2006-12-13 04:49:30 +00001020 def testLdexp(self):
1021 self.assertRaises(TypeError, math.ldexp)
1022 self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
1023 self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
1024 self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
1025 self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
Christian Heimes53876d92008-04-19 00:31:39 +00001026 self.assertRaises(OverflowError, math.ldexp, 1., 1000000)
1027 self.assertRaises(OverflowError, math.ldexp, -1., 1000000)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001028 self.assertEqual(math.ldexp(1., -1000000), 0.)
1029 self.assertEqual(math.ldexp(-1., -1000000), -0.)
1030 self.assertEqual(math.ldexp(INF, 30), INF)
1031 self.assertEqual(math.ldexp(NINF, -213), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001032 self.assertTrue(math.isnan(math.ldexp(NAN, 0)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001033
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001034 # large second argument
1035 for n in [10**5, 10**10, 10**20, 10**40]:
Ezio Melottib3aedd42010-11-20 19:04:17 +00001036 self.assertEqual(math.ldexp(INF, -n), INF)
1037 self.assertEqual(math.ldexp(NINF, -n), NINF)
1038 self.assertEqual(math.ldexp(1., -n), 0.)
1039 self.assertEqual(math.ldexp(-1., -n), -0.)
1040 self.assertEqual(math.ldexp(0., -n), 0.)
1041 self.assertEqual(math.ldexp(-0., -n), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001042 self.assertTrue(math.isnan(math.ldexp(NAN, -n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001043
1044 self.assertRaises(OverflowError, math.ldexp, 1., n)
1045 self.assertRaises(OverflowError, math.ldexp, -1., n)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001046 self.assertEqual(math.ldexp(0., n), 0.)
1047 self.assertEqual(math.ldexp(-0., n), -0.)
1048 self.assertEqual(math.ldexp(INF, n), INF)
1049 self.assertEqual(math.ldexp(NINF, n), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001050 self.assertTrue(math.isnan(math.ldexp(NAN, n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001051
Thomas Wouters89f507f2006-12-13 04:49:30 +00001052 def testLog(self):
1053 self.assertRaises(TypeError, math.log)
1054 self.ftest('log(1/e)', math.log(1/math.e), -1)
1055 self.ftest('log(1)', math.log(1), 0)
1056 self.ftest('log(e)', math.log(math.e), 1)
1057 self.ftest('log(32,2)', math.log(32,2), 5)
1058 self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
1059 self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001060 self.ftest('log(10**1000)', math.log(10**1000),
1061 2302.5850929940457)
1062 self.assertRaises(ValueError, math.log, -1.5)
1063 self.assertRaises(ValueError, math.log, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001064 self.assertRaises(ValueError, math.log, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001065 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001066 self.assertTrue(math.isnan(math.log(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001067
1068 def testLog1p(self):
1069 self.assertRaises(TypeError, math.log1p)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001070 for n in [2, 2**90, 2**300]:
1071 self.assertAlmostEqual(math.log1p(n), math.log1p(float(n)))
1072 self.assertRaises(ValueError, math.log1p, -1)
1073 self.assertEqual(math.log1p(INF), INF)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001074
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001075 @requires_IEEE_754
1076 def testLog2(self):
1077 self.assertRaises(TypeError, math.log2)
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001078
1079 # Check some integer values
1080 self.assertEqual(math.log2(1), 0.0)
1081 self.assertEqual(math.log2(2), 1.0)
1082 self.assertEqual(math.log2(4), 2.0)
1083
1084 # Large integer values
1085 self.assertEqual(math.log2(2**1023), 1023.0)
1086 self.assertEqual(math.log2(2**1024), 1024.0)
1087 self.assertEqual(math.log2(2**2000), 2000.0)
1088
1089 self.assertRaises(ValueError, math.log2, -1.5)
1090 self.assertRaises(ValueError, math.log2, NINF)
1091 self.assertTrue(math.isnan(math.log2(NAN)))
1092
Victor Stinnercd9dd372011-05-10 23:40:17 +02001093 @requires_IEEE_754
Victor Stinnerebbbdaf2011-06-01 13:19:07 +02001094 # log2() is not accurate enough on Mac OS X Tiger (10.4)
1095 @support.requires_mac_ver(10, 5)
Victor Stinnercd9dd372011-05-10 23:40:17 +02001096 def testLog2Exact(self):
1097 # Check that we get exact equality for log2 of powers of 2.
1098 actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)]
1099 expected = [float(n) for n in range(-1074, 1024)]
1100 self.assertEqual(actual, expected)
1101
Thomas Wouters89f507f2006-12-13 04:49:30 +00001102 def testLog10(self):
1103 self.assertRaises(TypeError, math.log10)
1104 self.ftest('log10(0.1)', math.log10(0.1), -1)
1105 self.ftest('log10(1)', math.log10(1), 0)
1106 self.ftest('log10(10)', math.log10(10), 1)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001107 self.ftest('log10(10**1000)', math.log10(10**1000), 1000.0)
1108 self.assertRaises(ValueError, math.log10, -1.5)
1109 self.assertRaises(ValueError, math.log10, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001110 self.assertRaises(ValueError, math.log10, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001111 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001112 self.assertTrue(math.isnan(math.log10(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001113
Thomas Wouters89f507f2006-12-13 04:49:30 +00001114 def testModf(self):
1115 self.assertRaises(TypeError, math.modf)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001116
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001117 def testmodf(name, result, expected):
1118 (v1, v2), (e1, e2) = result, expected
Thomas Wouters89f507f2006-12-13 04:49:30 +00001119 if abs(v1-e1) > eps or abs(v2-e2):
1120 self.fail('%s returned %r, expected %r'%\
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001121 (name, result, expected))
Raymond Hettinger64108af2002-05-13 03:55:01 +00001122
Thomas Wouters89f507f2006-12-13 04:49:30 +00001123 testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
1124 testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001125
Ezio Melottib3aedd42010-11-20 19:04:17 +00001126 self.assertEqual(math.modf(INF), (0.0, INF))
1127 self.assertEqual(math.modf(NINF), (-0.0, NINF))
Christian Heimes53876d92008-04-19 00:31:39 +00001128
1129 modf_nan = math.modf(NAN)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001130 self.assertTrue(math.isnan(modf_nan[0]))
1131 self.assertTrue(math.isnan(modf_nan[1]))
Christian Heimes53876d92008-04-19 00:31:39 +00001132
Thomas Wouters89f507f2006-12-13 04:49:30 +00001133 def testPow(self):
1134 self.assertRaises(TypeError, math.pow)
1135 self.ftest('pow(0,1)', math.pow(0,1), 0)
1136 self.ftest('pow(1,0)', math.pow(1,0), 1)
1137 self.ftest('pow(2,1)', math.pow(2,1), 2)
1138 self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
Christian Heimes53876d92008-04-19 00:31:39 +00001139 self.assertEqual(math.pow(INF, 1), INF)
1140 self.assertEqual(math.pow(NINF, 1), NINF)
1141 self.assertEqual((math.pow(1, INF)), 1.)
1142 self.assertEqual((math.pow(1, NINF)), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001143 self.assertTrue(math.isnan(math.pow(NAN, 1)))
1144 self.assertTrue(math.isnan(math.pow(2, NAN)))
1145 self.assertTrue(math.isnan(math.pow(0, NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001146 self.assertEqual(math.pow(1, NAN), 1)
Christian Heimesa342c012008-04-20 21:01:16 +00001147
1148 # pow(0., x)
1149 self.assertEqual(math.pow(0., INF), 0.)
1150 self.assertEqual(math.pow(0., 3.), 0.)
1151 self.assertEqual(math.pow(0., 2.3), 0.)
1152 self.assertEqual(math.pow(0., 2.), 0.)
1153 self.assertEqual(math.pow(0., 0.), 1.)
1154 self.assertEqual(math.pow(0., -0.), 1.)
1155 self.assertRaises(ValueError, math.pow, 0., -2.)
1156 self.assertRaises(ValueError, math.pow, 0., -2.3)
1157 self.assertRaises(ValueError, math.pow, 0., -3.)
1158 self.assertRaises(ValueError, math.pow, 0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001159 self.assertTrue(math.isnan(math.pow(0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001160
1161 # pow(INF, x)
1162 self.assertEqual(math.pow(INF, INF), INF)
1163 self.assertEqual(math.pow(INF, 3.), INF)
1164 self.assertEqual(math.pow(INF, 2.3), INF)
1165 self.assertEqual(math.pow(INF, 2.), INF)
1166 self.assertEqual(math.pow(INF, 0.), 1.)
1167 self.assertEqual(math.pow(INF, -0.), 1.)
1168 self.assertEqual(math.pow(INF, -2.), 0.)
1169 self.assertEqual(math.pow(INF, -2.3), 0.)
1170 self.assertEqual(math.pow(INF, -3.), 0.)
1171 self.assertEqual(math.pow(INF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001172 self.assertTrue(math.isnan(math.pow(INF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001173
1174 # pow(-0., x)
1175 self.assertEqual(math.pow(-0., INF), 0.)
1176 self.assertEqual(math.pow(-0., 3.), -0.)
1177 self.assertEqual(math.pow(-0., 2.3), 0.)
1178 self.assertEqual(math.pow(-0., 2.), 0.)
1179 self.assertEqual(math.pow(-0., 0.), 1.)
1180 self.assertEqual(math.pow(-0., -0.), 1.)
1181 self.assertRaises(ValueError, math.pow, -0., -2.)
1182 self.assertRaises(ValueError, math.pow, -0., -2.3)
1183 self.assertRaises(ValueError, math.pow, -0., -3.)
1184 self.assertRaises(ValueError, math.pow, -0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001185 self.assertTrue(math.isnan(math.pow(-0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001186
1187 # pow(NINF, x)
1188 self.assertEqual(math.pow(NINF, INF), INF)
1189 self.assertEqual(math.pow(NINF, 3.), NINF)
1190 self.assertEqual(math.pow(NINF, 2.3), INF)
1191 self.assertEqual(math.pow(NINF, 2.), INF)
1192 self.assertEqual(math.pow(NINF, 0.), 1.)
1193 self.assertEqual(math.pow(NINF, -0.), 1.)
1194 self.assertEqual(math.pow(NINF, -2.), 0.)
1195 self.assertEqual(math.pow(NINF, -2.3), 0.)
1196 self.assertEqual(math.pow(NINF, -3.), -0.)
1197 self.assertEqual(math.pow(NINF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001198 self.assertTrue(math.isnan(math.pow(NINF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001199
1200 # pow(-1, x)
1201 self.assertEqual(math.pow(-1., INF), 1.)
1202 self.assertEqual(math.pow(-1., 3.), -1.)
1203 self.assertRaises(ValueError, math.pow, -1., 2.3)
1204 self.assertEqual(math.pow(-1., 2.), 1.)
1205 self.assertEqual(math.pow(-1., 0.), 1.)
1206 self.assertEqual(math.pow(-1., -0.), 1.)
1207 self.assertEqual(math.pow(-1., -2.), 1.)
1208 self.assertRaises(ValueError, math.pow, -1., -2.3)
1209 self.assertEqual(math.pow(-1., -3.), -1.)
1210 self.assertEqual(math.pow(-1., NINF), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001211 self.assertTrue(math.isnan(math.pow(-1., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001212
1213 # pow(1, x)
1214 self.assertEqual(math.pow(1., INF), 1.)
1215 self.assertEqual(math.pow(1., 3.), 1.)
1216 self.assertEqual(math.pow(1., 2.3), 1.)
1217 self.assertEqual(math.pow(1., 2.), 1.)
1218 self.assertEqual(math.pow(1., 0.), 1.)
1219 self.assertEqual(math.pow(1., -0.), 1.)
1220 self.assertEqual(math.pow(1., -2.), 1.)
1221 self.assertEqual(math.pow(1., -2.3), 1.)
1222 self.assertEqual(math.pow(1., -3.), 1.)
1223 self.assertEqual(math.pow(1., NINF), 1.)
1224 self.assertEqual(math.pow(1., NAN), 1.)
1225
1226 # pow(x, 0) should be 1 for any x
1227 self.assertEqual(math.pow(2.3, 0.), 1.)
1228 self.assertEqual(math.pow(-2.3, 0.), 1.)
1229 self.assertEqual(math.pow(NAN, 0.), 1.)
1230 self.assertEqual(math.pow(2.3, -0.), 1.)
1231 self.assertEqual(math.pow(-2.3, -0.), 1.)
1232 self.assertEqual(math.pow(NAN, -0.), 1.)
1233
1234 # pow(x, y) is invalid if x is negative and y is not integral
1235 self.assertRaises(ValueError, math.pow, -1., 2.3)
1236 self.assertRaises(ValueError, math.pow, -15., -3.1)
1237
1238 # pow(x, NINF)
1239 self.assertEqual(math.pow(1.9, NINF), 0.)
1240 self.assertEqual(math.pow(1.1, NINF), 0.)
1241 self.assertEqual(math.pow(0.9, NINF), INF)
1242 self.assertEqual(math.pow(0.1, NINF), INF)
1243 self.assertEqual(math.pow(-0.1, NINF), INF)
1244 self.assertEqual(math.pow(-0.9, NINF), INF)
1245 self.assertEqual(math.pow(-1.1, NINF), 0.)
1246 self.assertEqual(math.pow(-1.9, NINF), 0.)
1247
1248 # pow(x, INF)
1249 self.assertEqual(math.pow(1.9, INF), INF)
1250 self.assertEqual(math.pow(1.1, INF), INF)
1251 self.assertEqual(math.pow(0.9, INF), 0.)
1252 self.assertEqual(math.pow(0.1, INF), 0.)
1253 self.assertEqual(math.pow(-0.1, INF), 0.)
1254 self.assertEqual(math.pow(-0.9, INF), 0.)
1255 self.assertEqual(math.pow(-1.1, INF), INF)
1256 self.assertEqual(math.pow(-1.9, INF), INF)
1257
1258 # pow(x, y) should work for x negative, y an integer
1259 self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
1260 self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
1261 self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
1262 self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
1263 self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
1264 self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
1265 self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
1266 self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
1267 self.assertRaises(ValueError, math.pow, -2.0, -0.5)
1268 self.assertRaises(ValueError, math.pow, -2.0, 0.5)
1269
1270 # the following tests have been commented out since they don't
1271 # really belong here: the implementation of ** for floats is
Ezio Melotti13925002011-03-16 11:05:33 +02001272 # independent of the implementation of math.pow
Christian Heimesa342c012008-04-20 21:01:16 +00001273 #self.assertEqual(1**NAN, 1)
1274 #self.assertEqual(1**INF, 1)
1275 #self.assertEqual(1**NINF, 1)
1276 #self.assertEqual(1**0, 1)
1277 #self.assertEqual(1.**NAN, 1)
1278 #self.assertEqual(1.**INF, 1)
1279 #self.assertEqual(1.**NINF, 1)
1280 #self.assertEqual(1.**0, 1)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001281
Thomas Wouters89f507f2006-12-13 04:49:30 +00001282 def testRadians(self):
1283 self.assertRaises(TypeError, math.radians)
1284 self.ftest('radians(180)', math.radians(180), math.pi)
1285 self.ftest('radians(90)', math.radians(90), math.pi/2)
1286 self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001287 self.ftest('radians(0)', math.radians(0), 0)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001288
Mark Dickinsona0ce3752017-04-05 18:34:27 +01001289 @requires_IEEE_754
1290 def testRemainder(self):
1291 from fractions import Fraction
1292
1293 def validate_spec(x, y, r):
1294 """
1295 Check that r matches remainder(x, y) according to the IEEE 754
1296 specification. Assumes that x, y and r are finite and y is nonzero.
1297 """
1298 fx, fy, fr = Fraction(x), Fraction(y), Fraction(r)
1299 # r should not exceed y/2 in absolute value
1300 self.assertLessEqual(abs(fr), abs(fy/2))
1301 # x - r should be an exact integer multiple of y
1302 n = (fx - fr) / fy
1303 self.assertEqual(n, int(n))
1304 if abs(fr) == abs(fy/2):
1305 # If |r| == |y/2|, n should be even.
1306 self.assertEqual(n/2, int(n/2))
1307
1308 # triples (x, y, remainder(x, y)) in hexadecimal form.
1309 testcases = [
1310 # Remainders modulo 1, showing the ties-to-even behaviour.
1311 '-4.0 1 -0.0',
1312 '-3.8 1 0.8',
1313 '-3.0 1 -0.0',
1314 '-2.8 1 -0.8',
1315 '-2.0 1 -0.0',
1316 '-1.8 1 0.8',
1317 '-1.0 1 -0.0',
1318 '-0.8 1 -0.8',
1319 '-0.0 1 -0.0',
1320 ' 0.0 1 0.0',
1321 ' 0.8 1 0.8',
1322 ' 1.0 1 0.0',
1323 ' 1.8 1 -0.8',
1324 ' 2.0 1 0.0',
1325 ' 2.8 1 0.8',
1326 ' 3.0 1 0.0',
1327 ' 3.8 1 -0.8',
1328 ' 4.0 1 0.0',
1329
1330 # Reductions modulo 2*pi
1331 '0x0.0p+0 0x1.921fb54442d18p+2 0x0.0p+0',
1332 '0x1.921fb54442d18p+0 0x1.921fb54442d18p+2 0x1.921fb54442d18p+0',
1333 '0x1.921fb54442d17p+1 0x1.921fb54442d18p+2 0x1.921fb54442d17p+1',
1334 '0x1.921fb54442d18p+1 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1335 '0x1.921fb54442d19p+1 0x1.921fb54442d18p+2 -0x1.921fb54442d17p+1',
1336 '0x1.921fb54442d17p+2 0x1.921fb54442d18p+2 -0x0.0000000000001p+2',
1337 '0x1.921fb54442d18p+2 0x1.921fb54442d18p+2 0x0p0',
1338 '0x1.921fb54442d19p+2 0x1.921fb54442d18p+2 0x0.0000000000001p+2',
1339 '0x1.2d97c7f3321d1p+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1340 '0x1.2d97c7f3321d2p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d18p+1',
1341 '0x1.2d97c7f3321d3p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1342 '0x1.921fb54442d17p+3 0x1.921fb54442d18p+2 -0x0.0000000000001p+3',
1343 '0x1.921fb54442d18p+3 0x1.921fb54442d18p+2 0x0p0',
1344 '0x1.921fb54442d19p+3 0x1.921fb54442d18p+2 0x0.0000000000001p+3',
1345 '0x1.f6a7a2955385dp+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1346 '0x1.f6a7a2955385ep+3 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1347 '0x1.f6a7a2955385fp+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1348 '0x1.1475cc9eedf00p+5 0x1.921fb54442d18p+2 0x1.921fb54442d10p+1',
1349 '0x1.1475cc9eedf01p+5 0x1.921fb54442d18p+2 -0x1.921fb54442d10p+1',
1350
1351 # Symmetry with respect to signs.
1352 ' 1 0.c 0.4',
1353 '-1 0.c -0.4',
1354 ' 1 -0.c 0.4',
1355 '-1 -0.c -0.4',
1356 ' 1.4 0.c -0.4',
1357 '-1.4 0.c 0.4',
1358 ' 1.4 -0.c -0.4',
1359 '-1.4 -0.c 0.4',
1360
1361 # Huge modulus, to check that the underlying algorithm doesn't
1362 # rely on 2.0 * modulus being representable.
1363 '0x1.dp+1023 0x1.4p+1023 0x0.9p+1023',
1364 '0x1.ep+1023 0x1.4p+1023 -0x0.ap+1023',
1365 '0x1.fp+1023 0x1.4p+1023 -0x0.9p+1023',
1366 ]
1367
1368 for case in testcases:
1369 with self.subTest(case=case):
1370 x_hex, y_hex, expected_hex = case.split()
1371 x = float.fromhex(x_hex)
1372 y = float.fromhex(y_hex)
1373 expected = float.fromhex(expected_hex)
1374 validate_spec(x, y, expected)
1375 actual = math.remainder(x, y)
1376 # Cheap way of checking that the floats are
1377 # as identical as we need them to be.
1378 self.assertEqual(actual.hex(), expected.hex())
1379
1380 # Test tiny subnormal modulus: there's potential for
1381 # getting the implementation wrong here (for example,
1382 # by assuming that modulus/2 is exactly representable).
1383 tiny = float.fromhex('1p-1074') # min +ve subnormal
1384 for n in range(-25, 25):
1385 if n == 0:
1386 continue
1387 y = n * tiny
1388 for m in range(100):
1389 x = m * tiny
1390 actual = math.remainder(x, y)
1391 validate_spec(x, y, actual)
1392 actual = math.remainder(-x, y)
1393 validate_spec(-x, y, actual)
1394
1395 # Special values.
1396 # NaNs should propagate as usual.
1397 for value in [NAN, 0.0, -0.0, 2.0, -2.3, NINF, INF]:
1398 self.assertIsNaN(math.remainder(NAN, value))
1399 self.assertIsNaN(math.remainder(value, NAN))
1400
1401 # remainder(x, inf) is x, for non-nan non-infinite x.
1402 for value in [-2.3, -0.0, 0.0, 2.3]:
1403 self.assertEqual(math.remainder(value, INF), value)
1404 self.assertEqual(math.remainder(value, NINF), value)
1405
1406 # remainder(x, 0) and remainder(infinity, x) for non-NaN x are invalid
1407 # operations according to IEEE 754-2008 7.2(f), and should raise.
1408 for value in [NINF, -2.3, -0.0, 0.0, 2.3, INF]:
1409 with self.assertRaises(ValueError):
1410 math.remainder(INF, value)
1411 with self.assertRaises(ValueError):
1412 math.remainder(NINF, value)
1413 with self.assertRaises(ValueError):
1414 math.remainder(value, 0.0)
1415 with self.assertRaises(ValueError):
1416 math.remainder(value, -0.0)
1417
Thomas Wouters89f507f2006-12-13 04:49:30 +00001418 def testSin(self):
1419 self.assertRaises(TypeError, math.sin)
1420 self.ftest('sin(0)', math.sin(0), 0)
1421 self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
1422 self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001423 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001424 self.assertTrue(math.isnan(math.sin(INF)))
1425 self.assertTrue(math.isnan(math.sin(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001426 except ValueError:
1427 self.assertRaises(ValueError, math.sin, INF)
1428 self.assertRaises(ValueError, math.sin, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001429 self.assertTrue(math.isnan(math.sin(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001430
Thomas Wouters89f507f2006-12-13 04:49:30 +00001431 def testSinh(self):
1432 self.assertRaises(TypeError, math.sinh)
1433 self.ftest('sinh(0)', math.sinh(0), 0)
1434 self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
1435 self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001436 self.assertEqual(math.sinh(INF), INF)
1437 self.assertEqual(math.sinh(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001438 self.assertTrue(math.isnan(math.sinh(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001439
Thomas Wouters89f507f2006-12-13 04:49:30 +00001440 def testSqrt(self):
1441 self.assertRaises(TypeError, math.sqrt)
1442 self.ftest('sqrt(0)', math.sqrt(0), 0)
1443 self.ftest('sqrt(1)', math.sqrt(1), 1)
1444 self.ftest('sqrt(4)', math.sqrt(4), 2)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001445 self.assertEqual(math.sqrt(INF), INF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001446 self.assertRaises(ValueError, math.sqrt, -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001447 self.assertRaises(ValueError, math.sqrt, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001448 self.assertTrue(math.isnan(math.sqrt(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001449
Thomas Wouters89f507f2006-12-13 04:49:30 +00001450 def testTan(self):
1451 self.assertRaises(TypeError, math.tan)
1452 self.ftest('tan(0)', math.tan(0), 0)
1453 self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
1454 self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001455 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001456 self.assertTrue(math.isnan(math.tan(INF)))
1457 self.assertTrue(math.isnan(math.tan(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001458 except:
1459 self.assertRaises(ValueError, math.tan, INF)
1460 self.assertRaises(ValueError, math.tan, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001461 self.assertTrue(math.isnan(math.tan(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001462
Thomas Wouters89f507f2006-12-13 04:49:30 +00001463 def testTanh(self):
1464 self.assertRaises(TypeError, math.tanh)
1465 self.ftest('tanh(0)', math.tanh(0), 0)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001466 self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0,
Victor Stinner0b2ab212020-01-13 12:44:35 +01001467 abs_tol=math.ulp(1))
Christian Heimes53876d92008-04-19 00:31:39 +00001468 self.ftest('tanh(inf)', math.tanh(INF), 1)
1469 self.ftest('tanh(-inf)', math.tanh(NINF), -1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001470 self.assertTrue(math.isnan(math.tanh(NAN)))
Victor Stinnerbe3da382010-11-07 14:14:27 +00001471
1472 @requires_IEEE_754
Victor Stinnerbe3da382010-11-07 14:14:27 +00001473 def testTanhSign(self):
Christian Heimese57950f2008-04-21 13:08:03 +00001474 # check that tanh(-0.) == -0. on IEEE 754 systems
Victor Stinnerbe3da382010-11-07 14:14:27 +00001475 self.assertEqual(math.tanh(-0.), -0.)
1476 self.assertEqual(math.copysign(1., math.tanh(-0.)),
1477 math.copysign(1., -0.))
Tim Peters1d120612000-10-12 06:10:25 +00001478
Christian Heimes400adb02008-02-01 08:12:03 +00001479 def test_trunc(self):
1480 self.assertEqual(math.trunc(1), 1)
1481 self.assertEqual(math.trunc(-1), -1)
1482 self.assertEqual(type(math.trunc(1)), int)
1483 self.assertEqual(type(math.trunc(1.5)), int)
1484 self.assertEqual(math.trunc(1.5), 1)
1485 self.assertEqual(math.trunc(-1.5), -1)
1486 self.assertEqual(math.trunc(1.999999), 1)
1487 self.assertEqual(math.trunc(-1.999999), -1)
1488 self.assertEqual(math.trunc(-0.999999), -0)
1489 self.assertEqual(math.trunc(-100.999), -100)
1490
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001491 class TestTrunc:
Christian Heimes400adb02008-02-01 08:12:03 +00001492 def __trunc__(self):
1493 return 23
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001494 class FloatTrunc(float):
1495 def __trunc__(self):
1496 return 23
1497 class TestNoTrunc:
Christian Heimes400adb02008-02-01 08:12:03 +00001498 pass
1499
1500 self.assertEqual(math.trunc(TestTrunc()), 23)
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001501 self.assertEqual(math.trunc(FloatTrunc()), 23)
Christian Heimes400adb02008-02-01 08:12:03 +00001502
1503 self.assertRaises(TypeError, math.trunc)
1504 self.assertRaises(TypeError, math.trunc, 1, 2)
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001505 self.assertRaises(TypeError, math.trunc, FloatLike(23.5))
Christian Heimes400adb02008-02-01 08:12:03 +00001506 self.assertRaises(TypeError, math.trunc, TestNoTrunc())
1507
Mark Dickinson8e0c9962010-07-11 17:38:24 +00001508 def testIsfinite(self):
1509 self.assertTrue(math.isfinite(0.0))
1510 self.assertTrue(math.isfinite(-0.0))
1511 self.assertTrue(math.isfinite(1.0))
1512 self.assertTrue(math.isfinite(-1.0))
1513 self.assertFalse(math.isfinite(float("nan")))
1514 self.assertFalse(math.isfinite(float("inf")))
1515 self.assertFalse(math.isfinite(float("-inf")))
1516
Christian Heimes072c0f12008-01-03 23:01:04 +00001517 def testIsnan(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001518 self.assertTrue(math.isnan(float("nan")))
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001519 self.assertTrue(math.isnan(float("-nan")))
1520 self.assertTrue(math.isnan(float("inf") * 0.))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001521 self.assertFalse(math.isnan(float("inf")))
1522 self.assertFalse(math.isnan(0.))
1523 self.assertFalse(math.isnan(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001524
1525 def testIsinf(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001526 self.assertTrue(math.isinf(float("inf")))
1527 self.assertTrue(math.isinf(float("-inf")))
1528 self.assertTrue(math.isinf(1E400))
1529 self.assertTrue(math.isinf(-1E400))
1530 self.assertFalse(math.isinf(float("nan")))
1531 self.assertFalse(math.isinf(0.))
1532 self.assertFalse(math.isinf(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001533
Mark Dickinsona5d0c7c2015-01-11 11:55:29 +00001534 @requires_IEEE_754
1535 def test_nan_constant(self):
1536 self.assertTrue(math.isnan(math.nan))
1537
1538 @requires_IEEE_754
1539 def test_inf_constant(self):
1540 self.assertTrue(math.isinf(math.inf))
1541 self.assertGreater(math.inf, 0.0)
1542 self.assertEqual(math.inf, float("inf"))
1543 self.assertEqual(-math.inf, float("-inf"))
1544
Thomas Wouters89f507f2006-12-13 04:49:30 +00001545 # RED_FLAG 16-Oct-2000 Tim
1546 # While 2.0 is more consistent about exceptions than previous releases, it
1547 # still fails this part of the test on some platforms. For now, we only
1548 # *run* test_exceptions() in verbose mode, so that this isn't normally
1549 # tested.
Serhiy Storchaka43767632013-11-03 21:31:38 +02001550 @unittest.skipUnless(verbose, 'requires verbose mode')
1551 def test_exceptions(self):
1552 try:
1553 x = math.exp(-1000000000)
1554 except:
1555 # mathmodule.c is failing to weed out underflows from libm, or
1556 # we've got an fp format with huge dynamic range
1557 self.fail("underflowing exp() should not have raised "
1558 "an exception")
1559 if x != 0:
1560 self.fail("underflowing exp() should have returned 0")
Tim Peters98c81842000-10-16 17:35:13 +00001561
Serhiy Storchaka43767632013-11-03 21:31:38 +02001562 # If this fails, probably using a strict IEEE-754 conforming libm, and x
1563 # is +Inf afterwards. But Python wants overflows detected by default.
1564 try:
1565 x = math.exp(1000000000)
1566 except OverflowError:
1567 pass
1568 else:
1569 self.fail("overflowing exp() didn't trigger OverflowError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001570
Serhiy Storchaka43767632013-11-03 21:31:38 +02001571 # If this fails, it could be a puzzle. One odd possibility is that
1572 # mathmodule.c's macros are getting confused while comparing
1573 # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
1574 # as a result (and so raising OverflowError instead).
1575 try:
1576 x = math.sqrt(-1.0)
1577 except ValueError:
1578 pass
1579 else:
1580 self.fail("sqrt(-1) didn't raise ValueError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001581
Mark Dickinson63566232009-09-18 21:04:19 +00001582 @requires_IEEE_754
Christian Heimes53876d92008-04-19 00:31:39 +00001583 def test_testfile(self):
Mark Dickinson85746542016-09-04 09:58:51 +01001584 # Some tests need to be skipped on ancient OS X versions.
1585 # See issue #27953.
1586 SKIP_ON_TIGER = {'tan0064'}
1587
1588 osx_version = None
1589 if sys.platform == 'darwin':
1590 version_txt = platform.mac_ver()[0]
1591 try:
1592 osx_version = tuple(map(int, version_txt.split('.')))
1593 except ValueError:
1594 pass
1595
Mark Dickinson96f774d2016-09-03 19:30:22 +01001596 fail_fmt = "{}: {}({!r}): {}"
1597
1598 failures = []
Christian Heimes53876d92008-04-19 00:31:39 +00001599 for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001600 # Skip if either the input or result is complex
1601 if ai != 0.0 or ei != 0.0:
Christian Heimes53876d92008-04-19 00:31:39 +00001602 continue
1603 if fn in ['rect', 'polar']:
1604 # no real versions of rect, polar
1605 continue
Mark Dickinson85746542016-09-04 09:58:51 +01001606 # Skip certain tests on OS X 10.4.
1607 if osx_version is not None and osx_version < (10, 5):
1608 if id in SKIP_ON_TIGER:
1609 continue
Mark Dickinson96f774d2016-09-03 19:30:22 +01001610
Christian Heimes53876d92008-04-19 00:31:39 +00001611 func = getattr(math, fn)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001612
1613 if 'invalid' in flags or 'divide-by-zero' in flags:
1614 er = 'ValueError'
1615 elif 'overflow' in flags:
1616 er = 'OverflowError'
1617
Christian Heimesa342c012008-04-20 21:01:16 +00001618 try:
1619 result = func(ar)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001620 except ValueError:
1621 result = 'ValueError'
Benjamin Peterson2b7411d2008-05-26 17:36:47 +00001622 except OverflowError:
Mark Dickinson96f774d2016-09-03 19:30:22 +01001623 result = 'OverflowError'
1624
1625 # Default tolerances
1626 ulp_tol, abs_tol = 5, 0.0
1627
1628 failure = result_check(er, result, ulp_tol, abs_tol)
1629 if failure is None:
1630 continue
1631
1632 msg = fail_fmt.format(id, fn, ar, failure)
1633 failures.append(msg)
1634
1635 if failures:
1636 self.fail('Failures in test_testfile:\n ' +
1637 '\n '.join(failures))
Thomas Wouters89f507f2006-12-13 04:49:30 +00001638
Victor Stinnerbe3da382010-11-07 14:14:27 +00001639 @requires_IEEE_754
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001640 def test_mtestfile(self):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001641 fail_fmt = "{}: {}({!r}): {}"
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001642
1643 failures = []
1644 for id, fn, arg, expected, flags in parse_mtestfile(math_testcases):
1645 func = getattr(math, fn)
1646
1647 if 'invalid' in flags or 'divide-by-zero' in flags:
1648 expected = 'ValueError'
1649 elif 'overflow' in flags:
1650 expected = 'OverflowError'
1651
1652 try:
1653 got = func(arg)
1654 except ValueError:
1655 got = 'ValueError'
1656 except OverflowError:
1657 got = 'OverflowError'
1658
Mark Dickinson96f774d2016-09-03 19:30:22 +01001659 # Default tolerances
1660 ulp_tol, abs_tol = 5, 0.0
Mark Dickinsonbcdf9da2010-06-13 10:52:38 +00001661
Mark Dickinson96f774d2016-09-03 19:30:22 +01001662 # Exceptions to the defaults
1663 if fn == 'gamma':
1664 # Experimental results on one platform gave
1665 # an accuracy of <= 10 ulps across the entire float
1666 # domain. We weaken that to require 20 ulp accuracy.
1667 ulp_tol = 20
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001668
Mark Dickinson96f774d2016-09-03 19:30:22 +01001669 elif fn == 'lgamma':
1670 # we use a weaker accuracy test for lgamma;
1671 # lgamma only achieves an absolute error of
1672 # a few multiples of the machine accuracy, in
1673 # general.
1674 abs_tol = 1e-15
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001675
Mark Dickinson96f774d2016-09-03 19:30:22 +01001676 elif fn == 'erfc' and arg >= 0.0:
1677 # erfc has less-than-ideal accuracy for large
1678 # arguments (x ~ 25 or so), mainly due to the
1679 # error involved in computing exp(-x*x).
1680 #
1681 # Observed between CPython and mpmath at 25 dp:
1682 # x < 0 : err <= 2 ulp
1683 # 0 <= x < 1 : err <= 10 ulp
1684 # 1 <= x < 10 : err <= 100 ulp
1685 # 10 <= x < 20 : err <= 300 ulp
1686 # 20 <= x : < 600 ulp
1687 #
1688 if arg < 1.0:
1689 ulp_tol = 10
1690 elif arg < 10.0:
1691 ulp_tol = 100
1692 else:
1693 ulp_tol = 1000
1694
1695 failure = result_check(expected, got, ulp_tol, abs_tol)
1696 if failure is None:
1697 continue
1698
1699 msg = fail_fmt.format(id, fn, arg, failure)
1700 failures.append(msg)
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001701
1702 if failures:
1703 self.fail('Failures in test_mtestfile:\n ' +
1704 '\n '.join(failures))
1705
Pablo Galindo04114112019-03-09 19:18:08 +00001706 def test_prod(self):
1707 prod = math.prod
1708 self.assertEqual(prod([]), 1)
1709 self.assertEqual(prod([], start=5), 5)
1710 self.assertEqual(prod(list(range(2,8))), 5040)
1711 self.assertEqual(prod(iter(list(range(2,8)))), 5040)
1712 self.assertEqual(prod(range(1, 10), start=10), 3628800)
1713
1714 self.assertEqual(prod([1, 2, 3, 4, 5]), 120)
1715 self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0)
1716 self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0)
1717 self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0)
1718
1719 # Test overflow in fast-path for integers
1720 self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32)
1721 # Test overflow in fast-path for floats
1722 self.assertEqual(prod([1.0, 1.0, 2**32, 1, 1]), float(2**32))
1723
1724 self.assertRaises(TypeError, prod)
1725 self.assertRaises(TypeError, prod, 42)
1726 self.assertRaises(TypeError, prod, ['a', 'b', 'c'])
1727 self.assertRaises(TypeError, prod, ['a', 'b', 'c'], '')
1728 self.assertRaises(TypeError, prod, [b'a', b'c'], b'')
1729 values = [bytearray(b'a'), bytearray(b'b')]
1730 self.assertRaises(TypeError, prod, values, bytearray(b''))
1731 self.assertRaises(TypeError, prod, [[1], [2], [3]])
1732 self.assertRaises(TypeError, prod, [{2:3}])
1733 self.assertRaises(TypeError, prod, [{2:3}]*2, {2:3})
1734 self.assertRaises(TypeError, prod, [[1], [2], [3]], [])
1735 with self.assertRaises(TypeError):
1736 prod([10, 20], [30, 40]) # start is a keyword-only argument
1737
1738 self.assertEqual(prod([0, 1, 2, 3]), 0)
1739 self.assertEqual(prod([1, 0, 2, 3]), 0)
1740 self.assertEqual(prod([1, 2, 3, 0]), 0)
1741
1742 def _naive_prod(iterable, start=1):
1743 for elem in iterable:
1744 start *= elem
1745 return start
1746
1747 # Big integers
1748
1749 iterable = range(1, 10000)
1750 self.assertEqual(prod(iterable), _naive_prod(iterable))
1751 iterable = range(-10000, -1)
1752 self.assertEqual(prod(iterable), _naive_prod(iterable))
1753 iterable = range(-1000, 1000)
1754 self.assertEqual(prod(iterable), 0)
1755
1756 # Big floats
1757
1758 iterable = [float(x) for x in range(1, 1000)]
1759 self.assertEqual(prod(iterable), _naive_prod(iterable))
1760 iterable = [float(x) for x in range(-1000, -1)]
1761 self.assertEqual(prod(iterable), _naive_prod(iterable))
1762 iterable = [float(x) for x in range(-1000, 1000)]
1763 self.assertIsNaN(prod(iterable))
1764
1765 # Float tests
1766
1767 self.assertIsNaN(prod([1, 2, 3, float("nan"), 2, 3]))
1768 self.assertIsNaN(prod([1, 0, float("nan"), 2, 3]))
1769 self.assertIsNaN(prod([1, float("nan"), 0, 3]))
1770 self.assertIsNaN(prod([1, float("inf"), float("nan"),3]))
1771 self.assertIsNaN(prod([1, float("-inf"), float("nan"),3]))
1772 self.assertIsNaN(prod([1, float("nan"), float("inf"),3]))
1773 self.assertIsNaN(prod([1, float("nan"), float("-inf"),3]))
1774
1775 self.assertEqual(prod([1, 2, 3, float('inf'),-3,4]), float('-inf'))
1776 self.assertEqual(prod([1, 2, 3, float('-inf'),-3,4]), float('inf'))
1777
1778 self.assertIsNaN(prod([1,2,0,float('inf'), -3, 4]))
1779 self.assertIsNaN(prod([1,2,0,float('-inf'), -3, 4]))
1780 self.assertIsNaN(prod([1, 2, 3, float('inf'), -3, 0, 3]))
1781 self.assertIsNaN(prod([1, 2, 3, float('-inf'), -3, 0, 2]))
1782
1783 # Type preservation
1784
1785 self.assertEqual(type(prod([1, 2, 3, 4, 5, 6])), int)
1786 self.assertEqual(type(prod([1, 2.0, 3, 4, 5, 6])), float)
1787 self.assertEqual(type(prod(range(1, 10000))), int)
1788 self.assertEqual(type(prod(range(1, 10000), start=1.0)), float)
1789 self.assertEqual(type(prod([1, decimal.Decimal(2.0), 3, 4, 5, 6])),
1790 decimal.Decimal)
1791
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001792 def testPerm(self):
1793 perm = math.perm
1794 factorial = math.factorial
Min ho Kim96e12d52019-07-22 06:12:33 +10001795 # Test if factorial definition is satisfied
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001796 for n in range(100):
1797 for k in range(n + 1):
1798 self.assertEqual(perm(n, k),
1799 factorial(n) // factorial(n - k))
1800
1801 # Test for Pascal's identity
1802 for n in range(1, 100):
1803 for k in range(1, n):
1804 self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k))
1805
1806 # Test corner cases
1807 for n in range(1, 100):
1808 self.assertEqual(perm(n, 0), 1)
1809 self.assertEqual(perm(n, 1), n)
1810 self.assertEqual(perm(n, n), factorial(n))
1811
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001812 # Test one argument form
1813 for n in range(20):
1814 self.assertEqual(perm(n), factorial(n))
1815 self.assertEqual(perm(n, None), factorial(n))
1816
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001817 # Raises TypeError if any argument is non-integer or argument count is
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001818 # not 1 or 2
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001819 self.assertRaises(TypeError, perm, 10, 1.0)
1820 self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
1821 self.assertRaises(TypeError, perm, 10, "1")
1822 self.assertRaises(TypeError, perm, 10.0, 1)
1823 self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
1824 self.assertRaises(TypeError, perm, "10", 1)
1825
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001826 self.assertRaises(TypeError, perm)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001827 self.assertRaises(TypeError, perm, 10, 1, 3)
1828 self.assertRaises(TypeError, perm)
1829
1830 # Raises Value error if not k or n are negative numbers
1831 self.assertRaises(ValueError, perm, -1, 1)
1832 self.assertRaises(ValueError, perm, -2**1000, 1)
1833 self.assertRaises(ValueError, perm, 1, -1)
1834 self.assertRaises(ValueError, perm, 1, -2**1000)
1835
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07001836 # Returns zero if k is greater than n
1837 self.assertEqual(perm(1, 2), 0)
1838 self.assertEqual(perm(1, 2**1000), 0)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001839
1840 n = 2**1000
1841 self.assertEqual(perm(n, 0), 1)
1842 self.assertEqual(perm(n, 1), n)
1843 self.assertEqual(perm(n, 2), n * (n-1))
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +03001844 if support.check_impl_detail(cpython=True):
1845 self.assertRaises(OverflowError, perm, n, n)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001846
1847 for n, k in (True, True), (True, False), (False, False):
1848 self.assertEqual(perm(n, k), 1)
1849 self.assertIs(type(perm(n, k)), int)
1850 self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20)
1851 self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20)
1852 for k in range(3):
1853 self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int)
1854 self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int)
1855
Yash Aggarwal4a686502019-06-01 12:51:27 +05301856 def testComb(self):
1857 comb = math.comb
1858 factorial = math.factorial
Min ho Kim96e12d52019-07-22 06:12:33 +10001859 # Test if factorial definition is satisfied
Yash Aggarwal4a686502019-06-01 12:51:27 +05301860 for n in range(100):
1861 for k in range(n + 1):
1862 self.assertEqual(comb(n, k), factorial(n)
1863 // (factorial(k) * factorial(n - k)))
1864
1865 # Test for Pascal's identity
1866 for n in range(1, 100):
1867 for k in range(1, n):
1868 self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k))
1869
1870 # Test corner cases
1871 for n in range(100):
1872 self.assertEqual(comb(n, 0), 1)
1873 self.assertEqual(comb(n, n), 1)
1874
1875 for n in range(1, 100):
1876 self.assertEqual(comb(n, 1), n)
1877 self.assertEqual(comb(n, n - 1), n)
1878
1879 # Test Symmetry
1880 for n in range(100):
1881 for k in range(n // 2):
1882 self.assertEqual(comb(n, k), comb(n, n - k))
1883
1884 # Raises TypeError if any argument is non-integer or argument count is
1885 # not 2
1886 self.assertRaises(TypeError, comb, 10, 1.0)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001887 self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0))
Yash Aggarwal4a686502019-06-01 12:51:27 +05301888 self.assertRaises(TypeError, comb, 10, "1")
Yash Aggarwal4a686502019-06-01 12:51:27 +05301889 self.assertRaises(TypeError, comb, 10.0, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001890 self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1)
1891 self.assertRaises(TypeError, comb, "10", 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301892
1893 self.assertRaises(TypeError, comb, 10)
1894 self.assertRaises(TypeError, comb, 10, 1, 3)
1895 self.assertRaises(TypeError, comb)
1896
1897 # Raises Value error if not k or n are negative numbers
1898 self.assertRaises(ValueError, comb, -1, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001899 self.assertRaises(ValueError, comb, -2**1000, 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301900 self.assertRaises(ValueError, comb, 1, -1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001901 self.assertRaises(ValueError, comb, 1, -2**1000)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301902
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07001903 # Returns zero if k is greater than n
1904 self.assertEqual(comb(1, 2), 0)
1905 self.assertEqual(comb(1, 2**1000), 0)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301906
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001907 n = 2**1000
1908 self.assertEqual(comb(n, 0), 1)
1909 self.assertEqual(comb(n, 1), n)
1910 self.assertEqual(comb(n, 2), n * (n-1) // 2)
1911 self.assertEqual(comb(n, n), 1)
1912 self.assertEqual(comb(n, n-1), n)
1913 self.assertEqual(comb(n, n-2), n * (n-1) // 2)
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +03001914 if support.check_impl_detail(cpython=True):
1915 self.assertRaises(OverflowError, comb, n, n//2)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301916
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001917 for n, k in (True, True), (True, False), (False, False):
1918 self.assertEqual(comb(n, k), 1)
1919 self.assertIs(type(comb(n, k)), int)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001920 self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001921 self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001922 for k in range(3):
1923 self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int)
1924 self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301925
Victor Stinner59e2d262020-01-21 12:48:16 +01001926 @requires_IEEE_754
1927 def test_nextafter(self):
1928 # around 2^52 and 2^63
1929 self.assertEqual(math.nextafter(4503599627370496.0, -INF),
1930 4503599627370495.5)
1931 self.assertEqual(math.nextafter(4503599627370496.0, INF),
1932 4503599627370497.0)
1933 self.assertEqual(math.nextafter(9223372036854775808.0, 0.0),
1934 9223372036854774784.0)
1935 self.assertEqual(math.nextafter(-9223372036854775808.0, 0.0),
1936 -9223372036854774784.0)
1937
1938 # around 1.0
1939 self.assertEqual(math.nextafter(1.0, -INF),
1940 float.fromhex('0x1.fffffffffffffp-1'))
1941 self.assertEqual(math.nextafter(1.0, INF),
1942 float.fromhex('0x1.0000000000001p+0'))
1943
1944 # x == y: y is returned
1945 self.assertEqual(math.nextafter(2.0, 2.0), 2.0)
1946 self.assertEqualSign(math.nextafter(-0.0, +0.0), +0.0)
1947 self.assertEqualSign(math.nextafter(+0.0, -0.0), -0.0)
1948
1949 # around 0.0
1950 smallest_subnormal = sys.float_info.min * sys.float_info.epsilon
1951 self.assertEqual(math.nextafter(+0.0, INF), smallest_subnormal)
1952 self.assertEqual(math.nextafter(-0.0, INF), smallest_subnormal)
1953 self.assertEqual(math.nextafter(+0.0, -INF), -smallest_subnormal)
1954 self.assertEqual(math.nextafter(-0.0, -INF), -smallest_subnormal)
1955 self.assertEqualSign(math.nextafter(smallest_subnormal, +0.0), +0.0)
1956 self.assertEqualSign(math.nextafter(-smallest_subnormal, +0.0), -0.0)
1957 self.assertEqualSign(math.nextafter(smallest_subnormal, -0.0), +0.0)
1958 self.assertEqualSign(math.nextafter(-smallest_subnormal, -0.0), -0.0)
1959
1960 # around infinity
1961 largest_normal = sys.float_info.max
1962 self.assertEqual(math.nextafter(INF, 0.0), largest_normal)
1963 self.assertEqual(math.nextafter(-INF, 0.0), -largest_normal)
1964 self.assertEqual(math.nextafter(largest_normal, INF), INF)
1965 self.assertEqual(math.nextafter(-largest_normal, -INF), -INF)
1966
1967 # NaN
1968 self.assertIsNaN(math.nextafter(NAN, 1.0))
1969 self.assertIsNaN(math.nextafter(1.0, NAN))
1970 self.assertIsNaN(math.nextafter(NAN, NAN))
1971
1972 @requires_IEEE_754
1973 def test_ulp(self):
1974 self.assertEqual(math.ulp(1.0), sys.float_info.epsilon)
1975 # use int ** int rather than float ** int to not rely on pow() accuracy
1976 self.assertEqual(math.ulp(2 ** 52), 1.0)
1977 self.assertEqual(math.ulp(2 ** 53), 2.0)
1978 self.assertEqual(math.ulp(2 ** 64), 4096.0)
1979
1980 # min and max
1981 self.assertEqual(math.ulp(0.0),
1982 sys.float_info.min * sys.float_info.epsilon)
1983 self.assertEqual(math.ulp(FLOAT_MAX),
1984 FLOAT_MAX - math.nextafter(FLOAT_MAX, -INF))
1985
1986 # special cases
1987 self.assertEqual(math.ulp(INF), INF)
1988 self.assertIsNaN(math.ulp(math.nan))
1989
1990 # negative number: ulp(-x) == ulp(x)
1991 for x in (0.0, 1.0, 2 ** 52, 2 ** 64, INF):
1992 with self.subTest(x=x):
1993 self.assertEqual(math.ulp(-x), math.ulp(x))
1994
Zackery Spytz5208b4b2020-03-14 04:45:32 -06001995 def test_issue39871(self):
1996 # A SystemError should not be raised if the first arg to atan2(),
1997 # copysign(), or remainder() cannot be converted to a float.
1998 class F:
1999 def __float__(self):
2000 self.converted = True
2001 1/0
2002 for func in math.atan2, math.copysign, math.remainder:
2003 y = F()
2004 with self.assertRaises(TypeError):
2005 func("not a number", y)
2006
2007 # There should not have been any attempt to convert the second
2008 # argument to a float.
2009 self.assertFalse(getattr(y, "converted", False))
2010
Victor Stinner59e2d262020-01-21 12:48:16 +01002011 # Custom assertions.
2012
2013 def assertIsNaN(self, value):
2014 if not math.isnan(value):
2015 self.fail("Expected a NaN, got {!r}.".format(value))
2016
2017 def assertEqualSign(self, x, y):
2018 """Similar to assertEqual(), but compare also the sign with copysign().
2019
2020 Function useful to compare signed zeros.
2021 """
2022 self.assertEqual(x, y)
2023 self.assertEqual(math.copysign(1.0, x), math.copysign(1.0, y))
2024
2025
2026class IsCloseTests(unittest.TestCase):
2027 isclose = math.isclose # subclasses should override this
2028
2029 def assertIsClose(self, a, b, *args, **kwargs):
2030 self.assertTrue(self.isclose(a, b, *args, **kwargs),
2031 msg="%s and %s should be close!" % (a, b))
2032
2033 def assertIsNotClose(self, a, b, *args, **kwargs):
2034 self.assertFalse(self.isclose(a, b, *args, **kwargs),
2035 msg="%s and %s should not be close!" % (a, b))
2036
2037 def assertAllClose(self, examples, *args, **kwargs):
2038 for a, b in examples:
2039 self.assertIsClose(a, b, *args, **kwargs)
2040
2041 def assertAllNotClose(self, examples, *args, **kwargs):
2042 for a, b in examples:
2043 self.assertIsNotClose(a, b, *args, **kwargs)
2044
2045 def test_negative_tolerances(self):
2046 # ValueError should be raised if either tolerance is less than zero
2047 with self.assertRaises(ValueError):
2048 self.assertIsClose(1, 1, rel_tol=-1e-100)
2049 with self.assertRaises(ValueError):
2050 self.assertIsClose(1, 1, rel_tol=1e-100, abs_tol=-1e10)
2051
2052 def test_identical(self):
2053 # identical values must test as close
2054 identical_examples = [(2.0, 2.0),
2055 (0.1e200, 0.1e200),
2056 (1.123e-300, 1.123e-300),
2057 (12345, 12345.0),
2058 (0.0, -0.0),
2059 (345678, 345678)]
2060 self.assertAllClose(identical_examples, rel_tol=0.0, abs_tol=0.0)
2061
2062 def test_eight_decimal_places(self):
2063 # examples that are close to 1e-8, but not 1e-9
2064 eight_decimal_places_examples = [(1e8, 1e8 + 1),
2065 (-1e-8, -1.000000009e-8),
2066 (1.12345678, 1.12345679)]
2067 self.assertAllClose(eight_decimal_places_examples, rel_tol=1e-8)
2068 self.assertAllNotClose(eight_decimal_places_examples, rel_tol=1e-9)
2069
2070 def test_near_zero(self):
2071 # values close to zero
2072 near_zero_examples = [(1e-9, 0.0),
2073 (-1e-9, 0.0),
2074 (-1e-150, 0.0)]
2075 # these should not be close to any rel_tol
2076 self.assertAllNotClose(near_zero_examples, rel_tol=0.9)
2077 # these should be close to abs_tol=1e-8
2078 self.assertAllClose(near_zero_examples, abs_tol=1e-8)
2079
2080 def test_identical_infinite(self):
2081 # these are close regardless of tolerance -- i.e. they are equal
2082 self.assertIsClose(INF, INF)
2083 self.assertIsClose(INF, INF, abs_tol=0.0)
2084 self.assertIsClose(NINF, NINF)
2085 self.assertIsClose(NINF, NINF, abs_tol=0.0)
2086
2087 def test_inf_ninf_nan(self):
2088 # these should never be close (following IEEE 754 rules for equality)
2089 not_close_examples = [(NAN, NAN),
2090 (NAN, 1e-100),
2091 (1e-100, NAN),
2092 (INF, NAN),
2093 (NAN, INF),
2094 (INF, NINF),
2095 (INF, 1.0),
2096 (1.0, INF),
2097 (INF, 1e308),
2098 (1e308, INF)]
2099 # use largest reasonable tolerance
2100 self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999)
2101
2102 def test_zero_tolerance(self):
2103 # test with zero tolerance
2104 zero_tolerance_close_examples = [(1.0, 1.0),
2105 (-3.4, -3.4),
2106 (-1e-300, -1e-300)]
2107 self.assertAllClose(zero_tolerance_close_examples, rel_tol=0.0)
2108
2109 zero_tolerance_not_close_examples = [(1.0, 1.000000000000001),
2110 (0.99999999999999, 1.0),
2111 (1.0e200, .999999999999999e200)]
2112 self.assertAllNotClose(zero_tolerance_not_close_examples, rel_tol=0.0)
2113
2114 def test_asymmetry(self):
2115 # test the asymmetry example from PEP 485
2116 self.assertAllClose([(9, 10), (10, 9)], rel_tol=0.1)
2117
2118 def test_integers(self):
2119 # test with integer values
2120 integer_examples = [(100000001, 100000000),
2121 (123456789, 123456788)]
2122
2123 self.assertAllClose(integer_examples, rel_tol=1e-8)
2124 self.assertAllNotClose(integer_examples, rel_tol=1e-9)
2125
2126 def test_decimals(self):
2127 # test with Decimal values
2128 from decimal import Decimal
2129
2130 decimal_examples = [(Decimal('1.00000001'), Decimal('1.0')),
2131 (Decimal('1.00000001e-20'), Decimal('1.0e-20')),
2132 (Decimal('1.00000001e-100'), Decimal('1.0e-100')),
2133 (Decimal('1.00000001e20'), Decimal('1.0e20'))]
2134 self.assertAllClose(decimal_examples, rel_tol=1e-8)
2135 self.assertAllNotClose(decimal_examples, rel_tol=1e-9)
2136
2137 def test_fractions(self):
2138 # test with Fraction values
2139 from fractions import Fraction
2140
2141 fraction_examples = [
2142 (Fraction(1, 100000000) + 1, Fraction(1)),
2143 (Fraction(100000001), Fraction(100000000)),
2144 (Fraction(10**8 + 1, 10**28), Fraction(1, 10**20))]
2145 self.assertAllClose(fraction_examples, rel_tol=1e-8)
2146 self.assertAllNotClose(fraction_examples, rel_tol=1e-9)
2147
Pablo Galindo42079072019-02-10 19:56:58 +00002148
Thomas Wouters89f507f2006-12-13 04:49:30 +00002149def test_main():
Christian Heimes53876d92008-04-19 00:31:39 +00002150 from doctest import DocFileSuite
2151 suite = unittest.TestSuite()
2152 suite.addTest(unittest.makeSuite(MathTests))
Tal Einatd5519ed2015-05-31 22:05:00 +03002153 suite.addTest(unittest.makeSuite(IsCloseTests))
Christian Heimes53876d92008-04-19 00:31:39 +00002154 suite.addTest(DocFileSuite("ieee754.txt"))
2155 run_unittest(suite)
Thomas Wouters89f507f2006-12-13 04:49:30 +00002156
2157if __name__ == '__main__':
2158 test_main()