blob: 86e3923af6d07463f907eed97c2a3810b9c9cf90 [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 Stinnerbe3da382010-11-07 14:14:27 +000015import sysconfig
Guido van Rossumfcce6301996-08-08 18:26:25 +000016
Christian Heimes53876d92008-04-19 00:31:39 +000017eps = 1E-05
18NAN = float('nan')
19INF = float('inf')
20NINF = float('-inf')
Mark Dickinson31ba1c32016-09-04 12:29:14 +010021FLOAT_MAX = sys.float_info.max
Raymond Hettingerc6dabe32018-07-28 07:48:04 -070022FLOAT_MIN = sys.float_info.min
Christian Heimes53876d92008-04-19 00:31:39 +000023
Mark Dickinson5c567082009-04-24 16:39:07 +000024# detect evidence of double-rounding: fsum is not always correctly
25# rounded on machines that suffer from double rounding.
26x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer
27HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4)
28
Christian Heimes53876d92008-04-19 00:31:39 +000029# locate file with test values
30if __name__ == '__main__':
31 file = sys.argv[0]
32else:
33 file = __file__
34test_dir = os.path.dirname(file) or os.curdir
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000035math_testcases = os.path.join(test_dir, 'math_testcases.txt')
Christian Heimes53876d92008-04-19 00:31:39 +000036test_file = os.path.join(test_dir, 'cmath_testcases.txt')
37
Mark Dickinson96f774d2016-09-03 19:30:22 +010038
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000039def to_ulps(x):
40 """Convert a non-NaN float x to an integer, in such a way that
41 adjacent floats are converted to adjacent integers. Then
42 abs(ulps(x) - ulps(y)) gives the difference in ulps between two
43 floats.
44
45 The results from this function will only make sense on platforms
Mark Dickinson96f774d2016-09-03 19:30:22 +010046 where native doubles are represented in IEEE 754 binary64 format.
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000047
Mark Dickinson96f774d2016-09-03 19:30:22 +010048 Note: 0.0 and -0.0 are converted to 0 and -1, respectively.
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000049 """
Mark Dickinsond412ab52009-10-17 07:10:00 +000050 n = struct.unpack('<q', struct.pack('<d', x))[0]
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000051 if n < 0:
52 n = ~(n+2**63)
53 return n
54
Mark Dickinson05d2e082009-12-11 20:17:17 +000055
Mark Dickinson96f774d2016-09-03 19:30:22 +010056def ulp(x):
57 """Return the value of the least significant bit of a
58 float x, such that the first float bigger than x is x+ulp(x).
59 Then, given an expected result x and a tolerance of n ulps,
60 the result y should be such that abs(y-x) <= n * ulp(x).
61 The results from this function will only make sense on platforms
62 where native doubles are represented in IEEE 754 binary64 format.
63 """
64 x = abs(float(x))
65 if math.isnan(x) or math.isinf(x):
66 return x
Mark Dickinson05d2e082009-12-11 20:17:17 +000067
Mark Dickinson96f774d2016-09-03 19:30:22 +010068 # Find next float up from x.
69 n = struct.unpack('<q', struct.pack('<d', x))[0]
70 x_next = struct.unpack('<d', struct.pack('<q', n + 1))[0]
71 if math.isinf(x_next):
72 # Corner case: x was the largest finite float. Then it's
73 # not an exact power of two, so we can take the difference
74 # between x and the previous float.
75 x_prev = struct.unpack('<d', struct.pack('<q', n - 1))[0]
76 return x - x_prev
77 else:
78 return x_next - x
Mark Dickinson05d2e082009-12-11 20:17:17 +000079
Mark Dickinson4c8a9a22010-05-15 17:02:38 +000080# Here's a pure Python version of the math.factorial algorithm, for
81# documentation and comparison purposes.
82#
83# Formula:
84#
85# factorial(n) = factorial_odd_part(n) << (n - count_set_bits(n))
86#
87# where
88#
89# factorial_odd_part(n) = product_{i >= 0} product_{0 < j <= n >> i; j odd} j
90#
91# The outer product above is an infinite product, but once i >= n.bit_length,
92# (n >> i) < 1 and the corresponding term of the product is empty. So only the
93# finitely many terms for 0 <= i < n.bit_length() contribute anything.
94#
95# We iterate downwards from i == n.bit_length() - 1 to i == 0. The inner
96# product in the formula above starts at 1 for i == n.bit_length(); for each i
97# < n.bit_length() we get the inner product for i from that for i + 1 by
98# multiplying by all j in {n >> i+1 < j <= n >> i; j odd}. In Python terms,
99# this set is range((n >> i+1) + 1 | 1, (n >> i) + 1 | 1, 2).
100
101def count_set_bits(n):
102 """Number of '1' bits in binary expansion of a nonnnegative integer."""
103 return 1 + count_set_bits(n & n - 1) if n else 0
104
105def partial_product(start, stop):
106 """Product of integers in range(start, stop, 2), computed recursively.
107 start and stop should both be odd, with start <= stop.
108
109 """
110 numfactors = (stop - start) >> 1
111 if not numfactors:
112 return 1
113 elif numfactors == 1:
114 return start
115 else:
116 mid = (start + numfactors) | 1
117 return partial_product(start, mid) * partial_product(mid, stop)
118
119def py_factorial(n):
120 """Factorial of nonnegative integer n, via "Binary Split Factorial Formula"
121 described at http://www.luschny.de/math/factorial/binarysplitfact.html
122
123 """
124 inner = outer = 1
125 for i in reversed(range(n.bit_length())):
126 inner *= partial_product((n >> i + 1) + 1 | 1, (n >> i) + 1 | 1)
127 outer *= inner
128 return outer << (n - count_set_bits(n))
129
Mark Dickinson96f774d2016-09-03 19:30:22 +0100130def ulp_abs_check(expected, got, ulp_tol, abs_tol):
131 """Given finite floats `expected` and `got`, check that they're
132 approximately equal to within the given number of ulps or the
133 given absolute tolerance, whichever is bigger.
Mark Dickinson05d2e082009-12-11 20:17:17 +0000134
Mark Dickinson96f774d2016-09-03 19:30:22 +0100135 Returns None on success and an error message on failure.
136 """
137 ulp_error = abs(to_ulps(expected) - to_ulps(got))
138 abs_error = abs(expected - got)
139
140 # Succeed if either abs_error <= abs_tol or ulp_error <= ulp_tol.
141 if abs_error <= abs_tol or ulp_error <= ulp_tol:
Mark Dickinson05d2e082009-12-11 20:17:17 +0000142 return None
Mark Dickinson96f774d2016-09-03 19:30:22 +0100143 else:
144 fmt = ("error = {:.3g} ({:d} ulps); "
145 "permitted error = {:.3g} or {:d} ulps")
146 return fmt.format(abs_error, ulp_error, abs_tol, ulp_tol)
Mark Dickinson12c4bdb2009-09-28 19:21:11 +0000147
148def parse_mtestfile(fname):
149 """Parse a file with test values
150
151 -- starts a comment
152 blank lines, or lines containing only a comment, are ignored
153 other lines are expected to have the form
154 id fn arg -> expected [flag]*
155
156 """
157 with open(fname) as fp:
158 for line in fp:
159 # strip comments, and skip blank lines
160 if '--' in line:
161 line = line[:line.index('--')]
162 if not line.strip():
163 continue
164
165 lhs, rhs = line.split('->')
166 id, fn, arg = lhs.split()
167 rhs_pieces = rhs.split()
168 exp = rhs_pieces[0]
169 flags = rhs_pieces[1:]
170
171 yield (id, fn, float(arg), float(exp), flags)
172
Mark Dickinson96f774d2016-09-03 19:30:22 +0100173
Christian Heimes53876d92008-04-19 00:31:39 +0000174def parse_testfile(fname):
175 """Parse a file with test values
176
177 Empty lines or lines starting with -- are ignored
178 yields id, fn, arg_real, arg_imag, exp_real, exp_imag
179 """
180 with open(fname) as fp:
181 for line in fp:
182 # skip comment lines and blank lines
183 if line.startswith('--') or not line.strip():
184 continue
185
186 lhs, rhs = line.split('->')
187 id, fn, arg_real, arg_imag = lhs.split()
188 rhs_pieces = rhs.split()
189 exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1]
190 flags = rhs_pieces[2:]
191
192 yield (id, fn,
193 float(arg_real), float(arg_imag),
194 float(exp_real), float(exp_imag),
Mark Dickinson96f774d2016-09-03 19:30:22 +0100195 flags)
196
197
198def result_check(expected, got, ulp_tol=5, abs_tol=0.0):
199 # Common logic of MathTests.(ftest, test_testcases, test_mtestcases)
200 """Compare arguments expected and got, as floats, if either
201 is a float, using a tolerance expressed in multiples of
202 ulp(expected) or absolutely (if given and greater).
203
204 As a convenience, when neither argument is a float, and for
205 non-finite floats, exact equality is demanded. Also, nan==nan
206 as far as this function is concerned.
207
208 Returns None on success and an error message on failure.
209 """
210
211 # Check exactly equal (applies also to strings representing exceptions)
212 if got == expected:
213 return None
214
215 failure = "not equal"
216
217 # Turn mixed float and int comparison (e.g. floor()) to all-float
218 if isinstance(expected, float) and isinstance(got, int):
219 got = float(got)
220 elif isinstance(got, float) and isinstance(expected, int):
221 expected = float(expected)
222
223 if isinstance(expected, float) and isinstance(got, float):
224 if math.isnan(expected) and math.isnan(got):
225 # Pass, since both nan
226 failure = None
227 elif math.isinf(expected) or math.isinf(got):
228 # We already know they're not equal, drop through to failure
229 pass
230 else:
231 # Both are finite floats (now). Are they close enough?
232 failure = ulp_abs_check(expected, got, ulp_tol, abs_tol)
233
234 # arguments are not equal, and if numeric, are too far apart
235 if failure is not None:
236 fail_fmt = "expected {!r}, got {!r}"
237 fail_msg = fail_fmt.format(expected, got)
238 fail_msg += ' ({})'.format(failure)
239 return fail_msg
240 else:
241 return None
Guido van Rossumfcce6301996-08-08 18:26:25 +0000242
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +0300243class IntSubclass(int):
244 pass
245
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300246# Class providing an __index__ method.
247class MyIndexable(object):
248 def __init__(self, value):
249 self.value = value
250
251 def __index__(self):
252 return self.value
253
Thomas Wouters89f507f2006-12-13 04:49:30 +0000254class MathTests(unittest.TestCase):
Guido van Rossumfcce6301996-08-08 18:26:25 +0000255
Mark Dickinson96f774d2016-09-03 19:30:22 +0100256 def ftest(self, name, got, expected, ulp_tol=5, abs_tol=0.0):
257 """Compare arguments expected and got, as floats, if either
258 is a float, using a tolerance expressed in multiples of
259 ulp(expected) or absolutely, whichever is greater.
260
261 As a convenience, when neither argument is a float, and for
262 non-finite floats, exact equality is demanded. Also, nan==nan
263 in this function.
264 """
265 failure = result_check(expected, got, ulp_tol, abs_tol)
266 if failure is not None:
267 self.fail("{}: {}".format(name, failure))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000268
Thomas Wouters89f507f2006-12-13 04:49:30 +0000269 def testConstants(self):
Mark Dickinson96f774d2016-09-03 19:30:22 +0100270 # Ref: Abramowitz & Stegun (Dover, 1965)
271 self.ftest('pi', math.pi, 3.141592653589793238462643)
272 self.ftest('e', math.e, 2.718281828459045235360287)
Guido van Rossum0a891d72016-08-15 09:12:52 -0700273 self.assertEqual(math.tau, 2*math.pi)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000274
Thomas Wouters89f507f2006-12-13 04:49:30 +0000275 def testAcos(self):
276 self.assertRaises(TypeError, math.acos)
277 self.ftest('acos(-1)', math.acos(-1), math.pi)
278 self.ftest('acos(0)', math.acos(0), math.pi/2)
279 self.ftest('acos(1)', math.acos(1), 0)
Christian Heimes53876d92008-04-19 00:31:39 +0000280 self.assertRaises(ValueError, math.acos, INF)
281 self.assertRaises(ValueError, math.acos, NINF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100282 self.assertRaises(ValueError, math.acos, 1 + eps)
283 self.assertRaises(ValueError, math.acos, -1 - eps)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000284 self.assertTrue(math.isnan(math.acos(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000285
286 def testAcosh(self):
287 self.assertRaises(TypeError, math.acosh)
288 self.ftest('acosh(1)', math.acosh(1), 0)
289 self.ftest('acosh(2)', math.acosh(2), 1.3169578969248168)
290 self.assertRaises(ValueError, math.acosh, 0)
291 self.assertRaises(ValueError, math.acosh, -1)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000292 self.assertEqual(math.acosh(INF), INF)
Christian Heimes53876d92008-04-19 00:31:39 +0000293 self.assertRaises(ValueError, math.acosh, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000294 self.assertTrue(math.isnan(math.acosh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000295
Thomas Wouters89f507f2006-12-13 04:49:30 +0000296 def testAsin(self):
297 self.assertRaises(TypeError, math.asin)
298 self.ftest('asin(-1)', math.asin(-1), -math.pi/2)
299 self.ftest('asin(0)', math.asin(0), 0)
300 self.ftest('asin(1)', math.asin(1), math.pi/2)
Christian Heimes53876d92008-04-19 00:31:39 +0000301 self.assertRaises(ValueError, math.asin, INF)
302 self.assertRaises(ValueError, math.asin, NINF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100303 self.assertRaises(ValueError, math.asin, 1 + eps)
304 self.assertRaises(ValueError, math.asin, -1 - eps)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000305 self.assertTrue(math.isnan(math.asin(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000306
307 def testAsinh(self):
308 self.assertRaises(TypeError, math.asinh)
309 self.ftest('asinh(0)', math.asinh(0), 0)
310 self.ftest('asinh(1)', math.asinh(1), 0.88137358701954305)
311 self.ftest('asinh(-1)', math.asinh(-1), -0.88137358701954305)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000312 self.assertEqual(math.asinh(INF), INF)
313 self.assertEqual(math.asinh(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000314 self.assertTrue(math.isnan(math.asinh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000315
Thomas Wouters89f507f2006-12-13 04:49:30 +0000316 def testAtan(self):
317 self.assertRaises(TypeError, math.atan)
318 self.ftest('atan(-1)', math.atan(-1), -math.pi/4)
319 self.ftest('atan(0)', math.atan(0), 0)
320 self.ftest('atan(1)', math.atan(1), math.pi/4)
Christian Heimes53876d92008-04-19 00:31:39 +0000321 self.ftest('atan(inf)', math.atan(INF), math.pi/2)
Christian Heimesa342c012008-04-20 21:01:16 +0000322 self.ftest('atan(-inf)', math.atan(NINF), -math.pi/2)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000323 self.assertTrue(math.isnan(math.atan(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000324
325 def testAtanh(self):
326 self.assertRaises(TypeError, math.atan)
327 self.ftest('atanh(0)', math.atanh(0), 0)
328 self.ftest('atanh(0.5)', math.atanh(0.5), 0.54930614433405489)
329 self.ftest('atanh(-0.5)', math.atanh(-0.5), -0.54930614433405489)
330 self.assertRaises(ValueError, math.atanh, 1)
331 self.assertRaises(ValueError, math.atanh, -1)
332 self.assertRaises(ValueError, math.atanh, INF)
333 self.assertRaises(ValueError, math.atanh, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000334 self.assertTrue(math.isnan(math.atanh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000335
Thomas Wouters89f507f2006-12-13 04:49:30 +0000336 def testAtan2(self):
337 self.assertRaises(TypeError, math.atan2)
338 self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
339 self.ftest('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
340 self.ftest('atan2(0, 1)', math.atan2(0, 1), 0)
341 self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
342 self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000343
Christian Heimese57950f2008-04-21 13:08:03 +0000344 # math.atan2(0, x)
345 self.ftest('atan2(0., -inf)', math.atan2(0., NINF), math.pi)
346 self.ftest('atan2(0., -2.3)', math.atan2(0., -2.3), math.pi)
347 self.ftest('atan2(0., -0.)', math.atan2(0., -0.), math.pi)
348 self.assertEqual(math.atan2(0., 0.), 0.)
349 self.assertEqual(math.atan2(0., 2.3), 0.)
350 self.assertEqual(math.atan2(0., INF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000351 self.assertTrue(math.isnan(math.atan2(0., NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000352 # math.atan2(-0, x)
353 self.ftest('atan2(-0., -inf)', math.atan2(-0., NINF), -math.pi)
354 self.ftest('atan2(-0., -2.3)', math.atan2(-0., -2.3), -math.pi)
355 self.ftest('atan2(-0., -0.)', math.atan2(-0., -0.), -math.pi)
356 self.assertEqual(math.atan2(-0., 0.), -0.)
357 self.assertEqual(math.atan2(-0., 2.3), -0.)
358 self.assertEqual(math.atan2(-0., INF), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000359 self.assertTrue(math.isnan(math.atan2(-0., NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000360 # math.atan2(INF, x)
361 self.ftest('atan2(inf, -inf)', math.atan2(INF, NINF), math.pi*3/4)
362 self.ftest('atan2(inf, -2.3)', math.atan2(INF, -2.3), math.pi/2)
363 self.ftest('atan2(inf, -0.)', math.atan2(INF, -0.0), math.pi/2)
364 self.ftest('atan2(inf, 0.)', math.atan2(INF, 0.0), math.pi/2)
365 self.ftest('atan2(inf, 2.3)', math.atan2(INF, 2.3), math.pi/2)
366 self.ftest('atan2(inf, inf)', math.atan2(INF, INF), math.pi/4)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000367 self.assertTrue(math.isnan(math.atan2(INF, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000368 # math.atan2(NINF, x)
369 self.ftest('atan2(-inf, -inf)', math.atan2(NINF, NINF), -math.pi*3/4)
370 self.ftest('atan2(-inf, -2.3)', math.atan2(NINF, -2.3), -math.pi/2)
371 self.ftest('atan2(-inf, -0.)', math.atan2(NINF, -0.0), -math.pi/2)
372 self.ftest('atan2(-inf, 0.)', math.atan2(NINF, 0.0), -math.pi/2)
373 self.ftest('atan2(-inf, 2.3)', math.atan2(NINF, 2.3), -math.pi/2)
374 self.ftest('atan2(-inf, inf)', math.atan2(NINF, INF), -math.pi/4)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000375 self.assertTrue(math.isnan(math.atan2(NINF, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000376 # math.atan2(+finite, x)
377 self.ftest('atan2(2.3, -inf)', math.atan2(2.3, NINF), math.pi)
378 self.ftest('atan2(2.3, -0.)', math.atan2(2.3, -0.), math.pi/2)
379 self.ftest('atan2(2.3, 0.)', math.atan2(2.3, 0.), math.pi/2)
380 self.assertEqual(math.atan2(2.3, INF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000381 self.assertTrue(math.isnan(math.atan2(2.3, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000382 # math.atan2(-finite, x)
383 self.ftest('atan2(-2.3, -inf)', math.atan2(-2.3, NINF), -math.pi)
384 self.ftest('atan2(-2.3, -0.)', math.atan2(-2.3, -0.), -math.pi/2)
385 self.ftest('atan2(-2.3, 0.)', math.atan2(-2.3, 0.), -math.pi/2)
386 self.assertEqual(math.atan2(-2.3, INF), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000387 self.assertTrue(math.isnan(math.atan2(-2.3, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000388 # math.atan2(NAN, x)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000389 self.assertTrue(math.isnan(math.atan2(NAN, NINF)))
390 self.assertTrue(math.isnan(math.atan2(NAN, -2.3)))
391 self.assertTrue(math.isnan(math.atan2(NAN, -0.)))
392 self.assertTrue(math.isnan(math.atan2(NAN, 0.)))
393 self.assertTrue(math.isnan(math.atan2(NAN, 2.3)))
394 self.assertTrue(math.isnan(math.atan2(NAN, INF)))
395 self.assertTrue(math.isnan(math.atan2(NAN, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000396
Thomas Wouters89f507f2006-12-13 04:49:30 +0000397 def testCeil(self):
398 self.assertRaises(TypeError, math.ceil)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000399 self.assertEqual(int, type(math.ceil(0.5)))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000400 self.ftest('ceil(0.5)', math.ceil(0.5), 1)
401 self.ftest('ceil(1.0)', math.ceil(1.0), 1)
402 self.ftest('ceil(1.5)', math.ceil(1.5), 2)
403 self.ftest('ceil(-0.5)', math.ceil(-0.5), 0)
404 self.ftest('ceil(-1.0)', math.ceil(-1.0), -1)
405 self.ftest('ceil(-1.5)', math.ceil(-1.5), -1)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000406 #self.assertEqual(math.ceil(INF), INF)
407 #self.assertEqual(math.ceil(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000408 #self.assertTrue(math.isnan(math.ceil(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000409
Guido van Rossum13e05de2007-08-23 22:56:55 +0000410 class TestCeil:
411 def __ceil__(self):
412 return 42
413 class TestNoCeil:
414 pass
415 self.ftest('ceil(TestCeil())', math.ceil(TestCeil()), 42)
416 self.assertRaises(TypeError, math.ceil, TestNoCeil())
417
418 t = TestNoCeil()
419 t.__ceil__ = lambda *args: args
420 self.assertRaises(TypeError, math.ceil, t)
421 self.assertRaises(TypeError, math.ceil, t, 0)
422
Mark Dickinson63566232009-09-18 21:04:19 +0000423 @requires_IEEE_754
424 def testCopysign(self):
Mark Dickinson06b59e02010-02-06 23:16:50 +0000425 self.assertEqual(math.copysign(1, 42), 1.0)
426 self.assertEqual(math.copysign(0., 42), 0.0)
427 self.assertEqual(math.copysign(1., -42), -1.0)
428 self.assertEqual(math.copysign(3, 0.), 3.0)
429 self.assertEqual(math.copysign(4., -0.), -4.0)
430
Mark Dickinson63566232009-09-18 21:04:19 +0000431 self.assertRaises(TypeError, math.copysign)
432 # copysign should let us distinguish signs of zeros
Ezio Melottib3aedd42010-11-20 19:04:17 +0000433 self.assertEqual(math.copysign(1., 0.), 1.)
434 self.assertEqual(math.copysign(1., -0.), -1.)
435 self.assertEqual(math.copysign(INF, 0.), INF)
436 self.assertEqual(math.copysign(INF, -0.), NINF)
437 self.assertEqual(math.copysign(NINF, 0.), INF)
438 self.assertEqual(math.copysign(NINF, -0.), NINF)
Mark Dickinson63566232009-09-18 21:04:19 +0000439 # and of infinities
Ezio Melottib3aedd42010-11-20 19:04:17 +0000440 self.assertEqual(math.copysign(1., INF), 1.)
441 self.assertEqual(math.copysign(1., NINF), -1.)
442 self.assertEqual(math.copysign(INF, INF), INF)
443 self.assertEqual(math.copysign(INF, NINF), NINF)
444 self.assertEqual(math.copysign(NINF, INF), INF)
445 self.assertEqual(math.copysign(NINF, NINF), NINF)
Mark Dickinson06b59e02010-02-06 23:16:50 +0000446 self.assertTrue(math.isnan(math.copysign(NAN, 1.)))
447 self.assertTrue(math.isnan(math.copysign(NAN, INF)))
448 self.assertTrue(math.isnan(math.copysign(NAN, NINF)))
449 self.assertTrue(math.isnan(math.copysign(NAN, NAN)))
Mark Dickinson63566232009-09-18 21:04:19 +0000450 # copysign(INF, NAN) may be INF or it may be NINF, since
451 # we don't know whether the sign bit of NAN is set on any
452 # given platform.
Mark Dickinson06b59e02010-02-06 23:16:50 +0000453 self.assertTrue(math.isinf(math.copysign(INF, NAN)))
Mark Dickinson63566232009-09-18 21:04:19 +0000454 # similarly, copysign(2., NAN) could be 2. or -2.
Ezio Melottib3aedd42010-11-20 19:04:17 +0000455 self.assertEqual(abs(math.copysign(2., NAN)), 2.)
Christian Heimes53876d92008-04-19 00:31:39 +0000456
Thomas Wouters89f507f2006-12-13 04:49:30 +0000457 def testCos(self):
458 self.assertRaises(TypeError, math.cos)
Mark Dickinson96f774d2016-09-03 19:30:22 +0100459 self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0, abs_tol=ulp(1))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000460 self.ftest('cos(0)', math.cos(0), 1)
Mark Dickinson96f774d2016-09-03 19:30:22 +0100461 self.ftest('cos(pi/2)', math.cos(math.pi/2), 0, abs_tol=ulp(1))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000462 self.ftest('cos(pi)', math.cos(math.pi), -1)
Christian Heimes53876d92008-04-19 00:31:39 +0000463 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000464 self.assertTrue(math.isnan(math.cos(INF)))
465 self.assertTrue(math.isnan(math.cos(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +0000466 except ValueError:
467 self.assertRaises(ValueError, math.cos, INF)
468 self.assertRaises(ValueError, math.cos, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000469 self.assertTrue(math.isnan(math.cos(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000470
Thomas Wouters89f507f2006-12-13 04:49:30 +0000471 def testCosh(self):
472 self.assertRaises(TypeError, math.cosh)
473 self.ftest('cosh(0)', math.cosh(0), 1)
474 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 +0000475 self.assertEqual(math.cosh(INF), INF)
476 self.assertEqual(math.cosh(NINF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000477 self.assertTrue(math.isnan(math.cosh(NAN)))
Raymond Hettinger64108af2002-05-13 03:55:01 +0000478
Thomas Wouters89f507f2006-12-13 04:49:30 +0000479 def testDegrees(self):
480 self.assertRaises(TypeError, math.degrees)
481 self.ftest('degrees(pi)', math.degrees(math.pi), 180.0)
482 self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
483 self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100484 self.ftest('degrees(0)', math.degrees(0), 0)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000485
Thomas Wouters89f507f2006-12-13 04:49:30 +0000486 def testExp(self):
487 self.assertRaises(TypeError, math.exp)
488 self.ftest('exp(-1)', math.exp(-1), 1/math.e)
489 self.ftest('exp(0)', math.exp(0), 1)
490 self.ftest('exp(1)', math.exp(1), math.e)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000491 self.assertEqual(math.exp(INF), INF)
492 self.assertEqual(math.exp(NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000493 self.assertTrue(math.isnan(math.exp(NAN)))
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100494 self.assertRaises(OverflowError, math.exp, 1000000)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000495
Thomas Wouters89f507f2006-12-13 04:49:30 +0000496 def testFabs(self):
497 self.assertRaises(TypeError, math.fabs)
498 self.ftest('fabs(-1)', math.fabs(-1), 1)
499 self.ftest('fabs(0)', math.fabs(0), 0)
500 self.ftest('fabs(1)', math.fabs(1), 1)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000501
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000502 def testFactorial(self):
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000503 self.assertEqual(math.factorial(0), 1)
504 self.assertEqual(math.factorial(0.0), 1)
505 total = 1
506 for i in range(1, 1000):
507 total *= i
508 self.assertEqual(math.factorial(i), total)
509 self.assertEqual(math.factorial(float(i)), total)
510 self.assertEqual(math.factorial(i), py_factorial(i))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000511 self.assertRaises(ValueError, math.factorial, -1)
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000512 self.assertRaises(ValueError, math.factorial, -1.0)
Mark Dickinson5990d282014-04-10 09:29:39 -0400513 self.assertRaises(ValueError, math.factorial, -10**100)
514 self.assertRaises(ValueError, math.factorial, -1e100)
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000515 self.assertRaises(ValueError, math.factorial, math.pi)
Mark Dickinson5990d282014-04-10 09:29:39 -0400516
Pablo Galindoe9ba3702018-09-03 22:20:06 +0100517 def testFactorialNonIntegers(self):
518 self.assertRaises(TypeError, math.factorial, decimal.Decimal(5.2))
519 self.assertRaises(TypeError, math.factorial, "5")
520
Mark Dickinson5990d282014-04-10 09:29:39 -0400521 # Other implementations may place different upper bounds.
522 @support.cpython_only
523 def testFactorialHugeInputs(self):
524 # Currently raises ValueError for inputs that are too large
525 # to fit into a C long.
526 self.assertRaises(OverflowError, math.factorial, 10**100)
527 self.assertRaises(OverflowError, math.factorial, 1e100)
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000528
Thomas Wouters89f507f2006-12-13 04:49:30 +0000529 def testFloor(self):
530 self.assertRaises(TypeError, math.floor)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000531 self.assertEqual(int, type(math.floor(0.5)))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000532 self.ftest('floor(0.5)', math.floor(0.5), 0)
533 self.ftest('floor(1.0)', math.floor(1.0), 1)
534 self.ftest('floor(1.5)', math.floor(1.5), 1)
535 self.ftest('floor(-0.5)', math.floor(-0.5), -1)
536 self.ftest('floor(-1.0)', math.floor(-1.0), -1)
537 self.ftest('floor(-1.5)', math.floor(-1.5), -2)
Guido van Rossum806c2462007-08-06 23:33:07 +0000538 # pow() relies on floor() to check for integers
539 # This fails on some platforms - so check it here
540 self.ftest('floor(1.23e167)', math.floor(1.23e167), 1.23e167)
541 self.ftest('floor(-1.23e167)', math.floor(-1.23e167), -1.23e167)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000542 #self.assertEqual(math.ceil(INF), INF)
543 #self.assertEqual(math.ceil(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000544 #self.assertTrue(math.isnan(math.floor(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000545
Guido van Rossum13e05de2007-08-23 22:56:55 +0000546 class TestFloor:
547 def __floor__(self):
548 return 42
549 class TestNoFloor:
550 pass
551 self.ftest('floor(TestFloor())', math.floor(TestFloor()), 42)
552 self.assertRaises(TypeError, math.floor, TestNoFloor())
553
554 t = TestNoFloor()
555 t.__floor__ = lambda *args: args
556 self.assertRaises(TypeError, math.floor, t)
557 self.assertRaises(TypeError, math.floor, t, 0)
558
Thomas Wouters89f507f2006-12-13 04:49:30 +0000559 def testFmod(self):
560 self.assertRaises(TypeError, math.fmod)
Mark Dickinson5bc7a442011-05-03 21:13:40 +0100561 self.ftest('fmod(10, 1)', math.fmod(10, 1), 0.0)
562 self.ftest('fmod(10, 0.5)', math.fmod(10, 0.5), 0.0)
563 self.ftest('fmod(10, 1.5)', math.fmod(10, 1.5), 1.0)
564 self.ftest('fmod(-10, 1)', math.fmod(-10, 1), -0.0)
565 self.ftest('fmod(-10, 0.5)', math.fmod(-10, 0.5), -0.0)
566 self.ftest('fmod(-10, 1.5)', math.fmod(-10, 1.5), -1.0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000567 self.assertTrue(math.isnan(math.fmod(NAN, 1.)))
568 self.assertTrue(math.isnan(math.fmod(1., NAN)))
569 self.assertTrue(math.isnan(math.fmod(NAN, NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000570 self.assertRaises(ValueError, math.fmod, 1., 0.)
571 self.assertRaises(ValueError, math.fmod, INF, 1.)
572 self.assertRaises(ValueError, math.fmod, NINF, 1.)
573 self.assertRaises(ValueError, math.fmod, INF, 0.)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000574 self.assertEqual(math.fmod(3.0, INF), 3.0)
575 self.assertEqual(math.fmod(-3.0, INF), -3.0)
576 self.assertEqual(math.fmod(3.0, NINF), 3.0)
577 self.assertEqual(math.fmod(-3.0, NINF), -3.0)
578 self.assertEqual(math.fmod(0.0, 3.0), 0.0)
579 self.assertEqual(math.fmod(0.0, NINF), 0.0)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000580
Thomas Wouters89f507f2006-12-13 04:49:30 +0000581 def testFrexp(self):
582 self.assertRaises(TypeError, math.frexp)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000583
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000584 def testfrexp(name, result, expected):
585 (mant, exp), (emant, eexp) = result, expected
Thomas Wouters89f507f2006-12-13 04:49:30 +0000586 if abs(mant-emant) > eps or exp != eexp:
587 self.fail('%s returned %r, expected %r'%\
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000588 (name, result, expected))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000589
Thomas Wouters89f507f2006-12-13 04:49:30 +0000590 testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
591 testfrexp('frexp(0)', math.frexp(0), (0, 0))
592 testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
593 testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000594
Ezio Melottib3aedd42010-11-20 19:04:17 +0000595 self.assertEqual(math.frexp(INF)[0], INF)
596 self.assertEqual(math.frexp(NINF)[0], NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000597 self.assertTrue(math.isnan(math.frexp(NAN)[0]))
Christian Heimes53876d92008-04-19 00:31:39 +0000598
Mark Dickinson63566232009-09-18 21:04:19 +0000599 @requires_IEEE_754
Mark Dickinson5c567082009-04-24 16:39:07 +0000600 @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
601 "fsum is not exact on machines with double rounding")
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000602 def testFsum(self):
603 # math.fsum relies on exact rounding for correct operation.
604 # There's a known problem with IA32 floating-point that causes
605 # inexact rounding in some situations, and will cause the
606 # math.fsum tests below to fail; see issue #2937. On non IEEE
607 # 754 platforms, and on IEEE 754 platforms that exhibit the
608 # problem described in issue #2937, we simply skip the whole
609 # test.
610
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000611 # Python version of math.fsum, for comparison. Uses a
612 # different algorithm based on frexp, ldexp and integer
613 # arithmetic.
614 from sys import float_info
615 mant_dig = float_info.mant_dig
616 etiny = float_info.min_exp - mant_dig
617
618 def msum(iterable):
619 """Full precision summation. Compute sum(iterable) without any
620 intermediate accumulation of error. Based on the 'lsum' function
621 at http://code.activestate.com/recipes/393090/
622
623 """
624 tmant, texp = 0, 0
625 for x in iterable:
626 mant, exp = math.frexp(x)
627 mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig
628 if texp > exp:
629 tmant <<= texp-exp
630 texp = exp
631 else:
632 mant <<= exp-texp
633 tmant += mant
634 # Round tmant * 2**texp to a float. The original recipe
635 # used float(str(tmant)) * 2.0**texp for this, but that's
636 # a little unsafe because str -> float conversion can't be
637 # relied upon to do correct rounding on all platforms.
638 tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp)
639 if tail > 0:
640 h = 1 << (tail-1)
641 tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1)
642 texp += tail
643 return math.ldexp(tmant, texp)
644
645 test_values = [
646 ([], 0.0),
647 ([0.0], 0.0),
648 ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
649 ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
650 ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
651 ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
652 ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
653 ([1./n for n in range(1, 1001)],
654 float.fromhex('0x1.df11f45f4e61ap+2')),
655 ([(-1.)**n/n for n in range(1, 1001)],
656 float.fromhex('-0x1.62a2af1bd3624p-1')),
657 ([1.7**(i+1)-1.7**i for i in range(1000)] + [-1.7**1000], -1.0),
658 ([1e16, 1., 1e-16], 10000000000000002.0),
659 ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
660 # exercise code for resizing partials array
661 ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] +
662 [-2.**1022],
663 float.fromhex('0x1.5555555555555p+970')),
664 ]
665
666 for i, (vals, expected) in enumerate(test_values):
667 try:
668 actual = math.fsum(vals)
669 except OverflowError:
670 self.fail("test %d failed: got OverflowError, expected %r "
671 "for math.fsum(%.100r)" % (i, expected, vals))
672 except ValueError:
673 self.fail("test %d failed: got ValueError, expected %r "
674 "for math.fsum(%.100r)" % (i, expected, vals))
675 self.assertEqual(actual, expected)
676
677 from random import random, gauss, shuffle
678 for j in range(1000):
679 vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
680 s = 0
681 for i in range(200):
682 v = gauss(0, random()) ** 7 - s
683 s += v
684 vals.append(v)
685 shuffle(vals)
686
687 s = msum(vals)
688 self.assertEqual(msum(vals), math.fsum(vals))
689
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300690 def testGcd(self):
691 gcd = math.gcd
692 self.assertEqual(gcd(0, 0), 0)
693 self.assertEqual(gcd(1, 0), 1)
694 self.assertEqual(gcd(-1, 0), 1)
695 self.assertEqual(gcd(0, 1), 1)
696 self.assertEqual(gcd(0, -1), 1)
697 self.assertEqual(gcd(7, 1), 1)
698 self.assertEqual(gcd(7, -1), 1)
699 self.assertEqual(gcd(-23, 15), 1)
700 self.assertEqual(gcd(120, 84), 12)
701 self.assertEqual(gcd(84, -120), 12)
702 self.assertEqual(gcd(1216342683557601535506311712,
703 436522681849110124616458784), 32)
704 c = 652560
705 x = 434610456570399902378880679233098819019853229470286994367836600566
706 y = 1064502245825115327754847244914921553977
707 a = x * c
708 b = y * c
709 self.assertEqual(gcd(a, b), c)
710 self.assertEqual(gcd(b, a), c)
711 self.assertEqual(gcd(-a, b), c)
712 self.assertEqual(gcd(b, -a), c)
713 self.assertEqual(gcd(a, -b), c)
714 self.assertEqual(gcd(-b, a), c)
715 self.assertEqual(gcd(-a, -b), c)
716 self.assertEqual(gcd(-b, -a), c)
717 c = 576559230871654959816130551884856912003141446781646602790216406874
718 a = x * c
719 b = y * c
720 self.assertEqual(gcd(a, b), c)
721 self.assertEqual(gcd(b, a), c)
722 self.assertEqual(gcd(-a, b), c)
723 self.assertEqual(gcd(b, -a), c)
724 self.assertEqual(gcd(a, -b), c)
725 self.assertEqual(gcd(-b, a), c)
726 self.assertEqual(gcd(-a, -b), c)
727 self.assertEqual(gcd(-b, -a), c)
728
729 self.assertRaises(TypeError, gcd, 120.0, 84)
730 self.assertRaises(TypeError, gcd, 120, 84.0)
731 self.assertEqual(gcd(MyIndexable(120), MyIndexable(84)), 12)
732
Thomas Wouters89f507f2006-12-13 04:49:30 +0000733 def testHypot(self):
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700734 from decimal import Decimal
735 from fractions import Fraction
736
737 hypot = math.hypot
738
739 # Test different numbers of arguments (from zero to five)
740 # against a straightforward pure python implementation
741 args = math.e, math.pi, math.sqrt(2.0), math.gamma(3.5), math.sin(2.1)
742 for i in range(len(args)+1):
743 self.assertAlmostEqual(
744 hypot(*args[:i]),
745 math.sqrt(sum(s**2 for s in args[:i]))
746 )
747
748 # Test allowable types (those with __float__)
749 self.assertEqual(hypot(12.0, 5.0), 13.0)
750 self.assertEqual(hypot(12, 5), 13)
751 self.assertEqual(hypot(Decimal(12), Decimal(5)), 13)
752 self.assertEqual(hypot(Fraction(12, 32), Fraction(5, 32)), Fraction(13, 32))
753 self.assertEqual(hypot(bool(1), bool(0), bool(1), bool(1)), math.sqrt(3))
754
755 # Test corner cases
756 self.assertEqual(hypot(0.0, 0.0), 0.0) # Max input is zero
757 self.assertEqual(hypot(-10.5), 10.5) # Negative input
758 self.assertEqual(hypot(), 0.0) # Negative input
759 self.assertEqual(1.0,
760 math.copysign(1.0, hypot(-0.0)) # Convert negative zero to positive zero
761 )
Raymond Hettinger00414592018-08-12 12:15:23 -0700762 self.assertEqual( # Handling of moving max to the end
763 hypot(1.5, 1.5, 0.5),
764 hypot(1.5, 0.5, 1.5),
765 )
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700766
767 # Test handling of bad arguments
768 with self.assertRaises(TypeError): # Reject keyword args
769 hypot(x=1)
770 with self.assertRaises(TypeError): # Reject values without __float__
771 hypot(1.1, 'string', 2.2)
Raymond Hettinger808180c2019-01-28 13:59:56 -0800772 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
773 with self.assertRaises((ValueError, OverflowError)):
774 hypot(1, int_too_big_for_float)
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700775
776 # Any infinity gives positive infinity.
777 self.assertEqual(hypot(INF), INF)
778 self.assertEqual(hypot(0, INF), INF)
779 self.assertEqual(hypot(10, INF), INF)
780 self.assertEqual(hypot(-10, INF), INF)
781 self.assertEqual(hypot(NAN, INF), INF)
782 self.assertEqual(hypot(INF, NAN), INF)
783 self.assertEqual(hypot(NINF, NAN), INF)
784 self.assertEqual(hypot(NAN, NINF), INF)
785 self.assertEqual(hypot(-INF, INF), INF)
786 self.assertEqual(hypot(-INF, -INF), INF)
787 self.assertEqual(hypot(10, -INF), INF)
788
Raymond Hettinger00414592018-08-12 12:15:23 -0700789 # If no infinity, any NaN gives a NaN.
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700790 self.assertTrue(math.isnan(hypot(NAN)))
791 self.assertTrue(math.isnan(hypot(0, NAN)))
792 self.assertTrue(math.isnan(hypot(NAN, 10)))
793 self.assertTrue(math.isnan(hypot(10, NAN)))
794 self.assertTrue(math.isnan(hypot(NAN, NAN)))
795 self.assertTrue(math.isnan(hypot(NAN)))
796
797 # Verify scaling for extremely large values
798 fourthmax = FLOAT_MAX / 4.0
799 for n in range(32):
800 self.assertEqual(hypot(*([fourthmax]*n)), fourthmax * math.sqrt(n))
801
802 # Verify scaling for extremely small values
803 for exp in range(32):
804 scale = FLOAT_MIN / 2.0 ** exp
805 self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000806
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700807 def testDist(self):
808 from decimal import Decimal as D
809 from fractions import Fraction as F
810
811 dist = math.dist
812 sqrt = math.sqrt
813
Raymond Hettinger808180c2019-01-28 13:59:56 -0800814 # Simple exact cases
815 self.assertEqual(dist((1.0, 2.0, 3.0), (4.0, 2.0, -1.0)), 5.0)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700816 self.assertEqual(dist((1, 2, 3), (4, 2, -1)), 5.0)
817
818 # Test different numbers of arguments (from zero to nine)
819 # against a straightforward pure python implementation
820 for i in range(9):
821 for j in range(5):
822 p = tuple(random.uniform(-5, 5) for k in range(i))
823 q = tuple(random.uniform(-5, 5) for k in range(i))
824 self.assertAlmostEqual(
825 dist(p, q),
826 sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
827 )
828
829 # Test allowable types (those with __float__)
830 self.assertEqual(dist((14.0, 1.0), (2.0, -4.0)), 13.0)
831 self.assertEqual(dist((14, 1), (2, -4)), 13)
832 self.assertEqual(dist((D(14), D(1)), (D(2), D(-4))), D(13))
833 self.assertEqual(dist((F(14, 32), F(1, 32)), (F(2, 32), F(-4, 32))),
834 F(13, 32))
835 self.assertEqual(dist((True, True, False, True, False),
836 (True, False, True, True, False)),
837 sqrt(2.0))
838
839 # Test corner cases
840 self.assertEqual(dist((13.25, 12.5, -3.25),
841 (13.25, 12.5, -3.25)),
842 0.0) # Distance with self is zero
843 self.assertEqual(dist((), ()), 0.0) # Zero-dimensional case
844 self.assertEqual(1.0, # Convert negative zero to positive zero
845 math.copysign(1.0, dist((-0.0,), (0.0,)))
846 )
847 self.assertEqual(1.0, # Convert negative zero to positive zero
848 math.copysign(1.0, dist((0.0,), (-0.0,)))
849 )
Raymond Hettinger00414592018-08-12 12:15:23 -0700850 self.assertEqual( # Handling of moving max to the end
851 dist((1.5, 1.5, 0.5), (0, 0, 0)),
852 dist((1.5, 0.5, 1.5), (0, 0, 0))
853 )
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700854
855 # Verify tuple subclasses are allowed
Raymond Hettinger00414592018-08-12 12:15:23 -0700856 class T(tuple):
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700857 pass
858 self.assertEqual(dist(T((1, 2, 3)), ((4, 2, -1))), 5.0)
859
860 # Test handling of bad arguments
861 with self.assertRaises(TypeError): # Reject keyword args
862 dist(p=(1, 2, 3), q=(4, 5, 6))
863 with self.assertRaises(TypeError): # Too few args
864 dist((1, 2, 3))
865 with self.assertRaises(TypeError): # Too many args
866 dist((1, 2, 3), (4, 5, 6), (7, 8, 9))
867 with self.assertRaises(TypeError): # Scalars not allowed
868 dist(1, 2)
869 with self.assertRaises(TypeError): # Lists not allowed
870 dist([1, 2, 3], [4, 5, 6])
871 with self.assertRaises(TypeError): # Reject values without __float__
872 dist((1.1, 'string', 2.2), (1, 2, 3))
873 with self.assertRaises(ValueError): # Check dimension agree
874 dist((1, 2, 3, 4), (5, 6, 7))
875 with self.assertRaises(ValueError): # Check dimension agree
876 dist((1, 2, 3), (4, 5, 6, 7))
Ammar Askarcb08a712019-01-12 01:23:41 -0500877 with self.assertRaises(TypeError): # Rejects invalid types
878 dist("abc", "xyz")
Raymond Hettinger808180c2019-01-28 13:59:56 -0800879 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
880 with self.assertRaises((ValueError, OverflowError)):
881 dist((1, int_too_big_for_float), (2, 3))
882 with self.assertRaises((ValueError, OverflowError)):
883 dist((2, 3), (1, int_too_big_for_float))
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700884
Raymond Hettinger00414592018-08-12 12:15:23 -0700885 # Verify that the one dimensional case is equivalent to abs()
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700886 for i in range(20):
887 p, q = random.random(), random.random()
888 self.assertEqual(dist((p,), (q,)), abs(p - q))
889
890 # Test special values
891 values = [NINF, -10.5, -0.0, 0.0, 10.5, INF, NAN]
892 for p in itertools.product(values, repeat=3):
893 for q in itertools.product(values, repeat=3):
894 diffs = [px - qx for px, qx in zip(p, q)]
895 if any(map(math.isinf, diffs)):
896 # Any infinite difference gives positive infinity.
897 self.assertEqual(dist(p, q), INF)
898 elif any(map(math.isnan, diffs)):
Raymond Hettinger00414592018-08-12 12:15:23 -0700899 # If no infinity, any NaN gives a NaN.
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700900 self.assertTrue(math.isnan(dist(p, q)))
901
902 # Verify scaling for extremely large values
903 fourthmax = FLOAT_MAX / 4.0
904 for n in range(32):
905 p = (fourthmax,) * n
906 q = (0.0,) * n
907 self.assertEqual(dist(p, q), fourthmax * math.sqrt(n))
908 self.assertEqual(dist(q, p), fourthmax * math.sqrt(n))
909
910 # Verify scaling for extremely small values
911 for exp in range(32):
912 scale = FLOAT_MIN / 2.0 ** exp
913 p = (4*scale, 3*scale)
914 q = (0.0, 0.0)
915 self.assertEqual(math.dist(p, q), 5*scale)
916 self.assertEqual(math.dist(q, p), 5*scale)
917
Mark Dickinson73934b92019-05-18 12:29:50 +0100918 def testIsqrt(self):
919 # Test a variety of inputs, large and small.
920 test_values = (
921 list(range(1000))
922 + list(range(10**6 - 1000, 10**6 + 1000))
Mark Dickinson5c08ce92019-05-19 17:51:56 +0100923 + [2**e + i for e in range(60, 200) for i in range(-40, 40)]
Mark Dickinson73934b92019-05-18 12:29:50 +0100924 + [3**9999, 10**5001]
925 )
926
927 for value in test_values:
928 with self.subTest(value=value):
929 s = math.isqrt(value)
930 self.assertIs(type(s), int)
931 self.assertLessEqual(s*s, value)
932 self.assertLess(value, (s+1)*(s+1))
933
934 # Negative values
935 with self.assertRaises(ValueError):
936 math.isqrt(-1)
937
938 # Integer-like things
939 s = math.isqrt(True)
940 self.assertIs(type(s), int)
941 self.assertEqual(s, 1)
942
943 s = math.isqrt(False)
944 self.assertIs(type(s), int)
945 self.assertEqual(s, 0)
946
947 class IntegerLike(object):
948 def __init__(self, value):
949 self.value = value
950
951 def __index__(self):
952 return self.value
953
954 s = math.isqrt(IntegerLike(1729))
955 self.assertIs(type(s), int)
956 self.assertEqual(s, 41)
957
958 with self.assertRaises(ValueError):
959 math.isqrt(IntegerLike(-3))
960
961 # Non-integer-like things
962 bad_values = [
963 3.5, "a string", decimal.Decimal("3.5"), 3.5j,
964 100.0, -4.0,
965 ]
966 for value in bad_values:
967 with self.subTest(value=value):
968 with self.assertRaises(TypeError):
969 math.isqrt(value)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700970
Thomas Wouters89f507f2006-12-13 04:49:30 +0000971 def testLdexp(self):
972 self.assertRaises(TypeError, math.ldexp)
973 self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
974 self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
975 self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
976 self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
Christian Heimes53876d92008-04-19 00:31:39 +0000977 self.assertRaises(OverflowError, math.ldexp, 1., 1000000)
978 self.assertRaises(OverflowError, math.ldexp, -1., 1000000)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000979 self.assertEqual(math.ldexp(1., -1000000), 0.)
980 self.assertEqual(math.ldexp(-1., -1000000), -0.)
981 self.assertEqual(math.ldexp(INF, 30), INF)
982 self.assertEqual(math.ldexp(NINF, -213), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000983 self.assertTrue(math.isnan(math.ldexp(NAN, 0)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000984
Alexandre Vassalotti6461e102008-05-15 22:09:29 +0000985 # large second argument
986 for n in [10**5, 10**10, 10**20, 10**40]:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000987 self.assertEqual(math.ldexp(INF, -n), INF)
988 self.assertEqual(math.ldexp(NINF, -n), NINF)
989 self.assertEqual(math.ldexp(1., -n), 0.)
990 self.assertEqual(math.ldexp(-1., -n), -0.)
991 self.assertEqual(math.ldexp(0., -n), 0.)
992 self.assertEqual(math.ldexp(-0., -n), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000993 self.assertTrue(math.isnan(math.ldexp(NAN, -n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +0000994
995 self.assertRaises(OverflowError, math.ldexp, 1., n)
996 self.assertRaises(OverflowError, math.ldexp, -1., n)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000997 self.assertEqual(math.ldexp(0., n), 0.)
998 self.assertEqual(math.ldexp(-0., n), -0.)
999 self.assertEqual(math.ldexp(INF, n), INF)
1000 self.assertEqual(math.ldexp(NINF, n), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001001 self.assertTrue(math.isnan(math.ldexp(NAN, n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001002
Thomas Wouters89f507f2006-12-13 04:49:30 +00001003 def testLog(self):
1004 self.assertRaises(TypeError, math.log)
1005 self.ftest('log(1/e)', math.log(1/math.e), -1)
1006 self.ftest('log(1)', math.log(1), 0)
1007 self.ftest('log(e)', math.log(math.e), 1)
1008 self.ftest('log(32,2)', math.log(32,2), 5)
1009 self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
1010 self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001011 self.ftest('log(10**1000)', math.log(10**1000),
1012 2302.5850929940457)
1013 self.assertRaises(ValueError, math.log, -1.5)
1014 self.assertRaises(ValueError, math.log, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001015 self.assertRaises(ValueError, math.log, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001016 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001017 self.assertTrue(math.isnan(math.log(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001018
1019 def testLog1p(self):
1020 self.assertRaises(TypeError, math.log1p)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001021 for n in [2, 2**90, 2**300]:
1022 self.assertAlmostEqual(math.log1p(n), math.log1p(float(n)))
1023 self.assertRaises(ValueError, math.log1p, -1)
1024 self.assertEqual(math.log1p(INF), INF)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001025
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001026 @requires_IEEE_754
1027 def testLog2(self):
1028 self.assertRaises(TypeError, math.log2)
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001029
1030 # Check some integer values
1031 self.assertEqual(math.log2(1), 0.0)
1032 self.assertEqual(math.log2(2), 1.0)
1033 self.assertEqual(math.log2(4), 2.0)
1034
1035 # Large integer values
1036 self.assertEqual(math.log2(2**1023), 1023.0)
1037 self.assertEqual(math.log2(2**1024), 1024.0)
1038 self.assertEqual(math.log2(2**2000), 2000.0)
1039
1040 self.assertRaises(ValueError, math.log2, -1.5)
1041 self.assertRaises(ValueError, math.log2, NINF)
1042 self.assertTrue(math.isnan(math.log2(NAN)))
1043
Victor Stinnercd9dd372011-05-10 23:40:17 +02001044 @requires_IEEE_754
Victor Stinnerebbbdaf2011-06-01 13:19:07 +02001045 # log2() is not accurate enough on Mac OS X Tiger (10.4)
1046 @support.requires_mac_ver(10, 5)
Victor Stinnercd9dd372011-05-10 23:40:17 +02001047 def testLog2Exact(self):
1048 # Check that we get exact equality for log2 of powers of 2.
1049 actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)]
1050 expected = [float(n) for n in range(-1074, 1024)]
1051 self.assertEqual(actual, expected)
1052
Thomas Wouters89f507f2006-12-13 04:49:30 +00001053 def testLog10(self):
1054 self.assertRaises(TypeError, math.log10)
1055 self.ftest('log10(0.1)', math.log10(0.1), -1)
1056 self.ftest('log10(1)', math.log10(1), 0)
1057 self.ftest('log10(10)', math.log10(10), 1)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001058 self.ftest('log10(10**1000)', math.log10(10**1000), 1000.0)
1059 self.assertRaises(ValueError, math.log10, -1.5)
1060 self.assertRaises(ValueError, math.log10, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001061 self.assertRaises(ValueError, math.log10, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001062 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001063 self.assertTrue(math.isnan(math.log10(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001064
Thomas Wouters89f507f2006-12-13 04:49:30 +00001065 def testModf(self):
1066 self.assertRaises(TypeError, math.modf)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001067
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001068 def testmodf(name, result, expected):
1069 (v1, v2), (e1, e2) = result, expected
Thomas Wouters89f507f2006-12-13 04:49:30 +00001070 if abs(v1-e1) > eps or abs(v2-e2):
1071 self.fail('%s returned %r, expected %r'%\
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001072 (name, result, expected))
Raymond Hettinger64108af2002-05-13 03:55:01 +00001073
Thomas Wouters89f507f2006-12-13 04:49:30 +00001074 testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
1075 testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001076
Ezio Melottib3aedd42010-11-20 19:04:17 +00001077 self.assertEqual(math.modf(INF), (0.0, INF))
1078 self.assertEqual(math.modf(NINF), (-0.0, NINF))
Christian Heimes53876d92008-04-19 00:31:39 +00001079
1080 modf_nan = math.modf(NAN)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001081 self.assertTrue(math.isnan(modf_nan[0]))
1082 self.assertTrue(math.isnan(modf_nan[1]))
Christian Heimes53876d92008-04-19 00:31:39 +00001083
Thomas Wouters89f507f2006-12-13 04:49:30 +00001084 def testPow(self):
1085 self.assertRaises(TypeError, math.pow)
1086 self.ftest('pow(0,1)', math.pow(0,1), 0)
1087 self.ftest('pow(1,0)', math.pow(1,0), 1)
1088 self.ftest('pow(2,1)', math.pow(2,1), 2)
1089 self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
Christian Heimes53876d92008-04-19 00:31:39 +00001090 self.assertEqual(math.pow(INF, 1), INF)
1091 self.assertEqual(math.pow(NINF, 1), NINF)
1092 self.assertEqual((math.pow(1, INF)), 1.)
1093 self.assertEqual((math.pow(1, NINF)), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001094 self.assertTrue(math.isnan(math.pow(NAN, 1)))
1095 self.assertTrue(math.isnan(math.pow(2, NAN)))
1096 self.assertTrue(math.isnan(math.pow(0, NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001097 self.assertEqual(math.pow(1, NAN), 1)
Christian Heimesa342c012008-04-20 21:01:16 +00001098
1099 # pow(0., x)
1100 self.assertEqual(math.pow(0., INF), 0.)
1101 self.assertEqual(math.pow(0., 3.), 0.)
1102 self.assertEqual(math.pow(0., 2.3), 0.)
1103 self.assertEqual(math.pow(0., 2.), 0.)
1104 self.assertEqual(math.pow(0., 0.), 1.)
1105 self.assertEqual(math.pow(0., -0.), 1.)
1106 self.assertRaises(ValueError, math.pow, 0., -2.)
1107 self.assertRaises(ValueError, math.pow, 0., -2.3)
1108 self.assertRaises(ValueError, math.pow, 0., -3.)
1109 self.assertRaises(ValueError, math.pow, 0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001110 self.assertTrue(math.isnan(math.pow(0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001111
1112 # pow(INF, x)
1113 self.assertEqual(math.pow(INF, INF), INF)
1114 self.assertEqual(math.pow(INF, 3.), INF)
1115 self.assertEqual(math.pow(INF, 2.3), INF)
1116 self.assertEqual(math.pow(INF, 2.), INF)
1117 self.assertEqual(math.pow(INF, 0.), 1.)
1118 self.assertEqual(math.pow(INF, -0.), 1.)
1119 self.assertEqual(math.pow(INF, -2.), 0.)
1120 self.assertEqual(math.pow(INF, -2.3), 0.)
1121 self.assertEqual(math.pow(INF, -3.), 0.)
1122 self.assertEqual(math.pow(INF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001123 self.assertTrue(math.isnan(math.pow(INF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001124
1125 # pow(-0., x)
1126 self.assertEqual(math.pow(-0., INF), 0.)
1127 self.assertEqual(math.pow(-0., 3.), -0.)
1128 self.assertEqual(math.pow(-0., 2.3), 0.)
1129 self.assertEqual(math.pow(-0., 2.), 0.)
1130 self.assertEqual(math.pow(-0., 0.), 1.)
1131 self.assertEqual(math.pow(-0., -0.), 1.)
1132 self.assertRaises(ValueError, math.pow, -0., -2.)
1133 self.assertRaises(ValueError, math.pow, -0., -2.3)
1134 self.assertRaises(ValueError, math.pow, -0., -3.)
1135 self.assertRaises(ValueError, math.pow, -0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001136 self.assertTrue(math.isnan(math.pow(-0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001137
1138 # pow(NINF, x)
1139 self.assertEqual(math.pow(NINF, INF), INF)
1140 self.assertEqual(math.pow(NINF, 3.), NINF)
1141 self.assertEqual(math.pow(NINF, 2.3), INF)
1142 self.assertEqual(math.pow(NINF, 2.), INF)
1143 self.assertEqual(math.pow(NINF, 0.), 1.)
1144 self.assertEqual(math.pow(NINF, -0.), 1.)
1145 self.assertEqual(math.pow(NINF, -2.), 0.)
1146 self.assertEqual(math.pow(NINF, -2.3), 0.)
1147 self.assertEqual(math.pow(NINF, -3.), -0.)
1148 self.assertEqual(math.pow(NINF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001149 self.assertTrue(math.isnan(math.pow(NINF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001150
1151 # pow(-1, x)
1152 self.assertEqual(math.pow(-1., INF), 1.)
1153 self.assertEqual(math.pow(-1., 3.), -1.)
1154 self.assertRaises(ValueError, math.pow, -1., 2.3)
1155 self.assertEqual(math.pow(-1., 2.), 1.)
1156 self.assertEqual(math.pow(-1., 0.), 1.)
1157 self.assertEqual(math.pow(-1., -0.), 1.)
1158 self.assertEqual(math.pow(-1., -2.), 1.)
1159 self.assertRaises(ValueError, math.pow, -1., -2.3)
1160 self.assertEqual(math.pow(-1., -3.), -1.)
1161 self.assertEqual(math.pow(-1., NINF), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001162 self.assertTrue(math.isnan(math.pow(-1., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001163
1164 # pow(1, x)
1165 self.assertEqual(math.pow(1., INF), 1.)
1166 self.assertEqual(math.pow(1., 3.), 1.)
1167 self.assertEqual(math.pow(1., 2.3), 1.)
1168 self.assertEqual(math.pow(1., 2.), 1.)
1169 self.assertEqual(math.pow(1., 0.), 1.)
1170 self.assertEqual(math.pow(1., -0.), 1.)
1171 self.assertEqual(math.pow(1., -2.), 1.)
1172 self.assertEqual(math.pow(1., -2.3), 1.)
1173 self.assertEqual(math.pow(1., -3.), 1.)
1174 self.assertEqual(math.pow(1., NINF), 1.)
1175 self.assertEqual(math.pow(1., NAN), 1.)
1176
1177 # pow(x, 0) should be 1 for any x
1178 self.assertEqual(math.pow(2.3, 0.), 1.)
1179 self.assertEqual(math.pow(-2.3, 0.), 1.)
1180 self.assertEqual(math.pow(NAN, 0.), 1.)
1181 self.assertEqual(math.pow(2.3, -0.), 1.)
1182 self.assertEqual(math.pow(-2.3, -0.), 1.)
1183 self.assertEqual(math.pow(NAN, -0.), 1.)
1184
1185 # pow(x, y) is invalid if x is negative and y is not integral
1186 self.assertRaises(ValueError, math.pow, -1., 2.3)
1187 self.assertRaises(ValueError, math.pow, -15., -3.1)
1188
1189 # pow(x, NINF)
1190 self.assertEqual(math.pow(1.9, NINF), 0.)
1191 self.assertEqual(math.pow(1.1, NINF), 0.)
1192 self.assertEqual(math.pow(0.9, NINF), INF)
1193 self.assertEqual(math.pow(0.1, NINF), INF)
1194 self.assertEqual(math.pow(-0.1, NINF), INF)
1195 self.assertEqual(math.pow(-0.9, NINF), INF)
1196 self.assertEqual(math.pow(-1.1, NINF), 0.)
1197 self.assertEqual(math.pow(-1.9, NINF), 0.)
1198
1199 # pow(x, INF)
1200 self.assertEqual(math.pow(1.9, INF), INF)
1201 self.assertEqual(math.pow(1.1, INF), INF)
1202 self.assertEqual(math.pow(0.9, INF), 0.)
1203 self.assertEqual(math.pow(0.1, INF), 0.)
1204 self.assertEqual(math.pow(-0.1, INF), 0.)
1205 self.assertEqual(math.pow(-0.9, INF), 0.)
1206 self.assertEqual(math.pow(-1.1, INF), INF)
1207 self.assertEqual(math.pow(-1.9, INF), INF)
1208
1209 # pow(x, y) should work for x negative, y an integer
1210 self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
1211 self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
1212 self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
1213 self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
1214 self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
1215 self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
1216 self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
1217 self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
1218 self.assertRaises(ValueError, math.pow, -2.0, -0.5)
1219 self.assertRaises(ValueError, math.pow, -2.0, 0.5)
1220
1221 # the following tests have been commented out since they don't
1222 # really belong here: the implementation of ** for floats is
Ezio Melotti13925002011-03-16 11:05:33 +02001223 # independent of the implementation of math.pow
Christian Heimesa342c012008-04-20 21:01:16 +00001224 #self.assertEqual(1**NAN, 1)
1225 #self.assertEqual(1**INF, 1)
1226 #self.assertEqual(1**NINF, 1)
1227 #self.assertEqual(1**0, 1)
1228 #self.assertEqual(1.**NAN, 1)
1229 #self.assertEqual(1.**INF, 1)
1230 #self.assertEqual(1.**NINF, 1)
1231 #self.assertEqual(1.**0, 1)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001232
Thomas Wouters89f507f2006-12-13 04:49:30 +00001233 def testRadians(self):
1234 self.assertRaises(TypeError, math.radians)
1235 self.ftest('radians(180)', math.radians(180), math.pi)
1236 self.ftest('radians(90)', math.radians(90), math.pi/2)
1237 self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001238 self.ftest('radians(0)', math.radians(0), 0)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001239
Mark Dickinsona0ce3752017-04-05 18:34:27 +01001240 @requires_IEEE_754
1241 def testRemainder(self):
1242 from fractions import Fraction
1243
1244 def validate_spec(x, y, r):
1245 """
1246 Check that r matches remainder(x, y) according to the IEEE 754
1247 specification. Assumes that x, y and r are finite and y is nonzero.
1248 """
1249 fx, fy, fr = Fraction(x), Fraction(y), Fraction(r)
1250 # r should not exceed y/2 in absolute value
1251 self.assertLessEqual(abs(fr), abs(fy/2))
1252 # x - r should be an exact integer multiple of y
1253 n = (fx - fr) / fy
1254 self.assertEqual(n, int(n))
1255 if abs(fr) == abs(fy/2):
1256 # If |r| == |y/2|, n should be even.
1257 self.assertEqual(n/2, int(n/2))
1258
1259 # triples (x, y, remainder(x, y)) in hexadecimal form.
1260 testcases = [
1261 # Remainders modulo 1, showing the ties-to-even behaviour.
1262 '-4.0 1 -0.0',
1263 '-3.8 1 0.8',
1264 '-3.0 1 -0.0',
1265 '-2.8 1 -0.8',
1266 '-2.0 1 -0.0',
1267 '-1.8 1 0.8',
1268 '-1.0 1 -0.0',
1269 '-0.8 1 -0.8',
1270 '-0.0 1 -0.0',
1271 ' 0.0 1 0.0',
1272 ' 0.8 1 0.8',
1273 ' 1.0 1 0.0',
1274 ' 1.8 1 -0.8',
1275 ' 2.0 1 0.0',
1276 ' 2.8 1 0.8',
1277 ' 3.0 1 0.0',
1278 ' 3.8 1 -0.8',
1279 ' 4.0 1 0.0',
1280
1281 # Reductions modulo 2*pi
1282 '0x0.0p+0 0x1.921fb54442d18p+2 0x0.0p+0',
1283 '0x1.921fb54442d18p+0 0x1.921fb54442d18p+2 0x1.921fb54442d18p+0',
1284 '0x1.921fb54442d17p+1 0x1.921fb54442d18p+2 0x1.921fb54442d17p+1',
1285 '0x1.921fb54442d18p+1 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1286 '0x1.921fb54442d19p+1 0x1.921fb54442d18p+2 -0x1.921fb54442d17p+1',
1287 '0x1.921fb54442d17p+2 0x1.921fb54442d18p+2 -0x0.0000000000001p+2',
1288 '0x1.921fb54442d18p+2 0x1.921fb54442d18p+2 0x0p0',
1289 '0x1.921fb54442d19p+2 0x1.921fb54442d18p+2 0x0.0000000000001p+2',
1290 '0x1.2d97c7f3321d1p+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1291 '0x1.2d97c7f3321d2p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d18p+1',
1292 '0x1.2d97c7f3321d3p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1293 '0x1.921fb54442d17p+3 0x1.921fb54442d18p+2 -0x0.0000000000001p+3',
1294 '0x1.921fb54442d18p+3 0x1.921fb54442d18p+2 0x0p0',
1295 '0x1.921fb54442d19p+3 0x1.921fb54442d18p+2 0x0.0000000000001p+3',
1296 '0x1.f6a7a2955385dp+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1297 '0x1.f6a7a2955385ep+3 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1298 '0x1.f6a7a2955385fp+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1299 '0x1.1475cc9eedf00p+5 0x1.921fb54442d18p+2 0x1.921fb54442d10p+1',
1300 '0x1.1475cc9eedf01p+5 0x1.921fb54442d18p+2 -0x1.921fb54442d10p+1',
1301
1302 # Symmetry with respect to signs.
1303 ' 1 0.c 0.4',
1304 '-1 0.c -0.4',
1305 ' 1 -0.c 0.4',
1306 '-1 -0.c -0.4',
1307 ' 1.4 0.c -0.4',
1308 '-1.4 0.c 0.4',
1309 ' 1.4 -0.c -0.4',
1310 '-1.4 -0.c 0.4',
1311
1312 # Huge modulus, to check that the underlying algorithm doesn't
1313 # rely on 2.0 * modulus being representable.
1314 '0x1.dp+1023 0x1.4p+1023 0x0.9p+1023',
1315 '0x1.ep+1023 0x1.4p+1023 -0x0.ap+1023',
1316 '0x1.fp+1023 0x1.4p+1023 -0x0.9p+1023',
1317 ]
1318
1319 for case in testcases:
1320 with self.subTest(case=case):
1321 x_hex, y_hex, expected_hex = case.split()
1322 x = float.fromhex(x_hex)
1323 y = float.fromhex(y_hex)
1324 expected = float.fromhex(expected_hex)
1325 validate_spec(x, y, expected)
1326 actual = math.remainder(x, y)
1327 # Cheap way of checking that the floats are
1328 # as identical as we need them to be.
1329 self.assertEqual(actual.hex(), expected.hex())
1330
1331 # Test tiny subnormal modulus: there's potential for
1332 # getting the implementation wrong here (for example,
1333 # by assuming that modulus/2 is exactly representable).
1334 tiny = float.fromhex('1p-1074') # min +ve subnormal
1335 for n in range(-25, 25):
1336 if n == 0:
1337 continue
1338 y = n * tiny
1339 for m in range(100):
1340 x = m * tiny
1341 actual = math.remainder(x, y)
1342 validate_spec(x, y, actual)
1343 actual = math.remainder(-x, y)
1344 validate_spec(-x, y, actual)
1345
1346 # Special values.
1347 # NaNs should propagate as usual.
1348 for value in [NAN, 0.0, -0.0, 2.0, -2.3, NINF, INF]:
1349 self.assertIsNaN(math.remainder(NAN, value))
1350 self.assertIsNaN(math.remainder(value, NAN))
1351
1352 # remainder(x, inf) is x, for non-nan non-infinite x.
1353 for value in [-2.3, -0.0, 0.0, 2.3]:
1354 self.assertEqual(math.remainder(value, INF), value)
1355 self.assertEqual(math.remainder(value, NINF), value)
1356
1357 # remainder(x, 0) and remainder(infinity, x) for non-NaN x are invalid
1358 # operations according to IEEE 754-2008 7.2(f), and should raise.
1359 for value in [NINF, -2.3, -0.0, 0.0, 2.3, INF]:
1360 with self.assertRaises(ValueError):
1361 math.remainder(INF, value)
1362 with self.assertRaises(ValueError):
1363 math.remainder(NINF, value)
1364 with self.assertRaises(ValueError):
1365 math.remainder(value, 0.0)
1366 with self.assertRaises(ValueError):
1367 math.remainder(value, -0.0)
1368
Thomas Wouters89f507f2006-12-13 04:49:30 +00001369 def testSin(self):
1370 self.assertRaises(TypeError, math.sin)
1371 self.ftest('sin(0)', math.sin(0), 0)
1372 self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
1373 self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001374 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001375 self.assertTrue(math.isnan(math.sin(INF)))
1376 self.assertTrue(math.isnan(math.sin(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001377 except ValueError:
1378 self.assertRaises(ValueError, math.sin, INF)
1379 self.assertRaises(ValueError, math.sin, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001380 self.assertTrue(math.isnan(math.sin(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001381
Thomas Wouters89f507f2006-12-13 04:49:30 +00001382 def testSinh(self):
1383 self.assertRaises(TypeError, math.sinh)
1384 self.ftest('sinh(0)', math.sinh(0), 0)
1385 self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
1386 self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001387 self.assertEqual(math.sinh(INF), INF)
1388 self.assertEqual(math.sinh(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001389 self.assertTrue(math.isnan(math.sinh(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001390
Thomas Wouters89f507f2006-12-13 04:49:30 +00001391 def testSqrt(self):
1392 self.assertRaises(TypeError, math.sqrt)
1393 self.ftest('sqrt(0)', math.sqrt(0), 0)
1394 self.ftest('sqrt(1)', math.sqrt(1), 1)
1395 self.ftest('sqrt(4)', math.sqrt(4), 2)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001396 self.assertEqual(math.sqrt(INF), INF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001397 self.assertRaises(ValueError, math.sqrt, -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001398 self.assertRaises(ValueError, math.sqrt, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001399 self.assertTrue(math.isnan(math.sqrt(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001400
Thomas Wouters89f507f2006-12-13 04:49:30 +00001401 def testTan(self):
1402 self.assertRaises(TypeError, math.tan)
1403 self.ftest('tan(0)', math.tan(0), 0)
1404 self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
1405 self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001406 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001407 self.assertTrue(math.isnan(math.tan(INF)))
1408 self.assertTrue(math.isnan(math.tan(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001409 except:
1410 self.assertRaises(ValueError, math.tan, INF)
1411 self.assertRaises(ValueError, math.tan, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001412 self.assertTrue(math.isnan(math.tan(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001413
Thomas Wouters89f507f2006-12-13 04:49:30 +00001414 def testTanh(self):
1415 self.assertRaises(TypeError, math.tanh)
1416 self.ftest('tanh(0)', math.tanh(0), 0)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001417 self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0,
1418 abs_tol=ulp(1))
Christian Heimes53876d92008-04-19 00:31:39 +00001419 self.ftest('tanh(inf)', math.tanh(INF), 1)
1420 self.ftest('tanh(-inf)', math.tanh(NINF), -1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001421 self.assertTrue(math.isnan(math.tanh(NAN)))
Victor Stinnerbe3da382010-11-07 14:14:27 +00001422
1423 @requires_IEEE_754
Victor Stinnerbe3da382010-11-07 14:14:27 +00001424 def testTanhSign(self):
Christian Heimese57950f2008-04-21 13:08:03 +00001425 # check that tanh(-0.) == -0. on IEEE 754 systems
Victor Stinnerbe3da382010-11-07 14:14:27 +00001426 self.assertEqual(math.tanh(-0.), -0.)
1427 self.assertEqual(math.copysign(1., math.tanh(-0.)),
1428 math.copysign(1., -0.))
Tim Peters1d120612000-10-12 06:10:25 +00001429
Christian Heimes400adb02008-02-01 08:12:03 +00001430 def test_trunc(self):
1431 self.assertEqual(math.trunc(1), 1)
1432 self.assertEqual(math.trunc(-1), -1)
1433 self.assertEqual(type(math.trunc(1)), int)
1434 self.assertEqual(type(math.trunc(1.5)), int)
1435 self.assertEqual(math.trunc(1.5), 1)
1436 self.assertEqual(math.trunc(-1.5), -1)
1437 self.assertEqual(math.trunc(1.999999), 1)
1438 self.assertEqual(math.trunc(-1.999999), -1)
1439 self.assertEqual(math.trunc(-0.999999), -0)
1440 self.assertEqual(math.trunc(-100.999), -100)
1441
1442 class TestTrunc(object):
1443 def __trunc__(self):
1444 return 23
1445
1446 class TestNoTrunc(object):
1447 pass
1448
1449 self.assertEqual(math.trunc(TestTrunc()), 23)
1450
1451 self.assertRaises(TypeError, math.trunc)
1452 self.assertRaises(TypeError, math.trunc, 1, 2)
1453 self.assertRaises(TypeError, math.trunc, TestNoTrunc())
1454
Mark Dickinson8e0c9962010-07-11 17:38:24 +00001455 def testIsfinite(self):
1456 self.assertTrue(math.isfinite(0.0))
1457 self.assertTrue(math.isfinite(-0.0))
1458 self.assertTrue(math.isfinite(1.0))
1459 self.assertTrue(math.isfinite(-1.0))
1460 self.assertFalse(math.isfinite(float("nan")))
1461 self.assertFalse(math.isfinite(float("inf")))
1462 self.assertFalse(math.isfinite(float("-inf")))
1463
Christian Heimes072c0f12008-01-03 23:01:04 +00001464 def testIsnan(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001465 self.assertTrue(math.isnan(float("nan")))
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001466 self.assertTrue(math.isnan(float("-nan")))
1467 self.assertTrue(math.isnan(float("inf") * 0.))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001468 self.assertFalse(math.isnan(float("inf")))
1469 self.assertFalse(math.isnan(0.))
1470 self.assertFalse(math.isnan(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001471
1472 def testIsinf(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001473 self.assertTrue(math.isinf(float("inf")))
1474 self.assertTrue(math.isinf(float("-inf")))
1475 self.assertTrue(math.isinf(1E400))
1476 self.assertTrue(math.isinf(-1E400))
1477 self.assertFalse(math.isinf(float("nan")))
1478 self.assertFalse(math.isinf(0.))
1479 self.assertFalse(math.isinf(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001480
Mark Dickinsona5d0c7c2015-01-11 11:55:29 +00001481 @requires_IEEE_754
1482 def test_nan_constant(self):
1483 self.assertTrue(math.isnan(math.nan))
1484
1485 @requires_IEEE_754
1486 def test_inf_constant(self):
1487 self.assertTrue(math.isinf(math.inf))
1488 self.assertGreater(math.inf, 0.0)
1489 self.assertEqual(math.inf, float("inf"))
1490 self.assertEqual(-math.inf, float("-inf"))
1491
Thomas Wouters89f507f2006-12-13 04:49:30 +00001492 # RED_FLAG 16-Oct-2000 Tim
1493 # While 2.0 is more consistent about exceptions than previous releases, it
1494 # still fails this part of the test on some platforms. For now, we only
1495 # *run* test_exceptions() in verbose mode, so that this isn't normally
1496 # tested.
Serhiy Storchaka43767632013-11-03 21:31:38 +02001497 @unittest.skipUnless(verbose, 'requires verbose mode')
1498 def test_exceptions(self):
1499 try:
1500 x = math.exp(-1000000000)
1501 except:
1502 # mathmodule.c is failing to weed out underflows from libm, or
1503 # we've got an fp format with huge dynamic range
1504 self.fail("underflowing exp() should not have raised "
1505 "an exception")
1506 if x != 0:
1507 self.fail("underflowing exp() should have returned 0")
Tim Peters98c81842000-10-16 17:35:13 +00001508
Serhiy Storchaka43767632013-11-03 21:31:38 +02001509 # If this fails, probably using a strict IEEE-754 conforming libm, and x
1510 # is +Inf afterwards. But Python wants overflows detected by default.
1511 try:
1512 x = math.exp(1000000000)
1513 except OverflowError:
1514 pass
1515 else:
1516 self.fail("overflowing exp() didn't trigger OverflowError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001517
Serhiy Storchaka43767632013-11-03 21:31:38 +02001518 # If this fails, it could be a puzzle. One odd possibility is that
1519 # mathmodule.c's macros are getting confused while comparing
1520 # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
1521 # as a result (and so raising OverflowError instead).
1522 try:
1523 x = math.sqrt(-1.0)
1524 except ValueError:
1525 pass
1526 else:
1527 self.fail("sqrt(-1) didn't raise ValueError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001528
Mark Dickinson63566232009-09-18 21:04:19 +00001529 @requires_IEEE_754
Christian Heimes53876d92008-04-19 00:31:39 +00001530 def test_testfile(self):
Mark Dickinson85746542016-09-04 09:58:51 +01001531 # Some tests need to be skipped on ancient OS X versions.
1532 # See issue #27953.
1533 SKIP_ON_TIGER = {'tan0064'}
1534
1535 osx_version = None
1536 if sys.platform == 'darwin':
1537 version_txt = platform.mac_ver()[0]
1538 try:
1539 osx_version = tuple(map(int, version_txt.split('.')))
1540 except ValueError:
1541 pass
1542
Mark Dickinson96f774d2016-09-03 19:30:22 +01001543 fail_fmt = "{}: {}({!r}): {}"
1544
1545 failures = []
Christian Heimes53876d92008-04-19 00:31:39 +00001546 for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001547 # Skip if either the input or result is complex
1548 if ai != 0.0 or ei != 0.0:
Christian Heimes53876d92008-04-19 00:31:39 +00001549 continue
1550 if fn in ['rect', 'polar']:
1551 # no real versions of rect, polar
1552 continue
Mark Dickinson85746542016-09-04 09:58:51 +01001553 # Skip certain tests on OS X 10.4.
1554 if osx_version is not None and osx_version < (10, 5):
1555 if id in SKIP_ON_TIGER:
1556 continue
Mark Dickinson96f774d2016-09-03 19:30:22 +01001557
Christian Heimes53876d92008-04-19 00:31:39 +00001558 func = getattr(math, fn)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001559
1560 if 'invalid' in flags or 'divide-by-zero' in flags:
1561 er = 'ValueError'
1562 elif 'overflow' in flags:
1563 er = 'OverflowError'
1564
Christian Heimesa342c012008-04-20 21:01:16 +00001565 try:
1566 result = func(ar)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001567 except ValueError:
1568 result = 'ValueError'
Benjamin Peterson2b7411d2008-05-26 17:36:47 +00001569 except OverflowError:
Mark Dickinson96f774d2016-09-03 19:30:22 +01001570 result = 'OverflowError'
1571
1572 # Default tolerances
1573 ulp_tol, abs_tol = 5, 0.0
1574
1575 failure = result_check(er, result, ulp_tol, abs_tol)
1576 if failure is None:
1577 continue
1578
1579 msg = fail_fmt.format(id, fn, ar, failure)
1580 failures.append(msg)
1581
1582 if failures:
1583 self.fail('Failures in test_testfile:\n ' +
1584 '\n '.join(failures))
Thomas Wouters89f507f2006-12-13 04:49:30 +00001585
Victor Stinnerbe3da382010-11-07 14:14:27 +00001586 @requires_IEEE_754
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001587 def test_mtestfile(self):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001588 fail_fmt = "{}: {}({!r}): {}"
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001589
1590 failures = []
1591 for id, fn, arg, expected, flags in parse_mtestfile(math_testcases):
1592 func = getattr(math, fn)
1593
1594 if 'invalid' in flags or 'divide-by-zero' in flags:
1595 expected = 'ValueError'
1596 elif 'overflow' in flags:
1597 expected = 'OverflowError'
1598
1599 try:
1600 got = func(arg)
1601 except ValueError:
1602 got = 'ValueError'
1603 except OverflowError:
1604 got = 'OverflowError'
1605
Mark Dickinson96f774d2016-09-03 19:30:22 +01001606 # Default tolerances
1607 ulp_tol, abs_tol = 5, 0.0
Mark Dickinsonbcdf9da2010-06-13 10:52:38 +00001608
Mark Dickinson96f774d2016-09-03 19:30:22 +01001609 # Exceptions to the defaults
1610 if fn == 'gamma':
1611 # Experimental results on one platform gave
1612 # an accuracy of <= 10 ulps across the entire float
1613 # domain. We weaken that to require 20 ulp accuracy.
1614 ulp_tol = 20
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001615
Mark Dickinson96f774d2016-09-03 19:30:22 +01001616 elif fn == 'lgamma':
1617 # we use a weaker accuracy test for lgamma;
1618 # lgamma only achieves an absolute error of
1619 # a few multiples of the machine accuracy, in
1620 # general.
1621 abs_tol = 1e-15
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001622
Mark Dickinson96f774d2016-09-03 19:30:22 +01001623 elif fn == 'erfc' and arg >= 0.0:
1624 # erfc has less-than-ideal accuracy for large
1625 # arguments (x ~ 25 or so), mainly due to the
1626 # error involved in computing exp(-x*x).
1627 #
1628 # Observed between CPython and mpmath at 25 dp:
1629 # x < 0 : err <= 2 ulp
1630 # 0 <= x < 1 : err <= 10 ulp
1631 # 1 <= x < 10 : err <= 100 ulp
1632 # 10 <= x < 20 : err <= 300 ulp
1633 # 20 <= x : < 600 ulp
1634 #
1635 if arg < 1.0:
1636 ulp_tol = 10
1637 elif arg < 10.0:
1638 ulp_tol = 100
1639 else:
1640 ulp_tol = 1000
1641
1642 failure = result_check(expected, got, ulp_tol, abs_tol)
1643 if failure is None:
1644 continue
1645
1646 msg = fail_fmt.format(id, fn, arg, failure)
1647 failures.append(msg)
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001648
1649 if failures:
1650 self.fail('Failures in test_mtestfile:\n ' +
1651 '\n '.join(failures))
1652
Pablo Galindo04114112019-03-09 19:18:08 +00001653 def test_prod(self):
1654 prod = math.prod
1655 self.assertEqual(prod([]), 1)
1656 self.assertEqual(prod([], start=5), 5)
1657 self.assertEqual(prod(list(range(2,8))), 5040)
1658 self.assertEqual(prod(iter(list(range(2,8)))), 5040)
1659 self.assertEqual(prod(range(1, 10), start=10), 3628800)
1660
1661 self.assertEqual(prod([1, 2, 3, 4, 5]), 120)
1662 self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0)
1663 self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0)
1664 self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0)
1665
1666 # Test overflow in fast-path for integers
1667 self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32)
1668 # Test overflow in fast-path for floats
1669 self.assertEqual(prod([1.0, 1.0, 2**32, 1, 1]), float(2**32))
1670
1671 self.assertRaises(TypeError, prod)
1672 self.assertRaises(TypeError, prod, 42)
1673 self.assertRaises(TypeError, prod, ['a', 'b', 'c'])
1674 self.assertRaises(TypeError, prod, ['a', 'b', 'c'], '')
1675 self.assertRaises(TypeError, prod, [b'a', b'c'], b'')
1676 values = [bytearray(b'a'), bytearray(b'b')]
1677 self.assertRaises(TypeError, prod, values, bytearray(b''))
1678 self.assertRaises(TypeError, prod, [[1], [2], [3]])
1679 self.assertRaises(TypeError, prod, [{2:3}])
1680 self.assertRaises(TypeError, prod, [{2:3}]*2, {2:3})
1681 self.assertRaises(TypeError, prod, [[1], [2], [3]], [])
1682 with self.assertRaises(TypeError):
1683 prod([10, 20], [30, 40]) # start is a keyword-only argument
1684
1685 self.assertEqual(prod([0, 1, 2, 3]), 0)
1686 self.assertEqual(prod([1, 0, 2, 3]), 0)
1687 self.assertEqual(prod([1, 2, 3, 0]), 0)
1688
1689 def _naive_prod(iterable, start=1):
1690 for elem in iterable:
1691 start *= elem
1692 return start
1693
1694 # Big integers
1695
1696 iterable = range(1, 10000)
1697 self.assertEqual(prod(iterable), _naive_prod(iterable))
1698 iterable = range(-10000, -1)
1699 self.assertEqual(prod(iterable), _naive_prod(iterable))
1700 iterable = range(-1000, 1000)
1701 self.assertEqual(prod(iterable), 0)
1702
1703 # Big floats
1704
1705 iterable = [float(x) for x in range(1, 1000)]
1706 self.assertEqual(prod(iterable), _naive_prod(iterable))
1707 iterable = [float(x) for x in range(-1000, -1)]
1708 self.assertEqual(prod(iterable), _naive_prod(iterable))
1709 iterable = [float(x) for x in range(-1000, 1000)]
1710 self.assertIsNaN(prod(iterable))
1711
1712 # Float tests
1713
1714 self.assertIsNaN(prod([1, 2, 3, float("nan"), 2, 3]))
1715 self.assertIsNaN(prod([1, 0, float("nan"), 2, 3]))
1716 self.assertIsNaN(prod([1, float("nan"), 0, 3]))
1717 self.assertIsNaN(prod([1, float("inf"), float("nan"),3]))
1718 self.assertIsNaN(prod([1, float("-inf"), float("nan"),3]))
1719 self.assertIsNaN(prod([1, float("nan"), float("inf"),3]))
1720 self.assertIsNaN(prod([1, float("nan"), float("-inf"),3]))
1721
1722 self.assertEqual(prod([1, 2, 3, float('inf'),-3,4]), float('-inf'))
1723 self.assertEqual(prod([1, 2, 3, float('-inf'),-3,4]), float('inf'))
1724
1725 self.assertIsNaN(prod([1,2,0,float('inf'), -3, 4]))
1726 self.assertIsNaN(prod([1,2,0,float('-inf'), -3, 4]))
1727 self.assertIsNaN(prod([1, 2, 3, float('inf'), -3, 0, 3]))
1728 self.assertIsNaN(prod([1, 2, 3, float('-inf'), -3, 0, 2]))
1729
1730 # Type preservation
1731
1732 self.assertEqual(type(prod([1, 2, 3, 4, 5, 6])), int)
1733 self.assertEqual(type(prod([1, 2.0, 3, 4, 5, 6])), float)
1734 self.assertEqual(type(prod(range(1, 10000))), int)
1735 self.assertEqual(type(prod(range(1, 10000), start=1.0)), float)
1736 self.assertEqual(type(prod([1, decimal.Decimal(2.0), 3, 4, 5, 6])),
1737 decimal.Decimal)
1738
Mark Dickinsona0ce3752017-04-05 18:34:27 +01001739 # Custom assertions.
1740
1741 def assertIsNaN(self, value):
1742 if not math.isnan(value):
1743 self.fail("Expected a NaN, got {!r}.".format(value))
1744
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001745
Tal Einatd5519ed2015-05-31 22:05:00 +03001746class IsCloseTests(unittest.TestCase):
Mike53f7a7c2017-12-14 14:04:53 +03001747 isclose = math.isclose # subclasses should override this
Tal Einatd5519ed2015-05-31 22:05:00 +03001748
1749 def assertIsClose(self, a, b, *args, **kwargs):
1750 self.assertTrue(self.isclose(a, b, *args, **kwargs),
1751 msg="%s and %s should be close!" % (a, b))
1752
1753 def assertIsNotClose(self, a, b, *args, **kwargs):
1754 self.assertFalse(self.isclose(a, b, *args, **kwargs),
1755 msg="%s and %s should not be close!" % (a, b))
1756
1757 def assertAllClose(self, examples, *args, **kwargs):
1758 for a, b in examples:
1759 self.assertIsClose(a, b, *args, **kwargs)
1760
1761 def assertAllNotClose(self, examples, *args, **kwargs):
1762 for a, b in examples:
1763 self.assertIsNotClose(a, b, *args, **kwargs)
1764
1765 def test_negative_tolerances(self):
1766 # ValueError should be raised if either tolerance is less than zero
1767 with self.assertRaises(ValueError):
1768 self.assertIsClose(1, 1, rel_tol=-1e-100)
1769 with self.assertRaises(ValueError):
1770 self.assertIsClose(1, 1, rel_tol=1e-100, abs_tol=-1e10)
1771
1772 def test_identical(self):
1773 # identical values must test as close
1774 identical_examples = [(2.0, 2.0),
1775 (0.1e200, 0.1e200),
1776 (1.123e-300, 1.123e-300),
1777 (12345, 12345.0),
1778 (0.0, -0.0),
1779 (345678, 345678)]
1780 self.assertAllClose(identical_examples, rel_tol=0.0, abs_tol=0.0)
1781
1782 def test_eight_decimal_places(self):
1783 # examples that are close to 1e-8, but not 1e-9
1784 eight_decimal_places_examples = [(1e8, 1e8 + 1),
1785 (-1e-8, -1.000000009e-8),
1786 (1.12345678, 1.12345679)]
1787 self.assertAllClose(eight_decimal_places_examples, rel_tol=1e-8)
1788 self.assertAllNotClose(eight_decimal_places_examples, rel_tol=1e-9)
1789
1790 def test_near_zero(self):
1791 # values close to zero
1792 near_zero_examples = [(1e-9, 0.0),
1793 (-1e-9, 0.0),
1794 (-1e-150, 0.0)]
1795 # these should not be close to any rel_tol
1796 self.assertAllNotClose(near_zero_examples, rel_tol=0.9)
1797 # these should be close to abs_tol=1e-8
1798 self.assertAllClose(near_zero_examples, abs_tol=1e-8)
1799
1800 def test_identical_infinite(self):
1801 # these are close regardless of tolerance -- i.e. they are equal
1802 self.assertIsClose(INF, INF)
1803 self.assertIsClose(INF, INF, abs_tol=0.0)
1804 self.assertIsClose(NINF, NINF)
1805 self.assertIsClose(NINF, NINF, abs_tol=0.0)
1806
1807 def test_inf_ninf_nan(self):
1808 # these should never be close (following IEEE 754 rules for equality)
1809 not_close_examples = [(NAN, NAN),
1810 (NAN, 1e-100),
1811 (1e-100, NAN),
1812 (INF, NAN),
1813 (NAN, INF),
1814 (INF, NINF),
1815 (INF, 1.0),
1816 (1.0, INF),
1817 (INF, 1e308),
1818 (1e308, INF)]
1819 # use largest reasonable tolerance
1820 self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999)
1821
1822 def test_zero_tolerance(self):
1823 # test with zero tolerance
1824 zero_tolerance_close_examples = [(1.0, 1.0),
1825 (-3.4, -3.4),
1826 (-1e-300, -1e-300)]
1827 self.assertAllClose(zero_tolerance_close_examples, rel_tol=0.0)
1828
1829 zero_tolerance_not_close_examples = [(1.0, 1.000000000000001),
1830 (0.99999999999999, 1.0),
1831 (1.0e200, .999999999999999e200)]
1832 self.assertAllNotClose(zero_tolerance_not_close_examples, rel_tol=0.0)
1833
Martin Pantereb995702016-07-28 01:11:04 +00001834 def test_asymmetry(self):
1835 # test the asymmetry example from PEP 485
Tal Einatd5519ed2015-05-31 22:05:00 +03001836 self.assertAllClose([(9, 10), (10, 9)], rel_tol=0.1)
1837
1838 def test_integers(self):
1839 # test with integer values
1840 integer_examples = [(100000001, 100000000),
1841 (123456789, 123456788)]
1842
1843 self.assertAllClose(integer_examples, rel_tol=1e-8)
1844 self.assertAllNotClose(integer_examples, rel_tol=1e-9)
1845
1846 def test_decimals(self):
1847 # test with Decimal values
1848 from decimal import Decimal
1849
1850 decimal_examples = [(Decimal('1.00000001'), Decimal('1.0')),
1851 (Decimal('1.00000001e-20'), Decimal('1.0e-20')),
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001852 (Decimal('1.00000001e-100'), Decimal('1.0e-100')),
1853 (Decimal('1.00000001e20'), Decimal('1.0e20'))]
Tal Einatd5519ed2015-05-31 22:05:00 +03001854 self.assertAllClose(decimal_examples, rel_tol=1e-8)
1855 self.assertAllNotClose(decimal_examples, rel_tol=1e-9)
1856
1857 def test_fractions(self):
1858 # test with Fraction values
1859 from fractions import Fraction
1860
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001861 fraction_examples = [
1862 (Fraction(1, 100000000) + 1, Fraction(1)),
1863 (Fraction(100000001), Fraction(100000000)),
1864 (Fraction(10**8 + 1, 10**28), Fraction(1, 10**20))]
Tal Einatd5519ed2015-05-31 22:05:00 +03001865 self.assertAllClose(fraction_examples, rel_tol=1e-8)
1866 self.assertAllNotClose(fraction_examples, rel_tol=1e-9)
1867
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001868 def testPerm(self):
1869 perm = math.perm
1870 factorial = math.factorial
1871 # Test if factorial defintion is satisfied
1872 for n in range(100):
1873 for k in range(n + 1):
1874 self.assertEqual(perm(n, k),
1875 factorial(n) // factorial(n - k))
1876
1877 # Test for Pascal's identity
1878 for n in range(1, 100):
1879 for k in range(1, n):
1880 self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k))
1881
1882 # Test corner cases
1883 for n in range(1, 100):
1884 self.assertEqual(perm(n, 0), 1)
1885 self.assertEqual(perm(n, 1), n)
1886 self.assertEqual(perm(n, n), factorial(n))
1887
1888 # Raises TypeError if any argument is non-integer or argument count is
1889 # not 2
1890 self.assertRaises(TypeError, perm, 10, 1.0)
1891 self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
1892 self.assertRaises(TypeError, perm, 10, "1")
1893 self.assertRaises(TypeError, perm, 10.0, 1)
1894 self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
1895 self.assertRaises(TypeError, perm, "10", 1)
1896
1897 self.assertRaises(TypeError, perm, 10)
1898 self.assertRaises(TypeError, perm, 10, 1, 3)
1899 self.assertRaises(TypeError, perm)
1900
1901 # Raises Value error if not k or n are negative numbers
1902 self.assertRaises(ValueError, perm, -1, 1)
1903 self.assertRaises(ValueError, perm, -2**1000, 1)
1904 self.assertRaises(ValueError, perm, 1, -1)
1905 self.assertRaises(ValueError, perm, 1, -2**1000)
1906
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07001907 # Returns zero if k is greater than n
1908 self.assertEqual(perm(1, 2), 0)
1909 self.assertEqual(perm(1, 2**1000), 0)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001910
1911 n = 2**1000
1912 self.assertEqual(perm(n, 0), 1)
1913 self.assertEqual(perm(n, 1), n)
1914 self.assertEqual(perm(n, 2), n * (n-1))
1915 self.assertRaises((OverflowError, MemoryError), perm, n, n)
1916
1917 for n, k in (True, True), (True, False), (False, False):
1918 self.assertEqual(perm(n, k), 1)
1919 self.assertIs(type(perm(n, k)), int)
1920 self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20)
1921 self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20)
1922 for k in range(3):
1923 self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int)
1924 self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int)
1925
Yash Aggarwal4a686502019-06-01 12:51:27 +05301926 def testComb(self):
1927 comb = math.comb
1928 factorial = math.factorial
1929 # Test if factorial defintion is satisfied
1930 for n in range(100):
1931 for k in range(n + 1):
1932 self.assertEqual(comb(n, k), factorial(n)
1933 // (factorial(k) * factorial(n - k)))
1934
1935 # Test for Pascal's identity
1936 for n in range(1, 100):
1937 for k in range(1, n):
1938 self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k))
1939
1940 # Test corner cases
1941 for n in range(100):
1942 self.assertEqual(comb(n, 0), 1)
1943 self.assertEqual(comb(n, n), 1)
1944
1945 for n in range(1, 100):
1946 self.assertEqual(comb(n, 1), n)
1947 self.assertEqual(comb(n, n - 1), n)
1948
1949 # Test Symmetry
1950 for n in range(100):
1951 for k in range(n // 2):
1952 self.assertEqual(comb(n, k), comb(n, n - k))
1953
1954 # Raises TypeError if any argument is non-integer or argument count is
1955 # not 2
1956 self.assertRaises(TypeError, comb, 10, 1.0)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001957 self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0))
Yash Aggarwal4a686502019-06-01 12:51:27 +05301958 self.assertRaises(TypeError, comb, 10, "1")
Yash Aggarwal4a686502019-06-01 12:51:27 +05301959 self.assertRaises(TypeError, comb, 10.0, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001960 self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1)
1961 self.assertRaises(TypeError, comb, "10", 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301962
1963 self.assertRaises(TypeError, comb, 10)
1964 self.assertRaises(TypeError, comb, 10, 1, 3)
1965 self.assertRaises(TypeError, comb)
1966
1967 # Raises Value error if not k or n are negative numbers
1968 self.assertRaises(ValueError, comb, -1, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001969 self.assertRaises(ValueError, comb, -2**1000, 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301970 self.assertRaises(ValueError, comb, 1, -1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001971 self.assertRaises(ValueError, comb, 1, -2**1000)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301972
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07001973 # Returns zero if k is greater than n
1974 self.assertEqual(comb(1, 2), 0)
1975 self.assertEqual(comb(1, 2**1000), 0)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301976
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001977 n = 2**1000
1978 self.assertEqual(comb(n, 0), 1)
1979 self.assertEqual(comb(n, 1), n)
1980 self.assertEqual(comb(n, 2), n * (n-1) // 2)
1981 self.assertEqual(comb(n, n), 1)
1982 self.assertEqual(comb(n, n-1), n)
1983 self.assertEqual(comb(n, n-2), n * (n-1) // 2)
1984 self.assertRaises((OverflowError, MemoryError), comb, n, n//2)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301985
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001986 for n, k in (True, True), (True, False), (False, False):
1987 self.assertEqual(comb(n, k), 1)
1988 self.assertIs(type(comb(n, k)), int)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001989 self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001990 self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001991 for k in range(3):
1992 self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int)
1993 self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301994
Pablo Galindo42079072019-02-10 19:56:58 +00001995
Thomas Wouters89f507f2006-12-13 04:49:30 +00001996def test_main():
Christian Heimes53876d92008-04-19 00:31:39 +00001997 from doctest import DocFileSuite
1998 suite = unittest.TestSuite()
1999 suite.addTest(unittest.makeSuite(MathTests))
Tal Einatd5519ed2015-05-31 22:05:00 +03002000 suite.addTest(unittest.makeSuite(IsCloseTests))
Christian Heimes53876d92008-04-19 00:31:39 +00002001 suite.addTest(DocFileSuite("ieee754.txt"))
2002 run_unittest(suite)
Thomas Wouters89f507f2006-12-13 04:49:30 +00002003
2004if __name__ == '__main__':
2005 test_main()