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