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 testIsqrt(self): 1010 # Test a variety of inputs, large and small. 1011 test_values = ( 1012 list(range(1000)) 1013 + list(range(10**6 - 1000, 10**6 + 1000)) 1014 + [2**e + i for e in range(60, 200) for i in range(-40, 40)] 1015 + [3**9999, 10**5001] 1016 ) 1017 1018 for value in test_values: 1019 with self.subTest(value=value): 1020 s = math.isqrt(value) 1021 self.assertIs(type(s), int) 1022 self.assertLessEqual(s*s, value) 1023 self.assertLess(value, (s+1)*(s+1)) 1024 1025 # Negative values 1026 with self.assertRaises(ValueError): 1027 math.isqrt(-1) 1028 1029 # Integer-like things 1030 s = math.isqrt(True) 1031 self.assertIs(type(s), int) 1032 self.assertEqual(s, 1) 1033 1034 s = math.isqrt(False) 1035 self.assertIs(type(s), int) 1036 self.assertEqual(s, 0) 1037 1038 class IntegerLike(object): 1039 def __init__(self, value): 1040 self.value = value 1041 1042 def __index__(self): 1043 return self.value 1044 1045 s = math.isqrt(IntegerLike(1729)) 1046 self.assertIs(type(s), int) 1047 self.assertEqual(s, 41) 1048 1049 with self.assertRaises(ValueError): 1050 math.isqrt(IntegerLike(-3)) 1051 1052 # Non-integer-like things 1053 bad_values = [ 1054 3.5, "a string", decimal.Decimal("3.5"), 3.5j, 1055 100.0, -4.0, 1056 ] 1057 for value in bad_values: 1058 with self.subTest(value=value): 1059 with self.assertRaises(TypeError): 1060 math.isqrt(value) 1061 1062 def test_lcm(self): 1063 lcm = math.lcm 1064 self.assertEqual(lcm(0, 0), 0) 1065 self.assertEqual(lcm(1, 0), 0) 1066 self.assertEqual(lcm(-1, 0), 0) 1067 self.assertEqual(lcm(0, 1), 0) 1068 self.assertEqual(lcm(0, -1), 0) 1069 self.assertEqual(lcm(7, 1), 7) 1070 self.assertEqual(lcm(7, -1), 7) 1071 self.assertEqual(lcm(-23, 15), 345) 1072 self.assertEqual(lcm(120, 84), 840) 1073 self.assertEqual(lcm(84, -120), 840) 1074 self.assertEqual(lcm(1216342683557601535506311712, 1075 436522681849110124616458784), 1076 16592536571065866494401400422922201534178938447014944) 1077 1078 x = 43461045657039990237 1079 y = 10645022458251153277 1080 for c in (652560, 1081 57655923087165495981): 1082 a = x * c 1083 b = y * c 1084 d = x * y * c 1085 self.assertEqual(lcm(a, b), d) 1086 self.assertEqual(lcm(b, a), d) 1087 self.assertEqual(lcm(-a, b), d) 1088 self.assertEqual(lcm(b, -a), d) 1089 self.assertEqual(lcm(a, -b), d) 1090 self.assertEqual(lcm(-b, a), d) 1091 self.assertEqual(lcm(-a, -b), d) 1092 self.assertEqual(lcm(-b, -a), d) 1093 1094 self.assertEqual(lcm(), 1) 1095 self.assertEqual(lcm(120), 120) 1096 self.assertEqual(lcm(-120), 120) 1097 self.assertEqual(lcm(120, 84, 102), 14280) 1098 self.assertEqual(lcm(120, 0, 84), 0) 1099 1100 self.assertRaises(TypeError, lcm, 120.0) 1101 self.assertRaises(TypeError, lcm, 120.0, 84) 1102 self.assertRaises(TypeError, lcm, 120, 84.0) 1103 self.assertRaises(TypeError, lcm, 120, 0, 84.0) 1104 self.assertEqual(lcm(MyIndexable(120), MyIndexable(84)), 840) 1105 1106 def testLdexp(self): 1107 self.assertRaises(TypeError, math.ldexp) 1108 self.ftest('ldexp(0,1)', math.ldexp(0,1), 0) 1109 self.ftest('ldexp(1,1)', math.ldexp(1,1), 2) 1110 self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5) 1111 self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2) 1112 self.assertRaises(OverflowError, math.ldexp, 1., 1000000) 1113 self.assertRaises(OverflowError, math.ldexp, -1., 1000000) 1114 self.assertEqual(math.ldexp(1., -1000000), 0.) 1115 self.assertEqual(math.ldexp(-1., -1000000), -0.) 1116 self.assertEqual(math.ldexp(INF, 30), INF) 1117 self.assertEqual(math.ldexp(NINF, -213), NINF) 1118 self.assertTrue(math.isnan(math.ldexp(NAN, 0))) 1119 1120 # large second argument 1121 for n in [10**5, 10**10, 10**20, 10**40]: 1122 self.assertEqual(math.ldexp(INF, -n), INF) 1123 self.assertEqual(math.ldexp(NINF, -n), NINF) 1124 self.assertEqual(math.ldexp(1., -n), 0.) 1125 self.assertEqual(math.ldexp(-1., -n), -0.) 1126 self.assertEqual(math.ldexp(0., -n), 0.) 1127 self.assertEqual(math.ldexp(-0., -n), -0.) 1128 self.assertTrue(math.isnan(math.ldexp(NAN, -n))) 1129 1130 self.assertRaises(OverflowError, math.ldexp, 1., n) 1131 self.assertRaises(OverflowError, math.ldexp, -1., n) 1132 self.assertEqual(math.ldexp(0., n), 0.) 1133 self.assertEqual(math.ldexp(-0., n), -0.) 1134 self.assertEqual(math.ldexp(INF, n), INF) 1135 self.assertEqual(math.ldexp(NINF, n), NINF) 1136 self.assertTrue(math.isnan(math.ldexp(NAN, n))) 1137 1138 def testLog(self): 1139 self.assertRaises(TypeError, math.log) 1140 self.ftest('log(1/e)', math.log(1/math.e), -1) 1141 self.ftest('log(1)', math.log(1), 0) 1142 self.ftest('log(e)', math.log(math.e), 1) 1143 self.ftest('log(32,2)', math.log(32,2), 5) 1144 self.ftest('log(10**40, 10)', math.log(10**40, 10), 40) 1145 self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2) 1146 self.ftest('log(10**1000)', math.log(10**1000), 1147 2302.5850929940457) 1148 self.assertRaises(ValueError, math.log, -1.5) 1149 self.assertRaises(ValueError, math.log, -10**1000) 1150 self.assertRaises(ValueError, math.log, NINF) 1151 self.assertEqual(math.log(INF), INF) 1152 self.assertTrue(math.isnan(math.log(NAN))) 1153 1154 def testLog1p(self): 1155 self.assertRaises(TypeError, math.log1p) 1156 for n in [2, 2**90, 2**300]: 1157 self.assertAlmostEqual(math.log1p(n), math.log1p(float(n))) 1158 self.assertRaises(ValueError, math.log1p, -1) 1159 self.assertEqual(math.log1p(INF), INF) 1160 1161 @requires_IEEE_754 1162 def testLog2(self): 1163 self.assertRaises(TypeError, math.log2) 1164 1165 # Check some integer values 1166 self.assertEqual(math.log2(1), 0.0) 1167 self.assertEqual(math.log2(2), 1.0) 1168 self.assertEqual(math.log2(4), 2.0) 1169 1170 # Large integer values 1171 self.assertEqual(math.log2(2**1023), 1023.0) 1172 self.assertEqual(math.log2(2**1024), 1024.0) 1173 self.assertEqual(math.log2(2**2000), 2000.0) 1174 1175 self.assertRaises(ValueError, math.log2, -1.5) 1176 self.assertRaises(ValueError, math.log2, NINF) 1177 self.assertTrue(math.isnan(math.log2(NAN))) 1178 1179 @requires_IEEE_754 1180 # log2() is not accurate enough on Mac OS X Tiger (10.4) 1181 @support.requires_mac_ver(10, 5) 1182 def testLog2Exact(self): 1183 # Check that we get exact equality for log2 of powers of 2. 1184 actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)] 1185 expected = [float(n) for n in range(-1074, 1024)] 1186 self.assertEqual(actual, expected) 1187 1188 def testLog10(self): 1189 self.assertRaises(TypeError, math.log10) 1190 self.ftest('log10(0.1)', math.log10(0.1), -1) 1191 self.ftest('log10(1)', math.log10(1), 0) 1192 self.ftest('log10(10)', math.log10(10), 1) 1193 self.ftest('log10(10**1000)', math.log10(10**1000), 1000.0) 1194 self.assertRaises(ValueError, math.log10, -1.5) 1195 self.assertRaises(ValueError, math.log10, -10**1000) 1196 self.assertRaises(ValueError, math.log10, NINF) 1197 self.assertEqual(math.log(INF), INF) 1198 self.assertTrue(math.isnan(math.log10(NAN))) 1199 1200 def testModf(self): 1201 self.assertRaises(TypeError, math.modf) 1202 1203 def testmodf(name, result, expected): 1204 (v1, v2), (e1, e2) = result, expected 1205 if abs(v1-e1) > eps or abs(v2-e2): 1206 self.fail('%s returned %r, expected %r'%\ 1207 (name, result, expected)) 1208 1209 testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0)) 1210 testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0)) 1211 1212 self.assertEqual(math.modf(INF), (0.0, INF)) 1213 self.assertEqual(math.modf(NINF), (-0.0, NINF)) 1214 1215 modf_nan = math.modf(NAN) 1216 self.assertTrue(math.isnan(modf_nan[0])) 1217 self.assertTrue(math.isnan(modf_nan[1])) 1218 1219 def testPow(self): 1220 self.assertRaises(TypeError, math.pow) 1221 self.ftest('pow(0,1)', math.pow(0,1), 0) 1222 self.ftest('pow(1,0)', math.pow(1,0), 1) 1223 self.ftest('pow(2,1)', math.pow(2,1), 2) 1224 self.ftest('pow(2,-1)', math.pow(2,-1), 0.5) 1225 self.assertEqual(math.pow(INF, 1), INF) 1226 self.assertEqual(math.pow(NINF, 1), NINF) 1227 self.assertEqual((math.pow(1, INF)), 1.) 1228 self.assertEqual((math.pow(1, NINF)), 1.) 1229 self.assertTrue(math.isnan(math.pow(NAN, 1))) 1230 self.assertTrue(math.isnan(math.pow(2, NAN))) 1231 self.assertTrue(math.isnan(math.pow(0, NAN))) 1232 self.assertEqual(math.pow(1, NAN), 1) 1233 1234 # pow(0., x) 1235 self.assertEqual(math.pow(0., INF), 0.) 1236 self.assertEqual(math.pow(0., 3.), 0.) 1237 self.assertEqual(math.pow(0., 2.3), 0.) 1238 self.assertEqual(math.pow(0., 2.), 0.) 1239 self.assertEqual(math.pow(0., 0.), 1.) 1240 self.assertEqual(math.pow(0., -0.), 1.) 1241 self.assertRaises(ValueError, math.pow, 0., -2.) 1242 self.assertRaises(ValueError, math.pow, 0., -2.3) 1243 self.assertRaises(ValueError, math.pow, 0., -3.) 1244 self.assertEqual(math.pow(0., NINF), INF) 1245 self.assertTrue(math.isnan(math.pow(0., NAN))) 1246 1247 # pow(INF, x) 1248 self.assertEqual(math.pow(INF, INF), INF) 1249 self.assertEqual(math.pow(INF, 3.), INF) 1250 self.assertEqual(math.pow(INF, 2.3), INF) 1251 self.assertEqual(math.pow(INF, 2.), INF) 1252 self.assertEqual(math.pow(INF, 0.), 1.) 1253 self.assertEqual(math.pow(INF, -0.), 1.) 1254 self.assertEqual(math.pow(INF, -2.), 0.) 1255 self.assertEqual(math.pow(INF, -2.3), 0.) 1256 self.assertEqual(math.pow(INF, -3.), 0.) 1257 self.assertEqual(math.pow(INF, NINF), 0.) 1258 self.assertTrue(math.isnan(math.pow(INF, NAN))) 1259 1260 # pow(-0., x) 1261 self.assertEqual(math.pow(-0., INF), 0.) 1262 self.assertEqual(math.pow(-0., 3.), -0.) 1263 self.assertEqual(math.pow(-0., 2.3), 0.) 1264 self.assertEqual(math.pow(-0., 2.), 0.) 1265 self.assertEqual(math.pow(-0., 0.), 1.) 1266 self.assertEqual(math.pow(-0., -0.), 1.) 1267 self.assertRaises(ValueError, math.pow, -0., -2.) 1268 self.assertRaises(ValueError, math.pow, -0., -2.3) 1269 self.assertRaises(ValueError, math.pow, -0., -3.) 1270 self.assertEqual(math.pow(-0., NINF), INF) 1271 self.assertTrue(math.isnan(math.pow(-0., NAN))) 1272 1273 # pow(NINF, x) 1274 self.assertEqual(math.pow(NINF, INF), INF) 1275 self.assertEqual(math.pow(NINF, 3.), NINF) 1276 self.assertEqual(math.pow(NINF, 2.3), INF) 1277 self.assertEqual(math.pow(NINF, 2.), INF) 1278 self.assertEqual(math.pow(NINF, 0.), 1.) 1279 self.assertEqual(math.pow(NINF, -0.), 1.) 1280 self.assertEqual(math.pow(NINF, -2.), 0.) 1281 self.assertEqual(math.pow(NINF, -2.3), 0.) 1282 self.assertEqual(math.pow(NINF, -3.), -0.) 1283 self.assertEqual(math.pow(NINF, NINF), 0.) 1284 self.assertTrue(math.isnan(math.pow(NINF, NAN))) 1285 1286 # pow(-1, x) 1287 self.assertEqual(math.pow(-1., INF), 1.) 1288 self.assertEqual(math.pow(-1., 3.), -1.) 1289 self.assertRaises(ValueError, math.pow, -1., 2.3) 1290 self.assertEqual(math.pow(-1., 2.), 1.) 1291 self.assertEqual(math.pow(-1., 0.), 1.) 1292 self.assertEqual(math.pow(-1., -0.), 1.) 1293 self.assertEqual(math.pow(-1., -2.), 1.) 1294 self.assertRaises(ValueError, math.pow, -1., -2.3) 1295 self.assertEqual(math.pow(-1., -3.), -1.) 1296 self.assertEqual(math.pow(-1., NINF), 1.) 1297 self.assertTrue(math.isnan(math.pow(-1., NAN))) 1298 1299 # pow(1, x) 1300 self.assertEqual(math.pow(1., INF), 1.) 1301 self.assertEqual(math.pow(1., 3.), 1.) 1302 self.assertEqual(math.pow(1., 2.3), 1.) 1303 self.assertEqual(math.pow(1., 2.), 1.) 1304 self.assertEqual(math.pow(1., 0.), 1.) 1305 self.assertEqual(math.pow(1., -0.), 1.) 1306 self.assertEqual(math.pow(1., -2.), 1.) 1307 self.assertEqual(math.pow(1., -2.3), 1.) 1308 self.assertEqual(math.pow(1., -3.), 1.) 1309 self.assertEqual(math.pow(1., NINF), 1.) 1310 self.assertEqual(math.pow(1., NAN), 1.) 1311 1312 # pow(x, 0) should be 1 for any x 1313 self.assertEqual(math.pow(2.3, 0.), 1.) 1314 self.assertEqual(math.pow(-2.3, 0.), 1.) 1315 self.assertEqual(math.pow(NAN, 0.), 1.) 1316 self.assertEqual(math.pow(2.3, -0.), 1.) 1317 self.assertEqual(math.pow(-2.3, -0.), 1.) 1318 self.assertEqual(math.pow(NAN, -0.), 1.) 1319 1320 # pow(x, y) is invalid if x is negative and y is not integral 1321 self.assertRaises(ValueError, math.pow, -1., 2.3) 1322 self.assertRaises(ValueError, math.pow, -15., -3.1) 1323 1324 # pow(x, NINF) 1325 self.assertEqual(math.pow(1.9, NINF), 0.) 1326 self.assertEqual(math.pow(1.1, NINF), 0.) 1327 self.assertEqual(math.pow(0.9, NINF), INF) 1328 self.assertEqual(math.pow(0.1, NINF), INF) 1329 self.assertEqual(math.pow(-0.1, NINF), INF) 1330 self.assertEqual(math.pow(-0.9, NINF), INF) 1331 self.assertEqual(math.pow(-1.1, NINF), 0.) 1332 self.assertEqual(math.pow(-1.9, NINF), 0.) 1333 1334 # pow(x, INF) 1335 self.assertEqual(math.pow(1.9, INF), INF) 1336 self.assertEqual(math.pow(1.1, INF), INF) 1337 self.assertEqual(math.pow(0.9, INF), 0.) 1338 self.assertEqual(math.pow(0.1, INF), 0.) 1339 self.assertEqual(math.pow(-0.1, INF), 0.) 1340 self.assertEqual(math.pow(-0.9, INF), 0.) 1341 self.assertEqual(math.pow(-1.1, INF), INF) 1342 self.assertEqual(math.pow(-1.9, INF), INF) 1343 1344 # pow(x, y) should work for x negative, y an integer 1345 self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0) 1346 self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0) 1347 self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0) 1348 self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0) 1349 self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0) 1350 self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5) 1351 self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25) 1352 self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125) 1353 self.assertRaises(ValueError, math.pow, -2.0, -0.5) 1354 self.assertRaises(ValueError, math.pow, -2.0, 0.5) 1355 1356 # the following tests have been commented out since they don't 1357 # really belong here: the implementation of ** for floats is 1358 # independent of the implementation of math.pow 1359 #self.assertEqual(1**NAN, 1) 1360 #self.assertEqual(1**INF, 1) 1361 #self.assertEqual(1**NINF, 1) 1362 #self.assertEqual(1**0, 1) 1363 #self.assertEqual(1.**NAN, 1) 1364 #self.assertEqual(1.**INF, 1) 1365 #self.assertEqual(1.**NINF, 1) 1366 #self.assertEqual(1.**0, 1) 1367 1368 def testRadians(self): 1369 self.assertRaises(TypeError, math.radians) 1370 self.ftest('radians(180)', math.radians(180), math.pi) 1371 self.ftest('radians(90)', math.radians(90), math.pi/2) 1372 self.ftest('radians(-45)', math.radians(-45), -math.pi/4) 1373 self.ftest('radians(0)', math.radians(0), 0) 1374 1375 @requires_IEEE_754 1376 def testRemainder(self): 1377 from fractions import Fraction 1378 1379 def validate_spec(x, y, r): 1380 """ 1381 Check that r matches remainder(x, y) according to the IEEE 754 1382 specification. Assumes that x, y and r are finite and y is nonzero. 1383 """ 1384 fx, fy, fr = Fraction(x), Fraction(y), Fraction(r) 1385 # r should not exceed y/2 in absolute value 1386 self.assertLessEqual(abs(fr), abs(fy/2)) 1387 # x - r should be an exact integer multiple of y 1388 n = (fx - fr) / fy 1389 self.assertEqual(n, int(n)) 1390 if abs(fr) == abs(fy/2): 1391 # If |r| == |y/2|, n should be even. 1392 self.assertEqual(n/2, int(n/2)) 1393 1394 # triples (x, y, remainder(x, y)) in hexadecimal form. 1395 testcases = [ 1396 # Remainders modulo 1, showing the ties-to-even behaviour. 1397 '-4.0 1 -0.0', 1398 '-3.8 1 0.8', 1399 '-3.0 1 -0.0', 1400 '-2.8 1 -0.8', 1401 '-2.0 1 -0.0', 1402 '-1.8 1 0.8', 1403 '-1.0 1 -0.0', 1404 '-0.8 1 -0.8', 1405 '-0.0 1 -0.0', 1406 ' 0.0 1 0.0', 1407 ' 0.8 1 0.8', 1408 ' 1.0 1 0.0', 1409 ' 1.8 1 -0.8', 1410 ' 2.0 1 0.0', 1411 ' 2.8 1 0.8', 1412 ' 3.0 1 0.0', 1413 ' 3.8 1 -0.8', 1414 ' 4.0 1 0.0', 1415 1416 # Reductions modulo 2*pi 1417 '0x0.0p+0 0x1.921fb54442d18p+2 0x0.0p+0', 1418 '0x1.921fb54442d18p+0 0x1.921fb54442d18p+2 0x1.921fb54442d18p+0', 1419 '0x1.921fb54442d17p+1 0x1.921fb54442d18p+2 0x1.921fb54442d17p+1', 1420 '0x1.921fb54442d18p+1 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1', 1421 '0x1.921fb54442d19p+1 0x1.921fb54442d18p+2 -0x1.921fb54442d17p+1', 1422 '0x1.921fb54442d17p+2 0x1.921fb54442d18p+2 -0x0.0000000000001p+2', 1423 '0x1.921fb54442d18p+2 0x1.921fb54442d18p+2 0x0p0', 1424 '0x1.921fb54442d19p+2 0x1.921fb54442d18p+2 0x0.0000000000001p+2', 1425 '0x1.2d97c7f3321d1p+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1', 1426 '0x1.2d97c7f3321d2p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d18p+1', 1427 '0x1.2d97c7f3321d3p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1', 1428 '0x1.921fb54442d17p+3 0x1.921fb54442d18p+2 -0x0.0000000000001p+3', 1429 '0x1.921fb54442d18p+3 0x1.921fb54442d18p+2 0x0p0', 1430 '0x1.921fb54442d19p+3 0x1.921fb54442d18p+2 0x0.0000000000001p+3', 1431 '0x1.f6a7a2955385dp+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1', 1432 '0x1.f6a7a2955385ep+3 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1', 1433 '0x1.f6a7a2955385fp+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1', 1434 '0x1.1475cc9eedf00p+5 0x1.921fb54442d18p+2 0x1.921fb54442d10p+1', 1435 '0x1.1475cc9eedf01p+5 0x1.921fb54442d18p+2 -0x1.921fb54442d10p+1', 1436 1437 # Symmetry with respect to signs. 1438 ' 1 0.c 0.4', 1439 '-1 0.c -0.4', 1440 ' 1 -0.c 0.4', 1441 '-1 -0.c -0.4', 1442 ' 1.4 0.c -0.4', 1443 '-1.4 0.c 0.4', 1444 ' 1.4 -0.c -0.4', 1445 '-1.4 -0.c 0.4', 1446 1447 # Huge modulus, to check that the underlying algorithm doesn't 1448 # rely on 2.0 * modulus being representable. 1449 '0x1.dp+1023 0x1.4p+1023 0x0.9p+1023', 1450 '0x1.ep+1023 0x1.4p+1023 -0x0.ap+1023', 1451 '0x1.fp+1023 0x1.4p+1023 -0x0.9p+1023', 1452 ] 1453 1454 for case in testcases: 1455 with self.subTest(case=case): 1456 x_hex, y_hex, expected_hex = case.split() 1457 x = float.fromhex(x_hex) 1458 y = float.fromhex(y_hex) 1459 expected = float.fromhex(expected_hex) 1460 validate_spec(x, y, expected) 1461 actual = math.remainder(x, y) 1462 # Cheap way of checking that the floats are 1463 # as identical as we need them to be. 1464 self.assertEqual(actual.hex(), expected.hex()) 1465 1466 # Test tiny subnormal modulus: there's potential for 1467 # getting the implementation wrong here (for example, 1468 # by assuming that modulus/2 is exactly representable). 1469 tiny = float.fromhex('1p-1074') # min +ve subnormal 1470 for n in range(-25, 25): 1471 if n == 0: 1472 continue 1473 y = n * tiny 1474 for m in range(100): 1475 x = m * tiny 1476 actual = math.remainder(x, y) 1477 validate_spec(x, y, actual) 1478 actual = math.remainder(-x, y) 1479 validate_spec(-x, y, actual) 1480 1481 # Special values. 1482 # NaNs should propagate as usual. 1483 for value in [NAN, 0.0, -0.0, 2.0, -2.3, NINF, INF]: 1484 self.assertIsNaN(math.remainder(NAN, value)) 1485 self.assertIsNaN(math.remainder(value, NAN)) 1486 1487 # remainder(x, inf) is x, for non-nan non-infinite x. 1488 for value in [-2.3, -0.0, 0.0, 2.3]: 1489 self.assertEqual(math.remainder(value, INF), value) 1490 self.assertEqual(math.remainder(value, NINF), value) 1491 1492 # remainder(x, 0) and remainder(infinity, x) for non-NaN x are invalid 1493 # operations according to IEEE 754-2008 7.2(f), and should raise. 1494 for value in [NINF, -2.3, -0.0, 0.0, 2.3, INF]: 1495 with self.assertRaises(ValueError): 1496 math.remainder(INF, value) 1497 with self.assertRaises(ValueError): 1498 math.remainder(NINF, value) 1499 with self.assertRaises(ValueError): 1500 math.remainder(value, 0.0) 1501 with self.assertRaises(ValueError): 1502 math.remainder(value, -0.0) 1503 1504 def testSin(self): 1505 self.assertRaises(TypeError, math.sin) 1506 self.ftest('sin(0)', math.sin(0), 0) 1507 self.ftest('sin(pi/2)', math.sin(math.pi/2), 1) 1508 self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1) 1509 try: 1510 self.assertTrue(math.isnan(math.sin(INF))) 1511 self.assertTrue(math.isnan(math.sin(NINF))) 1512 except ValueError: 1513 self.assertRaises(ValueError, math.sin, INF) 1514 self.assertRaises(ValueError, math.sin, NINF) 1515 self.assertTrue(math.isnan(math.sin(NAN))) 1516 1517 def testSinh(self): 1518 self.assertRaises(TypeError, math.sinh) 1519 self.ftest('sinh(0)', math.sinh(0), 0) 1520 self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1) 1521 self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0) 1522 self.assertEqual(math.sinh(INF), INF) 1523 self.assertEqual(math.sinh(NINF), NINF) 1524 self.assertTrue(math.isnan(math.sinh(NAN))) 1525 1526 def testSqrt(self): 1527 self.assertRaises(TypeError, math.sqrt) 1528 self.ftest('sqrt(0)', math.sqrt(0), 0) 1529 self.ftest('sqrt(0)', math.sqrt(0.0), 0.0) 1530 self.ftest('sqrt(2.5)', math.sqrt(2.5), 1.5811388300841898) 1531 self.ftest('sqrt(0.25)', math.sqrt(0.25), 0.5) 1532 self.ftest('sqrt(25.25)', math.sqrt(25.25), 5.024937810560445) 1533 self.ftest('sqrt(1)', math.sqrt(1), 1) 1534 self.ftest('sqrt(4)', math.sqrt(4), 2) 1535 self.assertEqual(math.sqrt(INF), INF) 1536 self.assertRaises(ValueError, math.sqrt, -1) 1537 self.assertRaises(ValueError, math.sqrt, NINF) 1538 self.assertTrue(math.isnan(math.sqrt(NAN))) 1539 1540 def testTan(self): 1541 self.assertRaises(TypeError, math.tan) 1542 self.ftest('tan(0)', math.tan(0), 0) 1543 self.ftest('tan(pi/4)', math.tan(math.pi/4), 1) 1544 self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1) 1545 try: 1546 self.assertTrue(math.isnan(math.tan(INF))) 1547 self.assertTrue(math.isnan(math.tan(NINF))) 1548 except: 1549 self.assertRaises(ValueError, math.tan, INF) 1550 self.assertRaises(ValueError, math.tan, NINF) 1551 self.assertTrue(math.isnan(math.tan(NAN))) 1552 1553 def testTanh(self): 1554 self.assertRaises(TypeError, math.tanh) 1555 self.ftest('tanh(0)', math.tanh(0), 0) 1556 self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0, 1557 abs_tol=math.ulp(1)) 1558 self.ftest('tanh(inf)', math.tanh(INF), 1) 1559 self.ftest('tanh(-inf)', math.tanh(NINF), -1) 1560 self.assertTrue(math.isnan(math.tanh(NAN))) 1561 1562 @requires_IEEE_754 1563 def testTanhSign(self): 1564 # check that tanh(-0.) == -0. on IEEE 754 systems 1565 self.assertEqual(math.tanh(-0.), -0.) 1566 self.assertEqual(math.copysign(1., math.tanh(-0.)), 1567 math.copysign(1., -0.)) 1568 1569 def test_trunc(self): 1570 self.assertEqual(math.trunc(1), 1) 1571 self.assertEqual(math.trunc(-1), -1) 1572 self.assertEqual(type(math.trunc(1)), int) 1573 self.assertEqual(type(math.trunc(1.5)), int) 1574 self.assertEqual(math.trunc(1.5), 1) 1575 self.assertEqual(math.trunc(-1.5), -1) 1576 self.assertEqual(math.trunc(1.999999), 1) 1577 self.assertEqual(math.trunc(-1.999999), -1) 1578 self.assertEqual(math.trunc(-0.999999), -0) 1579 self.assertEqual(math.trunc(-100.999), -100) 1580 1581 class TestTrunc: 1582 def __trunc__(self): 1583 return 23 1584 class FloatTrunc(float): 1585 def __trunc__(self): 1586 return 23 1587 class TestNoTrunc: 1588 pass 1589 1590 self.assertEqual(math.trunc(TestTrunc()), 23) 1591 self.assertEqual(math.trunc(FloatTrunc()), 23) 1592 1593 self.assertRaises(TypeError, math.trunc) 1594 self.assertRaises(TypeError, math.trunc, 1, 2) 1595 self.assertRaises(TypeError, math.trunc, FloatLike(23.5)) 1596 self.assertRaises(TypeError, math.trunc, TestNoTrunc()) 1597 1598 def testIsfinite(self): 1599 self.assertTrue(math.isfinite(0.0)) 1600 self.assertTrue(math.isfinite(-0.0)) 1601 self.assertTrue(math.isfinite(1.0)) 1602 self.assertTrue(math.isfinite(-1.0)) 1603 self.assertFalse(math.isfinite(float("nan"))) 1604 self.assertFalse(math.isfinite(float("inf"))) 1605 self.assertFalse(math.isfinite(float("-inf"))) 1606 1607 def testIsnan(self): 1608 self.assertTrue(math.isnan(float("nan"))) 1609 self.assertTrue(math.isnan(float("-nan"))) 1610 self.assertTrue(math.isnan(float("inf") * 0.)) 1611 self.assertFalse(math.isnan(float("inf"))) 1612 self.assertFalse(math.isnan(0.)) 1613 self.assertFalse(math.isnan(1.)) 1614 1615 def testIsinf(self): 1616 self.assertTrue(math.isinf(float("inf"))) 1617 self.assertTrue(math.isinf(float("-inf"))) 1618 self.assertTrue(math.isinf(1E400)) 1619 self.assertTrue(math.isinf(-1E400)) 1620 self.assertFalse(math.isinf(float("nan"))) 1621 self.assertFalse(math.isinf(0.)) 1622 self.assertFalse(math.isinf(1.)) 1623 1624 @requires_IEEE_754 1625 def test_nan_constant(self): 1626 self.assertTrue(math.isnan(math.nan)) 1627 1628 @requires_IEEE_754 1629 def test_inf_constant(self): 1630 self.assertTrue(math.isinf(math.inf)) 1631 self.assertGreater(math.inf, 0.0) 1632 self.assertEqual(math.inf, float("inf")) 1633 self.assertEqual(-math.inf, float("-inf")) 1634 1635 # RED_FLAG 16-Oct-2000 Tim 1636 # While 2.0 is more consistent about exceptions than previous releases, it 1637 # still fails this part of the test on some platforms. For now, we only 1638 # *run* test_exceptions() in verbose mode, so that this isn't normally 1639 # tested. 1640 @unittest.skipUnless(verbose, 'requires verbose mode') 1641 def test_exceptions(self): 1642 try: 1643 x = math.exp(-1000000000) 1644 except: 1645 # mathmodule.c is failing to weed out underflows from libm, or 1646 # we've got an fp format with huge dynamic range 1647 self.fail("underflowing exp() should not have raised " 1648 "an exception") 1649 if x != 0: 1650 self.fail("underflowing exp() should have returned 0") 1651 1652 # If this fails, probably using a strict IEEE-754 conforming libm, and x 1653 # is +Inf afterwards. But Python wants overflows detected by default. 1654 try: 1655 x = math.exp(1000000000) 1656 except OverflowError: 1657 pass 1658 else: 1659 self.fail("overflowing exp() didn't trigger OverflowError") 1660 1661 # If this fails, it could be a puzzle. One odd possibility is that 1662 # mathmodule.c's macros are getting confused while comparing 1663 # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE 1664 # as a result (and so raising OverflowError instead). 1665 try: 1666 x = math.sqrt(-1.0) 1667 except ValueError: 1668 pass 1669 else: 1670 self.fail("sqrt(-1) didn't raise ValueError") 1671 1672 @requires_IEEE_754 1673 def test_testfile(self): 1674 # Some tests need to be skipped on ancient OS X versions. 1675 # See issue #27953. 1676 SKIP_ON_TIGER = {'tan0064'} 1677 1678 osx_version = None 1679 if sys.platform == 'darwin': 1680 version_txt = platform.mac_ver()[0] 1681 try: 1682 osx_version = tuple(map(int, version_txt.split('.'))) 1683 except ValueError: 1684 pass 1685 1686 fail_fmt = "{}: {}({!r}): {}" 1687 1688 failures = [] 1689 for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file): 1690 # Skip if either the input or result is complex 1691 if ai != 0.0 or ei != 0.0: 1692 continue 1693 if fn in ['rect', 'polar']: 1694 # no real versions of rect, polar 1695 continue 1696 # Skip certain tests on OS X 10.4. 1697 if osx_version is not None and osx_version < (10, 5): 1698 if id in SKIP_ON_TIGER: 1699 continue 1700 1701 func = getattr(math, fn) 1702 1703 if 'invalid' in flags or 'divide-by-zero' in flags: 1704 er = 'ValueError' 1705 elif 'overflow' in flags: 1706 er = 'OverflowError' 1707 1708 try: 1709 result = func(ar) 1710 except ValueError: 1711 result = 'ValueError' 1712 except OverflowError: 1713 result = 'OverflowError' 1714 1715 # Default tolerances 1716 ulp_tol, abs_tol = 5, 0.0 1717 1718 failure = result_check(er, result, ulp_tol, abs_tol) 1719 if failure is None: 1720 continue 1721 1722 msg = fail_fmt.format(id, fn, ar, failure) 1723 failures.append(msg) 1724 1725 if failures: 1726 self.fail('Failures in test_testfile:\n ' + 1727 '\n '.join(failures)) 1728 1729 @requires_IEEE_754 1730 def test_mtestfile(self): 1731 fail_fmt = "{}: {}({!r}): {}" 1732 1733 failures = [] 1734 for id, fn, arg, expected, flags in parse_mtestfile(math_testcases): 1735 func = getattr(math, fn) 1736 1737 if 'invalid' in flags or 'divide-by-zero' in flags: 1738 expected = 'ValueError' 1739 elif 'overflow' in flags: 1740 expected = 'OverflowError' 1741 1742 try: 1743 got = func(arg) 1744 except ValueError: 1745 got = 'ValueError' 1746 except OverflowError: 1747 got = 'OverflowError' 1748 1749 # Default tolerances 1750 ulp_tol, abs_tol = 5, 0.0 1751 1752 # Exceptions to the defaults 1753 if fn == 'gamma': 1754 # Experimental results on one platform gave 1755 # an accuracy of <= 10 ulps across the entire float 1756 # domain. We weaken that to require 20 ulp accuracy. 1757 ulp_tol = 20 1758 1759 elif fn == 'lgamma': 1760 # we use a weaker accuracy test for lgamma; 1761 # lgamma only achieves an absolute error of 1762 # a few multiples of the machine accuracy, in 1763 # general. 1764 abs_tol = 1e-15 1765 1766 elif fn == 'erfc' and arg >= 0.0: 1767 # erfc has less-than-ideal accuracy for large 1768 # arguments (x ~ 25 or so), mainly due to the 1769 # error involved in computing exp(-x*x). 1770 # 1771 # Observed between CPython and mpmath at 25 dp: 1772 # x < 0 : err <= 2 ulp 1773 # 0 <= x < 1 : err <= 10 ulp 1774 # 1 <= x < 10 : err <= 100 ulp 1775 # 10 <= x < 20 : err <= 300 ulp 1776 # 20 <= x : < 600 ulp 1777 # 1778 if arg < 1.0: 1779 ulp_tol = 10 1780 elif arg < 10.0: 1781 ulp_tol = 100 1782 else: 1783 ulp_tol = 1000 1784 1785 failure = result_check(expected, got, ulp_tol, abs_tol) 1786 if failure is None: 1787 continue 1788 1789 msg = fail_fmt.format(id, fn, arg, failure) 1790 failures.append(msg) 1791 1792 if failures: 1793 self.fail('Failures in test_mtestfile:\n ' + 1794 '\n '.join(failures)) 1795 1796 def test_prod(self): 1797 prod = math.prod 1798 self.assertEqual(prod([]), 1) 1799 self.assertEqual(prod([], start=5), 5) 1800 self.assertEqual(prod(list(range(2,8))), 5040) 1801 self.assertEqual(prod(iter(list(range(2,8)))), 5040) 1802 self.assertEqual(prod(range(1, 10), start=10), 3628800) 1803 1804 self.assertEqual(prod([1, 2, 3, 4, 5]), 120) 1805 self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0) 1806 self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0) 1807 self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0) 1808 1809 # Test overflow in fast-path for integers 1810 self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32) 1811 # Test overflow in fast-path for floats 1812 self.assertEqual(prod([1.0, 1.0, 2**32, 1, 1]), float(2**32)) 1813 1814 self.assertRaises(TypeError, prod) 1815 self.assertRaises(TypeError, prod, 42) 1816 self.assertRaises(TypeError, prod, ['a', 'b', 'c']) 1817 self.assertRaises(TypeError, prod, ['a', 'b', 'c'], start='') 1818 self.assertRaises(TypeError, prod, [b'a', b'c'], start=b'') 1819 values = [bytearray(b'a'), bytearray(b'b')] 1820 self.assertRaises(TypeError, prod, values, start=bytearray(b'')) 1821 self.assertRaises(TypeError, prod, [[1], [2], [3]]) 1822 self.assertRaises(TypeError, prod, [{2:3}]) 1823 self.assertRaises(TypeError, prod, [{2:3}]*2, start={2:3}) 1824 self.assertRaises(TypeError, prod, [[1], [2], [3]], start=[]) 1825 1826 # Some odd cases 1827 self.assertEqual(prod([2, 3], start='ab'), 'abababababab') 1828 self.assertEqual(prod([2, 3], start=[1, 2]), [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]) 1829 self.assertEqual(prod([], start={2: 3}), {2:3}) 1830 1831 with self.assertRaises(TypeError): 1832 prod([10, 20], 1) # start is a keyword-only argument 1833 1834 self.assertEqual(prod([0, 1, 2, 3]), 0) 1835 self.assertEqual(prod([1, 0, 2, 3]), 0) 1836 self.assertEqual(prod([1, 2, 3, 0]), 0) 1837 1838 def _naive_prod(iterable, start=1): 1839 for elem in iterable: 1840 start *= elem 1841 return start 1842 1843 # Big integers 1844 1845 iterable = range(1, 10000) 1846 self.assertEqual(prod(iterable), _naive_prod(iterable)) 1847 iterable = range(-10000, -1) 1848 self.assertEqual(prod(iterable), _naive_prod(iterable)) 1849 iterable = range(-1000, 1000) 1850 self.assertEqual(prod(iterable), 0) 1851 1852 # Big floats 1853 1854 iterable = [float(x) for x in range(1, 1000)] 1855 self.assertEqual(prod(iterable), _naive_prod(iterable)) 1856 iterable = [float(x) for x in range(-1000, -1)] 1857 self.assertEqual(prod(iterable), _naive_prod(iterable)) 1858 iterable = [float(x) for x in range(-1000, 1000)] 1859 self.assertIsNaN(prod(iterable)) 1860 1861 # Float tests 1862 1863 self.assertIsNaN(prod([1, 2, 3, float("nan"), 2, 3])) 1864 self.assertIsNaN(prod([1, 0, float("nan"), 2, 3])) 1865 self.assertIsNaN(prod([1, float("nan"), 0, 3])) 1866 self.assertIsNaN(prod([1, float("inf"), float("nan"),3])) 1867 self.assertIsNaN(prod([1, float("-inf"), float("nan"),3])) 1868 self.assertIsNaN(prod([1, float("nan"), float("inf"),3])) 1869 self.assertIsNaN(prod([1, float("nan"), float("-inf"),3])) 1870 1871 self.assertEqual(prod([1, 2, 3, float('inf'),-3,4]), float('-inf')) 1872 self.assertEqual(prod([1, 2, 3, float('-inf'),-3,4]), float('inf')) 1873 1874 self.assertIsNaN(prod([1,2,0,float('inf'), -3, 4])) 1875 self.assertIsNaN(prod([1,2,0,float('-inf'), -3, 4])) 1876 self.assertIsNaN(prod([1, 2, 3, float('inf'), -3, 0, 3])) 1877 self.assertIsNaN(prod([1, 2, 3, float('-inf'), -3, 0, 2])) 1878 1879 # Type preservation 1880 1881 self.assertEqual(type(prod([1, 2, 3, 4, 5, 6])), int) 1882 self.assertEqual(type(prod([1, 2.0, 3, 4, 5, 6])), float) 1883 self.assertEqual(type(prod(range(1, 10000))), int) 1884 self.assertEqual(type(prod(range(1, 10000), start=1.0)), float) 1885 self.assertEqual(type(prod([1, decimal.Decimal(2.0), 3, 4, 5, 6])), 1886 decimal.Decimal) 1887 1888 def testPerm(self): 1889 perm = math.perm 1890 factorial = math.factorial 1891 # Test if factorial definition is satisfied 1892 for n in range(100): 1893 for k in range(n + 1): 1894 self.assertEqual(perm(n, k), 1895 factorial(n) // factorial(n - k)) 1896 1897 # Test for Pascal's identity 1898 for n in range(1, 100): 1899 for k in range(1, n): 1900 self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k)) 1901 1902 # Test corner cases 1903 for n in range(1, 100): 1904 self.assertEqual(perm(n, 0), 1) 1905 self.assertEqual(perm(n, 1), n) 1906 self.assertEqual(perm(n, n), factorial(n)) 1907 1908 # Test one argument form 1909 for n in range(20): 1910 self.assertEqual(perm(n), factorial(n)) 1911 self.assertEqual(perm(n, None), factorial(n)) 1912 1913 # Raises TypeError if any argument is non-integer or argument count is 1914 # not 1 or 2 1915 self.assertRaises(TypeError, perm, 10, 1.0) 1916 self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0)) 1917 self.assertRaises(TypeError, perm, 10, "1") 1918 self.assertRaises(TypeError, perm, 10.0, 1) 1919 self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1) 1920 self.assertRaises(TypeError, perm, "10", 1) 1921 1922 self.assertRaises(TypeError, perm) 1923 self.assertRaises(TypeError, perm, 10, 1, 3) 1924 self.assertRaises(TypeError, perm) 1925 1926 # Raises Value error if not k or n are negative numbers 1927 self.assertRaises(ValueError, perm, -1, 1) 1928 self.assertRaises(ValueError, perm, -2**1000, 1) 1929 self.assertRaises(ValueError, perm, 1, -1) 1930 self.assertRaises(ValueError, perm, 1, -2**1000) 1931 1932 # Returns zero if k is greater than n 1933 self.assertEqual(perm(1, 2), 0) 1934 self.assertEqual(perm(1, 2**1000), 0) 1935 1936 n = 2**1000 1937 self.assertEqual(perm(n, 0), 1) 1938 self.assertEqual(perm(n, 1), n) 1939 self.assertEqual(perm(n, 2), n * (n-1)) 1940 if support.check_impl_detail(cpython=True): 1941 self.assertRaises(OverflowError, perm, n, n) 1942 1943 for n, k in (True, True), (True, False), (False, False): 1944 self.assertEqual(perm(n, k), 1) 1945 self.assertIs(type(perm(n, k)), int) 1946 self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20) 1947 self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20) 1948 for k in range(3): 1949 self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int) 1950 self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int) 1951 1952 def testComb(self): 1953 comb = math.comb 1954 factorial = math.factorial 1955 # Test if factorial definition is satisfied 1956 for n in range(100): 1957 for k in range(n + 1): 1958 self.assertEqual(comb(n, k), factorial(n) 1959 // (factorial(k) * factorial(n - k))) 1960 1961 # Test for Pascal's identity 1962 for n in range(1, 100): 1963 for k in range(1, n): 1964 self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k)) 1965 1966 # Test corner cases 1967 for n in range(100): 1968 self.assertEqual(comb(n, 0), 1) 1969 self.assertEqual(comb(n, n), 1) 1970 1971 for n in range(1, 100): 1972 self.assertEqual(comb(n, 1), n) 1973 self.assertEqual(comb(n, n - 1), n) 1974 1975 # Test Symmetry 1976 for n in range(100): 1977 for k in range(n // 2): 1978 self.assertEqual(comb(n, k), comb(n, n - k)) 1979 1980 # Raises TypeError if any argument is non-integer or argument count is 1981 # not 2 1982 self.assertRaises(TypeError, comb, 10, 1.0) 1983 self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0)) 1984 self.assertRaises(TypeError, comb, 10, "1") 1985 self.assertRaises(TypeError, comb, 10.0, 1) 1986 self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1) 1987 self.assertRaises(TypeError, comb, "10", 1) 1988 1989 self.assertRaises(TypeError, comb, 10) 1990 self.assertRaises(TypeError, comb, 10, 1, 3) 1991 self.assertRaises(TypeError, comb) 1992 1993 # Raises Value error if not k or n are negative numbers 1994 self.assertRaises(ValueError, comb, -1, 1) 1995 self.assertRaises(ValueError, comb, -2**1000, 1) 1996 self.assertRaises(ValueError, comb, 1, -1) 1997 self.assertRaises(ValueError, comb, 1, -2**1000) 1998 1999 # Returns zero if k is greater than n 2000 self.assertEqual(comb(1, 2), 0) 2001 self.assertEqual(comb(1, 2**1000), 0) 2002 2003 n = 2**1000 2004 self.assertEqual(comb(n, 0), 1) 2005 self.assertEqual(comb(n, 1), n) 2006 self.assertEqual(comb(n, 2), n * (n-1) // 2) 2007 self.assertEqual(comb(n, n), 1) 2008 self.assertEqual(comb(n, n-1), n) 2009 self.assertEqual(comb(n, n-2), n * (n-1) // 2) 2010 if support.check_impl_detail(cpython=True): 2011 self.assertRaises(OverflowError, comb, n, n//2) 2012 2013 for n, k in (True, True), (True, False), (False, False): 2014 self.assertEqual(comb(n, k), 1) 2015 self.assertIs(type(comb(n, k)), int) 2016 self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10) 2017 self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10) 2018 for k in range(3): 2019 self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int) 2020 self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int) 2021 2022 @requires_IEEE_754 2023 def test_nextafter(self): 2024 # around 2^52 and 2^63 2025 self.assertEqual(math.nextafter(4503599627370496.0, -INF), 2026 4503599627370495.5) 2027 self.assertEqual(math.nextafter(4503599627370496.0, INF), 2028 4503599627370497.0) 2029 self.assertEqual(math.nextafter(9223372036854775808.0, 0.0), 2030 9223372036854774784.0) 2031 self.assertEqual(math.nextafter(-9223372036854775808.0, 0.0), 2032 -9223372036854774784.0) 2033 2034 # around 1.0 2035 self.assertEqual(math.nextafter(1.0, -INF), 2036 float.fromhex('0x1.fffffffffffffp-1')) 2037 self.assertEqual(math.nextafter(1.0, INF), 2038 float.fromhex('0x1.0000000000001p+0')) 2039 2040 # x == y: y is returned 2041 self.assertEqual(math.nextafter(2.0, 2.0), 2.0) 2042 self.assertEqualSign(math.nextafter(-0.0, +0.0), +0.0) 2043 self.assertEqualSign(math.nextafter(+0.0, -0.0), -0.0) 2044 2045 # around 0.0 2046 smallest_subnormal = sys.float_info.min * sys.float_info.epsilon 2047 self.assertEqual(math.nextafter(+0.0, INF), smallest_subnormal) 2048 self.assertEqual(math.nextafter(-0.0, INF), smallest_subnormal) 2049 self.assertEqual(math.nextafter(+0.0, -INF), -smallest_subnormal) 2050 self.assertEqual(math.nextafter(-0.0, -INF), -smallest_subnormal) 2051 self.assertEqualSign(math.nextafter(smallest_subnormal, +0.0), +0.0) 2052 self.assertEqualSign(math.nextafter(-smallest_subnormal, +0.0), -0.0) 2053 self.assertEqualSign(math.nextafter(smallest_subnormal, -0.0), +0.0) 2054 self.assertEqualSign(math.nextafter(-smallest_subnormal, -0.0), -0.0) 2055 2056 # around infinity 2057 largest_normal = sys.float_info.max 2058 self.assertEqual(math.nextafter(INF, 0.0), largest_normal) 2059 self.assertEqual(math.nextafter(-INF, 0.0), -largest_normal) 2060 self.assertEqual(math.nextafter(largest_normal, INF), INF) 2061 self.assertEqual(math.nextafter(-largest_normal, -INF), -INF) 2062 2063 # NaN 2064 self.assertIsNaN(math.nextafter(NAN, 1.0)) 2065 self.assertIsNaN(math.nextafter(1.0, NAN)) 2066 self.assertIsNaN(math.nextafter(NAN, NAN)) 2067 2068 @requires_IEEE_754 2069 def test_ulp(self): 2070 self.assertEqual(math.ulp(1.0), sys.float_info.epsilon) 2071 # use int ** int rather than float ** int to not rely on pow() accuracy 2072 self.assertEqual(math.ulp(2 ** 52), 1.0) 2073 self.assertEqual(math.ulp(2 ** 53), 2.0) 2074 self.assertEqual(math.ulp(2 ** 64), 4096.0) 2075 2076 # min and max 2077 self.assertEqual(math.ulp(0.0), 2078 sys.float_info.min * sys.float_info.epsilon) 2079 self.assertEqual(math.ulp(FLOAT_MAX), 2080 FLOAT_MAX - math.nextafter(FLOAT_MAX, -INF)) 2081 2082 # special cases 2083 self.assertEqual(math.ulp(INF), INF) 2084 self.assertIsNaN(math.ulp(math.nan)) 2085 2086 # negative number: ulp(-x) == ulp(x) 2087 for x in (0.0, 1.0, 2 ** 52, 2 ** 64, INF): 2088 with self.subTest(x=x): 2089 self.assertEqual(math.ulp(-x), math.ulp(x)) 2090 2091 def test_issue39871(self): 2092 # A SystemError should not be raised if the first arg to atan2(), 2093 # copysign(), or remainder() cannot be converted to a float. 2094 class F: 2095 def __float__(self): 2096 self.converted = True 2097 1/0 2098 for func in math.atan2, math.copysign, math.remainder: 2099 y = F() 2100 with self.assertRaises(TypeError): 2101 func("not a number", y) 2102 2103 # There should not have been any attempt to convert the second 2104 # argument to a float. 2105 self.assertFalse(getattr(y, "converted", False)) 2106 2107 # Custom assertions. 2108 2109 def assertIsNaN(self, value): 2110 if not math.isnan(value): 2111 self.fail("Expected a NaN, got {!r}.".format(value)) 2112 2113 def assertEqualSign(self, x, y): 2114 """Similar to assertEqual(), but compare also the sign with copysign(). 2115 2116 Function useful to compare signed zeros. 2117 """ 2118 self.assertEqual(x, y) 2119 self.assertEqual(math.copysign(1.0, x), math.copysign(1.0, y)) 2120 2121 2122class IsCloseTests(unittest.TestCase): 2123 isclose = math.isclose # subclasses should override this 2124 2125 def assertIsClose(self, a, b, *args, **kwargs): 2126 self.assertTrue(self.isclose(a, b, *args, **kwargs), 2127 msg="%s and %s should be close!" % (a, b)) 2128 2129 def assertIsNotClose(self, a, b, *args, **kwargs): 2130 self.assertFalse(self.isclose(a, b, *args, **kwargs), 2131 msg="%s and %s should not be close!" % (a, b)) 2132 2133 def assertAllClose(self, examples, *args, **kwargs): 2134 for a, b in examples: 2135 self.assertIsClose(a, b, *args, **kwargs) 2136 2137 def assertAllNotClose(self, examples, *args, **kwargs): 2138 for a, b in examples: 2139 self.assertIsNotClose(a, b, *args, **kwargs) 2140 2141 def test_negative_tolerances(self): 2142 # ValueError should be raised if either tolerance is less than zero 2143 with self.assertRaises(ValueError): 2144 self.assertIsClose(1, 1, rel_tol=-1e-100) 2145 with self.assertRaises(ValueError): 2146 self.assertIsClose(1, 1, rel_tol=1e-100, abs_tol=-1e10) 2147 2148 def test_identical(self): 2149 # identical values must test as close 2150 identical_examples = [(2.0, 2.0), 2151 (0.1e200, 0.1e200), 2152 (1.123e-300, 1.123e-300), 2153 (12345, 12345.0), 2154 (0.0, -0.0), 2155 (345678, 345678)] 2156 self.assertAllClose(identical_examples, rel_tol=0.0, abs_tol=0.0) 2157 2158 def test_eight_decimal_places(self): 2159 # examples that are close to 1e-8, but not 1e-9 2160 eight_decimal_places_examples = [(1e8, 1e8 + 1), 2161 (-1e-8, -1.000000009e-8), 2162 (1.12345678, 1.12345679)] 2163 self.assertAllClose(eight_decimal_places_examples, rel_tol=1e-8) 2164 self.assertAllNotClose(eight_decimal_places_examples, rel_tol=1e-9) 2165 2166 def test_near_zero(self): 2167 # values close to zero 2168 near_zero_examples = [(1e-9, 0.0), 2169 (-1e-9, 0.0), 2170 (-1e-150, 0.0)] 2171 # these should not be close to any rel_tol 2172 self.assertAllNotClose(near_zero_examples, rel_tol=0.9) 2173 # these should be close to abs_tol=1e-8 2174 self.assertAllClose(near_zero_examples, abs_tol=1e-8) 2175 2176 def test_identical_infinite(self): 2177 # these are close regardless of tolerance -- i.e. they are equal 2178 self.assertIsClose(INF, INF) 2179 self.assertIsClose(INF, INF, abs_tol=0.0) 2180 self.assertIsClose(NINF, NINF) 2181 self.assertIsClose(NINF, NINF, abs_tol=0.0) 2182 2183 def test_inf_ninf_nan(self): 2184 # these should never be close (following IEEE 754 rules for equality) 2185 not_close_examples = [(NAN, NAN), 2186 (NAN, 1e-100), 2187 (1e-100, NAN), 2188 (INF, NAN), 2189 (NAN, INF), 2190 (INF, NINF), 2191 (INF, 1.0), 2192 (1.0, INF), 2193 (INF, 1e308), 2194 (1e308, INF)] 2195 # use largest reasonable tolerance 2196 self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999) 2197 2198 def test_zero_tolerance(self): 2199 # test with zero tolerance 2200 zero_tolerance_close_examples = [(1.0, 1.0), 2201 (-3.4, -3.4), 2202 (-1e-300, -1e-300)] 2203 self.assertAllClose(zero_tolerance_close_examples, rel_tol=0.0) 2204 2205 zero_tolerance_not_close_examples = [(1.0, 1.000000000000001), 2206 (0.99999999999999, 1.0), 2207 (1.0e200, .999999999999999e200)] 2208 self.assertAllNotClose(zero_tolerance_not_close_examples, rel_tol=0.0) 2209 2210 def test_asymmetry(self): 2211 # test the asymmetry example from PEP 485 2212 self.assertAllClose([(9, 10), (10, 9)], rel_tol=0.1) 2213 2214 def test_integers(self): 2215 # test with integer values 2216 integer_examples = [(100000001, 100000000), 2217 (123456789, 123456788)] 2218 2219 self.assertAllClose(integer_examples, rel_tol=1e-8) 2220 self.assertAllNotClose(integer_examples, rel_tol=1e-9) 2221 2222 def test_decimals(self): 2223 # test with Decimal values 2224 from decimal import Decimal 2225 2226 decimal_examples = [(Decimal('1.00000001'), Decimal('1.0')), 2227 (Decimal('1.00000001e-20'), Decimal('1.0e-20')), 2228 (Decimal('1.00000001e-100'), Decimal('1.0e-100')), 2229 (Decimal('1.00000001e20'), Decimal('1.0e20'))] 2230 self.assertAllClose(decimal_examples, rel_tol=1e-8) 2231 self.assertAllNotClose(decimal_examples, rel_tol=1e-9) 2232 2233 def test_fractions(self): 2234 # test with Fraction values 2235 from fractions import Fraction 2236 2237 fraction_examples = [ 2238 (Fraction(1, 100000000) + 1, Fraction(1)), 2239 (Fraction(100000001), Fraction(100000000)), 2240 (Fraction(10**8 + 1, 10**28), Fraction(1, 10**20))] 2241 self.assertAllClose(fraction_examples, rel_tol=1e-8) 2242 self.assertAllNotClose(fraction_examples, rel_tol=1e-9) 2243 2244 2245def load_tests(loader, tests, pattern): 2246 from doctest import DocFileSuite 2247 tests.addTest(DocFileSuite("ieee754.txt")) 2248 return tests 2249 2250if __name__ == '__main__': 2251 unittest.main() 2252