blob: b3301f6a5cf74f08c5f67908b88622c99df7e217 [file] [log] [blame]
Guido van Rossumfcce6301996-08-08 18:26:25 +00001# Python test set -- math module
2# XXXX Should not do tests around zero only
3
Eric Smithf24a0d92010-12-04 13:32:18 +00004from test.support import run_unittest, verbose, requires_IEEE_754
Victor Stinnerfce92332011-06-01 12:28:04 +02005from test import support
Thomas Wouters89f507f2006-12-13 04:49:30 +00006import unittest
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -07007import itertools
Pablo Galindoe9ba3702018-09-03 22:20:06 +01008import decimal
Thomas Wouters89f507f2006-12-13 04:49:30 +00009import math
Christian Heimes53876d92008-04-19 00:31:39 +000010import os
Mark Dickinson85746542016-09-04 09:58:51 +010011import platform
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -070012import random
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000013import struct
Mark Dickinson85746542016-09-04 09:58:51 +010014import sys
Victor Stinner8f4ef3b2019-07-01 18:28:25 +020015
Guido van Rossumfcce6301996-08-08 18:26:25 +000016
Christian Heimes53876d92008-04-19 00:31:39 +000017eps = 1E-05
18NAN = float('nan')
19INF = float('inf')
20NINF = float('-inf')
Mark Dickinson31ba1c32016-09-04 12:29:14 +010021FLOAT_MAX = sys.float_info.max
Raymond Hettingerc6dabe32018-07-28 07:48:04 -070022FLOAT_MIN = sys.float_info.min
Christian Heimes53876d92008-04-19 00:31:39 +000023
Mark Dickinson5c567082009-04-24 16:39:07 +000024# detect evidence of double-rounding: fsum is not always correctly
25# rounded on machines that suffer from double rounding.
26x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer
27HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4)
28
Christian Heimes53876d92008-04-19 00:31:39 +000029# locate file with test values
30if __name__ == '__main__':
31 file = sys.argv[0]
32else:
33 file = __file__
34test_dir = os.path.dirname(file) or os.curdir
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000035math_testcases = os.path.join(test_dir, 'math_testcases.txt')
Christian Heimes53876d92008-04-19 00:31:39 +000036test_file = os.path.join(test_dir, 'cmath_testcases.txt')
37
Mark Dickinson96f774d2016-09-03 19:30:22 +010038
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000039def to_ulps(x):
40 """Convert a non-NaN float x to an integer, in such a way that
41 adjacent floats are converted to adjacent integers. Then
42 abs(ulps(x) - ulps(y)) gives the difference in ulps between two
43 floats.
44
45 The results from this function will only make sense on platforms
Mark Dickinson96f774d2016-09-03 19:30:22 +010046 where native doubles are represented in IEEE 754 binary64 format.
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000047
Mark Dickinson96f774d2016-09-03 19:30:22 +010048 Note: 0.0 and -0.0 are converted to 0 and -1, respectively.
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000049 """
Mark Dickinsond412ab52009-10-17 07:10:00 +000050 n = struct.unpack('<q', struct.pack('<d', x))[0]
Mark Dickinson12c4bdb2009-09-28 19:21:11 +000051 if n < 0:
52 n = ~(n+2**63)
53 return n
54
Mark Dickinson05d2e082009-12-11 20:17:17 +000055
Mark Dickinson4c8a9a22010-05-15 17:02:38 +000056# Here's a pure Python version of the math.factorial algorithm, for
57# documentation and comparison purposes.
58#
59# Formula:
60#
61# factorial(n) = factorial_odd_part(n) << (n - count_set_bits(n))
62#
63# where
64#
65# factorial_odd_part(n) = product_{i >= 0} product_{0 < j <= n >> i; j odd} j
66#
67# The outer product above is an infinite product, but once i >= n.bit_length,
68# (n >> i) < 1 and the corresponding term of the product is empty. So only the
69# finitely many terms for 0 <= i < n.bit_length() contribute anything.
70#
71# We iterate downwards from i == n.bit_length() - 1 to i == 0. The inner
72# product in the formula above starts at 1 for i == n.bit_length(); for each i
73# < n.bit_length() we get the inner product for i from that for i + 1 by
74# multiplying by all j in {n >> i+1 < j <= n >> i; j odd}. In Python terms,
75# this set is range((n >> i+1) + 1 | 1, (n >> i) + 1 | 1, 2).
76
77def count_set_bits(n):
78 """Number of '1' bits in binary expansion of a nonnnegative integer."""
79 return 1 + count_set_bits(n & n - 1) if n else 0
80
81def partial_product(start, stop):
82 """Product of integers in range(start, stop, 2), computed recursively.
83 start and stop should both be odd, with start <= stop.
84
85 """
86 numfactors = (stop - start) >> 1
87 if not numfactors:
88 return 1
89 elif numfactors == 1:
90 return start
91 else:
92 mid = (start + numfactors) | 1
93 return partial_product(start, mid) * partial_product(mid, stop)
94
95def py_factorial(n):
96 """Factorial of nonnegative integer n, via "Binary Split Factorial Formula"
97 described at http://www.luschny.de/math/factorial/binarysplitfact.html
98
99 """
100 inner = outer = 1
101 for i in reversed(range(n.bit_length())):
102 inner *= partial_product((n >> i + 1) + 1 | 1, (n >> i) + 1 | 1)
103 outer *= inner
104 return outer << (n - count_set_bits(n))
105
Mark Dickinson96f774d2016-09-03 19:30:22 +0100106def ulp_abs_check(expected, got, ulp_tol, abs_tol):
107 """Given finite floats `expected` and `got`, check that they're
108 approximately equal to within the given number of ulps or the
109 given absolute tolerance, whichever is bigger.
Mark Dickinson05d2e082009-12-11 20:17:17 +0000110
Mark Dickinson96f774d2016-09-03 19:30:22 +0100111 Returns None on success and an error message on failure.
112 """
113 ulp_error = abs(to_ulps(expected) - to_ulps(got))
114 abs_error = abs(expected - got)
115
116 # Succeed if either abs_error <= abs_tol or ulp_error <= ulp_tol.
117 if abs_error <= abs_tol or ulp_error <= ulp_tol:
Mark Dickinson05d2e082009-12-11 20:17:17 +0000118 return None
Mark Dickinson96f774d2016-09-03 19:30:22 +0100119 else:
120 fmt = ("error = {:.3g} ({:d} ulps); "
121 "permitted error = {:.3g} or {:d} ulps")
122 return fmt.format(abs_error, ulp_error, abs_tol, ulp_tol)
Mark Dickinson12c4bdb2009-09-28 19:21:11 +0000123
124def parse_mtestfile(fname):
125 """Parse a file with test values
126
127 -- starts a comment
128 blank lines, or lines containing only a comment, are ignored
129 other lines are expected to have the form
130 id fn arg -> expected [flag]*
131
132 """
133 with open(fname) as fp:
134 for line in fp:
135 # strip comments, and skip blank lines
136 if '--' in line:
137 line = line[:line.index('--')]
138 if not line.strip():
139 continue
140
141 lhs, rhs = line.split('->')
142 id, fn, arg = lhs.split()
143 rhs_pieces = rhs.split()
144 exp = rhs_pieces[0]
145 flags = rhs_pieces[1:]
146
147 yield (id, fn, float(arg), float(exp), flags)
148
Mark Dickinson96f774d2016-09-03 19:30:22 +0100149
Christian Heimes53876d92008-04-19 00:31:39 +0000150def parse_testfile(fname):
151 """Parse a file with test values
152
153 Empty lines or lines starting with -- are ignored
154 yields id, fn, arg_real, arg_imag, exp_real, exp_imag
155 """
156 with open(fname) as fp:
157 for line in fp:
158 # skip comment lines and blank lines
159 if line.startswith('--') or not line.strip():
160 continue
161
162 lhs, rhs = line.split('->')
163 id, fn, arg_real, arg_imag = lhs.split()
164 rhs_pieces = rhs.split()
165 exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1]
166 flags = rhs_pieces[2:]
167
168 yield (id, fn,
169 float(arg_real), float(arg_imag),
170 float(exp_real), float(exp_imag),
Mark Dickinson96f774d2016-09-03 19:30:22 +0100171 flags)
172
173
174def result_check(expected, got, ulp_tol=5, abs_tol=0.0):
175 # Common logic of MathTests.(ftest, test_testcases, test_mtestcases)
176 """Compare arguments expected and got, as floats, if either
177 is a float, using a tolerance expressed in multiples of
178 ulp(expected) or absolutely (if given and greater).
179
180 As a convenience, when neither argument is a float, and for
181 non-finite floats, exact equality is demanded. Also, nan==nan
182 as far as this function is concerned.
183
184 Returns None on success and an error message on failure.
185 """
186
187 # Check exactly equal (applies also to strings representing exceptions)
188 if got == expected:
189 return None
190
191 failure = "not equal"
192
193 # Turn mixed float and int comparison (e.g. floor()) to all-float
194 if isinstance(expected, float) and isinstance(got, int):
195 got = float(got)
196 elif isinstance(got, float) and isinstance(expected, int):
197 expected = float(expected)
198
199 if isinstance(expected, float) and isinstance(got, float):
200 if math.isnan(expected) and math.isnan(got):
201 # Pass, since both nan
202 failure = None
203 elif math.isinf(expected) or math.isinf(got):
204 # We already know they're not equal, drop through to failure
205 pass
206 else:
207 # Both are finite floats (now). Are they close enough?
208 failure = ulp_abs_check(expected, got, ulp_tol, abs_tol)
209
210 # arguments are not equal, and if numeric, are too far apart
211 if failure is not None:
212 fail_fmt = "expected {!r}, got {!r}"
213 fail_msg = fail_fmt.format(expected, got)
214 fail_msg += ' ({})'.format(failure)
215 return fail_msg
216 else:
217 return None
Guido van Rossumfcce6301996-08-08 18:26:25 +0000218
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200219class FloatLike:
220 def __init__(self, value):
221 self.value = value
222
223 def __float__(self):
224 return self.value
225
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +0300226class IntSubclass(int):
227 pass
228
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300229# Class providing an __index__ method.
230class MyIndexable(object):
231 def __init__(self, value):
232 self.value = value
233
234 def __index__(self):
235 return self.value
236
Thomas Wouters89f507f2006-12-13 04:49:30 +0000237class MathTests(unittest.TestCase):
Guido van Rossumfcce6301996-08-08 18:26:25 +0000238
Mark Dickinson96f774d2016-09-03 19:30:22 +0100239 def ftest(self, name, got, expected, ulp_tol=5, abs_tol=0.0):
240 """Compare arguments expected and got, as floats, if either
241 is a float, using a tolerance expressed in multiples of
242 ulp(expected) or absolutely, whichever is greater.
243
244 As a convenience, when neither argument is a float, and for
245 non-finite floats, exact equality is demanded. Also, nan==nan
246 in this function.
247 """
248 failure = result_check(expected, got, ulp_tol, abs_tol)
249 if failure is not None:
250 self.fail("{}: {}".format(name, failure))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000251
Thomas Wouters89f507f2006-12-13 04:49:30 +0000252 def testConstants(self):
Mark Dickinson96f774d2016-09-03 19:30:22 +0100253 # Ref: Abramowitz & Stegun (Dover, 1965)
254 self.ftest('pi', math.pi, 3.141592653589793238462643)
255 self.ftest('e', math.e, 2.718281828459045235360287)
Guido van Rossum0a891d72016-08-15 09:12:52 -0700256 self.assertEqual(math.tau, 2*math.pi)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000257
Thomas Wouters89f507f2006-12-13 04:49:30 +0000258 def testAcos(self):
259 self.assertRaises(TypeError, math.acos)
260 self.ftest('acos(-1)', math.acos(-1), math.pi)
261 self.ftest('acos(0)', math.acos(0), math.pi/2)
262 self.ftest('acos(1)', math.acos(1), 0)
Christian Heimes53876d92008-04-19 00:31:39 +0000263 self.assertRaises(ValueError, math.acos, INF)
264 self.assertRaises(ValueError, math.acos, NINF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100265 self.assertRaises(ValueError, math.acos, 1 + eps)
266 self.assertRaises(ValueError, math.acos, -1 - eps)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000267 self.assertTrue(math.isnan(math.acos(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000268
269 def testAcosh(self):
270 self.assertRaises(TypeError, math.acosh)
271 self.ftest('acosh(1)', math.acosh(1), 0)
272 self.ftest('acosh(2)', math.acosh(2), 1.3169578969248168)
273 self.assertRaises(ValueError, math.acosh, 0)
274 self.assertRaises(ValueError, math.acosh, -1)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000275 self.assertEqual(math.acosh(INF), INF)
Christian Heimes53876d92008-04-19 00:31:39 +0000276 self.assertRaises(ValueError, math.acosh, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000277 self.assertTrue(math.isnan(math.acosh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000278
Thomas Wouters89f507f2006-12-13 04:49:30 +0000279 def testAsin(self):
280 self.assertRaises(TypeError, math.asin)
281 self.ftest('asin(-1)', math.asin(-1), -math.pi/2)
282 self.ftest('asin(0)', math.asin(0), 0)
283 self.ftest('asin(1)', math.asin(1), math.pi/2)
Christian Heimes53876d92008-04-19 00:31:39 +0000284 self.assertRaises(ValueError, math.asin, INF)
285 self.assertRaises(ValueError, math.asin, NINF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100286 self.assertRaises(ValueError, math.asin, 1 + eps)
287 self.assertRaises(ValueError, math.asin, -1 - eps)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000288 self.assertTrue(math.isnan(math.asin(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000289
290 def testAsinh(self):
291 self.assertRaises(TypeError, math.asinh)
292 self.ftest('asinh(0)', math.asinh(0), 0)
293 self.ftest('asinh(1)', math.asinh(1), 0.88137358701954305)
294 self.ftest('asinh(-1)', math.asinh(-1), -0.88137358701954305)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000295 self.assertEqual(math.asinh(INF), INF)
296 self.assertEqual(math.asinh(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000297 self.assertTrue(math.isnan(math.asinh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000298
Thomas Wouters89f507f2006-12-13 04:49:30 +0000299 def testAtan(self):
300 self.assertRaises(TypeError, math.atan)
301 self.ftest('atan(-1)', math.atan(-1), -math.pi/4)
302 self.ftest('atan(0)', math.atan(0), 0)
303 self.ftest('atan(1)', math.atan(1), math.pi/4)
Christian Heimes53876d92008-04-19 00:31:39 +0000304 self.ftest('atan(inf)', math.atan(INF), math.pi/2)
Christian Heimesa342c012008-04-20 21:01:16 +0000305 self.ftest('atan(-inf)', math.atan(NINF), -math.pi/2)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000306 self.assertTrue(math.isnan(math.atan(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000307
308 def testAtanh(self):
309 self.assertRaises(TypeError, math.atan)
310 self.ftest('atanh(0)', math.atanh(0), 0)
311 self.ftest('atanh(0.5)', math.atanh(0.5), 0.54930614433405489)
312 self.ftest('atanh(-0.5)', math.atanh(-0.5), -0.54930614433405489)
313 self.assertRaises(ValueError, math.atanh, 1)
314 self.assertRaises(ValueError, math.atanh, -1)
315 self.assertRaises(ValueError, math.atanh, INF)
316 self.assertRaises(ValueError, math.atanh, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000317 self.assertTrue(math.isnan(math.atanh(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000318
Thomas Wouters89f507f2006-12-13 04:49:30 +0000319 def testAtan2(self):
320 self.assertRaises(TypeError, math.atan2)
321 self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
322 self.ftest('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
323 self.ftest('atan2(0, 1)', math.atan2(0, 1), 0)
324 self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
325 self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000326
Christian Heimese57950f2008-04-21 13:08:03 +0000327 # math.atan2(0, x)
328 self.ftest('atan2(0., -inf)', math.atan2(0., NINF), math.pi)
329 self.ftest('atan2(0., -2.3)', math.atan2(0., -2.3), math.pi)
330 self.ftest('atan2(0., -0.)', math.atan2(0., -0.), math.pi)
331 self.assertEqual(math.atan2(0., 0.), 0.)
332 self.assertEqual(math.atan2(0., 2.3), 0.)
333 self.assertEqual(math.atan2(0., INF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000334 self.assertTrue(math.isnan(math.atan2(0., NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000335 # math.atan2(-0, x)
336 self.ftest('atan2(-0., -inf)', math.atan2(-0., NINF), -math.pi)
337 self.ftest('atan2(-0., -2.3)', math.atan2(-0., -2.3), -math.pi)
338 self.ftest('atan2(-0., -0.)', math.atan2(-0., -0.), -math.pi)
339 self.assertEqual(math.atan2(-0., 0.), -0.)
340 self.assertEqual(math.atan2(-0., 2.3), -0.)
341 self.assertEqual(math.atan2(-0., INF), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000342 self.assertTrue(math.isnan(math.atan2(-0., NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000343 # math.atan2(INF, x)
344 self.ftest('atan2(inf, -inf)', math.atan2(INF, NINF), math.pi*3/4)
345 self.ftest('atan2(inf, -2.3)', math.atan2(INF, -2.3), math.pi/2)
346 self.ftest('atan2(inf, -0.)', math.atan2(INF, -0.0), math.pi/2)
347 self.ftest('atan2(inf, 0.)', math.atan2(INF, 0.0), math.pi/2)
348 self.ftest('atan2(inf, 2.3)', math.atan2(INF, 2.3), math.pi/2)
349 self.ftest('atan2(inf, inf)', math.atan2(INF, INF), math.pi/4)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000350 self.assertTrue(math.isnan(math.atan2(INF, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000351 # math.atan2(NINF, x)
352 self.ftest('atan2(-inf, -inf)', math.atan2(NINF, NINF), -math.pi*3/4)
353 self.ftest('atan2(-inf, -2.3)', math.atan2(NINF, -2.3), -math.pi/2)
354 self.ftest('atan2(-inf, -0.)', math.atan2(NINF, -0.0), -math.pi/2)
355 self.ftest('atan2(-inf, 0.)', math.atan2(NINF, 0.0), -math.pi/2)
356 self.ftest('atan2(-inf, 2.3)', math.atan2(NINF, 2.3), -math.pi/2)
357 self.ftest('atan2(-inf, inf)', math.atan2(NINF, INF), -math.pi/4)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000358 self.assertTrue(math.isnan(math.atan2(NINF, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000359 # math.atan2(+finite, x)
360 self.ftest('atan2(2.3, -inf)', math.atan2(2.3, NINF), math.pi)
361 self.ftest('atan2(2.3, -0.)', math.atan2(2.3, -0.), math.pi/2)
362 self.ftest('atan2(2.3, 0.)', math.atan2(2.3, 0.), math.pi/2)
363 self.assertEqual(math.atan2(2.3, INF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000364 self.assertTrue(math.isnan(math.atan2(2.3, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000365 # math.atan2(-finite, x)
366 self.ftest('atan2(-2.3, -inf)', math.atan2(-2.3, NINF), -math.pi)
367 self.ftest('atan2(-2.3, -0.)', math.atan2(-2.3, -0.), -math.pi/2)
368 self.ftest('atan2(-2.3, 0.)', math.atan2(-2.3, 0.), -math.pi/2)
369 self.assertEqual(math.atan2(-2.3, INF), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000370 self.assertTrue(math.isnan(math.atan2(-2.3, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000371 # math.atan2(NAN, x)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000372 self.assertTrue(math.isnan(math.atan2(NAN, NINF)))
373 self.assertTrue(math.isnan(math.atan2(NAN, -2.3)))
374 self.assertTrue(math.isnan(math.atan2(NAN, -0.)))
375 self.assertTrue(math.isnan(math.atan2(NAN, 0.)))
376 self.assertTrue(math.isnan(math.atan2(NAN, 2.3)))
377 self.assertTrue(math.isnan(math.atan2(NAN, INF)))
378 self.assertTrue(math.isnan(math.atan2(NAN, NAN)))
Christian Heimese57950f2008-04-21 13:08:03 +0000379
Thomas Wouters89f507f2006-12-13 04:49:30 +0000380 def testCeil(self):
381 self.assertRaises(TypeError, math.ceil)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000382 self.assertEqual(int, type(math.ceil(0.5)))
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200383 self.assertEqual(math.ceil(0.5), 1)
384 self.assertEqual(math.ceil(1.0), 1)
385 self.assertEqual(math.ceil(1.5), 2)
386 self.assertEqual(math.ceil(-0.5), 0)
387 self.assertEqual(math.ceil(-1.0), -1)
388 self.assertEqual(math.ceil(-1.5), -1)
389 self.assertEqual(math.ceil(0.0), 0)
390 self.assertEqual(math.ceil(-0.0), 0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000391 #self.assertEqual(math.ceil(INF), INF)
392 #self.assertEqual(math.ceil(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000393 #self.assertTrue(math.isnan(math.ceil(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000394
Guido van Rossum13e05de2007-08-23 22:56:55 +0000395 class TestCeil:
396 def __ceil__(self):
397 return 42
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200398 class FloatCeil(float):
399 def __ceil__(self):
400 return 42
Guido van Rossum13e05de2007-08-23 22:56:55 +0000401 class TestNoCeil:
402 pass
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200403 self.assertEqual(math.ceil(TestCeil()), 42)
404 self.assertEqual(math.ceil(FloatCeil()), 42)
405 self.assertEqual(math.ceil(FloatLike(42.5)), 43)
Guido van Rossum13e05de2007-08-23 22:56:55 +0000406 self.assertRaises(TypeError, math.ceil, TestNoCeil())
407
408 t = TestNoCeil()
409 t.__ceil__ = lambda *args: args
410 self.assertRaises(TypeError, math.ceil, t)
411 self.assertRaises(TypeError, math.ceil, t, 0)
412
Mark Dickinson63566232009-09-18 21:04:19 +0000413 @requires_IEEE_754
414 def testCopysign(self):
Mark Dickinson06b59e02010-02-06 23:16:50 +0000415 self.assertEqual(math.copysign(1, 42), 1.0)
416 self.assertEqual(math.copysign(0., 42), 0.0)
417 self.assertEqual(math.copysign(1., -42), -1.0)
418 self.assertEqual(math.copysign(3, 0.), 3.0)
419 self.assertEqual(math.copysign(4., -0.), -4.0)
420
Mark Dickinson63566232009-09-18 21:04:19 +0000421 self.assertRaises(TypeError, math.copysign)
422 # copysign should let us distinguish signs of zeros
Ezio Melottib3aedd42010-11-20 19:04:17 +0000423 self.assertEqual(math.copysign(1., 0.), 1.)
424 self.assertEqual(math.copysign(1., -0.), -1.)
425 self.assertEqual(math.copysign(INF, 0.), INF)
426 self.assertEqual(math.copysign(INF, -0.), NINF)
427 self.assertEqual(math.copysign(NINF, 0.), INF)
428 self.assertEqual(math.copysign(NINF, -0.), NINF)
Mark Dickinson63566232009-09-18 21:04:19 +0000429 # and of infinities
Ezio Melottib3aedd42010-11-20 19:04:17 +0000430 self.assertEqual(math.copysign(1., INF), 1.)
431 self.assertEqual(math.copysign(1., NINF), -1.)
432 self.assertEqual(math.copysign(INF, INF), INF)
433 self.assertEqual(math.copysign(INF, NINF), NINF)
434 self.assertEqual(math.copysign(NINF, INF), INF)
435 self.assertEqual(math.copysign(NINF, NINF), NINF)
Mark Dickinson06b59e02010-02-06 23:16:50 +0000436 self.assertTrue(math.isnan(math.copysign(NAN, 1.)))
437 self.assertTrue(math.isnan(math.copysign(NAN, INF)))
438 self.assertTrue(math.isnan(math.copysign(NAN, NINF)))
439 self.assertTrue(math.isnan(math.copysign(NAN, NAN)))
Mark Dickinson63566232009-09-18 21:04:19 +0000440 # copysign(INF, NAN) may be INF or it may be NINF, since
441 # we don't know whether the sign bit of NAN is set on any
442 # given platform.
Mark Dickinson06b59e02010-02-06 23:16:50 +0000443 self.assertTrue(math.isinf(math.copysign(INF, NAN)))
Mark Dickinson63566232009-09-18 21:04:19 +0000444 # similarly, copysign(2., NAN) could be 2. or -2.
Ezio Melottib3aedd42010-11-20 19:04:17 +0000445 self.assertEqual(abs(math.copysign(2., NAN)), 2.)
Christian Heimes53876d92008-04-19 00:31:39 +0000446
Thomas Wouters89f507f2006-12-13 04:49:30 +0000447 def testCos(self):
448 self.assertRaises(TypeError, math.cos)
Victor Stinner0b2ab212020-01-13 12:44:35 +0100449 self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0, abs_tol=math.ulp(1))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000450 self.ftest('cos(0)', math.cos(0), 1)
Victor Stinner0b2ab212020-01-13 12:44:35 +0100451 self.ftest('cos(pi/2)', math.cos(math.pi/2), 0, abs_tol=math.ulp(1))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000452 self.ftest('cos(pi)', math.cos(math.pi), -1)
Christian Heimes53876d92008-04-19 00:31:39 +0000453 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000454 self.assertTrue(math.isnan(math.cos(INF)))
455 self.assertTrue(math.isnan(math.cos(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +0000456 except ValueError:
457 self.assertRaises(ValueError, math.cos, INF)
458 self.assertRaises(ValueError, math.cos, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000459 self.assertTrue(math.isnan(math.cos(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000460
Paul Monsonf3550692019-06-19 13:09:54 -0700461 @unittest.skipIf(sys.platform == 'win32' and platform.machine() in ('ARM', 'ARM64'),
462 "Windows UCRT is off by 2 ULP this test requires accuracy within 1 ULP")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000463 def testCosh(self):
464 self.assertRaises(TypeError, math.cosh)
465 self.ftest('cosh(0)', math.cosh(0), 1)
466 self.ftest('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
Ezio Melottib3aedd42010-11-20 19:04:17 +0000467 self.assertEqual(math.cosh(INF), INF)
468 self.assertEqual(math.cosh(NINF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000469 self.assertTrue(math.isnan(math.cosh(NAN)))
Raymond Hettinger64108af2002-05-13 03:55:01 +0000470
Thomas Wouters89f507f2006-12-13 04:49:30 +0000471 def testDegrees(self):
472 self.assertRaises(TypeError, math.degrees)
473 self.ftest('degrees(pi)', math.degrees(math.pi), 180.0)
474 self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
475 self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100476 self.ftest('degrees(0)', math.degrees(0), 0)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000477
Thomas Wouters89f507f2006-12-13 04:49:30 +0000478 def testExp(self):
479 self.assertRaises(TypeError, math.exp)
480 self.ftest('exp(-1)', math.exp(-1), 1/math.e)
481 self.ftest('exp(0)', math.exp(0), 1)
482 self.ftest('exp(1)', math.exp(1), math.e)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000483 self.assertEqual(math.exp(INF), INF)
484 self.assertEqual(math.exp(NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000485 self.assertTrue(math.isnan(math.exp(NAN)))
Mark Dickinson31ba1c32016-09-04 12:29:14 +0100486 self.assertRaises(OverflowError, math.exp, 1000000)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000487
Thomas Wouters89f507f2006-12-13 04:49:30 +0000488 def testFabs(self):
489 self.assertRaises(TypeError, math.fabs)
490 self.ftest('fabs(-1)', math.fabs(-1), 1)
491 self.ftest('fabs(0)', math.fabs(0), 0)
492 self.ftest('fabs(1)', math.fabs(1), 1)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000493
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000494 def testFactorial(self):
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000495 self.assertEqual(math.factorial(0), 1)
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000496 total = 1
497 for i in range(1, 1000):
498 total *= i
499 self.assertEqual(math.factorial(i), total)
Mark Dickinson4c8a9a22010-05-15 17:02:38 +0000500 self.assertEqual(math.factorial(i), py_factorial(i))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000501 self.assertRaises(ValueError, math.factorial, -1)
Mark Dickinson5990d282014-04-10 09:29:39 -0400502 self.assertRaises(ValueError, math.factorial, -10**100)
Mark Dickinson5990d282014-04-10 09:29:39 -0400503
Pablo Galindoe9ba3702018-09-03 22:20:06 +0100504 def testFactorialNonIntegers(self):
Serhiy Storchaka231aad32019-06-17 16:57:27 +0300505 with self.assertWarns(DeprecationWarning):
506 self.assertEqual(math.factorial(5.0), 120)
507 with self.assertWarns(DeprecationWarning):
508 self.assertRaises(ValueError, math.factorial, 5.2)
509 with self.assertWarns(DeprecationWarning):
510 self.assertRaises(ValueError, math.factorial, -1.0)
511 with self.assertWarns(DeprecationWarning):
512 self.assertRaises(ValueError, math.factorial, -1e100)
513 self.assertRaises(TypeError, math.factorial, decimal.Decimal('5'))
514 self.assertRaises(TypeError, math.factorial, decimal.Decimal('5.2'))
Pablo Galindoe9ba3702018-09-03 22:20:06 +0100515 self.assertRaises(TypeError, math.factorial, "5")
516
Mark Dickinson5990d282014-04-10 09:29:39 -0400517 # Other implementations may place different upper bounds.
518 @support.cpython_only
519 def testFactorialHugeInputs(self):
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +0300520 # Currently raises OverflowError for inputs that are too large
Mark Dickinson5990d282014-04-10 09:29:39 -0400521 # to fit into a C long.
522 self.assertRaises(OverflowError, math.factorial, 10**100)
Serhiy Storchaka231aad32019-06-17 16:57:27 +0300523 with self.assertWarns(DeprecationWarning):
524 self.assertRaises(OverflowError, math.factorial, 1e100)
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000525
Thomas Wouters89f507f2006-12-13 04:49:30 +0000526 def testFloor(self):
527 self.assertRaises(TypeError, math.floor)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000528 self.assertEqual(int, type(math.floor(0.5)))
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200529 self.assertEqual(math.floor(0.5), 0)
530 self.assertEqual(math.floor(1.0), 1)
531 self.assertEqual(math.floor(1.5), 1)
532 self.assertEqual(math.floor(-0.5), -1)
533 self.assertEqual(math.floor(-1.0), -1)
534 self.assertEqual(math.floor(-1.5), -2)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000535 #self.assertEqual(math.ceil(INF), INF)
536 #self.assertEqual(math.ceil(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000537 #self.assertTrue(math.isnan(math.floor(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000538
Guido van Rossum13e05de2007-08-23 22:56:55 +0000539 class TestFloor:
540 def __floor__(self):
541 return 42
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200542 class FloatFloor(float):
543 def __floor__(self):
544 return 42
Guido van Rossum13e05de2007-08-23 22:56:55 +0000545 class TestNoFloor:
546 pass
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +0200547 self.assertEqual(math.floor(TestFloor()), 42)
548 self.assertEqual(math.floor(FloatFloor()), 42)
549 self.assertEqual(math.floor(FloatLike(41.9)), 41)
Guido van Rossum13e05de2007-08-23 22:56:55 +0000550 self.assertRaises(TypeError, math.floor, TestNoFloor())
551
552 t = TestNoFloor()
553 t.__floor__ = lambda *args: args
554 self.assertRaises(TypeError, math.floor, t)
555 self.assertRaises(TypeError, math.floor, t, 0)
556
Thomas Wouters89f507f2006-12-13 04:49:30 +0000557 def testFmod(self):
558 self.assertRaises(TypeError, math.fmod)
Mark Dickinson5bc7a442011-05-03 21:13:40 +0100559 self.ftest('fmod(10, 1)', math.fmod(10, 1), 0.0)
560 self.ftest('fmod(10, 0.5)', math.fmod(10, 0.5), 0.0)
561 self.ftest('fmod(10, 1.5)', math.fmod(10, 1.5), 1.0)
562 self.ftest('fmod(-10, 1)', math.fmod(-10, 1), -0.0)
563 self.ftest('fmod(-10, 0.5)', math.fmod(-10, 0.5), -0.0)
564 self.ftest('fmod(-10, 1.5)', math.fmod(-10, 1.5), -1.0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000565 self.assertTrue(math.isnan(math.fmod(NAN, 1.)))
566 self.assertTrue(math.isnan(math.fmod(1., NAN)))
567 self.assertTrue(math.isnan(math.fmod(NAN, NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +0000568 self.assertRaises(ValueError, math.fmod, 1., 0.)
569 self.assertRaises(ValueError, math.fmod, INF, 1.)
570 self.assertRaises(ValueError, math.fmod, NINF, 1.)
571 self.assertRaises(ValueError, math.fmod, INF, 0.)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000572 self.assertEqual(math.fmod(3.0, INF), 3.0)
573 self.assertEqual(math.fmod(-3.0, INF), -3.0)
574 self.assertEqual(math.fmod(3.0, NINF), 3.0)
575 self.assertEqual(math.fmod(-3.0, NINF), -3.0)
576 self.assertEqual(math.fmod(0.0, 3.0), 0.0)
577 self.assertEqual(math.fmod(0.0, NINF), 0.0)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000578
Thomas Wouters89f507f2006-12-13 04:49:30 +0000579 def testFrexp(self):
580 self.assertRaises(TypeError, math.frexp)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000581
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000582 def testfrexp(name, result, expected):
583 (mant, exp), (emant, eexp) = result, expected
Thomas Wouters89f507f2006-12-13 04:49:30 +0000584 if abs(mant-emant) > eps or exp != eexp:
585 self.fail('%s returned %r, expected %r'%\
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000586 (name, result, expected))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000587
Thomas Wouters89f507f2006-12-13 04:49:30 +0000588 testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
589 testfrexp('frexp(0)', math.frexp(0), (0, 0))
590 testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
591 testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000592
Ezio Melottib3aedd42010-11-20 19:04:17 +0000593 self.assertEqual(math.frexp(INF)[0], INF)
594 self.assertEqual(math.frexp(NINF)[0], NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000595 self.assertTrue(math.isnan(math.frexp(NAN)[0]))
Christian Heimes53876d92008-04-19 00:31:39 +0000596
Mark Dickinson63566232009-09-18 21:04:19 +0000597 @requires_IEEE_754
Mark Dickinson5c567082009-04-24 16:39:07 +0000598 @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
599 "fsum is not exact on machines with double rounding")
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000600 def testFsum(self):
601 # math.fsum relies on exact rounding for correct operation.
602 # There's a known problem with IA32 floating-point that causes
603 # inexact rounding in some situations, and will cause the
604 # math.fsum tests below to fail; see issue #2937. On non IEEE
605 # 754 platforms, and on IEEE 754 platforms that exhibit the
606 # problem described in issue #2937, we simply skip the whole
607 # test.
608
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000609 # Python version of math.fsum, for comparison. Uses a
610 # different algorithm based on frexp, ldexp and integer
611 # arithmetic.
612 from sys import float_info
613 mant_dig = float_info.mant_dig
614 etiny = float_info.min_exp - mant_dig
615
616 def msum(iterable):
617 """Full precision summation. Compute sum(iterable) without any
618 intermediate accumulation of error. Based on the 'lsum' function
619 at http://code.activestate.com/recipes/393090/
620
621 """
622 tmant, texp = 0, 0
623 for x in iterable:
624 mant, exp = math.frexp(x)
625 mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig
626 if texp > exp:
627 tmant <<= texp-exp
628 texp = exp
629 else:
630 mant <<= exp-texp
631 tmant += mant
632 # Round tmant * 2**texp to a float. The original recipe
633 # used float(str(tmant)) * 2.0**texp for this, but that's
634 # a little unsafe because str -> float conversion can't be
635 # relied upon to do correct rounding on all platforms.
636 tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp)
637 if tail > 0:
638 h = 1 << (tail-1)
639 tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1)
640 texp += tail
641 return math.ldexp(tmant, texp)
642
643 test_values = [
644 ([], 0.0),
645 ([0.0], 0.0),
646 ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
647 ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
648 ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
649 ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
650 ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
651 ([1./n for n in range(1, 1001)],
652 float.fromhex('0x1.df11f45f4e61ap+2')),
653 ([(-1.)**n/n for n in range(1, 1001)],
654 float.fromhex('-0x1.62a2af1bd3624p-1')),
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000655 ([1e16, 1., 1e-16], 10000000000000002.0),
656 ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
657 # exercise code for resizing partials array
658 ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] +
659 [-2.**1022],
660 float.fromhex('0x1.5555555555555p+970')),
661 ]
662
Mark Dickinsonbba873e2019-12-09 08:36:34 -0600663 # Telescoping sum, with exact differences (due to Sterbenz)
664 terms = [1.7**i for i in range(1001)]
665 test_values.append((
666 [terms[i+1] - terms[i] for i in range(1000)] + [-terms[1000]],
667 -terms[0]
668 ))
669
Mark Dickinsonaa7633a2008-08-01 08:16:13 +0000670 for i, (vals, expected) in enumerate(test_values):
671 try:
672 actual = math.fsum(vals)
673 except OverflowError:
674 self.fail("test %d failed: got OverflowError, expected %r "
675 "for math.fsum(%.100r)" % (i, expected, vals))
676 except ValueError:
677 self.fail("test %d failed: got ValueError, expected %r "
678 "for math.fsum(%.100r)" % (i, expected, vals))
679 self.assertEqual(actual, expected)
680
681 from random import random, gauss, shuffle
682 for j in range(1000):
683 vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
684 s = 0
685 for i in range(200):
686 v = gauss(0, random()) ** 7 - s
687 s += v
688 vals.append(v)
689 shuffle(vals)
690
691 s = msum(vals)
692 self.assertEqual(msum(vals), math.fsum(vals))
693
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300694 def testGcd(self):
695 gcd = math.gcd
696 self.assertEqual(gcd(0, 0), 0)
697 self.assertEqual(gcd(1, 0), 1)
698 self.assertEqual(gcd(-1, 0), 1)
699 self.assertEqual(gcd(0, 1), 1)
700 self.assertEqual(gcd(0, -1), 1)
701 self.assertEqual(gcd(7, 1), 1)
702 self.assertEqual(gcd(7, -1), 1)
703 self.assertEqual(gcd(-23, 15), 1)
704 self.assertEqual(gcd(120, 84), 12)
705 self.assertEqual(gcd(84, -120), 12)
706 self.assertEqual(gcd(1216342683557601535506311712,
707 436522681849110124616458784), 32)
708 c = 652560
709 x = 434610456570399902378880679233098819019853229470286994367836600566
710 y = 1064502245825115327754847244914921553977
711 a = x * c
712 b = y * 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 self.assertEqual(gcd(a, -b), c)
718 self.assertEqual(gcd(-b, a), c)
719 self.assertEqual(gcd(-a, -b), c)
720 self.assertEqual(gcd(-b, -a), c)
721 c = 576559230871654959816130551884856912003141446781646602790216406874
722 a = x * c
723 b = y * 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 self.assertEqual(gcd(a, -b), c)
729 self.assertEqual(gcd(-b, a), c)
730 self.assertEqual(gcd(-a, -b), c)
731 self.assertEqual(gcd(-b, -a), c)
732
733 self.assertRaises(TypeError, gcd, 120.0, 84)
734 self.assertRaises(TypeError, gcd, 120, 84.0)
735 self.assertEqual(gcd(MyIndexable(120), MyIndexable(84)), 12)
736
Thomas Wouters89f507f2006-12-13 04:49:30 +0000737 def testHypot(self):
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700738 from decimal import Decimal
739 from fractions import Fraction
740
741 hypot = math.hypot
742
743 # Test different numbers of arguments (from zero to five)
744 # against a straightforward pure python implementation
745 args = math.e, math.pi, math.sqrt(2.0), math.gamma(3.5), math.sin(2.1)
746 for i in range(len(args)+1):
747 self.assertAlmostEqual(
748 hypot(*args[:i]),
749 math.sqrt(sum(s**2 for s in args[:i]))
750 )
751
752 # Test allowable types (those with __float__)
753 self.assertEqual(hypot(12.0, 5.0), 13.0)
754 self.assertEqual(hypot(12, 5), 13)
755 self.assertEqual(hypot(Decimal(12), Decimal(5)), 13)
756 self.assertEqual(hypot(Fraction(12, 32), Fraction(5, 32)), Fraction(13, 32))
757 self.assertEqual(hypot(bool(1), bool(0), bool(1), bool(1)), math.sqrt(3))
758
759 # Test corner cases
760 self.assertEqual(hypot(0.0, 0.0), 0.0) # Max input is zero
761 self.assertEqual(hypot(-10.5), 10.5) # Negative input
762 self.assertEqual(hypot(), 0.0) # Negative input
763 self.assertEqual(1.0,
764 math.copysign(1.0, hypot(-0.0)) # Convert negative zero to positive zero
765 )
Raymond Hettinger00414592018-08-12 12:15:23 -0700766 self.assertEqual( # Handling of moving max to the end
767 hypot(1.5, 1.5, 0.5),
768 hypot(1.5, 0.5, 1.5),
769 )
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700770
771 # Test handling of bad arguments
772 with self.assertRaises(TypeError): # Reject keyword args
773 hypot(x=1)
774 with self.assertRaises(TypeError): # Reject values without __float__
775 hypot(1.1, 'string', 2.2)
Raymond Hettinger808180c2019-01-28 13:59:56 -0800776 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
777 with self.assertRaises((ValueError, OverflowError)):
778 hypot(1, int_too_big_for_float)
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700779
780 # Any infinity gives positive infinity.
781 self.assertEqual(hypot(INF), INF)
782 self.assertEqual(hypot(0, INF), INF)
783 self.assertEqual(hypot(10, INF), INF)
784 self.assertEqual(hypot(-10, INF), INF)
785 self.assertEqual(hypot(NAN, INF), INF)
786 self.assertEqual(hypot(INF, NAN), INF)
787 self.assertEqual(hypot(NINF, NAN), INF)
788 self.assertEqual(hypot(NAN, NINF), INF)
789 self.assertEqual(hypot(-INF, INF), INF)
790 self.assertEqual(hypot(-INF, -INF), INF)
791 self.assertEqual(hypot(10, -INF), INF)
792
Raymond Hettinger00414592018-08-12 12:15:23 -0700793 # If no infinity, any NaN gives a NaN.
Raymond Hettingerc6dabe32018-07-28 07:48:04 -0700794 self.assertTrue(math.isnan(hypot(NAN)))
795 self.assertTrue(math.isnan(hypot(0, NAN)))
796 self.assertTrue(math.isnan(hypot(NAN, 10)))
797 self.assertTrue(math.isnan(hypot(10, NAN)))
798 self.assertTrue(math.isnan(hypot(NAN, NAN)))
799 self.assertTrue(math.isnan(hypot(NAN)))
800
801 # Verify scaling for extremely large values
802 fourthmax = FLOAT_MAX / 4.0
803 for n in range(32):
804 self.assertEqual(hypot(*([fourthmax]*n)), fourthmax * math.sqrt(n))
805
806 # Verify scaling for extremely small values
807 for exp in range(32):
808 scale = FLOAT_MIN / 2.0 ** exp
809 self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale)
Guido van Rossumfcce6301996-08-08 18:26:25 +0000810
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700811 def testDist(self):
812 from decimal import Decimal as D
813 from fractions import Fraction as F
814
815 dist = math.dist
816 sqrt = math.sqrt
817
Raymond Hettinger808180c2019-01-28 13:59:56 -0800818 # Simple exact cases
819 self.assertEqual(dist((1.0, 2.0, 3.0), (4.0, 2.0, -1.0)), 5.0)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700820 self.assertEqual(dist((1, 2, 3), (4, 2, -1)), 5.0)
821
822 # Test different numbers of arguments (from zero to nine)
823 # against a straightforward pure python implementation
824 for i in range(9):
825 for j in range(5):
826 p = tuple(random.uniform(-5, 5) for k in range(i))
827 q = tuple(random.uniform(-5, 5) for k in range(i))
828 self.assertAlmostEqual(
829 dist(p, q),
830 sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
831 )
832
Raymond Hettinger6b5f1b42019-07-27 14:04:29 -0700833 # Test non-tuple inputs
834 self.assertEqual(dist([1.0, 2.0, 3.0], [4.0, 2.0, -1.0]), 5.0)
835 self.assertEqual(dist(iter([1.0, 2.0, 3.0]), iter([4.0, 2.0, -1.0])), 5.0)
836
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700837 # Test allowable types (those with __float__)
838 self.assertEqual(dist((14.0, 1.0), (2.0, -4.0)), 13.0)
839 self.assertEqual(dist((14, 1), (2, -4)), 13)
840 self.assertEqual(dist((D(14), D(1)), (D(2), D(-4))), D(13))
841 self.assertEqual(dist((F(14, 32), F(1, 32)), (F(2, 32), F(-4, 32))),
842 F(13, 32))
843 self.assertEqual(dist((True, True, False, True, False),
844 (True, False, True, True, False)),
845 sqrt(2.0))
846
847 # Test corner cases
848 self.assertEqual(dist((13.25, 12.5, -3.25),
849 (13.25, 12.5, -3.25)),
850 0.0) # Distance with self is zero
851 self.assertEqual(dist((), ()), 0.0) # Zero-dimensional case
852 self.assertEqual(1.0, # Convert negative zero to positive zero
853 math.copysign(1.0, dist((-0.0,), (0.0,)))
854 )
855 self.assertEqual(1.0, # Convert negative zero to positive zero
856 math.copysign(1.0, dist((0.0,), (-0.0,)))
857 )
Raymond Hettinger00414592018-08-12 12:15:23 -0700858 self.assertEqual( # Handling of moving max to the end
859 dist((1.5, 1.5, 0.5), (0, 0, 0)),
860 dist((1.5, 0.5, 1.5), (0, 0, 0))
861 )
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700862
863 # Verify tuple subclasses are allowed
Raymond Hettinger00414592018-08-12 12:15:23 -0700864 class T(tuple):
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700865 pass
866 self.assertEqual(dist(T((1, 2, 3)), ((4, 2, -1))), 5.0)
867
868 # Test handling of bad arguments
869 with self.assertRaises(TypeError): # Reject keyword args
870 dist(p=(1, 2, 3), q=(4, 5, 6))
871 with self.assertRaises(TypeError): # Too few args
872 dist((1, 2, 3))
873 with self.assertRaises(TypeError): # Too many args
874 dist((1, 2, 3), (4, 5, 6), (7, 8, 9))
875 with self.assertRaises(TypeError): # Scalars not allowed
876 dist(1, 2)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700877 with self.assertRaises(TypeError): # Reject values without __float__
878 dist((1.1, 'string', 2.2), (1, 2, 3))
879 with self.assertRaises(ValueError): # Check dimension agree
880 dist((1, 2, 3, 4), (5, 6, 7))
881 with self.assertRaises(ValueError): # Check dimension agree
882 dist((1, 2, 3), (4, 5, 6, 7))
Ammar Askarcb08a712019-01-12 01:23:41 -0500883 with self.assertRaises(TypeError): # Rejects invalid types
884 dist("abc", "xyz")
Raymond Hettinger808180c2019-01-28 13:59:56 -0800885 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
886 with self.assertRaises((ValueError, OverflowError)):
887 dist((1, int_too_big_for_float), (2, 3))
888 with self.assertRaises((ValueError, OverflowError)):
889 dist((2, 3), (1, int_too_big_for_float))
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700890
Raymond Hettinger00414592018-08-12 12:15:23 -0700891 # Verify that the one dimensional case is equivalent to abs()
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700892 for i in range(20):
893 p, q = random.random(), random.random()
894 self.assertEqual(dist((p,), (q,)), abs(p - q))
895
896 # Test special values
897 values = [NINF, -10.5, -0.0, 0.0, 10.5, INF, NAN]
898 for p in itertools.product(values, repeat=3):
899 for q in itertools.product(values, repeat=3):
900 diffs = [px - qx for px, qx in zip(p, q)]
901 if any(map(math.isinf, diffs)):
902 # Any infinite difference gives positive infinity.
903 self.assertEqual(dist(p, q), INF)
904 elif any(map(math.isnan, diffs)):
Raymond Hettinger00414592018-08-12 12:15:23 -0700905 # If no infinity, any NaN gives a NaN.
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700906 self.assertTrue(math.isnan(dist(p, q)))
907
908 # Verify scaling for extremely large values
909 fourthmax = FLOAT_MAX / 4.0
910 for n in range(32):
911 p = (fourthmax,) * n
912 q = (0.0,) * n
913 self.assertEqual(dist(p, q), fourthmax * math.sqrt(n))
914 self.assertEqual(dist(q, p), fourthmax * math.sqrt(n))
915
916 # Verify scaling for extremely small values
917 for exp in range(32):
918 scale = FLOAT_MIN / 2.0 ** exp
919 p = (4*scale, 3*scale)
920 q = (0.0, 0.0)
921 self.assertEqual(math.dist(p, q), 5*scale)
922 self.assertEqual(math.dist(q, p), 5*scale)
923
Mark Dickinson73934b92019-05-18 12:29:50 +0100924 def testIsqrt(self):
925 # Test a variety of inputs, large and small.
926 test_values = (
927 list(range(1000))
928 + list(range(10**6 - 1000, 10**6 + 1000))
Mark Dickinson5c08ce92019-05-19 17:51:56 +0100929 + [2**e + i for e in range(60, 200) for i in range(-40, 40)]
Mark Dickinson73934b92019-05-18 12:29:50 +0100930 + [3**9999, 10**5001]
931 )
932
933 for value in test_values:
934 with self.subTest(value=value):
935 s = math.isqrt(value)
936 self.assertIs(type(s), int)
937 self.assertLessEqual(s*s, value)
938 self.assertLess(value, (s+1)*(s+1))
939
940 # Negative values
941 with self.assertRaises(ValueError):
942 math.isqrt(-1)
943
944 # Integer-like things
945 s = math.isqrt(True)
946 self.assertIs(type(s), int)
947 self.assertEqual(s, 1)
948
949 s = math.isqrt(False)
950 self.assertIs(type(s), int)
951 self.assertEqual(s, 0)
952
953 class IntegerLike(object):
954 def __init__(self, value):
955 self.value = value
956
957 def __index__(self):
958 return self.value
959
960 s = math.isqrt(IntegerLike(1729))
961 self.assertIs(type(s), int)
962 self.assertEqual(s, 41)
963
964 with self.assertRaises(ValueError):
965 math.isqrt(IntegerLike(-3))
966
967 # Non-integer-like things
968 bad_values = [
969 3.5, "a string", decimal.Decimal("3.5"), 3.5j,
970 100.0, -4.0,
971 ]
972 for value in bad_values:
973 with self.subTest(value=value):
974 with self.assertRaises(TypeError):
975 math.isqrt(value)
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700976
Thomas Wouters89f507f2006-12-13 04:49:30 +0000977 def testLdexp(self):
978 self.assertRaises(TypeError, math.ldexp)
979 self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
980 self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
981 self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
982 self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
Christian Heimes53876d92008-04-19 00:31:39 +0000983 self.assertRaises(OverflowError, math.ldexp, 1., 1000000)
984 self.assertRaises(OverflowError, math.ldexp, -1., 1000000)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000985 self.assertEqual(math.ldexp(1., -1000000), 0.)
986 self.assertEqual(math.ldexp(-1., -1000000), -0.)
987 self.assertEqual(math.ldexp(INF, 30), INF)
988 self.assertEqual(math.ldexp(NINF, -213), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000989 self.assertTrue(math.isnan(math.ldexp(NAN, 0)))
Guido van Rossumfcce6301996-08-08 18:26:25 +0000990
Alexandre Vassalotti6461e102008-05-15 22:09:29 +0000991 # large second argument
992 for n in [10**5, 10**10, 10**20, 10**40]:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000993 self.assertEqual(math.ldexp(INF, -n), INF)
994 self.assertEqual(math.ldexp(NINF, -n), NINF)
995 self.assertEqual(math.ldexp(1., -n), 0.)
996 self.assertEqual(math.ldexp(-1., -n), -0.)
997 self.assertEqual(math.ldexp(0., -n), 0.)
998 self.assertEqual(math.ldexp(-0., -n), -0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000999 self.assertTrue(math.isnan(math.ldexp(NAN, -n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001000
1001 self.assertRaises(OverflowError, math.ldexp, 1., n)
1002 self.assertRaises(OverflowError, math.ldexp, -1., n)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001003 self.assertEqual(math.ldexp(0., n), 0.)
1004 self.assertEqual(math.ldexp(-0., n), -0.)
1005 self.assertEqual(math.ldexp(INF, n), INF)
1006 self.assertEqual(math.ldexp(NINF, n), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001007 self.assertTrue(math.isnan(math.ldexp(NAN, n)))
Alexandre Vassalotti6461e102008-05-15 22:09:29 +00001008
Thomas Wouters89f507f2006-12-13 04:49:30 +00001009 def testLog(self):
1010 self.assertRaises(TypeError, math.log)
1011 self.ftest('log(1/e)', math.log(1/math.e), -1)
1012 self.ftest('log(1)', math.log(1), 0)
1013 self.ftest('log(e)', math.log(math.e), 1)
1014 self.ftest('log(32,2)', math.log(32,2), 5)
1015 self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
1016 self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001017 self.ftest('log(10**1000)', math.log(10**1000),
1018 2302.5850929940457)
1019 self.assertRaises(ValueError, math.log, -1.5)
1020 self.assertRaises(ValueError, math.log, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001021 self.assertRaises(ValueError, math.log, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001022 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001023 self.assertTrue(math.isnan(math.log(NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001024
1025 def testLog1p(self):
1026 self.assertRaises(TypeError, math.log1p)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001027 for n in [2, 2**90, 2**300]:
1028 self.assertAlmostEqual(math.log1p(n), math.log1p(float(n)))
1029 self.assertRaises(ValueError, math.log1p, -1)
1030 self.assertEqual(math.log1p(INF), INF)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001031
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001032 @requires_IEEE_754
1033 def testLog2(self):
1034 self.assertRaises(TypeError, math.log2)
Victor Stinnerfa0e3d52011-05-09 01:01:09 +02001035
1036 # Check some integer values
1037 self.assertEqual(math.log2(1), 0.0)
1038 self.assertEqual(math.log2(2), 1.0)
1039 self.assertEqual(math.log2(4), 2.0)
1040
1041 # Large integer values
1042 self.assertEqual(math.log2(2**1023), 1023.0)
1043 self.assertEqual(math.log2(2**1024), 1024.0)
1044 self.assertEqual(math.log2(2**2000), 2000.0)
1045
1046 self.assertRaises(ValueError, math.log2, -1.5)
1047 self.assertRaises(ValueError, math.log2, NINF)
1048 self.assertTrue(math.isnan(math.log2(NAN)))
1049
Victor Stinnercd9dd372011-05-10 23:40:17 +02001050 @requires_IEEE_754
Victor Stinnerebbbdaf2011-06-01 13:19:07 +02001051 # log2() is not accurate enough on Mac OS X Tiger (10.4)
1052 @support.requires_mac_ver(10, 5)
Victor Stinnercd9dd372011-05-10 23:40:17 +02001053 def testLog2Exact(self):
1054 # Check that we get exact equality for log2 of powers of 2.
1055 actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)]
1056 expected = [float(n) for n in range(-1074, 1024)]
1057 self.assertEqual(actual, expected)
1058
Thomas Wouters89f507f2006-12-13 04:49:30 +00001059 def testLog10(self):
1060 self.assertRaises(TypeError, math.log10)
1061 self.ftest('log10(0.1)', math.log10(0.1), -1)
1062 self.ftest('log10(1)', math.log10(1), 0)
1063 self.ftest('log10(10)', math.log10(10), 1)
Mark Dickinsonc6037172010-09-29 19:06:36 +00001064 self.ftest('log10(10**1000)', math.log10(10**1000), 1000.0)
1065 self.assertRaises(ValueError, math.log10, -1.5)
1066 self.assertRaises(ValueError, math.log10, -10**1000)
Christian Heimes53876d92008-04-19 00:31:39 +00001067 self.assertRaises(ValueError, math.log10, NINF)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001068 self.assertEqual(math.log(INF), INF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001069 self.assertTrue(math.isnan(math.log10(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001070
Thomas Wouters89f507f2006-12-13 04:49:30 +00001071 def testModf(self):
1072 self.assertRaises(TypeError, math.modf)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001073
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001074 def testmodf(name, result, expected):
1075 (v1, v2), (e1, e2) = result, expected
Thomas Wouters89f507f2006-12-13 04:49:30 +00001076 if abs(v1-e1) > eps or abs(v2-e2):
1077 self.fail('%s returned %r, expected %r'%\
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001078 (name, result, expected))
Raymond Hettinger64108af2002-05-13 03:55:01 +00001079
Thomas Wouters89f507f2006-12-13 04:49:30 +00001080 testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
1081 testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001082
Ezio Melottib3aedd42010-11-20 19:04:17 +00001083 self.assertEqual(math.modf(INF), (0.0, INF))
1084 self.assertEqual(math.modf(NINF), (-0.0, NINF))
Christian Heimes53876d92008-04-19 00:31:39 +00001085
1086 modf_nan = math.modf(NAN)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001087 self.assertTrue(math.isnan(modf_nan[0]))
1088 self.assertTrue(math.isnan(modf_nan[1]))
Christian Heimes53876d92008-04-19 00:31:39 +00001089
Thomas Wouters89f507f2006-12-13 04:49:30 +00001090 def testPow(self):
1091 self.assertRaises(TypeError, math.pow)
1092 self.ftest('pow(0,1)', math.pow(0,1), 0)
1093 self.ftest('pow(1,0)', math.pow(1,0), 1)
1094 self.ftest('pow(2,1)', math.pow(2,1), 2)
1095 self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
Christian Heimes53876d92008-04-19 00:31:39 +00001096 self.assertEqual(math.pow(INF, 1), INF)
1097 self.assertEqual(math.pow(NINF, 1), NINF)
1098 self.assertEqual((math.pow(1, INF)), 1.)
1099 self.assertEqual((math.pow(1, NINF)), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001100 self.assertTrue(math.isnan(math.pow(NAN, 1)))
1101 self.assertTrue(math.isnan(math.pow(2, NAN)))
1102 self.assertTrue(math.isnan(math.pow(0, NAN)))
Christian Heimes53876d92008-04-19 00:31:39 +00001103 self.assertEqual(math.pow(1, NAN), 1)
Christian Heimesa342c012008-04-20 21:01:16 +00001104
1105 # pow(0., x)
1106 self.assertEqual(math.pow(0., INF), 0.)
1107 self.assertEqual(math.pow(0., 3.), 0.)
1108 self.assertEqual(math.pow(0., 2.3), 0.)
1109 self.assertEqual(math.pow(0., 2.), 0.)
1110 self.assertEqual(math.pow(0., 0.), 1.)
1111 self.assertEqual(math.pow(0., -0.), 1.)
1112 self.assertRaises(ValueError, math.pow, 0., -2.)
1113 self.assertRaises(ValueError, math.pow, 0., -2.3)
1114 self.assertRaises(ValueError, math.pow, 0., -3.)
1115 self.assertRaises(ValueError, math.pow, 0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001116 self.assertTrue(math.isnan(math.pow(0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001117
1118 # pow(INF, x)
1119 self.assertEqual(math.pow(INF, INF), INF)
1120 self.assertEqual(math.pow(INF, 3.), INF)
1121 self.assertEqual(math.pow(INF, 2.3), INF)
1122 self.assertEqual(math.pow(INF, 2.), INF)
1123 self.assertEqual(math.pow(INF, 0.), 1.)
1124 self.assertEqual(math.pow(INF, -0.), 1.)
1125 self.assertEqual(math.pow(INF, -2.), 0.)
1126 self.assertEqual(math.pow(INF, -2.3), 0.)
1127 self.assertEqual(math.pow(INF, -3.), 0.)
1128 self.assertEqual(math.pow(INF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001129 self.assertTrue(math.isnan(math.pow(INF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001130
1131 # pow(-0., x)
1132 self.assertEqual(math.pow(-0., INF), 0.)
1133 self.assertEqual(math.pow(-0., 3.), -0.)
1134 self.assertEqual(math.pow(-0., 2.3), 0.)
1135 self.assertEqual(math.pow(-0., 2.), 0.)
1136 self.assertEqual(math.pow(-0., 0.), 1.)
1137 self.assertEqual(math.pow(-0., -0.), 1.)
1138 self.assertRaises(ValueError, math.pow, -0., -2.)
1139 self.assertRaises(ValueError, math.pow, -0., -2.3)
1140 self.assertRaises(ValueError, math.pow, -0., -3.)
1141 self.assertRaises(ValueError, math.pow, -0., NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001142 self.assertTrue(math.isnan(math.pow(-0., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001143
1144 # pow(NINF, x)
1145 self.assertEqual(math.pow(NINF, INF), INF)
1146 self.assertEqual(math.pow(NINF, 3.), NINF)
1147 self.assertEqual(math.pow(NINF, 2.3), INF)
1148 self.assertEqual(math.pow(NINF, 2.), INF)
1149 self.assertEqual(math.pow(NINF, 0.), 1.)
1150 self.assertEqual(math.pow(NINF, -0.), 1.)
1151 self.assertEqual(math.pow(NINF, -2.), 0.)
1152 self.assertEqual(math.pow(NINF, -2.3), 0.)
1153 self.assertEqual(math.pow(NINF, -3.), -0.)
1154 self.assertEqual(math.pow(NINF, NINF), 0.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001155 self.assertTrue(math.isnan(math.pow(NINF, NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001156
1157 # pow(-1, x)
1158 self.assertEqual(math.pow(-1., INF), 1.)
1159 self.assertEqual(math.pow(-1., 3.), -1.)
1160 self.assertRaises(ValueError, math.pow, -1., 2.3)
1161 self.assertEqual(math.pow(-1., 2.), 1.)
1162 self.assertEqual(math.pow(-1., 0.), 1.)
1163 self.assertEqual(math.pow(-1., -0.), 1.)
1164 self.assertEqual(math.pow(-1., -2.), 1.)
1165 self.assertRaises(ValueError, math.pow, -1., -2.3)
1166 self.assertEqual(math.pow(-1., -3.), -1.)
1167 self.assertEqual(math.pow(-1., NINF), 1.)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001168 self.assertTrue(math.isnan(math.pow(-1., NAN)))
Christian Heimesa342c012008-04-20 21:01:16 +00001169
1170 # pow(1, x)
1171 self.assertEqual(math.pow(1., INF), 1.)
1172 self.assertEqual(math.pow(1., 3.), 1.)
1173 self.assertEqual(math.pow(1., 2.3), 1.)
1174 self.assertEqual(math.pow(1., 2.), 1.)
1175 self.assertEqual(math.pow(1., 0.), 1.)
1176 self.assertEqual(math.pow(1., -0.), 1.)
1177 self.assertEqual(math.pow(1., -2.), 1.)
1178 self.assertEqual(math.pow(1., -2.3), 1.)
1179 self.assertEqual(math.pow(1., -3.), 1.)
1180 self.assertEqual(math.pow(1., NINF), 1.)
1181 self.assertEqual(math.pow(1., NAN), 1.)
1182
1183 # pow(x, 0) should be 1 for any x
1184 self.assertEqual(math.pow(2.3, 0.), 1.)
1185 self.assertEqual(math.pow(-2.3, 0.), 1.)
1186 self.assertEqual(math.pow(NAN, 0.), 1.)
1187 self.assertEqual(math.pow(2.3, -0.), 1.)
1188 self.assertEqual(math.pow(-2.3, -0.), 1.)
1189 self.assertEqual(math.pow(NAN, -0.), 1.)
1190
1191 # pow(x, y) is invalid if x is negative and y is not integral
1192 self.assertRaises(ValueError, math.pow, -1., 2.3)
1193 self.assertRaises(ValueError, math.pow, -15., -3.1)
1194
1195 # pow(x, NINF)
1196 self.assertEqual(math.pow(1.9, NINF), 0.)
1197 self.assertEqual(math.pow(1.1, NINF), 0.)
1198 self.assertEqual(math.pow(0.9, NINF), INF)
1199 self.assertEqual(math.pow(0.1, NINF), INF)
1200 self.assertEqual(math.pow(-0.1, NINF), INF)
1201 self.assertEqual(math.pow(-0.9, NINF), INF)
1202 self.assertEqual(math.pow(-1.1, NINF), 0.)
1203 self.assertEqual(math.pow(-1.9, NINF), 0.)
1204
1205 # pow(x, INF)
1206 self.assertEqual(math.pow(1.9, INF), INF)
1207 self.assertEqual(math.pow(1.1, INF), INF)
1208 self.assertEqual(math.pow(0.9, INF), 0.)
1209 self.assertEqual(math.pow(0.1, INF), 0.)
1210 self.assertEqual(math.pow(-0.1, INF), 0.)
1211 self.assertEqual(math.pow(-0.9, INF), 0.)
1212 self.assertEqual(math.pow(-1.1, INF), INF)
1213 self.assertEqual(math.pow(-1.9, INF), INF)
1214
1215 # pow(x, y) should work for x negative, y an integer
1216 self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
1217 self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
1218 self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
1219 self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
1220 self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
1221 self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
1222 self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
1223 self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
1224 self.assertRaises(ValueError, math.pow, -2.0, -0.5)
1225 self.assertRaises(ValueError, math.pow, -2.0, 0.5)
1226
1227 # the following tests have been commented out since they don't
1228 # really belong here: the implementation of ** for floats is
Ezio Melotti13925002011-03-16 11:05:33 +02001229 # independent of the implementation of math.pow
Christian Heimesa342c012008-04-20 21:01:16 +00001230 #self.assertEqual(1**NAN, 1)
1231 #self.assertEqual(1**INF, 1)
1232 #self.assertEqual(1**NINF, 1)
1233 #self.assertEqual(1**0, 1)
1234 #self.assertEqual(1.**NAN, 1)
1235 #self.assertEqual(1.**INF, 1)
1236 #self.assertEqual(1.**NINF, 1)
1237 #self.assertEqual(1.**0, 1)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001238
Thomas Wouters89f507f2006-12-13 04:49:30 +00001239 def testRadians(self):
1240 self.assertRaises(TypeError, math.radians)
1241 self.ftest('radians(180)', math.radians(180), math.pi)
1242 self.ftest('radians(90)', math.radians(90), math.pi/2)
1243 self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001244 self.ftest('radians(0)', math.radians(0), 0)
Guido van Rossumfcce6301996-08-08 18:26:25 +00001245
Mark Dickinsona0ce3752017-04-05 18:34:27 +01001246 @requires_IEEE_754
1247 def testRemainder(self):
1248 from fractions import Fraction
1249
1250 def validate_spec(x, y, r):
1251 """
1252 Check that r matches remainder(x, y) according to the IEEE 754
1253 specification. Assumes that x, y and r are finite and y is nonzero.
1254 """
1255 fx, fy, fr = Fraction(x), Fraction(y), Fraction(r)
1256 # r should not exceed y/2 in absolute value
1257 self.assertLessEqual(abs(fr), abs(fy/2))
1258 # x - r should be an exact integer multiple of y
1259 n = (fx - fr) / fy
1260 self.assertEqual(n, int(n))
1261 if abs(fr) == abs(fy/2):
1262 # If |r| == |y/2|, n should be even.
1263 self.assertEqual(n/2, int(n/2))
1264
1265 # triples (x, y, remainder(x, y)) in hexadecimal form.
1266 testcases = [
1267 # Remainders modulo 1, showing the ties-to-even behaviour.
1268 '-4.0 1 -0.0',
1269 '-3.8 1 0.8',
1270 '-3.0 1 -0.0',
1271 '-2.8 1 -0.8',
1272 '-2.0 1 -0.0',
1273 '-1.8 1 0.8',
1274 '-1.0 1 -0.0',
1275 '-0.8 1 -0.8',
1276 '-0.0 1 -0.0',
1277 ' 0.0 1 0.0',
1278 ' 0.8 1 0.8',
1279 ' 1.0 1 0.0',
1280 ' 1.8 1 -0.8',
1281 ' 2.0 1 0.0',
1282 ' 2.8 1 0.8',
1283 ' 3.0 1 0.0',
1284 ' 3.8 1 -0.8',
1285 ' 4.0 1 0.0',
1286
1287 # Reductions modulo 2*pi
1288 '0x0.0p+0 0x1.921fb54442d18p+2 0x0.0p+0',
1289 '0x1.921fb54442d18p+0 0x1.921fb54442d18p+2 0x1.921fb54442d18p+0',
1290 '0x1.921fb54442d17p+1 0x1.921fb54442d18p+2 0x1.921fb54442d17p+1',
1291 '0x1.921fb54442d18p+1 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1292 '0x1.921fb54442d19p+1 0x1.921fb54442d18p+2 -0x1.921fb54442d17p+1',
1293 '0x1.921fb54442d17p+2 0x1.921fb54442d18p+2 -0x0.0000000000001p+2',
1294 '0x1.921fb54442d18p+2 0x1.921fb54442d18p+2 0x0p0',
1295 '0x1.921fb54442d19p+2 0x1.921fb54442d18p+2 0x0.0000000000001p+2',
1296 '0x1.2d97c7f3321d1p+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1297 '0x1.2d97c7f3321d2p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d18p+1',
1298 '0x1.2d97c7f3321d3p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1299 '0x1.921fb54442d17p+3 0x1.921fb54442d18p+2 -0x0.0000000000001p+3',
1300 '0x1.921fb54442d18p+3 0x1.921fb54442d18p+2 0x0p0',
1301 '0x1.921fb54442d19p+3 0x1.921fb54442d18p+2 0x0.0000000000001p+3',
1302 '0x1.f6a7a2955385dp+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1',
1303 '0x1.f6a7a2955385ep+3 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1',
1304 '0x1.f6a7a2955385fp+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
1305 '0x1.1475cc9eedf00p+5 0x1.921fb54442d18p+2 0x1.921fb54442d10p+1',
1306 '0x1.1475cc9eedf01p+5 0x1.921fb54442d18p+2 -0x1.921fb54442d10p+1',
1307
1308 # Symmetry with respect to signs.
1309 ' 1 0.c 0.4',
1310 '-1 0.c -0.4',
1311 ' 1 -0.c 0.4',
1312 '-1 -0.c -0.4',
1313 ' 1.4 0.c -0.4',
1314 '-1.4 0.c 0.4',
1315 ' 1.4 -0.c -0.4',
1316 '-1.4 -0.c 0.4',
1317
1318 # Huge modulus, to check that the underlying algorithm doesn't
1319 # rely on 2.0 * modulus being representable.
1320 '0x1.dp+1023 0x1.4p+1023 0x0.9p+1023',
1321 '0x1.ep+1023 0x1.4p+1023 -0x0.ap+1023',
1322 '0x1.fp+1023 0x1.4p+1023 -0x0.9p+1023',
1323 ]
1324
1325 for case in testcases:
1326 with self.subTest(case=case):
1327 x_hex, y_hex, expected_hex = case.split()
1328 x = float.fromhex(x_hex)
1329 y = float.fromhex(y_hex)
1330 expected = float.fromhex(expected_hex)
1331 validate_spec(x, y, expected)
1332 actual = math.remainder(x, y)
1333 # Cheap way of checking that the floats are
1334 # as identical as we need them to be.
1335 self.assertEqual(actual.hex(), expected.hex())
1336
1337 # Test tiny subnormal modulus: there's potential for
1338 # getting the implementation wrong here (for example,
1339 # by assuming that modulus/2 is exactly representable).
1340 tiny = float.fromhex('1p-1074') # min +ve subnormal
1341 for n in range(-25, 25):
1342 if n == 0:
1343 continue
1344 y = n * tiny
1345 for m in range(100):
1346 x = m * tiny
1347 actual = math.remainder(x, y)
1348 validate_spec(x, y, actual)
1349 actual = math.remainder(-x, y)
1350 validate_spec(-x, y, actual)
1351
1352 # Special values.
1353 # NaNs should propagate as usual.
1354 for value in [NAN, 0.0, -0.0, 2.0, -2.3, NINF, INF]:
1355 self.assertIsNaN(math.remainder(NAN, value))
1356 self.assertIsNaN(math.remainder(value, NAN))
1357
1358 # remainder(x, inf) is x, for non-nan non-infinite x.
1359 for value in [-2.3, -0.0, 0.0, 2.3]:
1360 self.assertEqual(math.remainder(value, INF), value)
1361 self.assertEqual(math.remainder(value, NINF), value)
1362
1363 # remainder(x, 0) and remainder(infinity, x) for non-NaN x are invalid
1364 # operations according to IEEE 754-2008 7.2(f), and should raise.
1365 for value in [NINF, -2.3, -0.0, 0.0, 2.3, INF]:
1366 with self.assertRaises(ValueError):
1367 math.remainder(INF, value)
1368 with self.assertRaises(ValueError):
1369 math.remainder(NINF, value)
1370 with self.assertRaises(ValueError):
1371 math.remainder(value, 0.0)
1372 with self.assertRaises(ValueError):
1373 math.remainder(value, -0.0)
1374
Thomas Wouters89f507f2006-12-13 04:49:30 +00001375 def testSin(self):
1376 self.assertRaises(TypeError, math.sin)
1377 self.ftest('sin(0)', math.sin(0), 0)
1378 self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
1379 self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001380 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001381 self.assertTrue(math.isnan(math.sin(INF)))
1382 self.assertTrue(math.isnan(math.sin(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001383 except ValueError:
1384 self.assertRaises(ValueError, math.sin, INF)
1385 self.assertRaises(ValueError, math.sin, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001386 self.assertTrue(math.isnan(math.sin(NAN)))
Guido van Rossumfcce6301996-08-08 18:26:25 +00001387
Thomas Wouters89f507f2006-12-13 04:49:30 +00001388 def testSinh(self):
1389 self.assertRaises(TypeError, math.sinh)
1390 self.ftest('sinh(0)', math.sinh(0), 0)
1391 self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
1392 self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001393 self.assertEqual(math.sinh(INF), INF)
1394 self.assertEqual(math.sinh(NINF), NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001395 self.assertTrue(math.isnan(math.sinh(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001396
Thomas Wouters89f507f2006-12-13 04:49:30 +00001397 def testSqrt(self):
1398 self.assertRaises(TypeError, math.sqrt)
1399 self.ftest('sqrt(0)', math.sqrt(0), 0)
1400 self.ftest('sqrt(1)', math.sqrt(1), 1)
1401 self.ftest('sqrt(4)', math.sqrt(4), 2)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001402 self.assertEqual(math.sqrt(INF), INF)
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001403 self.assertRaises(ValueError, math.sqrt, -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001404 self.assertRaises(ValueError, math.sqrt, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001405 self.assertTrue(math.isnan(math.sqrt(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001406
Thomas Wouters89f507f2006-12-13 04:49:30 +00001407 def testTan(self):
1408 self.assertRaises(TypeError, math.tan)
1409 self.ftest('tan(0)', math.tan(0), 0)
1410 self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
1411 self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
Christian Heimes53876d92008-04-19 00:31:39 +00001412 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001413 self.assertTrue(math.isnan(math.tan(INF)))
1414 self.assertTrue(math.isnan(math.tan(NINF)))
Christian Heimes53876d92008-04-19 00:31:39 +00001415 except:
1416 self.assertRaises(ValueError, math.tan, INF)
1417 self.assertRaises(ValueError, math.tan, NINF)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001418 self.assertTrue(math.isnan(math.tan(NAN)))
Tim Peters1d120612000-10-12 06:10:25 +00001419
Thomas Wouters89f507f2006-12-13 04:49:30 +00001420 def testTanh(self):
1421 self.assertRaises(TypeError, math.tanh)
1422 self.ftest('tanh(0)', math.tanh(0), 0)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001423 self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0,
Victor Stinner0b2ab212020-01-13 12:44:35 +01001424 abs_tol=math.ulp(1))
Christian Heimes53876d92008-04-19 00:31:39 +00001425 self.ftest('tanh(inf)', math.tanh(INF), 1)
1426 self.ftest('tanh(-inf)', math.tanh(NINF), -1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001427 self.assertTrue(math.isnan(math.tanh(NAN)))
Victor Stinnerbe3da382010-11-07 14:14:27 +00001428
1429 @requires_IEEE_754
Victor Stinnerbe3da382010-11-07 14:14:27 +00001430 def testTanhSign(self):
Christian Heimese57950f2008-04-21 13:08:03 +00001431 # check that tanh(-0.) == -0. on IEEE 754 systems
Victor Stinnerbe3da382010-11-07 14:14:27 +00001432 self.assertEqual(math.tanh(-0.), -0.)
1433 self.assertEqual(math.copysign(1., math.tanh(-0.)),
1434 math.copysign(1., -0.))
Tim Peters1d120612000-10-12 06:10:25 +00001435
Christian Heimes400adb02008-02-01 08:12:03 +00001436 def test_trunc(self):
1437 self.assertEqual(math.trunc(1), 1)
1438 self.assertEqual(math.trunc(-1), -1)
1439 self.assertEqual(type(math.trunc(1)), int)
1440 self.assertEqual(type(math.trunc(1.5)), int)
1441 self.assertEqual(math.trunc(1.5), 1)
1442 self.assertEqual(math.trunc(-1.5), -1)
1443 self.assertEqual(math.trunc(1.999999), 1)
1444 self.assertEqual(math.trunc(-1.999999), -1)
1445 self.assertEqual(math.trunc(-0.999999), -0)
1446 self.assertEqual(math.trunc(-100.999), -100)
1447
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001448 class TestTrunc:
Christian Heimes400adb02008-02-01 08:12:03 +00001449 def __trunc__(self):
1450 return 23
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001451 class FloatTrunc(float):
1452 def __trunc__(self):
1453 return 23
1454 class TestNoTrunc:
Christian Heimes400adb02008-02-01 08:12:03 +00001455 pass
1456
1457 self.assertEqual(math.trunc(TestTrunc()), 23)
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001458 self.assertEqual(math.trunc(FloatTrunc()), 23)
Christian Heimes400adb02008-02-01 08:12:03 +00001459
1460 self.assertRaises(TypeError, math.trunc)
1461 self.assertRaises(TypeError, math.trunc, 1, 2)
Serhiy Storchaka5fd5cb82019-11-16 18:00:57 +02001462 self.assertRaises(TypeError, math.trunc, FloatLike(23.5))
Christian Heimes400adb02008-02-01 08:12:03 +00001463 self.assertRaises(TypeError, math.trunc, TestNoTrunc())
1464
Mark Dickinson8e0c9962010-07-11 17:38:24 +00001465 def testIsfinite(self):
1466 self.assertTrue(math.isfinite(0.0))
1467 self.assertTrue(math.isfinite(-0.0))
1468 self.assertTrue(math.isfinite(1.0))
1469 self.assertTrue(math.isfinite(-1.0))
1470 self.assertFalse(math.isfinite(float("nan")))
1471 self.assertFalse(math.isfinite(float("inf")))
1472 self.assertFalse(math.isfinite(float("-inf")))
1473
Christian Heimes072c0f12008-01-03 23:01:04 +00001474 def testIsnan(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001475 self.assertTrue(math.isnan(float("nan")))
Mark Dickinson31ba1c32016-09-04 12:29:14 +01001476 self.assertTrue(math.isnan(float("-nan")))
1477 self.assertTrue(math.isnan(float("inf") * 0.))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001478 self.assertFalse(math.isnan(float("inf")))
1479 self.assertFalse(math.isnan(0.))
1480 self.assertFalse(math.isnan(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001481
1482 def testIsinf(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001483 self.assertTrue(math.isinf(float("inf")))
1484 self.assertTrue(math.isinf(float("-inf")))
1485 self.assertTrue(math.isinf(1E400))
1486 self.assertTrue(math.isinf(-1E400))
1487 self.assertFalse(math.isinf(float("nan")))
1488 self.assertFalse(math.isinf(0.))
1489 self.assertFalse(math.isinf(1.))
Christian Heimes072c0f12008-01-03 23:01:04 +00001490
Mark Dickinsona5d0c7c2015-01-11 11:55:29 +00001491 @requires_IEEE_754
1492 def test_nan_constant(self):
1493 self.assertTrue(math.isnan(math.nan))
1494
1495 @requires_IEEE_754
1496 def test_inf_constant(self):
1497 self.assertTrue(math.isinf(math.inf))
1498 self.assertGreater(math.inf, 0.0)
1499 self.assertEqual(math.inf, float("inf"))
1500 self.assertEqual(-math.inf, float("-inf"))
1501
Thomas Wouters89f507f2006-12-13 04:49:30 +00001502 # RED_FLAG 16-Oct-2000 Tim
1503 # While 2.0 is more consistent about exceptions than previous releases, it
1504 # still fails this part of the test on some platforms. For now, we only
1505 # *run* test_exceptions() in verbose mode, so that this isn't normally
1506 # tested.
Serhiy Storchaka43767632013-11-03 21:31:38 +02001507 @unittest.skipUnless(verbose, 'requires verbose mode')
1508 def test_exceptions(self):
1509 try:
1510 x = math.exp(-1000000000)
1511 except:
1512 # mathmodule.c is failing to weed out underflows from libm, or
1513 # we've got an fp format with huge dynamic range
1514 self.fail("underflowing exp() should not have raised "
1515 "an exception")
1516 if x != 0:
1517 self.fail("underflowing exp() should have returned 0")
Tim Peters98c81842000-10-16 17:35:13 +00001518
Serhiy Storchaka43767632013-11-03 21:31:38 +02001519 # If this fails, probably using a strict IEEE-754 conforming libm, and x
1520 # is +Inf afterwards. But Python wants overflows detected by default.
1521 try:
1522 x = math.exp(1000000000)
1523 except OverflowError:
1524 pass
1525 else:
1526 self.fail("overflowing exp() didn't trigger OverflowError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001527
Serhiy Storchaka43767632013-11-03 21:31:38 +02001528 # If this fails, it could be a puzzle. One odd possibility is that
1529 # mathmodule.c's macros are getting confused while comparing
1530 # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
1531 # as a result (and so raising OverflowError instead).
1532 try:
1533 x = math.sqrt(-1.0)
1534 except ValueError:
1535 pass
1536 else:
1537 self.fail("sqrt(-1) didn't raise ValueError")
Thomas Wouters89f507f2006-12-13 04:49:30 +00001538
Mark Dickinson63566232009-09-18 21:04:19 +00001539 @requires_IEEE_754
Christian Heimes53876d92008-04-19 00:31:39 +00001540 def test_testfile(self):
Mark Dickinson85746542016-09-04 09:58:51 +01001541 # Some tests need to be skipped on ancient OS X versions.
1542 # See issue #27953.
1543 SKIP_ON_TIGER = {'tan0064'}
1544
1545 osx_version = None
1546 if sys.platform == 'darwin':
1547 version_txt = platform.mac_ver()[0]
1548 try:
1549 osx_version = tuple(map(int, version_txt.split('.')))
1550 except ValueError:
1551 pass
1552
Mark Dickinson96f774d2016-09-03 19:30:22 +01001553 fail_fmt = "{}: {}({!r}): {}"
1554
1555 failures = []
Christian Heimes53876d92008-04-19 00:31:39 +00001556 for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001557 # Skip if either the input or result is complex
1558 if ai != 0.0 or ei != 0.0:
Christian Heimes53876d92008-04-19 00:31:39 +00001559 continue
1560 if fn in ['rect', 'polar']:
1561 # no real versions of rect, polar
1562 continue
Mark Dickinson85746542016-09-04 09:58:51 +01001563 # Skip certain tests on OS X 10.4.
1564 if osx_version is not None and osx_version < (10, 5):
1565 if id in SKIP_ON_TIGER:
1566 continue
Mark Dickinson96f774d2016-09-03 19:30:22 +01001567
Christian Heimes53876d92008-04-19 00:31:39 +00001568 func = getattr(math, fn)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001569
1570 if 'invalid' in flags or 'divide-by-zero' in flags:
1571 er = 'ValueError'
1572 elif 'overflow' in flags:
1573 er = 'OverflowError'
1574
Christian Heimesa342c012008-04-20 21:01:16 +00001575 try:
1576 result = func(ar)
Mark Dickinson96f774d2016-09-03 19:30:22 +01001577 except ValueError:
1578 result = 'ValueError'
Benjamin Peterson2b7411d2008-05-26 17:36:47 +00001579 except OverflowError:
Mark Dickinson96f774d2016-09-03 19:30:22 +01001580 result = 'OverflowError'
1581
1582 # Default tolerances
1583 ulp_tol, abs_tol = 5, 0.0
1584
1585 failure = result_check(er, result, ulp_tol, abs_tol)
1586 if failure is None:
1587 continue
1588
1589 msg = fail_fmt.format(id, fn, ar, failure)
1590 failures.append(msg)
1591
1592 if failures:
1593 self.fail('Failures in test_testfile:\n ' +
1594 '\n '.join(failures))
Thomas Wouters89f507f2006-12-13 04:49:30 +00001595
Victor Stinnerbe3da382010-11-07 14:14:27 +00001596 @requires_IEEE_754
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001597 def test_mtestfile(self):
Mark Dickinson96f774d2016-09-03 19:30:22 +01001598 fail_fmt = "{}: {}({!r}): {}"
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001599
1600 failures = []
1601 for id, fn, arg, expected, flags in parse_mtestfile(math_testcases):
1602 func = getattr(math, fn)
1603
1604 if 'invalid' in flags or 'divide-by-zero' in flags:
1605 expected = 'ValueError'
1606 elif 'overflow' in flags:
1607 expected = 'OverflowError'
1608
1609 try:
1610 got = func(arg)
1611 except ValueError:
1612 got = 'ValueError'
1613 except OverflowError:
1614 got = 'OverflowError'
1615
Mark Dickinson96f774d2016-09-03 19:30:22 +01001616 # Default tolerances
1617 ulp_tol, abs_tol = 5, 0.0
Mark Dickinsonbcdf9da2010-06-13 10:52:38 +00001618
Mark Dickinson96f774d2016-09-03 19:30:22 +01001619 # Exceptions to the defaults
1620 if fn == 'gamma':
1621 # Experimental results on one platform gave
1622 # an accuracy of <= 10 ulps across the entire float
1623 # domain. We weaken that to require 20 ulp accuracy.
1624 ulp_tol = 20
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001625
Mark Dickinson96f774d2016-09-03 19:30:22 +01001626 elif fn == 'lgamma':
1627 # we use a weaker accuracy test for lgamma;
1628 # lgamma only achieves an absolute error of
1629 # a few multiples of the machine accuracy, in
1630 # general.
1631 abs_tol = 1e-15
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001632
Mark Dickinson96f774d2016-09-03 19:30:22 +01001633 elif fn == 'erfc' and arg >= 0.0:
1634 # erfc has less-than-ideal accuracy for large
1635 # arguments (x ~ 25 or so), mainly due to the
1636 # error involved in computing exp(-x*x).
1637 #
1638 # Observed between CPython and mpmath at 25 dp:
1639 # x < 0 : err <= 2 ulp
1640 # 0 <= x < 1 : err <= 10 ulp
1641 # 1 <= x < 10 : err <= 100 ulp
1642 # 10 <= x < 20 : err <= 300 ulp
1643 # 20 <= x : < 600 ulp
1644 #
1645 if arg < 1.0:
1646 ulp_tol = 10
1647 elif arg < 10.0:
1648 ulp_tol = 100
1649 else:
1650 ulp_tol = 1000
1651
1652 failure = result_check(expected, got, ulp_tol, abs_tol)
1653 if failure is None:
1654 continue
1655
1656 msg = fail_fmt.format(id, fn, arg, failure)
1657 failures.append(msg)
Mark Dickinson12c4bdb2009-09-28 19:21:11 +00001658
1659 if failures:
1660 self.fail('Failures in test_mtestfile:\n ' +
1661 '\n '.join(failures))
1662
Pablo Galindo04114112019-03-09 19:18:08 +00001663 def test_prod(self):
1664 prod = math.prod
1665 self.assertEqual(prod([]), 1)
1666 self.assertEqual(prod([], start=5), 5)
1667 self.assertEqual(prod(list(range(2,8))), 5040)
1668 self.assertEqual(prod(iter(list(range(2,8)))), 5040)
1669 self.assertEqual(prod(range(1, 10), start=10), 3628800)
1670
1671 self.assertEqual(prod([1, 2, 3, 4, 5]), 120)
1672 self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0)
1673 self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0)
1674 self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0)
1675
1676 # Test overflow in fast-path for integers
1677 self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32)
1678 # Test overflow in fast-path for floats
1679 self.assertEqual(prod([1.0, 1.0, 2**32, 1, 1]), float(2**32))
1680
1681 self.assertRaises(TypeError, prod)
1682 self.assertRaises(TypeError, prod, 42)
1683 self.assertRaises(TypeError, prod, ['a', 'b', 'c'])
1684 self.assertRaises(TypeError, prod, ['a', 'b', 'c'], '')
1685 self.assertRaises(TypeError, prod, [b'a', b'c'], b'')
1686 values = [bytearray(b'a'), bytearray(b'b')]
1687 self.assertRaises(TypeError, prod, values, bytearray(b''))
1688 self.assertRaises(TypeError, prod, [[1], [2], [3]])
1689 self.assertRaises(TypeError, prod, [{2:3}])
1690 self.assertRaises(TypeError, prod, [{2:3}]*2, {2:3})
1691 self.assertRaises(TypeError, prod, [[1], [2], [3]], [])
1692 with self.assertRaises(TypeError):
1693 prod([10, 20], [30, 40]) # start is a keyword-only argument
1694
1695 self.assertEqual(prod([0, 1, 2, 3]), 0)
1696 self.assertEqual(prod([1, 0, 2, 3]), 0)
1697 self.assertEqual(prod([1, 2, 3, 0]), 0)
1698
1699 def _naive_prod(iterable, start=1):
1700 for elem in iterable:
1701 start *= elem
1702 return start
1703
1704 # Big integers
1705
1706 iterable = range(1, 10000)
1707 self.assertEqual(prod(iterable), _naive_prod(iterable))
1708 iterable = range(-10000, -1)
1709 self.assertEqual(prod(iterable), _naive_prod(iterable))
1710 iterable = range(-1000, 1000)
1711 self.assertEqual(prod(iterable), 0)
1712
1713 # Big floats
1714
1715 iterable = [float(x) for x in range(1, 1000)]
1716 self.assertEqual(prod(iterable), _naive_prod(iterable))
1717 iterable = [float(x) for x in range(-1000, -1)]
1718 self.assertEqual(prod(iterable), _naive_prod(iterable))
1719 iterable = [float(x) for x in range(-1000, 1000)]
1720 self.assertIsNaN(prod(iterable))
1721
1722 # Float tests
1723
1724 self.assertIsNaN(prod([1, 2, 3, float("nan"), 2, 3]))
1725 self.assertIsNaN(prod([1, 0, float("nan"), 2, 3]))
1726 self.assertIsNaN(prod([1, float("nan"), 0, 3]))
1727 self.assertIsNaN(prod([1, float("inf"), float("nan"),3]))
1728 self.assertIsNaN(prod([1, float("-inf"), float("nan"),3]))
1729 self.assertIsNaN(prod([1, float("nan"), float("inf"),3]))
1730 self.assertIsNaN(prod([1, float("nan"), float("-inf"),3]))
1731
1732 self.assertEqual(prod([1, 2, 3, float('inf'),-3,4]), float('-inf'))
1733 self.assertEqual(prod([1, 2, 3, float('-inf'),-3,4]), float('inf'))
1734
1735 self.assertIsNaN(prod([1,2,0,float('inf'), -3, 4]))
1736 self.assertIsNaN(prod([1,2,0,float('-inf'), -3, 4]))
1737 self.assertIsNaN(prod([1, 2, 3, float('inf'), -3, 0, 3]))
1738 self.assertIsNaN(prod([1, 2, 3, float('-inf'), -3, 0, 2]))
1739
1740 # Type preservation
1741
1742 self.assertEqual(type(prod([1, 2, 3, 4, 5, 6])), int)
1743 self.assertEqual(type(prod([1, 2.0, 3, 4, 5, 6])), float)
1744 self.assertEqual(type(prod(range(1, 10000))), int)
1745 self.assertEqual(type(prod(range(1, 10000), start=1.0)), float)
1746 self.assertEqual(type(prod([1, decimal.Decimal(2.0), 3, 4, 5, 6])),
1747 decimal.Decimal)
1748
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001749 def testPerm(self):
1750 perm = math.perm
1751 factorial = math.factorial
Min ho Kim96e12d52019-07-22 06:12:33 +10001752 # Test if factorial definition is satisfied
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001753 for n in range(100):
1754 for k in range(n + 1):
1755 self.assertEqual(perm(n, k),
1756 factorial(n) // factorial(n - k))
1757
1758 # Test for Pascal's identity
1759 for n in range(1, 100):
1760 for k in range(1, n):
1761 self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k))
1762
1763 # Test corner cases
1764 for n in range(1, 100):
1765 self.assertEqual(perm(n, 0), 1)
1766 self.assertEqual(perm(n, 1), n)
1767 self.assertEqual(perm(n, n), factorial(n))
1768
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001769 # Test one argument form
1770 for n in range(20):
1771 self.assertEqual(perm(n), factorial(n))
1772 self.assertEqual(perm(n, None), factorial(n))
1773
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001774 # Raises TypeError if any argument is non-integer or argument count is
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001775 # not 1 or 2
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001776 self.assertRaises(TypeError, perm, 10, 1.0)
1777 self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
1778 self.assertRaises(TypeError, perm, 10, "1")
1779 self.assertRaises(TypeError, perm, 10.0, 1)
1780 self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
1781 self.assertRaises(TypeError, perm, "10", 1)
1782
Raymond Hettingere119b3d2019-06-08 08:58:11 -07001783 self.assertRaises(TypeError, perm)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001784 self.assertRaises(TypeError, perm, 10, 1, 3)
1785 self.assertRaises(TypeError, perm)
1786
1787 # Raises Value error if not k or n are negative numbers
1788 self.assertRaises(ValueError, perm, -1, 1)
1789 self.assertRaises(ValueError, perm, -2**1000, 1)
1790 self.assertRaises(ValueError, perm, 1, -1)
1791 self.assertRaises(ValueError, perm, 1, -2**1000)
1792
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07001793 # Returns zero if k is greater than n
1794 self.assertEqual(perm(1, 2), 0)
1795 self.assertEqual(perm(1, 2**1000), 0)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001796
1797 n = 2**1000
1798 self.assertEqual(perm(n, 0), 1)
1799 self.assertEqual(perm(n, 1), n)
1800 self.assertEqual(perm(n, 2), n * (n-1))
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +03001801 if support.check_impl_detail(cpython=True):
1802 self.assertRaises(OverflowError, perm, n, n)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001803
1804 for n, k in (True, True), (True, False), (False, False):
1805 self.assertEqual(perm(n, k), 1)
1806 self.assertIs(type(perm(n, k)), int)
1807 self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20)
1808 self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20)
1809 for k in range(3):
1810 self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int)
1811 self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int)
1812
Yash Aggarwal4a686502019-06-01 12:51:27 +05301813 def testComb(self):
1814 comb = math.comb
1815 factorial = math.factorial
Min ho Kim96e12d52019-07-22 06:12:33 +10001816 # Test if factorial definition is satisfied
Yash Aggarwal4a686502019-06-01 12:51:27 +05301817 for n in range(100):
1818 for k in range(n + 1):
1819 self.assertEqual(comb(n, k), factorial(n)
1820 // (factorial(k) * factorial(n - k)))
1821
1822 # Test for Pascal's identity
1823 for n in range(1, 100):
1824 for k in range(1, n):
1825 self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k))
1826
1827 # Test corner cases
1828 for n in range(100):
1829 self.assertEqual(comb(n, 0), 1)
1830 self.assertEqual(comb(n, n), 1)
1831
1832 for n in range(1, 100):
1833 self.assertEqual(comb(n, 1), n)
1834 self.assertEqual(comb(n, n - 1), n)
1835
1836 # Test Symmetry
1837 for n in range(100):
1838 for k in range(n // 2):
1839 self.assertEqual(comb(n, k), comb(n, n - k))
1840
1841 # Raises TypeError if any argument is non-integer or argument count is
1842 # not 2
1843 self.assertRaises(TypeError, comb, 10, 1.0)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001844 self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0))
Yash Aggarwal4a686502019-06-01 12:51:27 +05301845 self.assertRaises(TypeError, comb, 10, "1")
Yash Aggarwal4a686502019-06-01 12:51:27 +05301846 self.assertRaises(TypeError, comb, 10.0, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001847 self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1)
1848 self.assertRaises(TypeError, comb, "10", 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301849
1850 self.assertRaises(TypeError, comb, 10)
1851 self.assertRaises(TypeError, comb, 10, 1, 3)
1852 self.assertRaises(TypeError, comb)
1853
1854 # Raises Value error if not k or n are negative numbers
1855 self.assertRaises(ValueError, comb, -1, 1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001856 self.assertRaises(ValueError, comb, -2**1000, 1)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301857 self.assertRaises(ValueError, comb, 1, -1)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001858 self.assertRaises(ValueError, comb, 1, -2**1000)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301859
Raymond Hettinger963eb0f2019-06-04 01:23:06 -07001860 # Returns zero if k is greater than n
1861 self.assertEqual(comb(1, 2), 0)
1862 self.assertEqual(comb(1, 2**1000), 0)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301863
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001864 n = 2**1000
1865 self.assertEqual(comb(n, 0), 1)
1866 self.assertEqual(comb(n, 1), n)
1867 self.assertEqual(comb(n, 2), n * (n-1) // 2)
1868 self.assertEqual(comb(n, n), 1)
1869 self.assertEqual(comb(n, n-1), n)
1870 self.assertEqual(comb(n, n-2), n * (n-1) // 2)
Serhiy Storchaka1b8a46d2019-06-17 16:58:32 +03001871 if support.check_impl_detail(cpython=True):
1872 self.assertRaises(OverflowError, comb, n, n//2)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301873
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001874 for n, k in (True, True), (True, False), (False, False):
1875 self.assertEqual(comb(n, k), 1)
1876 self.assertIs(type(comb(n, k)), int)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001877 self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10)
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +03001878 self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10)
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +03001879 for k in range(3):
1880 self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int)
1881 self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int)
Yash Aggarwal4a686502019-06-01 12:51:27 +05301882
Victor Stinner59e2d262020-01-21 12:48:16 +01001883 @requires_IEEE_754
1884 def test_nextafter(self):
1885 # around 2^52 and 2^63
1886 self.assertEqual(math.nextafter(4503599627370496.0, -INF),
1887 4503599627370495.5)
1888 self.assertEqual(math.nextafter(4503599627370496.0, INF),
1889 4503599627370497.0)
1890 self.assertEqual(math.nextafter(9223372036854775808.0, 0.0),
1891 9223372036854774784.0)
1892 self.assertEqual(math.nextafter(-9223372036854775808.0, 0.0),
1893 -9223372036854774784.0)
1894
1895 # around 1.0
1896 self.assertEqual(math.nextafter(1.0, -INF),
1897 float.fromhex('0x1.fffffffffffffp-1'))
1898 self.assertEqual(math.nextafter(1.0, INF),
1899 float.fromhex('0x1.0000000000001p+0'))
1900
1901 # x == y: y is returned
1902 self.assertEqual(math.nextafter(2.0, 2.0), 2.0)
1903 self.assertEqualSign(math.nextafter(-0.0, +0.0), +0.0)
1904 self.assertEqualSign(math.nextafter(+0.0, -0.0), -0.0)
1905
1906 # around 0.0
1907 smallest_subnormal = sys.float_info.min * sys.float_info.epsilon
1908 self.assertEqual(math.nextafter(+0.0, INF), smallest_subnormal)
1909 self.assertEqual(math.nextafter(-0.0, INF), smallest_subnormal)
1910 self.assertEqual(math.nextafter(+0.0, -INF), -smallest_subnormal)
1911 self.assertEqual(math.nextafter(-0.0, -INF), -smallest_subnormal)
1912 self.assertEqualSign(math.nextafter(smallest_subnormal, +0.0), +0.0)
1913 self.assertEqualSign(math.nextafter(-smallest_subnormal, +0.0), -0.0)
1914 self.assertEqualSign(math.nextafter(smallest_subnormal, -0.0), +0.0)
1915 self.assertEqualSign(math.nextafter(-smallest_subnormal, -0.0), -0.0)
1916
1917 # around infinity
1918 largest_normal = sys.float_info.max
1919 self.assertEqual(math.nextafter(INF, 0.0), largest_normal)
1920 self.assertEqual(math.nextafter(-INF, 0.0), -largest_normal)
1921 self.assertEqual(math.nextafter(largest_normal, INF), INF)
1922 self.assertEqual(math.nextafter(-largest_normal, -INF), -INF)
1923
1924 # NaN
1925 self.assertIsNaN(math.nextafter(NAN, 1.0))
1926 self.assertIsNaN(math.nextafter(1.0, NAN))
1927 self.assertIsNaN(math.nextafter(NAN, NAN))
1928
1929 @requires_IEEE_754
1930 def test_ulp(self):
1931 self.assertEqual(math.ulp(1.0), sys.float_info.epsilon)
1932 # use int ** int rather than float ** int to not rely on pow() accuracy
1933 self.assertEqual(math.ulp(2 ** 52), 1.0)
1934 self.assertEqual(math.ulp(2 ** 53), 2.0)
1935 self.assertEqual(math.ulp(2 ** 64), 4096.0)
1936
1937 # min and max
1938 self.assertEqual(math.ulp(0.0),
1939 sys.float_info.min * sys.float_info.epsilon)
1940 self.assertEqual(math.ulp(FLOAT_MAX),
1941 FLOAT_MAX - math.nextafter(FLOAT_MAX, -INF))
1942
1943 # special cases
1944 self.assertEqual(math.ulp(INF), INF)
1945 self.assertIsNaN(math.ulp(math.nan))
1946
1947 # negative number: ulp(-x) == ulp(x)
1948 for x in (0.0, 1.0, 2 ** 52, 2 ** 64, INF):
1949 with self.subTest(x=x):
1950 self.assertEqual(math.ulp(-x), math.ulp(x))
1951
1952 # Custom assertions.
1953
1954 def assertIsNaN(self, value):
1955 if not math.isnan(value):
1956 self.fail("Expected a NaN, got {!r}.".format(value))
1957
1958 def assertEqualSign(self, x, y):
1959 """Similar to assertEqual(), but compare also the sign with copysign().
1960
1961 Function useful to compare signed zeros.
1962 """
1963 self.assertEqual(x, y)
1964 self.assertEqual(math.copysign(1.0, x), math.copysign(1.0, y))
1965
1966
1967class IsCloseTests(unittest.TestCase):
1968 isclose = math.isclose # subclasses should override this
1969
1970 def assertIsClose(self, a, b, *args, **kwargs):
1971 self.assertTrue(self.isclose(a, b, *args, **kwargs),
1972 msg="%s and %s should be close!" % (a, b))
1973
1974 def assertIsNotClose(self, a, b, *args, **kwargs):
1975 self.assertFalse(self.isclose(a, b, *args, **kwargs),
1976 msg="%s and %s should not be close!" % (a, b))
1977
1978 def assertAllClose(self, examples, *args, **kwargs):
1979 for a, b in examples:
1980 self.assertIsClose(a, b, *args, **kwargs)
1981
1982 def assertAllNotClose(self, examples, *args, **kwargs):
1983 for a, b in examples:
1984 self.assertIsNotClose(a, b, *args, **kwargs)
1985
1986 def test_negative_tolerances(self):
1987 # ValueError should be raised if either tolerance is less than zero
1988 with self.assertRaises(ValueError):
1989 self.assertIsClose(1, 1, rel_tol=-1e-100)
1990 with self.assertRaises(ValueError):
1991 self.assertIsClose(1, 1, rel_tol=1e-100, abs_tol=-1e10)
1992
1993 def test_identical(self):
1994 # identical values must test as close
1995 identical_examples = [(2.0, 2.0),
1996 (0.1e200, 0.1e200),
1997 (1.123e-300, 1.123e-300),
1998 (12345, 12345.0),
1999 (0.0, -0.0),
2000 (345678, 345678)]
2001 self.assertAllClose(identical_examples, rel_tol=0.0, abs_tol=0.0)
2002
2003 def test_eight_decimal_places(self):
2004 # examples that are close to 1e-8, but not 1e-9
2005 eight_decimal_places_examples = [(1e8, 1e8 + 1),
2006 (-1e-8, -1.000000009e-8),
2007 (1.12345678, 1.12345679)]
2008 self.assertAllClose(eight_decimal_places_examples, rel_tol=1e-8)
2009 self.assertAllNotClose(eight_decimal_places_examples, rel_tol=1e-9)
2010
2011 def test_near_zero(self):
2012 # values close to zero
2013 near_zero_examples = [(1e-9, 0.0),
2014 (-1e-9, 0.0),
2015 (-1e-150, 0.0)]
2016 # these should not be close to any rel_tol
2017 self.assertAllNotClose(near_zero_examples, rel_tol=0.9)
2018 # these should be close to abs_tol=1e-8
2019 self.assertAllClose(near_zero_examples, abs_tol=1e-8)
2020
2021 def test_identical_infinite(self):
2022 # these are close regardless of tolerance -- i.e. they are equal
2023 self.assertIsClose(INF, INF)
2024 self.assertIsClose(INF, INF, abs_tol=0.0)
2025 self.assertIsClose(NINF, NINF)
2026 self.assertIsClose(NINF, NINF, abs_tol=0.0)
2027
2028 def test_inf_ninf_nan(self):
2029 # these should never be close (following IEEE 754 rules for equality)
2030 not_close_examples = [(NAN, NAN),
2031 (NAN, 1e-100),
2032 (1e-100, NAN),
2033 (INF, NAN),
2034 (NAN, INF),
2035 (INF, NINF),
2036 (INF, 1.0),
2037 (1.0, INF),
2038 (INF, 1e308),
2039 (1e308, INF)]
2040 # use largest reasonable tolerance
2041 self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999)
2042
2043 def test_zero_tolerance(self):
2044 # test with zero tolerance
2045 zero_tolerance_close_examples = [(1.0, 1.0),
2046 (-3.4, -3.4),
2047 (-1e-300, -1e-300)]
2048 self.assertAllClose(zero_tolerance_close_examples, rel_tol=0.0)
2049
2050 zero_tolerance_not_close_examples = [(1.0, 1.000000000000001),
2051 (0.99999999999999, 1.0),
2052 (1.0e200, .999999999999999e200)]
2053 self.assertAllNotClose(zero_tolerance_not_close_examples, rel_tol=0.0)
2054
2055 def test_asymmetry(self):
2056 # test the asymmetry example from PEP 485
2057 self.assertAllClose([(9, 10), (10, 9)], rel_tol=0.1)
2058
2059 def test_integers(self):
2060 # test with integer values
2061 integer_examples = [(100000001, 100000000),
2062 (123456789, 123456788)]
2063
2064 self.assertAllClose(integer_examples, rel_tol=1e-8)
2065 self.assertAllNotClose(integer_examples, rel_tol=1e-9)
2066
2067 def test_decimals(self):
2068 # test with Decimal values
2069 from decimal import Decimal
2070
2071 decimal_examples = [(Decimal('1.00000001'), Decimal('1.0')),
2072 (Decimal('1.00000001e-20'), Decimal('1.0e-20')),
2073 (Decimal('1.00000001e-100'), Decimal('1.0e-100')),
2074 (Decimal('1.00000001e20'), Decimal('1.0e20'))]
2075 self.assertAllClose(decimal_examples, rel_tol=1e-8)
2076 self.assertAllNotClose(decimal_examples, rel_tol=1e-9)
2077
2078 def test_fractions(self):
2079 # test with Fraction values
2080 from fractions import Fraction
2081
2082 fraction_examples = [
2083 (Fraction(1, 100000000) + 1, Fraction(1)),
2084 (Fraction(100000001), Fraction(100000000)),
2085 (Fraction(10**8 + 1, 10**28), Fraction(1, 10**20))]
2086 self.assertAllClose(fraction_examples, rel_tol=1e-8)
2087 self.assertAllNotClose(fraction_examples, rel_tol=1e-9)
2088
Pablo Galindo42079072019-02-10 19:56:58 +00002089
Thomas Wouters89f507f2006-12-13 04:49:30 +00002090def test_main():
Christian Heimes53876d92008-04-19 00:31:39 +00002091 from doctest import DocFileSuite
2092 suite = unittest.TestSuite()
2093 suite.addTest(unittest.makeSuite(MathTests))
Tal Einatd5519ed2015-05-31 22:05:00 +03002094 suite.addTest(unittest.makeSuite(IsCloseTests))
Christian Heimes53876d92008-04-19 00:31:39 +00002095 suite.addTest(DocFileSuite("ieee754.txt"))
2096 run_unittest(suite)
Thomas Wouters89f507f2006-12-13 04:49:30 +00002097
2098if __name__ == '__main__':
2099 test_main()