1# Python test set -- math module 2# XXXX Should not do tests around zero only 3 4from test.support import verbose, requires_IEEE_754 5from test import support 6import unittest 7import itertools 8import decimal 9import math 10import os 11import platform 12import random 13import struct 14import sys 15 16 17eps = 1E-05 18NAN = float('nan') 19INF = float('inf') 20NINF = float('-inf') 21FLOAT_MAX = sys.float_info.max 22FLOAT_MIN = sys.float_info.min 23 24# 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 29# 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 35math_testcases = os.path.join(test_dir, 'math_testcases.txt') 36test_file = os.path.join(test_dir, 'cmath_testcases.txt') 37 38 39def 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 46 where native doubles are represented in IEEE 754 binary64 format. 47 48 Note: 0.0 and -0.0 are converted to 0 and -1, respectively. 49 """ 50 n = struct.unpack('<q', struct.pack('<d', x))[0] 51 if n < 0: 52 n = ~(n+2**63) 53 return n 54 55 56# 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 106def 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. 110 111 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: 118 return None 119 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) 123 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, encoding="utf-8") 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 149 150def 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, encoding="utf-8") 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), 171 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 218 219class FloatLike: 220 def __init__(self, value): 221 self.value = value 222 223 def __float__(self): 224 return self.value 225 226class IntSubclass(int): 227 pass 228 229# 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 237class MathTests(unittest.TestCase): 238 239 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)) 251 252 def testConstants(self): 253 # Ref: Abramowitz & Stegun (Dover, 1965) 254 self.ftest('pi', math.pi, 3.141592653589793238462643) 255 self.ftest('e', math.e, 2.718281828459045235360287) 256 self.assertEqual(math.tau, 2*math.pi) 257 258 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) 263 self.assertRaises(ValueError, math.acos, INF) 264 self.assertRaises(ValueError, math.acos, NINF) 265 self.assertRaises(ValueError, math.acos, 1 + eps) 266 self.assertRaises(ValueError, math.acos, -1 - eps) 267 self.assertTrue(math.isnan(math.acos(NAN))) 268 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) 275 self.assertEqual(math.acosh(INF), INF) 276 self.assertRaises(ValueError, math.acosh, NINF) 277 self.assertTrue(math.isnan(math.acosh(NAN))) 278 279 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) 284 self.assertRaises(ValueError, math.asin, INF) 285 self.assertRaises(ValueError, math.asin, NINF) 286 self.assertRaises(ValueError, math.asin, 1 + eps) 287 self.assertRaises(ValueError, math.asin, -1 - eps) 288 self.assertTrue(math.isnan(math.asin(NAN))) 289 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) 295 self.assertEqual(math.asinh(INF), INF) 296 self.assertEqual(math.asinh(NINF), NINF) 297 self.assertTrue(math.isnan(math.asinh(NAN))) 298 299 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) 304 self.ftest('atan(inf)', math.atan(INF), math.pi/2) 305 self.ftest('atan(-inf)', math.atan(NINF), -math.pi/2) 306 self.assertTrue(math.isnan(math.atan(NAN))) 307 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) 317 self.assertTrue(math.isnan(math.atanh(NAN))) 318 319 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) 326 327 # 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.) 334 self.assertTrue(math.isnan(math.atan2(0., NAN))) 335 # 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.) 342 self.assertTrue(math.isnan(math.atan2(-0., NAN))) 343 # 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) 350 self.assertTrue(math.isnan(math.atan2(INF, NAN))) 351 # 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) 358 self.assertTrue(math.isnan(math.atan2(NINF, NAN))) 359 # 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.) 364 self.assertTrue(math.isnan(math.atan2(2.3, NAN))) 365 # 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.) 370 self.assertTrue(math.isnan(math.atan2(-2.3, NAN))) 371 # math.atan2(NAN, x) 372 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))) 379 380 def testCbrt(self): 381 self.assertRaises(TypeError, math.cbrt) 382 self.ftest('cbrt(0)', math.cbrt(0), 0) 383 self.ftest('cbrt(1)', math.cbrt(1), 1) 384 self.ftest('cbrt(8)', math.cbrt(8), 2) 385 self.ftest('cbrt(0.0)', math.cbrt(0.0), 0.0) 386 self.ftest('cbrt(-0.0)', math.cbrt(-0.0), -0.0) 387 self.ftest('cbrt(1.2)', math.cbrt(1.2), 1.062658569182611) 388 self.ftest('cbrt(-2.6)', math.cbrt(-2.6), -1.375068867074141) 389 self.ftest('cbrt(27)', math.cbrt(27), 3) 390 self.ftest('cbrt(-1)', math.cbrt(-1), -1) 391 self.ftest('cbrt(-27)', math.cbrt(-27), -3) 392 self.assertEqual(math.cbrt(INF), INF) 393 self.assertEqual(math.cbrt(NINF), NINF) 394 self.assertTrue(math.isnan(math.cbrt(NAN))) 395 396 def testCeil(self): 397 self.assertRaises(TypeError, math.ceil) 398 self.assertEqual(int, type(math.ceil(0.5))) 399 self.assertEqual(math.ceil(0.5), 1) 400 self.assertEqual(math.ceil(1.0), 1) 401 self.assertEqual(math.ceil(1.5), 2) 402 self.assertEqual(math.ceil(-0.5), 0) 403 self.assertEqual(math.ceil(-1.0), -1) 404 self.assertEqual(math.ceil(-1.5), -1) 405 self.assertEqual(math.ceil(0.0), 0) 406 self.assertEqual(math.ceil(-0.0), 0) 407 #self.assertEqual(math.ceil(INF), INF) 408 #self.assertEqual(math.ceil(NINF), NINF) 409 #self.assertTrue(math.isnan(math.ceil(NAN))) 410 411 class TestCeil: 412 def __ceil__(self): 413 return 42 414 class FloatCeil(float): 415 def __ceil__(self): 416 return 42 417 class TestNoCeil: 418 pass 419 self.assertEqual(math.ceil(TestCeil()), 42) 420 self.assertEqual(math.ceil(FloatCeil()), 42) 421 self.assertEqual(math.ceil(FloatLike(42.5)), 43) 422 self.assertRaises(TypeError, math.ceil, TestNoCeil()) 423 424 t = TestNoCeil() 425 t.__ceil__ = lambda *args: args 426 self.assertRaises(TypeError, math.ceil, t) 427 self.assertRaises(TypeError, math.ceil, t, 0) 428 429 @requires_IEEE_754 430 def testCopysign(self): 431 self.assertEqual(math.copysign(1, 42), 1.0) 432 self.assertEqual(math.copysign(0., 42), 0.0) 433 self.assertEqual(math.copysign(1., -42), -1.0) 434 self.assertEqual(math.copysign(3, 0.), 3.0) 435 self.assertEqual(math.copysign(4., -0.), -4.0) 436 437 self.assertRaises(TypeError, math.copysign) 438 # copysign should let us distinguish signs of zeros 439 self.assertEqual(math.copysign(1., 0.), 1.) 440 self.assertEqual(math.copysign(1., -0.), -1.) 441 self.assertEqual(math.copysign(INF, 0.), INF) 442 self.assertEqual(math.copysign(INF, -0.), NINF) 443 self.assertEqual(math.copysign(NINF, 0.), INF) 444 self.assertEqual(math.copysign(NINF, -0.), NINF) 445 # and of infinities 446 self.assertEqual(math.copysign(1., INF), 1.) 447 self.assertEqual(math.copysign(1., NINF), -1.) 448 self.assertEqual(math.copysign(INF, INF), INF) 449 self.assertEqual(math.copysign(INF, NINF), NINF) 450 self.assertEqual(math.copysign(NINF, INF), INF) 451 self.assertEqual(math.copysign(NINF, NINF), NINF) 452 self.assertTrue(math.isnan(math.copysign(NAN, 1.))) 453 self.assertTrue(math.isnan(math.copysign(NAN, INF))) 454 self.assertTrue(math.isnan(math.copysign(NAN, NINF))) 455 self.assertTrue(math.isnan(math.copysign(NAN, NAN))) 456 # copysign(INF, NAN) may be INF or it may be NINF, since 457 # we don't know whether the sign bit of NAN is set on any 458 # given platform. 459 self.assertTrue(math.isinf(math.copysign(INF, NAN))) 460 # similarly, copysign(2., NAN) could be 2. or -2. 461 self.assertEqual(abs(math.copysign(2., NAN)), 2.) 462 463 def testCos(self): 464 self.assertRaises(TypeError, math.cos) 465 self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0, abs_tol=math.ulp(1)) 466 self.ftest('cos(0)', math.cos(0), 1) 467 self.ftest('cos(pi/2)', math.cos(math.pi/2), 0, abs_tol=math.ulp(1)) 468 self.ftest('cos(pi)', math.cos(math.pi), -1) 469 try: 470 self.assertTrue(math.isnan(math.cos(INF))) 471 self.assertTrue(math.isnan(math.cos(NINF))) 472 except ValueError: 473 self.assertRaises(ValueError, math.cos, INF) 474 self.assertRaises(ValueError, math.cos, NINF) 475 self.assertTrue(math.isnan(math.cos(NAN))) 476 477 @unittest.skipIf(sys.platform == 'win32' and platform.machine() in ('ARM', 'ARM64'), 478 "Windows UCRT is off by 2 ULP this test requires accuracy within 1 ULP") 479 def testCosh(self): 480 self.assertRaises(TypeError, math.cosh) 481 self.ftest('cosh(0)', math.cosh(0), 1) 482 self.ftest('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert 483 self.assertEqual(math.cosh(INF), INF) 484 self.assertEqual(math.cosh(NINF), INF) 485 self.assertTrue(math.isnan(math.cosh(NAN))) 486 487 def testDegrees(self): 488 self.assertRaises(TypeError, math.degrees) 489 self.ftest('degrees(pi)', math.degrees(math.pi), 180.0) 490 self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0) 491 self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0) 492 self.ftest('degrees(0)', math.degrees(0), 0) 493 494 def testExp(self): 495 self.assertRaises(TypeError, math.exp) 496 self.ftest('exp(-1)', math.exp(-1), 1/math.e) 497 self.ftest('exp(0)', math.exp(0), 1) 498 self.ftest('exp(1)', math.exp(1), math.e) 499 self.assertEqual(math.exp(INF), INF) 500 self.assertEqual(math.exp(NINF), 0.) 501 self.assertTrue(math.isnan(math.exp(NAN))) 502 self.assertRaises(OverflowError, math.exp, 1000000) 503 504 def testExp2(self): 505 self.assertRaises(TypeError, math.exp2) 506 self.ftest('exp2(-1)', math.exp2(-1), 0.5) 507 self.ftest('exp2(0)', math.exp2(0), 1) 508 self.ftest('exp2(1)', math.exp2(1), 2) 509 self.ftest('exp2(2.3)', math.exp2(2.3), 4.924577653379665) 510 self.assertEqual(math.exp2(INF), INF) 511 self.assertEqual(math.exp2(NINF), 0.) 512 self.assertTrue(math.isnan(math.exp2(NAN))) 513 self.assertRaises(OverflowError, math.exp2, 1000000) 514 515 def testFabs(self): 516 self.assertRaises(TypeError, math.fabs) 517 self.ftest('fabs(-1)', math.fabs(-1), 1) 518 self.ftest('fabs(0)', math.fabs(0), 0) 519 self.ftest('fabs(1)', math.fabs(1), 1) 520 521 def testFactorial(self): 522 self.assertEqual(math.factorial(0), 1) 523 total = 1 524 for i in range(1, 1000): 525 total *= i 526 self.assertEqual(math.factorial(i), total) 527 self.assertEqual(math.factorial(i), py_factorial(i)) 528 self.assertRaises(ValueError, math.factorial, -1) 529 self.assertRaises(ValueError, math.factorial, -10**100) 530 531 def testFactorialNonIntegers(self): 532 self.assertRaises(TypeError, math.factorial, 5.0) 533 self.assertRaises(TypeError, math.factorial, 5.2) 534 self.assertRaises(TypeError, math.factorial, -1.0) 535 self.assertRaises(TypeError, math.factorial, -1e100) 536 self.assertRaises(TypeError, math.factorial, decimal.Decimal('5')) 537 self.assertRaises(TypeError, math.factorial, decimal.Decimal('5.2')) 538 self.assertRaises(TypeError, math.factorial, "5") 539 540 # Other implementations may place different upper bounds. 541 @support.cpython_only 542 def testFactorialHugeInputs(self): 543 # Currently raises OverflowError for inputs that are too large 544 # to fit into a C long. 545 self.assertRaises(OverflowError, math.factorial, 10**100) 546 self.assertRaises(TypeError, math.factorial, 1e100) 547 548 def testFloor(self): 549 self.assertRaises(TypeError, math.floor) 550 self.assertEqual(int, type(math.floor(0.5))) 551 self.assertEqual(math.floor(0.5), 0) 552 self.assertEqual(math.floor(1.0), 1) 553 self.assertEqual(math.floor(1.5), 1) 554 self.assertEqual(math.floor(-0.5), -1) 555 self.assertEqual(math.floor(-1.0), -1) 556 self.assertEqual(math.floor(-1.5), -2) 557 #self.assertEqual(math.ceil(INF), INF) 558 #self.assertEqual(math.ceil(NINF), NINF) 559 #self.assertTrue(math.isnan(math.floor(NAN))) 560 561 class TestFloor: 562 def __floor__(self): 563 return 42 564 class FloatFloor(float): 565 def __floor__(self): 566 return 42 567 class TestNoFloor: 568 pass 569 self.assertEqual(math.floor(TestFloor()), 42) 570 self.assertEqual(math.floor(FloatFloor()), 42) 571 self.assertEqual(math.floor(FloatLike(41.9)), 41) 572 self.assertRaises(TypeError, math.floor, TestNoFloor()) 573 574 t = TestNoFloor() 575 t.__floor__ = lambda *args: args 576 self.assertRaises(TypeError, math.floor, t) 577 self.assertRaises(TypeError, math.floor, t, 0) 578 579 def testFmod(self): 580 self.assertRaises(TypeError, math.fmod) 581 self.ftest('fmod(10, 1)', math.fmod(10, 1), 0.0) 582 self.ftest('fmod(10, 0.5)', math.fmod(10, 0.5), 0.0) 583 self.ftest('fmod(10, 1.5)', math.fmod(10, 1.5), 1.0) 584 self.ftest('fmod(-10, 1)', math.fmod(-10, 1), -0.0) 585 self.ftest('fmod(-10, 0.5)', math.fmod(-10, 0.5), -0.0) 586 self.ftest('fmod(-10, 1.5)', math.fmod(-10, 1.5), -1.0) 587 self.assertTrue(math.isnan(math.fmod(NAN, 1.))) 588 self.assertTrue(math.isnan(math.fmod(1., NAN))) 589 self.assertTrue(math.isnan(math.fmod(NAN, NAN))) 590 self.assertRaises(ValueError, math.fmod, 1., 0.) 591 self.assertRaises(ValueError, math.fmod, INF, 1.) 592 self.assertRaises(ValueError, math.fmod, NINF, 1.) 593 self.assertRaises(ValueError, math.fmod, INF, 0.) 594 self.assertEqual(math.fmod(3.0, INF), 3.0) 595 self.assertEqual(math.fmod(-3.0, INF), -3.0) 596 self.assertEqual(math.fmod(3.0, NINF), 3.0) 597 self.assertEqual(math.fmod(-3.0, NINF), -3.0) 598 self.assertEqual(math.fmod(0.0, 3.0), 0.0) 599 self.assertEqual(math.fmod(0.0, NINF), 0.0) 600 601 def testFrexp(self): 602 self.assertRaises(TypeError, math.frexp) 603 604 def testfrexp(name, result, expected): 605 (mant, exp), (emant, eexp) = result, expected 606 if abs(mant-emant) > eps or exp != eexp: 607 self.fail('%s returned %r, expected %r'%\ 608 (name, result, expected)) 609 610 testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1)) 611 testfrexp('frexp(0)', math.frexp(0), (0, 0)) 612 testfrexp('frexp(1)', math.frexp(1), (0.5, 1)) 613 testfrexp('frexp(2)', math.frexp(2), (0.5, 2)) 614 615 self.assertEqual(math.frexp(INF)[0], INF) 616 self.assertEqual(math.frexp(NINF)[0], NINF) 617 self.assertTrue(math.isnan(math.frexp(NAN)[0])) 618 619 @requires_IEEE_754 620 @unittest.skipIf(HAVE_DOUBLE_ROUNDING, 621 "fsum is not exact on machines with double rounding") 622 def testFsum(self): 623 # math.fsum relies on exact rounding for correct operation. 624 # There's a known problem with IA32 floating-point that causes 625 # inexact rounding in some situations, and will cause the 626 # math.fsum tests below to fail; see issue #2937. On non IEEE 627 # 754 platforms, and on IEEE 754 platforms that exhibit the 628 # problem described in issue #2937, we simply skip the whole 629 # test. 630 631 # Python version of math.fsum, for comparison. Uses a 632 # different algorithm based on frexp, ldexp and integer 633 # arithmetic. 634 from sys import float_info 635 mant_dig = float_info.mant_dig 636 etiny = float_info.min_exp - mant_dig 637 638 def msum(iterable): 639 """Full precision summation. Compute sum(iterable) without any 640 intermediate accumulation of error. Based on the 'lsum' function 641 at http://code.activestate.com/recipes/393090/ 642 643 """ 644 tmant, texp = 0, 0 645 for x in iterable: 646 mant, exp = math.frexp(x) 647 mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig 648 if texp > exp: 649 tmant <<= texp-exp 650 texp = exp 651 else: 652 mant <<= exp-texp 653 tmant += mant 654 # Round tmant * 2**texp to a float. The original recipe 655 # used float(str(tmant)) * 2.0**texp for this, but that's 656 # a little unsafe because str -> float conversion can't be 657 # relied upon to do correct rounding on all platforms. 658 tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp) 659 if tail > 0: 660 h = 1 << (tail-1) 661 tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1) 662 texp += tail 663 return math.ldexp(tmant, texp) 664 665 test_values = [ 666 ([], 0.0), 667 ([0.0], 0.0), 668 ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100), 669 ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0), 670 ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0), 671 ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0), 672 ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0), 673 ([1./n for n in range(1, 1001)], 674 float.fromhex('0x1.df11f45f4e61ap+2')), 675 ([(-1.)**n/n for n in range(1, 1001)], 676 float.fromhex('-0x1.62a2af1bd3624p-1')), 677 ([1e16, 1., 1e-16], 10000000000000002.0), 678 ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0), 679 # exercise code for resizing partials array 680 ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] + 681 [-2.**1022], 682 float.fromhex('0x1.5555555555555p+970')), 683 ] 684 685 # Telescoping sum, with exact differences (due to Sterbenz) 686 terms = [1.7**i for i in range(1001)] 687 test_values.append(( 688 [terms[i+1] - terms[i] for i in range(1000)] + [-terms[1000]], 689 -terms[0] 690 )) 691 692 for i, (vals, expected) in enumerate(test_values): 693 try: 694 actual = math.fsum(vals) 695 except OverflowError: 696 self.fail("test %d failed: got OverflowError, expected %r " 697 "for math.fsum(%.100r)" % (i, expected, vals)) 698 except ValueError: 699 self.fail("test %d failed: got ValueError, expected %r " 700 "for math.fsum(%.100r)" % (i, expected, vals)) 701 self.assertEqual(actual, expected) 702 703 from random import random, gauss, shuffle 704 for j in range(1000): 705 vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10 706 s = 0 707 for i in range(200): 708 v = gauss(0, random()) ** 7 - s 709 s += v 710 vals.append(v) 711 shuffle(vals) 712 713 s = msum(vals) 714 self.assertEqual(msum(vals), math.fsum(vals)) 715 716 def testGcd(self): 717 gcd = math.gcd 718 self.assertEqual(gcd(0, 0), 0) 719 self.assertEqual(gcd(1, 0), 1) 720 self.assertEqual(gcd(-1, 0), 1) 721 self.assertEqual(gcd(0, 1), 1) 722 self.assertEqual(gcd(0, -1), 1) 723 self.assertEqual(gcd(7, 1), 1) 724 self.assertEqual(gcd(7, -1), 1) 725 self.assertEqual(gcd(-23, 15), 1) 726 self.assertEqual(gcd(120, 84), 12) 727 self.assertEqual(gcd(84, -120), 12) 728 self.assertEqual(gcd(1216342683557601535506311712, 729 436522681849110124616458784), 32) 730 731 x = 434610456570399902378880679233098819019853229470286994367836600566 732 y = 1064502245825115327754847244914921553977 733 for c in (652560, 734 576559230871654959816130551884856912003141446781646602790216406874): 735 a = x * c 736 b = y * c 737 self.assertEqual(gcd(a, b), c) 738 self.assertEqual(gcd(b, a), c) 739 self.assertEqual(gcd(-a, b), c) 740 self.assertEqual(gcd(b, -a), c) 741 self.assertEqual(gcd(a, -b), c) 742 self.assertEqual(gcd(-b, a), c) 743 self.assertEqual(gcd(-a, -b), c) 744 self.assertEqual(gcd(-b, -a), c) 745 746 self.assertEqual(gcd(), 0) 747 self.assertEqual(gcd(120), 120) 748 self.assertEqual(gcd(-120), 120) 749 self.assertEqual(gcd(120, 84, 102), 6) 750 self.assertEqual(gcd(120, 1, 84), 1) 751 752 self.assertRaises(TypeError, gcd, 120.0) 753 self.assertRaises(TypeError, gcd, 120.0, 84) 754 self.assertRaises(TypeError, gcd, 120, 84.0) 755 self.assertRaises(TypeError, gcd, 120, 1, 84.0) 756 self.assertEqual(gcd(MyIndexable(120), MyIndexable(84)), 12) 757 758 def testHypot(self): 759 from decimal import Decimal 760 from fractions import Fraction 761 762 hypot = math.hypot 763 764 # Test different numbers of arguments (from zero to five) 765 # against a straightforward pure python implementation 766 args = math.e, math.pi, math.sqrt(2.0), math.gamma(3.5), math.sin(2.1) 767 for i in range(len(args)+1): 768 self.assertAlmostEqual( 769 hypot(*args[:i]), 770 math.sqrt(sum(s**2 for s in args[:i])) 771 ) 772 773 # Test allowable types (those with __float__) 774 self.assertEqual(hypot(12.0, 5.0), 13.0) 775 self.assertEqual(hypot(12, 5), 13) 776 self.assertEqual(hypot(Decimal(12), Decimal(5)), 13) 777 self.assertEqual(hypot(Fraction(12, 32), Fraction(5, 32)), Fraction(13, 32)) 778 self.assertEqual(hypot(bool(1), bool(0), bool(1), bool(1)), math.sqrt(3)) 779 780 # Test corner cases 781 self.assertEqual(hypot(0.0, 0.0), 0.0) # Max input is zero 782 self.assertEqual(hypot(-10.5), 10.5) # Negative input 783 self.assertEqual(hypot(), 0.0) # Negative input 784 self.assertEqual(1.0, 785 math.copysign(1.0, hypot(-0.0)) # Convert negative zero to positive zero 786 ) 787 self.assertEqual( # Handling of moving max to the end 788 hypot(1.5, 1.5, 0.5), 789 hypot(1.5, 0.5, 1.5), 790 ) 791 792 # Test handling of bad arguments 793 with self.assertRaises(TypeError): # Reject keyword args 794 hypot(x=1) 795 with self.assertRaises(TypeError): # Reject values without __float__ 796 hypot(1.1, 'string', 2.2) 797 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5) 798 with self.assertRaises((ValueError, OverflowError)): 799 hypot(1, int_too_big_for_float) 800 801 # Any infinity gives positive infinity. 802 self.assertEqual(hypot(INF), INF) 803 self.assertEqual(hypot(0, INF), INF) 804 self.assertEqual(hypot(10, INF), INF) 805 self.assertEqual(hypot(-10, INF), INF) 806 self.assertEqual(hypot(NAN, INF), INF) 807 self.assertEqual(hypot(INF, NAN), INF) 808 self.assertEqual(hypot(NINF, NAN), INF) 809 self.assertEqual(hypot(NAN, NINF), INF) 810 self.assertEqual(hypot(-INF, INF), INF) 811 self.assertEqual(hypot(-INF, -INF), INF) 812 self.assertEqual(hypot(10, -INF), INF) 813 814 # If no infinity, any NaN gives a NaN. 815 self.assertTrue(math.isnan(hypot(NAN))) 816 self.assertTrue(math.isnan(hypot(0, NAN))) 817 self.assertTrue(math.isnan(hypot(NAN, 10))) 818 self.assertTrue(math.isnan(hypot(10, NAN))) 819 self.assertTrue(math.isnan(hypot(NAN, NAN))) 820 self.assertTrue(math.isnan(hypot(NAN))) 821 822 # Verify scaling for extremely large values 823 fourthmax = FLOAT_MAX / 4.0 824 for n in range(32): 825 self.assertTrue(math.isclose(hypot(*([fourthmax]*n)), 826 fourthmax * math.sqrt(n))) 827 828 # Verify scaling for extremely small values 829 for exp in range(32): 830 scale = FLOAT_MIN / 2.0 ** exp 831 self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale) 832 833 @requires_IEEE_754 834 @unittest.skipIf(HAVE_DOUBLE_ROUNDING, 835 "hypot() loses accuracy on machines with double rounding") 836 def testHypotAccuracy(self): 837 # Verify improved accuracy in cases that were known to be inaccurate. 838 # 839 # The new algorithm's accuracy depends on IEEE 754 arithmetic 840 # guarantees, on having the usual ROUND HALF EVEN rounding mode, on 841 # the system not having double rounding due to extended precision, 842 # and on the compiler maintaining the specified order of operations. 843 # 844 # This test is known to succeed on most of our builds. If it fails 845 # some build, we either need to add another skipIf if the cause is 846 # identifiable; otherwise, we can remove this test entirely. 847 848 hypot = math.hypot 849 Decimal = decimal.Decimal 850 high_precision = decimal.Context(prec=500) 851 852 for hx, hy in [ 853 # Cases with a 1 ulp error in Python 3.7 compiled with Clang 854 ('0x1.10e89518dca48p+29', '0x1.1970f7565b7efp+30'), 855 ('0x1.10106eb4b44a2p+29', '0x1.ef0596cdc97f8p+29'), 856 ('0x1.459c058e20bb7p+30', '0x1.993ca009b9178p+29'), 857 ('0x1.378371ae67c0cp+30', '0x1.fbe6619854b4cp+29'), 858 ('0x1.f4cd0574fb97ap+29', '0x1.50fe31669340ep+30'), 859 ('0x1.494b2cdd3d446p+29', '0x1.212a5367b4c7cp+29'), 860 ('0x1.f84e649f1e46dp+29', '0x1.1fa56bef8eec4p+30'), 861 ('0x1.2e817edd3d6fap+30', '0x1.eb0814f1e9602p+29'), 862 ('0x1.0d3a6e3d04245p+29', '0x1.32a62fea52352p+30'), 863 ('0x1.888e19611bfc5p+29', '0x1.52b8e70b24353p+29'), 864 865 # Cases with 2 ulp error in Python 3.8 866 ('0x1.538816d48a13fp+29', '0x1.7967c5ca43e16p+29'), 867 ('0x1.57b47b7234530p+29', '0x1.74e2c7040e772p+29'), 868 ('0x1.821b685e9b168p+30', '0x1.677dc1c1e3dc6p+29'), 869 ('0x1.9e8247f67097bp+29', '0x1.24bd2dc4f4baep+29'), 870 ('0x1.b73b59e0cb5f9p+29', '0x1.da899ab784a97p+28'), 871 ('0x1.94a8d2842a7cfp+30', '0x1.326a51d4d8d8ap+30'), 872 ('0x1.e930b9cd99035p+29', '0x1.5a1030e18dff9p+30'), 873 ('0x1.1592bbb0e4690p+29', '0x1.a9c337b33fb9ap+29'), 874 ('0x1.1243a50751fd4p+29', '0x1.a5a10175622d9p+29'), 875 ('0x1.57a8596e74722p+30', '0x1.42d1af9d04da9p+30'), 876 877 # Cases with 1 ulp error in version fff3c28052e6b0 878 ('0x1.ee7dbd9565899p+29', '0x1.7ab4d6fc6e4b4p+29'), 879 ('0x1.5c6bfbec5c4dcp+30', '0x1.02511184b4970p+30'), 880 ('0x1.59dcebba995cap+30', '0x1.50ca7e7c38854p+29'), 881 ('0x1.768cdd94cf5aap+29', '0x1.9cfdc5571d38ep+29'), 882 ('0x1.dcf137d60262ep+29', '0x1.1101621990b3ep+30'), 883 ('0x1.3a2d006e288b0p+30', '0x1.e9a240914326cp+29'), 884 ('0x1.62a32f7f53c61p+29', '0x1.47eb6cd72684fp+29'), 885 ('0x1.d3bcb60748ef2p+29', '0x1.3f13c4056312cp+30'), 886 ('0x1.282bdb82f17f3p+30', '0x1.640ba4c4eed3ap+30'), 887 ('0x1.89d8c423ea0c6p+29', '0x1.d35dcfe902bc3p+29'), 888 ]: 889 x = float.fromhex(hx) 890 y = float.fromhex(hy) 891 with self.subTest(hx=hx, hy=hy, x=x, y=y): 892 with decimal.localcontext(high_precision): 893 z = float((Decimal(x)**2 + Decimal(y)**2).sqrt()) 894 self.assertEqual(hypot(x, y), z) 895 896 def testDist(self): 897 from decimal import Decimal as D 898 from fractions import Fraction as F 899 900 dist = math.dist 901 sqrt = math.sqrt 902 903 # Simple exact cases 904 self.assertEqual(dist((1.0, 2.0, 3.0), (4.0, 2.0, -1.0)), 5.0) 905 self.assertEqual(dist((1, 2, 3), (4, 2, -1)), 5.0) 906 907 # Test different numbers of arguments (from zero to nine) 908 # against a straightforward pure python implementation 909 for i in range(9): 910 for j in range(5): 911 p = tuple(random.uniform(-5, 5) for k in range(i)) 912 q = tuple(random.uniform(-5, 5) for k in range(i)) 913 self.assertAlmostEqual( 914 dist(p, q), 915 sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q))) 916 ) 917 918 # Test non-tuple inputs 919 self.assertEqual(dist([1.0, 2.0, 3.0], [4.0, 2.0, -1.0]), 5.0) 920 self.assertEqual(dist(iter([1.0, 2.0, 3.0]), iter([4.0, 2.0, -1.0])), 5.0) 921 922 # Test allowable types (those with __float__) 923 self.assertEqual(dist((14.0, 1.0), (2.0, -4.0)), 13.0) 924 self.assertEqual(dist((14, 1), (2, -4)), 13) 925 self.assertEqual(dist((D(14), D(1)), (D(2), D(-4))), D(13)) 926 self.assertEqual(dist((F(14, 32), F(1, 32)), (F(2, 32), F(-4, 32))), 927 F(13, 32)) 928 self.assertEqual(dist((True, True, False, True, False), 929 (True, False, True, True, False)), 930 sqrt(2.0)) 931 932 # Test corner cases 933 self.assertEqual(dist((13.25, 12.5, -3.25), 934 (13.25, 12.5, -3.25)), 935 0.0) # Distance with self is zero 936 self.assertEqual(dist((), ()), 0.0) # Zero-dimensional case 937 self.assertEqual(1.0, # Convert negative zero to positive zero 938 math.copysign(1.0, dist((-0.0,), (0.0,))) 939 ) 940 self.assertEqual(1.0, # Convert negative zero to positive zero 941 math.copysign(1.0, dist((0.0,), (-0.0,))) 942 ) 943 self.assertEqual( # Handling of moving max to the end 944 dist((1.5, 1.5, 0.5), (0, 0, 0)), 945 dist((1.5, 0.5, 1.5), (0, 0, 0)) 946 ) 947 948 # Verify tuple subclasses are allowed 949 class T(tuple): 950 pass 951 self.assertEqual(dist(T((1, 2, 3)), ((4, 2, -1))), 5.0) 952 953 # Test handling of bad arguments 954 with self.assertRaises(TypeError): # Reject keyword args 955 dist(p=(1, 2, 3), q=(4, 5, 6)) 956 with self.assertRaises(TypeError): # Too few args 957 dist((1, 2, 3)) 958 with self.assertRaises(TypeError): # Too many args 959 dist((1, 2, 3), (4, 5, 6), (7, 8, 9)) 960 with self.assertRaises(TypeError): # Scalars not allowed 961 dist(1, 2) 962 with self.assertRaises(TypeError): # Reject values without __float__ 963 dist((1.1, 'string', 2.2), (1, 2, 3)) 964 with self.assertRaises(ValueError): # Check dimension agree 965 dist((1, 2, 3, 4), (5, 6, 7)) 966 with self.assertRaises(ValueError): # Check dimension agree 967 dist((1, 2, 3), (4, 5, 6, 7)) 968 with self.assertRaises(TypeError): # Rejects invalid types 969 dist("abc", "xyz") 970 int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5) 971 with self.assertRaises((ValueError, OverflowError)): 972 dist((1, int_too_big_for_float), (2, 3)) 973 with self.assertRaises((ValueError, OverflowError)): 974 dist((2, 3), (1, int_too_big_for_float)) 975 976 # Verify that the one dimensional case is equivalent to abs() 977 for i in range(20): 978 p, q = random.random(), random.random() 979 self.assertEqual(dist((p,), (q,)), abs(p - q)) 980 981 # Test special values 982 values = [NINF, -10.5, -0.0, 0.0, 10.5, INF, NAN] 983 for p in itertools.product(values, repeat=3): 984 for q in itertools.product(values, repeat=3): 985 diffs = [px - qx for px, qx in zip(p, q)] 986 if any(map(math.isinf, diffs)): 987 # Any infinite difference gives positive infinity. 988 self.assertEqual(dist(p, q), INF) 989 elif any(map(math.isnan, diffs)): 990 # If no infinity, any NaN gives a NaN. 991 self.assertTrue(math.isnan(dist(p, q))) 992 993 # Verify scaling for extremely large values 994 fourthmax = FLOAT_MAX / 4.0 995 for n in range(32): 996 p = (fourthmax,) * n 997 q = (0.0,) * n 998 self.assertTrue(math.isclose(dist(p, q), fourthmax * math.sqrt(n))) 999 self.assertTrue(math.isclose(dist(q, p), fourthmax * math.sqrt(n))) 1000 1001 # Verify scaling for extremely small values 1002 for exp in range(32): 1003 scale = FLOAT_MIN / 2.0 ** exp 1004 p = (4*scale, 3*scale) 1005 q = (0.0, 0.0) 1006 self.assertEqual(math.dist(p, q), 5*scale) 1007 self.assertEqual(math.dist(q, p), 5*scale) 1008 1009 def test_math_dist_leak(self): 1010 # gh-98897: Check for error handling does not leak memory 1011 with self.assertRaises(ValueError): 1012 math.dist([1, 2], [3, 4, 5]) 1013 1014 def testIsqrt(self): 1015 # Test a variety of inputs, large and small. 1016 test_values = ( 1017 list(range(1000)) 1018 + list(range(10**6 - 1000, 10**6 + 1000)) 1019 + [2**e + i for e in range(60, 200) for i in range(-40, 40)] 1020 + [3**9999, 10**5001] 1021 ) 1022 1023 for value in test_values: 1024 with self.subTest(value=value): 1025 s = math.isqrt(value) 1026 self.assertIs(type(s), int) 1027 self.assertLessEqual(s*s, value) 1028 self.assertLess(value, (s+1)*(s+1)) 1029 1030 # Negative values 1031 with self.assertRaises(ValueError): 1032 math.isqrt(-1) 1033 1034 # Integer-like things 1035 s = math.isqrt(True) 1036 self.assertIs(type(s), int) 1037 self.assertEqual(s, 1) 1038 1039 s = math.isqrt(False) 1040 self.assertIs(type(s), int) 1041 self.assertEqual(s, 0) 1042 1043 class IntegerLike(object): 1044 def __init__(self, value): 1045 self.value = value 1046 1047 def __index__(self): 1048 return self.value 1049 1050 s = math.isqrt(IntegerLike(1729)) 1051 self.assertIs(type(s), int) 1052 self.assertEqual(s, 41) 1053 1054 with self.assertRaises(ValueError): 1055 math.isqrt(IntegerLike(-3)) 1056 1057 # Non-integer-like things 1058 bad_values = [ 1059 3.5, "a string", decimal.Decimal("3.5"), 3.5j, 1060 100.0, -4.0, 1061 ] 1062 for value in bad_values: 1063 with self.subTest(value=value): 1064 with self.assertRaises(TypeError): 1065 math.isqrt(value) 1066 1067 def test_lcm(self): 1068 lcm = math.lcm 1069 self.assertEqual(lcm(0, 0), 0) 1070 self.assertEqual(lcm(1, 0), 0) 1071 self.assertEqual(lcm(-1, 0), 0) 1072 self.assertEqual(lcm(0, 1), 0) 1073 self.assertEqual(lcm(0, -1), 0) 1074 self.assertEqual(lcm(7, 1), 7) 1075 self.assertEqual(lcm(7, -1), 7) 1076 self.assertEqual(lcm(-23, 15), 345) 1077 self.assertEqual(lcm(120, 84), 840) 1078 self.assertEqual(lcm(84, -120), 840) 1079 self.assertEqual(lcm(1216342683557601535506311712, 1080 436522681849110124616458784), 1081 16592536571065866494401400422922201534178938447014944) 1082 1083 x = 43461045657039990237 1084 y = 10645022458251153277 1085 for c in (652560, 1086 57655923087165495981): 1087 a = x * c 1088 b = y * c 1089 d = x * y * c 1090 self.assertEqual(lcm(a, b), d) 1091 self.assertEqual(lcm(b, a), d) 1092 self.assertEqual(lcm(-a, b), d) 1093 self.assertEqual(lcm(b, -a), d) 1094 self.assertEqual(lcm(a, -b), d) 1095 self.assertEqual(lcm(-b, a), d) 1096 self.assertEqual(lcm(-a, -b), d) 1097 self.assertEqual(lcm(-b, -a), d) 1098 1099 self.assertEqual(lcm(), 1) 1100 self.assertEqual(lcm(120), 120) 1101 self.assertEqual(lcm(-120), 120) 1102 self.assertEqual(lcm(120, 84, 102), 14280) 1103 self.assertEqual(lcm(120, 0, 84), 0) 1104 1105 self.assertRaises(TypeError, lcm, 120.0) 1106 self.assertRaises(TypeError, lcm, 120.0, 84) 1107 self.assertRaises(TypeError, lcm, 120, 84.0) 1108 self.assertRaises(TypeError, lcm, 120, 0, 84.0) 1109 self.assertEqual(lcm(MyIndexable(120), MyIndexable(84)), 840) 1110 1111 def testLdexp(self): 1112 self.assertRaises(TypeError, math.ldexp) 1113 self.ftest('ldexp(0,1)', math.ldexp(0,1), 0) 1114 self.ftest('ldexp(1,1)', math.ldexp(1,1), 2) 1115 self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5) 1116 self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2) 1117 self.assertRaises(OverflowError, math.ldexp, 1., 1000000) 1118 self.assertRaises(OverflowError, math.ldexp, -1., 1000000) 1119 self.assertEqual(math.ldexp(1., -1000000), 0.) 1120 self.assertEqual(math.ldexp(-1., -1000000), -0.) 1121 self.assertEqual(math.ldexp(INF, 30), INF) 1122 self.assertEqual(math.ldexp(NINF, -213), NINF) 1123 self.assertTrue(math.isnan(math.ldexp(NAN, 0))) 1124 1125 # large second argument 1126 for n in [10**5, 10**10, 10**20, 10**40]: 1127 self.assertEqual(math.ldexp(INF, -n), INF) 1128 self.assertEqual(math.ldexp(NINF, -n), NINF) 1129 self.assertEqual(math.ldexp(1., -n), 0.) 1130 self.assertEqual(math.ldexp(-1., -n), -0.) 1131 self.assertEqual(math.ldexp(0., -n), 0.) 1132 self.assertEqual(math.ldexp(-0., -n), -0.) 1133 self.assertTrue(math.isnan(math.ldexp(NAN, -n))) 1134 1135 self.assertRaises(OverflowError, math.ldexp, 1., n) 1136 self.assertRaises(OverflowError, math.ldexp, -1., n) 1137 self.assertEqual(math.ldexp(0., n), 0.) 1138 self.assertEqual(math.ldexp(-0., n), -0.) 1139 self.assertEqual(math.ldexp(INF, n), INF) 1140 self.assertEqual(math.ldexp(NINF, n), NINF) 1141 self.assertTrue(math.isnan(math.ldexp(NAN, n))) 1142 1143 def testLog(self): 1144 self.assertRaises(TypeError, math.log) 1145 self.ftest('log(1/e)', math.log(1/math.e), -1) 1146 self.ftest('log(1)', math.log(1), 0) 1147 self.ftest('log(e)', math.log(math.e), 1) 1148 self.ftest('log(32,2)', math.log(32,2), 5) 1149 self.ftest('log(10**40, 10)', math.log(10**40, 10), 40) 1150 self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2) 1151 self.ftest('log(10**1000)', math.log(10**1000), 1152 2302.5850929940457) 1153 self.assertRaises(ValueError, math.log, -1.5) 1154 self.assertRaises(ValueError, math.log, -10**1000) 1155 self.assertRaises(ValueError, math.log, NINF) 1156 self.assertEqual(math.log(INF), INF) 1157 self.assertTrue(math.isnan(math.log(NAN))) 1158 1159 def testLog1p(self): 1160 self.assertRaises(TypeError, math.log1p) 1161 for n in [2, 2**90, 2**300]: 1162 self.assertAlmostEqual(math.log1p(n), math.log1p(float(n))) 1163 self.assertRaises(ValueError, math.log1p, -1) 1164 self.assertEqual(math.log1p(INF), INF) 1165 1166 @requires_IEEE_754 1167 def testLog2(self): 1168 self.assertRaises(TypeError, math.log2) 1169 1170 # Check some integer values 1171 self.assertEqual(math.log2(1), 0.0) 1172 self.assertEqual(math.log2(2), 1.0) 1173 self.assertEqual(math.log2(4), 2.0) 1174 1175 # Large integer values 1176 self.assertEqual(math.log2(2**1023), 1023.0) 1177 self.assertEqual(math.log2(2**1024), 1024.0) 1178 self.assertEqual(math.log2(2**2000), 2000.0) 1179 1180 self.assertRaises(ValueError, math.log2, -1.5) 1181 self.assertRaises(ValueError, math.log2, NINF) 1182 self.assertTrue(math.isnan(math.log2(NAN))) 1183 1184 @requires_IEEE_754 1185 # log2() is not accurate enough on Mac OS X Tiger (10.4) 1186 @support.requires_mac_ver(10, 5) 1187 def testLog2Exact(self): 1188 # Check that we get exact equality for log2 of powers of 2. 1189 actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)] 1190 expected = [float(n) for n in range(-1074, 1024)] 1191 self.assertEqual(actual, expected) 1192 1193 def testLog10(self): 1194 self.assertRaises(TypeError, math.log10) 1195 self.ftest('log10(0.1)', math.log10(0.1), -1) 1196 self.ftest('log10(1)', math.log10(1), 0) 1197 self.ftest('log10(10)', math.log10(10), 1) 1198 self.ftest('log10(10**1000)', math.log10(10**1000), 1000.0) 1199 self.assertRaises(ValueError, math.log10, -1.5) 1200 self.assertRaises(ValueError, math.log10, -10**1000) 1201 self.assertRaises(ValueError, math.log10, NINF) 1202 self.assertEqual(math.log(INF), INF) 1203 self.assertTrue(math.isnan(math.log10(NAN))) 1204 1205 def testModf(self): 1206 self.assertRaises(TypeError, math.modf) 1207 1208 def testmodf(name, result, expected): 1209 (v1, v2), (e1, e2) = result, expected 1210 if abs(v1-e1) > eps or abs(v2-e2): 1211 self.fail('%s returned %r, expected %r'%\ 1212 (name, result, expected)) 1213 1214 testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0)) 1215 testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0)) 1216 1217 self.assertEqual(math.modf(INF), (0.0, INF)) 1218 self.assertEqual(math.modf(NINF), (-0.0, NINF)) 1219 1220 modf_nan = math.modf(NAN) 1221 self.assertTrue(math.isnan(modf_nan[0])) 1222 self.assertTrue(math.isnan(modf_nan[1])) 1223 1224 def testPow(self): 1225 self.assertRaises(TypeError, math.pow) 1226 self.ftest('pow(0,1)', math.pow(0,1), 0) 1227 self.ftest('pow(1,0)', math.pow(1,0), 1) 1228 self.ftest('pow(2,1)', math.pow(2,1), 2) 1229 self.ftest('pow(2,-1)', math.pow(2,-1), 0.5) 1230 self.assertEqual(math.pow(INF, 1), INF) 1231 self.assertEqual(math.pow(NINF, 1), NINF) 1232 self.assertEqual((math.pow(1, INF)), 1.) 1233 self.assertEqual((math.pow(1, NINF)), 1.) 1234 self.assertTrue(math.isnan(math.pow(NAN, 1))) 1235 self.assertTrue(math.isnan(math.pow(2, NAN))) 1236 self.assertTrue(math.isnan(math.pow(0, NAN))) 1237 self.assertEqual(math.pow(1, NAN), 1) 1238 1239 # pow(0., x) 1240 self.assertEqual(math.pow(0., INF), 0.) 1241 self.assertEqual(math.pow(0., 3.), 0.) 1242 self.assertEqual(math.pow(0., 2.3), 0.) 1243 self.assertEqual(math.pow(0., 2.), 0.) 1244 self.assertEqual(math.pow(0., 0.), 1.) 1245 self.assertEqual(math.pow(0., -0.), 1.) 1246 self.assertRaises(ValueError, math.pow, 0., -2.) 1247 self.assertRaises(ValueError, math.pow, 0., -2.3) 1248 self.assertRaises(ValueError, math.pow, 0., -3.) 1249 self.assertEqual(math.pow(0., NINF), INF) 1250 self.assertTrue(math.isnan(math.pow(0., NAN))) 1251 1252 # pow(INF, x) 1253 self.assertEqual(math.pow(INF, INF), INF) 1254 self.assertEqual(math.pow(INF, 3.), INF) 1255 self.assertEqual(math.pow(INF, 2.3), INF) 1256 self.assertEqual(math.pow(INF, 2.), INF) 1257 self.assertEqual(math.pow(INF, 0.), 1.) 1258 self.assertEqual(math.pow(INF, -0.), 1.) 1259 self.assertEqual(math.pow(INF, -2.), 0.) 1260 self.assertEqual(math.pow(INF, -2.3), 0.) 1261 self.assertEqual(math.pow(INF, -3.), 0.) 1262 self.assertEqual(math.pow(INF, NINF), 0.) 1263 self.assertTrue(math.isnan(math.pow(INF, NAN))) 1264 1265 # pow(-0., x) 1266 self.assertEqual(math.pow(-0., INF), 0.) 1267 self.assertEqual(math.pow(-0., 3.), -0.) 1268 self.assertEqual(math.pow(-0., 2.3), 0.) 1269 self.assertEqual(math.pow(-0., 2.), 0.) 1270 self.assertEqual(math.pow(-0., 0.), 1.) 1271 self.assertEqual(math.pow(-0., -0.), 1.) 1272 self.assertRaises(ValueError, math.pow, -0., -2.) 1273 self.assertRaises(ValueError, math.pow, -0., -2.3) 1274 self.assertRaises(ValueError, math.pow, -0., -3.) 1275 self.assertEqual(math.pow(-0., NINF), INF) 1276 self.assertTrue(math.isnan(math.pow(-0., NAN))) 1277 1278 # pow(NINF, x) 1279 self.assertEqual(math.pow(NINF, INF), INF) 1280 self.assertEqual(math.pow(NINF, 3.), NINF) 1281 self.assertEqual(math.pow(NINF, 2.3), INF) 1282 self.assertEqual(math.pow(NINF, 2.), INF) 1283 self.assertEqual(math.pow(NINF, 0.), 1.) 1284 self.assertEqual(math.pow(NINF, -0.), 1.) 1285 self.assertEqual(math.pow(NINF, -2.), 0.) 1286 self.assertEqual(math.pow(NINF, -2.3), 0.) 1287 self.assertEqual(math.pow(NINF, -3.), -0.) 1288 self.assertEqual(math.pow(NINF, NINF), 0.) 1289 self.assertTrue(math.isnan(math.pow(NINF, NAN))) 1290 1291 # pow(-1, x) 1292 self.assertEqual(math.pow(-1., INF), 1.) 1293 self.assertEqual(math.pow(-1., 3.), -1.) 1294 self.assertRaises(ValueError, math.pow, -1., 2.3) 1295 self.assertEqual(math.pow(-1., 2.), 1.) 1296 self.assertEqual(math.pow(-1., 0.), 1.) 1297 self.assertEqual(math.pow(-1., -0.), 1.) 1298 self.assertEqual(math.pow(-1., -2.), 1.) 1299 self.assertRaises(ValueError, math.pow, -1., -2.3) 1300 self.assertEqual(math.pow(-1., -3.), -1.) 1301 self.assertEqual(math.pow(-1., NINF), 1.) 1302 self.assertTrue(math.isnan(math.pow(-1., NAN))) 1303 1304 # pow(1, x) 1305 self.assertEqual(math.pow(1., INF), 1.) 1306 self.assertEqual(math.pow(1., 3.), 1.) 1307 self.assertEqual(math.pow(1., 2.3), 1.) 1308 self.assertEqual(math.pow(1., 2.), 1.) 1309 self.assertEqual(math.pow(1., 0.), 1.) 1310 self.assertEqual(math.pow(1., -0.), 1.) 1311 self.assertEqual(math.pow(1., -2.), 1.) 1312 self.assertEqual(math.pow(1., -2.3), 1.) 1313 self.assertEqual(math.pow(1., -3.), 1.) 1314 self.assertEqual(math.pow(1., NINF), 1.) 1315 self.assertEqual(math.pow(1., NAN), 1.) 1316 1317 # pow(x, 0) should be 1 for any x 1318 self.assertEqual(math.pow(2.3, 0.), 1.) 1319 self.assertEqual(math.pow(-2.3, 0.), 1.) 1320 self.assertEqual(math.pow(NAN, 0.), 1.) 1321 self.assertEqual(math.pow(2.3, -0.), 1.) 1322 self.assertEqual(math.pow(-2.3, -0.), 1.) 1323 self.assertEqual(math.pow(NAN, -0.), 1.) 1324 1325 # pow(x, y) is invalid if x is negative and y is not integral 1326 self.assertRaises(ValueError, math.pow, -1., 2.3) 1327 self.assertRaises(ValueError, math.pow, -15., -3.1) 1328 1329 # pow(x, NINF) 1330 self.assertEqual(math.pow(1.9, NINF), 0.) 1331 self.assertEqual(math.pow(1.1, NINF), 0.) 1332 self.assertEqual(math.pow(0.9, NINF), INF) 1333 self.assertEqual(math.pow(0.1, NINF), INF) 1334 self.assertEqual(math.pow(-0.1, NINF), INF) 1335 self.assertEqual(math.pow(-0.9, NINF), INF) 1336 self.assertEqual(math.pow(-1.1, NINF), 0.) 1337 self.assertEqual(math.pow(-1.9, NINF), 0.) 1338 1339 # pow(x, INF) 1340 self.assertEqual(math.pow(1.9, INF), INF) 1341 self.assertEqual(math.pow(1.1, INF), INF) 1342 self.assertEqual(math.pow(0.9, INF), 0.) 1343 self.assertEqual(math.pow(0.1, INF), 0.) 1344 self.assertEqual(math.pow(-0.1, INF), 0.) 1345 self.assertEqual(math.pow(-0.9, INF), 0.) 1346 self.assertEqual(math.pow(-1.1, INF), INF) 1347 self.assertEqual(math.pow(-1.9, INF), INF) 1348 1349 # pow(x, y) should work for x negative, y an integer 1350 self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0) 1351 self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0) 1352 self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0) 1353 self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0) 1354 self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0) 1355 self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5) 1356 self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25) 1357 self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125) 1358 self.assertRaises(ValueError, math.pow, -2.0, -0.5) 1359 self.assertRaises(ValueError, math.pow, -2.0, 0.5) 1360 1361 # the following tests have been commented out since they don't 1362 # really belong here: the implementation of ** for floats is 1363 # independent of the implementation of math.pow 1364 #self.assertEqual(1**NAN, 1) 1365 #self.assertEqual(1**INF, 1) 1366 #self.assertEqual(1**NINF, 1) 1367 #self.assertEqual(1**0, 1) 1368 #self.assertEqual(1.**NAN, 1) 1369 #self.assertEqual(1.**INF, 1) 1370 #self.assertEqual(1.**NINF, 1) 1371 #self.assertEqual(1.**0, 1) 1372 1373 def testRadians(self): 1374 self.assertRaises(TypeError, math.radians) 1375 self.ftest('radians(180)', math.radians(180), math.pi) 1376 self.ftest('radians(90)', math.radians(90), math.pi/2) 1377 self.ftest('radians(-45)', math.radians(-45), -math.pi/4) 1378 self.ftest('radians(0)', math.radians(0), 0) 1379 1380 @requires_IEEE_754 1381 def testRemainder(self): 1382 from fractions import Fraction 1383 1384 def validate_spec(x, y, r): 1385 """ 1386 Check that r matches remainder(x, y) according to the IEEE 754 1387 specification. Assumes that x, y and r are finite and y is nonzero. 1388 """ 1389 fx, fy, fr = Fraction(x), Fraction(y), Fraction(r) 1390 # r should not exceed y/2 in absolute value 1391 self.assertLessEqual(abs(fr), abs(fy/2)) 1392 # x - r should be an exact integer multiple of y 1393 n = (fx - fr) / fy 1394 self.assertEqual(n, int(n)) 1395 if abs(fr) == abs(fy/2): 1396 # If |r| == |y/2|, n should be even. 1397 self.assertEqual(n/2, int(n/2)) 1398 1399 # triples (x, y, remainder(x, y)) in hexadecimal form. 1400 testcases = [ 1401 # Remainders modulo 1, showing the ties-to-even behaviour. 1402 '-4.0 1 -0.0', 1403 '-3.8 1 0.8', 1404 '-3.0 1 -0.0', 1405 '-2.8 1 -0.8', 1406 '-2.0 1 -0.0', 1407 '-1.8 1 0.8', 1408 '-1.0 1 -0.0', 1409 '-0.8 1 -0.8', 1410 '-0.0 1 -0.0', 1411 ' 0.0 1 0.0', 1412 ' 0.8 1 0.8', 1413 ' 1.0 1 0.0', 1414 ' 1.8 1 -0.8', 1415 ' 2.0 1 0.0', 1416 ' 2.8 1 0.8', 1417 ' 3.0 1 0.0', 1418 ' 3.8 1 -0.8', 1419 ' 4.0 1 0.0', 1420 1421 # Reductions modulo 2*pi 1422 '0x0.0p+0 0x1.921fb54442d18p+2 0x0.0p+0', 1423 '0x1.921fb54442d18p+0 0x1.921fb54442d18p+2 0x1.921fb54442d18p+0', 1424 '0x1.921fb54442d17p+1 0x1.921fb54442d18p+2 0x1.921fb54442d17p+1', 1425 '0x1.921fb54442d18p+1 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1', 1426 '0x1.921fb54442d19p+1 0x1.921fb54442d18p+2 -0x1.921fb54442d17p+1', 1427 '0x1.921fb54442d17p+2 0x1.921fb54442d18p+2 -0x0.0000000000001p+2', 1428 '0x1.921fb54442d18p+2 0x1.921fb54442d18p+2 0x0p0', 1429 '0x1.921fb54442d19p+2 0x1.921fb54442d18p+2 0x0.0000000000001p+2', 1430 '0x1.2d97c7f3321d1p+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1', 1431 '0x1.2d97c7f3321d2p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d18p+1', 1432 '0x1.2d97c7f3321d3p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1', 1433 '0x1.921fb54442d17p+3 0x1.921fb54442d18p+2 -0x0.0000000000001p+3', 1434 '0x1.921fb54442d18p+3 0x1.921fb54442d18p+2 0x0p0', 1435 '0x1.921fb54442d19p+3 0x1.921fb54442d18p+2 0x0.0000000000001p+3', 1436 '0x1.f6a7a2955385dp+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1', 1437 '0x1.f6a7a2955385ep+3 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1', 1438 '0x1.f6a7a2955385fp+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1', 1439 '0x1.1475cc9eedf00p+5 0x1.921fb54442d18p+2 0x1.921fb54442d10p+1', 1440 '0x1.1475cc9eedf01p+5 0x1.921fb54442d18p+2 -0x1.921fb54442d10p+1', 1441 1442 # Symmetry with respect to signs. 1443 ' 1 0.c 0.4', 1444 '-1 0.c -0.4', 1445 ' 1 -0.c 0.4', 1446 '-1 -0.c -0.4', 1447 ' 1.4 0.c -0.4', 1448 '-1.4 0.c 0.4', 1449 ' 1.4 -0.c -0.4', 1450 '-1.4 -0.c 0.4', 1451 1452 # Huge modulus, to check that the underlying algorithm doesn't 1453 # rely on 2.0 * modulus being representable. 1454 '0x1.dp+1023 0x1.4p+1023 0x0.9p+1023', 1455 '0x1.ep+1023 0x1.4p+1023 -0x0.ap+1023', 1456 '0x1.fp+1023 0x1.4p+1023 -0x0.9p+1023', 1457 ] 1458 1459 for case in testcases: 1460 with self.subTest(case=case): 1461 x_hex, y_hex, expected_hex = case.split() 1462 x = float.fromhex(x_hex) 1463 y = float.fromhex(y_hex) 1464 expected = float.fromhex(expected_hex) 1465 validate_spec(x, y, expected) 1466 actual = math.remainder(x, y) 1467 # Cheap way of checking that the floats are 1468 # as identical as we need them to be. 1469 self.assertEqual(actual.hex(), expected.hex()) 1470 1471 # Test tiny subnormal modulus: there's potential for 1472 # getting the implementation wrong here (for example, 1473 # by assuming that modulus/2 is exactly representable). 1474 tiny = float.fromhex('1p-1074') # min +ve subnormal 1475 for n in range(-25, 25): 1476 if n == 0: 1477 continue 1478 y = n * tiny 1479 for m in range(100): 1480 x = m * tiny 1481 actual = math.remainder(x, y) 1482 validate_spec(x, y, actual) 1483 actual = math.remainder(-x, y) 1484 validate_spec(-x, y, actual) 1485 1486 # Special values. 1487 # NaNs should propagate as usual. 1488 for value in [NAN, 0.0, -0.0, 2.0, -2.3, NINF, INF]: 1489 self.assertIsNaN(math.remainder(NAN, value)) 1490 self.assertIsNaN(math.remainder(value, NAN)) 1491 1492 # remainder(x, inf) is x, for non-nan non-infinite x. 1493 for value in [-2.3, -0.0, 0.0, 2.3]: 1494 self.assertEqual(math.remainder(value, INF), value) 1495 self.assertEqual(math.remainder(value, NINF), value) 1496 1497 # remainder(x, 0) and remainder(infinity, x) for non-NaN x are invalid 1498 # operations according to IEEE 754-2008 7.2(f), and should raise. 1499 for value in [NINF, -2.3, -0.0, 0.0, 2.3, INF]: 1500 with self.assertRaises(ValueError): 1501 math.remainder(INF, value) 1502 with self.assertRaises(ValueError): 1503 math.remainder(NINF, value) 1504 with self.assertRaises(ValueError): 1505 math.remainder(value, 0.0) 1506 with self.assertRaises(ValueError): 1507 math.remainder(value, -0.0) 1508 1509 def testSin(self): 1510 self.assertRaises(TypeError, math.sin) 1511 self.ftest('sin(0)', math.sin(0), 0) 1512 self.ftest('sin(pi/2)', math.sin(math.pi/2), 1) 1513 self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1) 1514 try: 1515 self.assertTrue(math.isnan(math.sin(INF))) 1516 self.assertTrue(math.isnan(math.sin(NINF))) 1517 except ValueError: 1518 self.assertRaises(ValueError, math.sin, INF) 1519 self.assertRaises(ValueError, math.sin, NINF) 1520 self.assertTrue(math.isnan(math.sin(NAN))) 1521 1522 def testSinh(self): 1523 self.assertRaises(TypeError, math.sinh) 1524 self.ftest('sinh(0)', math.sinh(0), 0) 1525 self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1) 1526 self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0) 1527 self.assertEqual(math.sinh(INF), INF) 1528 self.assertEqual(math.sinh(NINF), NINF) 1529 self.assertTrue(math.isnan(math.sinh(NAN))) 1530 1531 def testSqrt(self): 1532 self.assertRaises(TypeError, math.sqrt) 1533 self.ftest('sqrt(0)', math.sqrt(0), 0) 1534 self.ftest('sqrt(0)', math.sqrt(0.0), 0.0) 1535 self.ftest('sqrt(2.5)', math.sqrt(2.5), 1.5811388300841898) 1536 self.ftest('sqrt(0.25)', math.sqrt(0.25), 0.5) 1537 self.ftest('sqrt(25.25)', math.sqrt(25.25), 5.024937810560445) 1538 self.ftest('sqrt(1)', math.sqrt(1), 1) 1539 self.ftest('sqrt(4)', math.sqrt(4), 2) 1540 self.assertEqual(math.sqrt(INF), INF) 1541 self.assertRaises(ValueError, math.sqrt, -1) 1542 self.assertRaises(ValueError, math.sqrt, NINF) 1543 self.assertTrue(math.isnan(math.sqrt(NAN))) 1544 1545 def testTan(self): 1546 self.assertRaises(TypeError, math.tan) 1547 self.ftest('tan(0)', math.tan(0), 0) 1548 self.ftest('tan(pi/4)', math.tan(math.pi/4), 1) 1549 self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1) 1550 try: 1551 self.assertTrue(math.isnan(math.tan(INF))) 1552 self.assertTrue(math.isnan(math.tan(NINF))) 1553 except: 1554 self.assertRaises(ValueError, math.tan, INF) 1555 self.assertRaises(ValueError, math.tan, NINF) 1556 self.assertTrue(math.isnan(math.tan(NAN))) 1557 1558 def testTanh(self): 1559 self.assertRaises(TypeError, math.tanh) 1560 self.ftest('tanh(0)', math.tanh(0), 0) 1561 self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0, 1562 abs_tol=math.ulp(1)) 1563 self.ftest('tanh(inf)', math.tanh(INF), 1) 1564 self.ftest('tanh(-inf)', math.tanh(NINF), -1) 1565 self.assertTrue(math.isnan(math.tanh(NAN))) 1566 1567 @requires_IEEE_754 1568 def testTanhSign(self): 1569 # check that tanh(-0.) == -0. on IEEE 754 systems 1570 self.assertEqual(math.tanh(-0.), -0.) 1571 self.assertEqual(math.copysign(1., math.tanh(-0.)), 1572 math.copysign(1., -0.)) 1573 1574 def test_trunc(self): 1575 self.assertEqual(math.trunc(1), 1) 1576 self.assertEqual(math.trunc(-1), -1) 1577 self.assertEqual(type(math.trunc(1)), int) 1578 self.assertEqual(type(math.trunc(1.5)), int) 1579 self.assertEqual(math.trunc(1.5), 1) 1580 self.assertEqual(math.trunc(-1.5), -1) 1581 self.assertEqual(math.trunc(1.999999), 1) 1582 self.assertEqual(math.trunc(-1.999999), -1) 1583 self.assertEqual(math.trunc(-0.999999), -0) 1584 self.assertEqual(math.trunc(-100.999), -100) 1585 1586 class TestTrunc: 1587 def __trunc__(self): 1588 return 23 1589 class FloatTrunc(float): 1590 def __trunc__(self): 1591 return 23 1592 class TestNoTrunc: 1593 pass 1594 1595 self.assertEqual(math.trunc(TestTrunc()), 23) 1596 self.assertEqual(math.trunc(FloatTrunc()), 23) 1597 1598 self.assertRaises(TypeError, math.trunc) 1599 self.assertRaises(TypeError, math.trunc, 1, 2) 1600 self.assertRaises(TypeError, math.trunc, FloatLike(23.5)) 1601 self.assertRaises(TypeError, math.trunc, TestNoTrunc()) 1602 1603 def testIsfinite(self): 1604 self.assertTrue(math.isfinite(0.0)) 1605 self.assertTrue(math.isfinite(-0.0)) 1606 self.assertTrue(math.isfinite(1.0)) 1607 self.assertTrue(math.isfinite(-1.0)) 1608 self.assertFalse(math.isfinite(float("nan"))) 1609 self.assertFalse(math.isfinite(float("inf"))) 1610 self.assertFalse(math.isfinite(float("-inf"))) 1611 1612 def testIsnan(self): 1613 self.assertTrue(math.isnan(float("nan"))) 1614 self.assertTrue(math.isnan(float("-nan"))) 1615 self.assertTrue(math.isnan(float("inf") * 0.)) 1616 self.assertFalse(math.isnan(float("inf"))) 1617 self.assertFalse(math.isnan(0.)) 1618 self.assertFalse(math.isnan(1.)) 1619 1620 def testIsinf(self): 1621 self.assertTrue(math.isinf(float("inf"))) 1622 self.assertTrue(math.isinf(float("-inf"))) 1623 self.assertTrue(math.isinf(1E400)) 1624 self.assertTrue(math.isinf(-1E400)) 1625 self.assertFalse(math.isinf(float("nan"))) 1626 self.assertFalse(math.isinf(0.)) 1627 self.assertFalse(math.isinf(1.)) 1628 1629 @requires_IEEE_754 1630 def test_nan_constant(self): 1631 self.assertTrue(math.isnan(math.nan)) 1632 1633 @requires_IEEE_754 1634 def test_inf_constant(self): 1635 self.assertTrue(math.isinf(math.inf)) 1636 self.assertGreater(math.inf, 0.0) 1637 self.assertEqual(math.inf, float("inf")) 1638 self.assertEqual(-math.inf, float("-inf")) 1639 1640 # RED_FLAG 16-Oct-2000 Tim 1641 # While 2.0 is more consistent about exceptions than previous releases, it 1642 # still fails this part of the test on some platforms. For now, we only 1643 # *run* test_exceptions() in verbose mode, so that this isn't normally 1644 # tested. 1645 @unittest.skipUnless(verbose, 'requires verbose mode') 1646 def test_exceptions(self): 1647 try: 1648 x = math.exp(-1000000000) 1649 except: 1650 # mathmodule.c is failing to weed out underflows from libm, or 1651 # we've got an fp format with huge dynamic range 1652 self.fail("underflowing exp() should not have raised " 1653 "an exception") 1654 if x != 0: 1655 self.fail("underflowing exp() should have returned 0") 1656 1657 # If this fails, probably using a strict IEEE-754 conforming libm, and x 1658 # is +Inf afterwards. But Python wants overflows detected by default. 1659 try: 1660 x = math.exp(1000000000) 1661 except OverflowError: 1662 pass 1663 else: 1664 self.fail("overflowing exp() didn't trigger OverflowError") 1665 1666 # If this fails, it could be a puzzle. One odd possibility is that 1667 # mathmodule.c's macros are getting confused while comparing 1668 # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE 1669 # as a result (and so raising OverflowError instead). 1670 try: 1671 x = math.sqrt(-1.0) 1672 except ValueError: 1673 pass 1674 else: 1675 self.fail("sqrt(-1) didn't raise ValueError") 1676 1677 @requires_IEEE_754 1678 def test_testfile(self): 1679 # Some tests need to be skipped on ancient OS X versions. 1680 # See issue #27953. 1681 SKIP_ON_TIGER = {'tan0064'} 1682 1683 osx_version = None 1684 if sys.platform == 'darwin': 1685 version_txt = platform.mac_ver()[0] 1686 try: 1687 osx_version = tuple(map(int, version_txt.split('.'))) 1688 except ValueError: 1689 pass 1690 1691 fail_fmt = "{}: {}({!r}): {}" 1692 1693 failures = [] 1694 for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file): 1695 # Skip if either the input or result is complex 1696 if ai != 0.0 or ei != 0.0: 1697 continue 1698 if fn in ['rect', 'polar']: 1699 # no real versions of rect, polar 1700 continue 1701 # Skip certain tests on OS X 10.4. 1702 if osx_version is not None and osx_version < (10, 5): 1703 if id in SKIP_ON_TIGER: 1704 continue 1705 1706 func = getattr(math, fn) 1707 1708 if 'invalid' in flags or 'divide-by-zero' in flags: 1709 er = 'ValueError' 1710 elif 'overflow' in flags: 1711 er = 'OverflowError' 1712 1713 try: 1714 result = func(ar) 1715 except ValueError: 1716 result = 'ValueError' 1717 except OverflowError: 1718 result = 'OverflowError' 1719 1720 # Default tolerances 1721 ulp_tol, abs_tol = 5, 0.0 1722 1723 failure = result_check(er, result, ulp_tol, abs_tol) 1724 if failure is None: 1725 continue 1726 1727 msg = fail_fmt.format(id, fn, ar, failure) 1728 failures.append(msg) 1729 1730 if failures: 1731 self.fail('Failures in test_testfile:\n ' + 1732 '\n '.join(failures)) 1733 1734 @requires_IEEE_754 1735 def test_mtestfile(self): 1736 fail_fmt = "{}: {}({!r}): {}" 1737 1738 failures = [] 1739 for id, fn, arg, expected, flags in parse_mtestfile(math_testcases): 1740 func = getattr(math, fn) 1741 1742 if 'invalid' in flags or 'divide-by-zero' in flags: 1743 expected = 'ValueError' 1744 elif 'overflow' in flags: 1745 expected = 'OverflowError' 1746 1747 try: 1748 got = func(arg) 1749 except ValueError: 1750 got = 'ValueError' 1751 except OverflowError: 1752 got = 'OverflowError' 1753 1754 # Default tolerances 1755 ulp_tol, abs_tol = 5, 0.0 1756 1757 # Exceptions to the defaults 1758 if fn == 'gamma': 1759 # Experimental results on one platform gave 1760 # an accuracy of <= 10 ulps across the entire float 1761 # domain. We weaken that to require 20 ulp accuracy. 1762 ulp_tol = 20 1763 1764 elif fn == 'lgamma': 1765 # we use a weaker accuracy test for lgamma; 1766 # lgamma only achieves an absolute error of 1767 # a few multiples of the machine accuracy, in 1768 # general. 1769 abs_tol = 1e-15 1770 1771 elif fn == 'erfc' and arg >= 0.0: 1772 # erfc has less-than-ideal accuracy for large 1773 # arguments (x ~ 25 or so), mainly due to the 1774 # error involved in computing exp(-x*x). 1775 # 1776 # Observed between CPython and mpmath at 25 dp: 1777 # x < 0 : err <= 2 ulp 1778 # 0 <= x < 1 : err <= 10 ulp 1779 # 1 <= x < 10 : err <= 100 ulp 1780 # 10 <= x < 20 : err <= 300 ulp 1781 # 20 <= x : < 600 ulp 1782 # 1783 if arg < 1.0: 1784 ulp_tol = 10 1785 elif arg < 10.0: 1786 ulp_tol = 100 1787 else: 1788 ulp_tol = 1000 1789 1790 failure = result_check(expected, got, ulp_tol, abs_tol) 1791 if failure is None: 1792 continue 1793 1794 msg = fail_fmt.format(id, fn, arg, failure) 1795 failures.append(msg) 1796 1797 if failures: 1798 self.fail('Failures in test_mtestfile:\n ' + 1799 '\n '.join(failures)) 1800 1801 def test_prod(self): 1802 prod = math.prod 1803 self.assertEqual(prod([]), 1) 1804 self.assertEqual(prod([], start=5), 5) 1805 self.assertEqual(prod(list(range(2,8))), 5040) 1806 self.assertEqual(prod(iter(list(range(2,8)))), 5040) 1807 self.assertEqual(prod(range(1, 10), start=10), 3628800) 1808 1809 self.assertEqual(prod([1, 2, 3, 4, 5]), 120) 1810 self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0) 1811 self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0) 1812 self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0) 1813 1814 # Test overflow in fast-path for integers 1815 self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32) 1816 # Test overflow in fast-path for floats 1817 self.assertEqual(prod([1.0, 1.0, 2**32, 1, 1]), float(2**32)) 1818 1819 self.assertRaises(TypeError, prod) 1820 self.assertRaises(TypeError, prod, 42) 1821 self.assertRaises(TypeError, prod, ['a', 'b', 'c']) 1822 self.assertRaises(TypeError, prod, ['a', 'b', 'c'], start='') 1823 self.assertRaises(TypeError, prod, [b'a', b'c'], start=b'') 1824 values = [bytearray(b'a'), bytearray(b'b')] 1825 self.assertRaises(TypeError, prod, values, start=bytearray(b'')) 1826 self.assertRaises(TypeError, prod, [[1], [2], [3]]) 1827 self.assertRaises(TypeError, prod, [{2:3}]) 1828 self.assertRaises(TypeError, prod, [{2:3}]*2, start={2:3}) 1829 self.assertRaises(TypeError, prod, [[1], [2], [3]], start=[]) 1830 1831 # Some odd cases 1832 self.assertEqual(prod([2, 3], start='ab'), 'abababababab') 1833 self.assertEqual(prod([2, 3], start=[1, 2]), [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]) 1834 self.assertEqual(prod([], start={2: 3}), {2:3}) 1835 1836 with self.assertRaises(TypeError): 1837 prod([10, 20], 1) # start is a keyword-only argument 1838 1839 self.assertEqual(prod([0, 1, 2, 3]), 0) 1840 self.assertEqual(prod([1, 0, 2, 3]), 0) 1841 self.assertEqual(prod([1, 2, 3, 0]), 0) 1842 1843 def _naive_prod(iterable, start=1): 1844 for elem in iterable: 1845 start *= elem 1846 return start 1847 1848 # Big integers 1849 1850 iterable = range(1, 10000) 1851 self.assertEqual(prod(iterable), _naive_prod(iterable)) 1852 iterable = range(-10000, -1) 1853 self.assertEqual(prod(iterable), _naive_prod(iterable)) 1854 iterable = range(-1000, 1000) 1855 self.assertEqual(prod(iterable), 0) 1856 1857 # Big floats 1858 1859 iterable = [float(x) for x in range(1, 1000)] 1860 self.assertEqual(prod(iterable), _naive_prod(iterable)) 1861 iterable = [float(x) for x in range(-1000, -1)] 1862 self.assertEqual(prod(iterable), _naive_prod(iterable)) 1863 iterable = [float(x) for x in range(-1000, 1000)] 1864 self.assertIsNaN(prod(iterable)) 1865 1866 # Float tests 1867 1868 self.assertIsNaN(prod([1, 2, 3, float("nan"), 2, 3])) 1869 self.assertIsNaN(prod([1, 0, float("nan"), 2, 3])) 1870 self.assertIsNaN(prod([1, float("nan"), 0, 3])) 1871 self.assertIsNaN(prod([1, float("inf"), float("nan"),3])) 1872 self.assertIsNaN(prod([1, float("-inf"), float("nan"),3])) 1873 self.assertIsNaN(prod([1, float("nan"), float("inf"),3])) 1874 self.assertIsNaN(prod([1, float("nan"), float("-inf"),3])) 1875 1876 self.assertEqual(prod([1, 2, 3, float('inf'),-3,4]), float('-inf')) 1877 self.assertEqual(prod([1, 2, 3, float('-inf'),-3,4]), float('inf')) 1878 1879 self.assertIsNaN(prod([1,2,0,float('inf'), -3, 4])) 1880 self.assertIsNaN(prod([1,2,0,float('-inf'), -3, 4])) 1881 self.assertIsNaN(prod([1, 2, 3, float('inf'), -3, 0, 3])) 1882 self.assertIsNaN(prod([1, 2, 3, float('-inf'), -3, 0, 2])) 1883 1884 # Type preservation 1885 1886 self.assertEqual(type(prod([1, 2, 3, 4, 5, 6])), int) 1887 self.assertEqual(type(prod([1, 2.0, 3, 4, 5, 6])), float) 1888 self.assertEqual(type(prod(range(1, 10000))), int) 1889 self.assertEqual(type(prod(range(1, 10000), start=1.0)), float) 1890 self.assertEqual(type(prod([1, decimal.Decimal(2.0), 3, 4, 5, 6])), 1891 decimal.Decimal) 1892 1893 def testPerm(self): 1894 perm = math.perm 1895 factorial = math.factorial 1896 # Test if factorial definition is satisfied 1897 for n in range(500): 1898 for k in (range(n + 1) if n < 100 else range(30) if n < 200 else range(10)): 1899 self.assertEqual(perm(n, k), 1900 factorial(n) // factorial(n - k)) 1901 1902 # Test for Pascal's identity 1903 for n in range(1, 100): 1904 for k in range(1, n): 1905 self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k)) 1906 1907 # Test corner cases 1908 for n in range(1, 100): 1909 self.assertEqual(perm(n, 0), 1) 1910 self.assertEqual(perm(n, 1), n) 1911 self.assertEqual(perm(n, n), factorial(n)) 1912 1913 # Test one argument form 1914 for n in range(20): 1915 self.assertEqual(perm(n), factorial(n)) 1916 self.assertEqual(perm(n, None), factorial(n)) 1917 1918 # Raises TypeError if any argument is non-integer or argument count is 1919 # not 1 or 2 1920 self.assertRaises(TypeError, perm, 10, 1.0) 1921 self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0)) 1922 self.assertRaises(TypeError, perm, 10, "1") 1923 self.assertRaises(TypeError, perm, 10.0, 1) 1924 self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1) 1925 self.assertRaises(TypeError, perm, "10", 1) 1926 1927 self.assertRaises(TypeError, perm) 1928 self.assertRaises(TypeError, perm, 10, 1, 3) 1929 self.assertRaises(TypeError, perm) 1930 1931 # Raises Value error if not k or n are negative numbers 1932 self.assertRaises(ValueError, perm, -1, 1) 1933 self.assertRaises(ValueError, perm, -2**1000, 1) 1934 self.assertRaises(ValueError, perm, 1, -1) 1935 self.assertRaises(ValueError, perm, 1, -2**1000) 1936 1937 # Returns zero if k is greater than n 1938 self.assertEqual(perm(1, 2), 0) 1939 self.assertEqual(perm(1, 2**1000), 0) 1940 1941 n = 2**1000 1942 self.assertEqual(perm(n, 0), 1) 1943 self.assertEqual(perm(n, 1), n) 1944 self.assertEqual(perm(n, 2), n * (n-1)) 1945 if support.check_impl_detail(cpython=True): 1946 self.assertRaises(OverflowError, perm, n, n) 1947 1948 for n, k in (True, True), (True, False), (False, False): 1949 self.assertEqual(perm(n, k), 1) 1950 self.assertIs(type(perm(n, k)), int) 1951 self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20) 1952 self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20) 1953 for k in range(3): 1954 self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int) 1955 self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int) 1956 1957 def testComb(self): 1958 comb = math.comb 1959 factorial = math.factorial 1960 # Test if factorial definition is satisfied 1961 for n in range(500): 1962 for k in (range(n + 1) if n < 100 else range(30) if n < 200 else range(10)): 1963 self.assertEqual(comb(n, k), factorial(n) 1964 // (factorial(k) * factorial(n - k))) 1965 1966 # Test for Pascal's identity 1967 for n in range(1, 100): 1968 for k in range(1, n): 1969 self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k)) 1970 1971 # Test corner cases 1972 for n in range(100): 1973 self.assertEqual(comb(n, 0), 1) 1974 self.assertEqual(comb(n, n), 1) 1975 1976 for n in range(1, 100): 1977 self.assertEqual(comb(n, 1), n) 1978 self.assertEqual(comb(n, n - 1), n) 1979 1980 # Test Symmetry 1981 for n in range(100): 1982 for k in range(n // 2): 1983 self.assertEqual(comb(n, k), comb(n, n - k)) 1984 1985 # Raises TypeError if any argument is non-integer or argument count is 1986 # not 2 1987 self.assertRaises(TypeError, comb, 10, 1.0) 1988 self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0)) 1989 self.assertRaises(TypeError, comb, 10, "1") 1990 self.assertRaises(TypeError, comb, 10.0, 1) 1991 self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1) 1992 self.assertRaises(TypeError, comb, "10", 1) 1993 1994 self.assertRaises(TypeError, comb, 10) 1995 self.assertRaises(TypeError, comb, 10, 1, 3) 1996 self.assertRaises(TypeError, comb) 1997 1998 # Raises Value error if not k or n are negative numbers 1999 self.assertRaises(ValueError, comb, -1, 1) 2000 self.assertRaises(ValueError, comb, -2**1000, 1) 2001 self.assertRaises(ValueError, comb, 1, -1) 2002 self.assertRaises(ValueError, comb, 1, -2**1000) 2003 2004 # Returns zero if k is greater than n 2005 self.assertEqual(comb(1, 2), 0) 2006 self.assertEqual(comb(1, 2**1000), 0) 2007 2008 n = 2**1000 2009 self.assertEqual(comb(n, 0), 1) 2010 self.assertEqual(comb(n, 1), n) 2011 self.assertEqual(comb(n, 2), n * (n-1) // 2) 2012 self.assertEqual(comb(n, n), 1) 2013 self.assertEqual(comb(n, n-1), n) 2014 self.assertEqual(comb(n, n-2), n * (n-1) // 2) 2015 if support.check_impl_detail(cpython=True): 2016 self.assertRaises(OverflowError, comb, n, n//2) 2017 2018 for n, k in (True, True), (True, False), (False, False): 2019 self.assertEqual(comb(n, k), 1) 2020 self.assertIs(type(comb(n, k)), int) 2021 self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10) 2022 self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10) 2023 for k in range(3): 2024 self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int) 2025 self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int) 2026 2027 @requires_IEEE_754 2028 def test_nextafter(self): 2029 # around 2^52 and 2^63 2030 self.assertEqual(math.nextafter(4503599627370496.0, -INF), 2031 4503599627370495.5) 2032 self.assertEqual(math.nextafter(4503599627370496.0, INF), 2033 4503599627370497.0) 2034 self.assertEqual(math.nextafter(9223372036854775808.0, 0.0), 2035 9223372036854774784.0) 2036 self.assertEqual(math.nextafter(-9223372036854775808.0, 0.0), 2037 -9223372036854774784.0) 2038 2039 # around 1.0 2040 self.assertEqual(math.nextafter(1.0, -INF), 2041 float.fromhex('0x1.fffffffffffffp-1')) 2042 self.assertEqual(math.nextafter(1.0, INF), 2043 float.fromhex('0x1.0000000000001p+0')) 2044 2045 # x == y: y is returned 2046 self.assertEqual(math.nextafter(2.0, 2.0), 2.0) 2047 self.assertEqualSign(math.nextafter(-0.0, +0.0), +0.0) 2048 self.assertEqualSign(math.nextafter(+0.0, -0.0), -0.0) 2049 2050 # around 0.0 2051 smallest_subnormal = sys.float_info.min * sys.float_info.epsilon 2052 self.assertEqual(math.nextafter(+0.0, INF), smallest_subnormal) 2053 self.assertEqual(math.nextafter(-0.0, INF), smallest_subnormal) 2054 self.assertEqual(math.nextafter(+0.0, -INF), -smallest_subnormal) 2055 self.assertEqual(math.nextafter(-0.0, -INF), -smallest_subnormal) 2056 self.assertEqualSign(math.nextafter(smallest_subnormal, +0.0), +0.0) 2057 self.assertEqualSign(math.nextafter(-smallest_subnormal, +0.0), -0.0) 2058 self.assertEqualSign(math.nextafter(smallest_subnormal, -0.0), +0.0) 2059 self.assertEqualSign(math.nextafter(-smallest_subnormal, -0.0), -0.0) 2060 2061 # around infinity 2062 largest_normal = sys.float_info.max 2063 self.assertEqual(math.nextafter(INF, 0.0), largest_normal) 2064 self.assertEqual(math.nextafter(-INF, 0.0), -largest_normal) 2065 self.assertEqual(math.nextafter(largest_normal, INF), INF) 2066 self.assertEqual(math.nextafter(-largest_normal, -INF), -INF) 2067 2068 # NaN 2069 self.assertIsNaN(math.nextafter(NAN, 1.0)) 2070 self.assertIsNaN(math.nextafter(1.0, NAN)) 2071 self.assertIsNaN(math.nextafter(NAN, NAN)) 2072 2073 @requires_IEEE_754 2074 def test_ulp(self): 2075 self.assertEqual(math.ulp(1.0), sys.float_info.epsilon) 2076 # use int ** int rather than float ** int to not rely on pow() accuracy 2077 self.assertEqual(math.ulp(2 ** 52), 1.0) 2078 self.assertEqual(math.ulp(2 ** 53), 2.0) 2079 self.assertEqual(math.ulp(2 ** 64), 4096.0) 2080 2081 # min and max 2082 self.assertEqual(math.ulp(0.0), 2083 sys.float_info.min * sys.float_info.epsilon) 2084 self.assertEqual(math.ulp(FLOAT_MAX), 2085 FLOAT_MAX - math.nextafter(FLOAT_MAX, -INF)) 2086 2087 # special cases 2088 self.assertEqual(math.ulp(INF), INF) 2089 self.assertIsNaN(math.ulp(math.nan)) 2090 2091 # negative number: ulp(-x) == ulp(x) 2092 for x in (0.0, 1.0, 2 ** 52, 2 ** 64, INF): 2093 with self.subTest(x=x): 2094 self.assertEqual(math.ulp(-x), math.ulp(x)) 2095 2096 def test_issue39871(self): 2097 # A SystemError should not be raised if the first arg to atan2(), 2098 # copysign(), or remainder() cannot be converted to a float. 2099 class F: 2100 def __float__(self): 2101 self.converted = True 2102 1/0 2103 for func in math.atan2, math.copysign, math.remainder: 2104 y = F() 2105 with self.assertRaises(TypeError): 2106 func("not a number", y) 2107 2108 # There should not have been any attempt to convert the second 2109 # argument to a float. 2110 self.assertFalse(getattr(y, "converted", False)) 2111 2112 # Custom assertions. 2113 2114 def assertIsNaN(self, value): 2115 if not math.isnan(value): 2116 self.fail("Expected a NaN, got {!r}.".format(value)) 2117 2118 def assertEqualSign(self, x, y): 2119 """Similar to assertEqual(), but compare also the sign with copysign(). 2120 2121 Function useful to compare signed zeros. 2122 """ 2123 self.assertEqual(x, y) 2124 self.assertEqual(math.copysign(1.0, x), math.copysign(1.0, y)) 2125 2126 2127class IsCloseTests(unittest.TestCase): 2128 isclose = math.isclose # subclasses should override this 2129 2130 def assertIsClose(self, a, b, *args, **kwargs): 2131 self.assertTrue(self.isclose(a, b, *args, **kwargs), 2132 msg="%s and %s should be close!" % (a, b)) 2133 2134 def assertIsNotClose(self, a, b, *args, **kwargs): 2135 self.assertFalse(self.isclose(a, b, *args, **kwargs), 2136 msg="%s and %s should not be close!" % (a, b)) 2137 2138 def assertAllClose(self, examples, *args, **kwargs): 2139 for a, b in examples: 2140 self.assertIsClose(a, b, *args, **kwargs) 2141 2142 def assertAllNotClose(self, examples, *args, **kwargs): 2143 for a, b in examples: 2144 self.assertIsNotClose(a, b, *args, **kwargs) 2145 2146 def test_negative_tolerances(self): 2147 # ValueError should be raised if either tolerance is less than zero 2148 with self.assertRaises(ValueError): 2149 self.assertIsClose(1, 1, rel_tol=-1e-100) 2150 with self.assertRaises(ValueError): 2151 self.assertIsClose(1, 1, rel_tol=1e-100, abs_tol=-1e10) 2152 2153 def test_identical(self): 2154 # identical values must test as close 2155 identical_examples = [(2.0, 2.0), 2156 (0.1e200, 0.1e200), 2157 (1.123e-300, 1.123e-300), 2158 (12345, 12345.0), 2159 (0.0, -0.0), 2160 (345678, 345678)] 2161 self.assertAllClose(identical_examples, rel_tol=0.0, abs_tol=0.0) 2162 2163 def test_eight_decimal_places(self): 2164 # examples that are close to 1e-8, but not 1e-9 2165 eight_decimal_places_examples = [(1e8, 1e8 + 1), 2166 (-1e-8, -1.000000009e-8), 2167 (1.12345678, 1.12345679)] 2168 self.assertAllClose(eight_decimal_places_examples, rel_tol=1e-8) 2169 self.assertAllNotClose(eight_decimal_places_examples, rel_tol=1e-9) 2170 2171 def test_near_zero(self): 2172 # values close to zero 2173 near_zero_examples = [(1e-9, 0.0), 2174 (-1e-9, 0.0), 2175 (-1e-150, 0.0)] 2176 # these should not be close to any rel_tol 2177 self.assertAllNotClose(near_zero_examples, rel_tol=0.9) 2178 # these should be close to abs_tol=1e-8 2179 self.assertAllClose(near_zero_examples, abs_tol=1e-8) 2180 2181 def test_identical_infinite(self): 2182 # these are close regardless of tolerance -- i.e. they are equal 2183 self.assertIsClose(INF, INF) 2184 self.assertIsClose(INF, INF, abs_tol=0.0) 2185 self.assertIsClose(NINF, NINF) 2186 self.assertIsClose(NINF, NINF, abs_tol=0.0) 2187 2188 def test_inf_ninf_nan(self): 2189 # these should never be close (following IEEE 754 rules for equality) 2190 not_close_examples = [(NAN, NAN), 2191 (NAN, 1e-100), 2192 (1e-100, NAN), 2193 (INF, NAN), 2194 (NAN, INF), 2195 (INF, NINF), 2196 (INF, 1.0), 2197 (1.0, INF), 2198 (INF, 1e308), 2199 (1e308, INF)] 2200 # use largest reasonable tolerance 2201 self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999) 2202 2203 def test_zero_tolerance(self): 2204 # test with zero tolerance 2205 zero_tolerance_close_examples = [(1.0, 1.0), 2206 (-3.4, -3.4), 2207 (-1e-300, -1e-300)] 2208 self.assertAllClose(zero_tolerance_close_examples, rel_tol=0.0) 2209 2210 zero_tolerance_not_close_examples = [(1.0, 1.000000000000001), 2211 (0.99999999999999, 1.0), 2212 (1.0e200, .999999999999999e200)] 2213 self.assertAllNotClose(zero_tolerance_not_close_examples, rel_tol=0.0) 2214 2215 def test_asymmetry(self): 2216 # test the asymmetry example from PEP 485 2217 self.assertAllClose([(9, 10), (10, 9)], rel_tol=0.1) 2218 2219 def test_integers(self): 2220 # test with integer values 2221 integer_examples = [(100000001, 100000000), 2222 (123456789, 123456788)] 2223 2224 self.assertAllClose(integer_examples, rel_tol=1e-8) 2225 self.assertAllNotClose(integer_examples, rel_tol=1e-9) 2226 2227 def test_decimals(self): 2228 # test with Decimal values 2229 from decimal import Decimal 2230 2231 decimal_examples = [(Decimal('1.00000001'), Decimal('1.0')), 2232 (Decimal('1.00000001e-20'), Decimal('1.0e-20')), 2233 (Decimal('1.00000001e-100'), Decimal('1.0e-100')), 2234 (Decimal('1.00000001e20'), Decimal('1.0e20'))] 2235 self.assertAllClose(decimal_examples, rel_tol=1e-8) 2236 self.assertAllNotClose(decimal_examples, rel_tol=1e-9) 2237 2238 def test_fractions(self): 2239 # test with Fraction values 2240 from fractions import Fraction 2241 2242 fraction_examples = [ 2243 (Fraction(1, 100000000) + 1, Fraction(1)), 2244 (Fraction(100000001), Fraction(100000000)), 2245 (Fraction(10**8 + 1, 10**28), Fraction(1, 10**20))] 2246 self.assertAllClose(fraction_examples, rel_tol=1e-8) 2247 self.assertAllNotClose(fraction_examples, rel_tol=1e-9) 2248 2249 2250def load_tests(loader, tests, pattern): 2251 from doctest import DocFileSuite 2252 tests.addTest(DocFileSuite("ieee754.txt")) 2253 return tests 2254 2255if __name__ == '__main__': 2256 unittest.main() 2257