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