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 math 8import os 9import platform 10import struct 11import sys 12import sysconfig 13 14eps = 1E-05 15NAN = float('nan') 16INF = float('inf') 17NINF = float('-inf') 18FLOAT_MAX = sys.float_info.max 19 20# detect evidence of double-rounding: fsum is not always correctly 21# rounded on machines that suffer from double rounding. 22x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer 23HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4) 24 25# locate file with test values 26if __name__ == '__main__': 27 file = sys.argv[0] 28else: 29 file = __file__ 30test_dir = os.path.dirname(file) or os.curdir 31math_testcases = os.path.join(test_dir, 'math_testcases.txt') 32test_file = os.path.join(test_dir, 'cmath_testcases.txt') 33 34 35def to_ulps(x): 36 """Convert a non-NaN float x to an integer, in such a way that 37 adjacent floats are converted to adjacent integers. Then 38 abs(ulps(x) - ulps(y)) gives the difference in ulps between two 39 floats. 40 41 The results from this function will only make sense on platforms 42 where native doubles are represented in IEEE 754 binary64 format. 43 44 Note: 0.0 and -0.0 are converted to 0 and -1, respectively. 45 """ 46 n = struct.unpack('<q', struct.pack('<d', x))[0] 47 if n < 0: 48 n = ~(n+2**63) 49 return n 50 51 52def ulp(x): 53 """Return the value of the least significant bit of a 54 float x, such that the first float bigger than x is x+ulp(x). 55 Then, given an expected result x and a tolerance of n ulps, 56 the result y should be such that abs(y-x) <= n * ulp(x). 57 The results from this function will only make sense on platforms 58 where native doubles are represented in IEEE 754 binary64 format. 59 """ 60 x = abs(float(x)) 61 if math.isnan(x) or math.isinf(x): 62 return x 63 64 # Find next float up from x. 65 n = struct.unpack('<q', struct.pack('<d', x))[0] 66 x_next = struct.unpack('<d', struct.pack('<q', n + 1))[0] 67 if math.isinf(x_next): 68 # Corner case: x was the largest finite float. Then it's 69 # not an exact power of two, so we can take the difference 70 # between x and the previous float. 71 x_prev = struct.unpack('<d', struct.pack('<q', n - 1))[0] 72 return x - x_prev 73 else: 74 return x_next - x 75 76# Here's a pure Python version of the math.factorial algorithm, for 77# documentation and comparison purposes. 78# 79# Formula: 80# 81# factorial(n) = factorial_odd_part(n) << (n - count_set_bits(n)) 82# 83# where 84# 85# factorial_odd_part(n) = product_{i >= 0} product_{0 < j <= n >> i; j odd} j 86# 87# The outer product above is an infinite product, but once i >= n.bit_length, 88# (n >> i) < 1 and the corresponding term of the product is empty. So only the 89# finitely many terms for 0 <= i < n.bit_length() contribute anything. 90# 91# We iterate downwards from i == n.bit_length() - 1 to i == 0. The inner 92# product in the formula above starts at 1 for i == n.bit_length(); for each i 93# < n.bit_length() we get the inner product for i from that for i + 1 by 94# multiplying by all j in {n >> i+1 < j <= n >> i; j odd}. In Python terms, 95# this set is range((n >> i+1) + 1 | 1, (n >> i) + 1 | 1, 2). 96 97def count_set_bits(n): 98 """Number of '1' bits in binary expansion of a nonnnegative integer.""" 99 return 1 + count_set_bits(n & n - 1) if n else 0 100 101def partial_product(start, stop): 102 """Product of integers in range(start, stop, 2), computed recursively. 103 start and stop should both be odd, with start <= stop. 104 105 """ 106 numfactors = (stop - start) >> 1 107 if not numfactors: 108 return 1 109 elif numfactors == 1: 110 return start 111 else: 112 mid = (start + numfactors) | 1 113 return partial_product(start, mid) * partial_product(mid, stop) 114 115def py_factorial(n): 116 """Factorial of nonnegative integer n, via "Binary Split Factorial Formula" 117 described at http://www.luschny.de/math/factorial/binarysplitfact.html 118 119 """ 120 inner = outer = 1 121 for i in reversed(range(n.bit_length())): 122 inner *= partial_product((n >> i + 1) + 1 | 1, (n >> i) + 1 | 1) 123 outer *= inner 124 return outer << (n - count_set_bits(n)) 125 126def ulp_abs_check(expected, got, ulp_tol, abs_tol): 127 """Given finite floats `expected` and `got`, check that they're 128 approximately equal to within the given number of ulps or the 129 given absolute tolerance, whichever is bigger. 130 131 Returns None on success and an error message on failure. 132 """ 133 ulp_error = abs(to_ulps(expected) - to_ulps(got)) 134 abs_error = abs(expected - got) 135 136 # Succeed if either abs_error <= abs_tol or ulp_error <= ulp_tol. 137 if abs_error <= abs_tol or ulp_error <= ulp_tol: 138 return None 139 else: 140 fmt = ("error = {:.3g} ({:d} ulps); " 141 "permitted error = {:.3g} or {:d} ulps") 142 return fmt.format(abs_error, ulp_error, abs_tol, ulp_tol) 143 144def parse_mtestfile(fname): 145 """Parse a file with test values 146 147 -- starts a comment 148 blank lines, or lines containing only a comment, are ignored 149 other lines are expected to have the form 150 id fn arg -> expected [flag]* 151 152 """ 153 with open(fname) as fp: 154 for line in fp: 155 # strip comments, and skip blank lines 156 if '--' in line: 157 line = line[:line.index('--')] 158 if not line.strip(): 159 continue 160 161 lhs, rhs = line.split('->') 162 id, fn, arg = lhs.split() 163 rhs_pieces = rhs.split() 164 exp = rhs_pieces[0] 165 flags = rhs_pieces[1:] 166 167 yield (id, fn, float(arg), float(exp), flags) 168 169 170def parse_testfile(fname): 171 """Parse a file with test values 172 173 Empty lines or lines starting with -- are ignored 174 yields id, fn, arg_real, arg_imag, exp_real, exp_imag 175 """ 176 with open(fname) as fp: 177 for line in fp: 178 # skip comment lines and blank lines 179 if line.startswith('--') or not line.strip(): 180 continue 181 182 lhs, rhs = line.split('->') 183 id, fn, arg_real, arg_imag = lhs.split() 184 rhs_pieces = rhs.split() 185 exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1] 186 flags = rhs_pieces[2:] 187 188 yield (id, fn, 189 float(arg_real), float(arg_imag), 190 float(exp_real), float(exp_imag), 191 flags) 192 193 194def result_check(expected, got, ulp_tol=5, abs_tol=0.0): 195 # Common logic of MathTests.(ftest, test_testcases, test_mtestcases) 196 """Compare arguments expected and got, as floats, if either 197 is a float, using a tolerance expressed in multiples of 198 ulp(expected) or absolutely (if given and greater). 199 200 As a convenience, when neither argument is a float, and for 201 non-finite floats, exact equality is demanded. Also, nan==nan 202 as far as this function is concerned. 203 204 Returns None on success and an error message on failure. 205 """ 206 207 # Check exactly equal (applies also to strings representing exceptions) 208 if got == expected: 209 return None 210 211 failure = "not equal" 212 213 # Turn mixed float and int comparison (e.g. floor()) to all-float 214 if isinstance(expected, float) and isinstance(got, int): 215 got = float(got) 216 elif isinstance(got, float) and isinstance(expected, int): 217 expected = float(expected) 218 219 if isinstance(expected, float) and isinstance(got, float): 220 if math.isnan(expected) and math.isnan(got): 221 # Pass, since both nan 222 failure = None 223 elif math.isinf(expected) or math.isinf(got): 224 # We already know they're not equal, drop through to failure 225 pass 226 else: 227 # Both are finite floats (now). Are they close enough? 228 failure = ulp_abs_check(expected, got, ulp_tol, abs_tol) 229 230 # arguments are not equal, and if numeric, are too far apart 231 if failure is not None: 232 fail_fmt = "expected {!r}, got {!r}" 233 fail_msg = fail_fmt.format(expected, got) 234 fail_msg += ' ({})'.format(failure) 235 return fail_msg 236 else: 237 return None 238 239# Class providing an __index__ method. 240class MyIndexable(object): 241 def __init__(self, value): 242 self.value = value 243 244 def __index__(self): 245 return self.value 246 247class MathTests(unittest.TestCase): 248 249 def ftest(self, name, got, expected, ulp_tol=5, abs_tol=0.0): 250 """Compare arguments expected and got, as floats, if either 251 is a float, using a tolerance expressed in multiples of 252 ulp(expected) or absolutely, whichever is greater. 253 254 As a convenience, when neither argument is a float, and for 255 non-finite floats, exact equality is demanded. Also, nan==nan 256 in this function. 257 """ 258 failure = result_check(expected, got, ulp_tol, abs_tol) 259 if failure is not None: 260 self.fail("{}: {}".format(name, failure)) 261 262 def testConstants(self): 263 # Ref: Abramowitz & Stegun (Dover, 1965) 264 self.ftest('pi', math.pi, 3.141592653589793238462643) 265 self.ftest('e', math.e, 2.718281828459045235360287) 266 self.assertEqual(math.tau, 2*math.pi) 267 268 def testAcos(self): 269 self.assertRaises(TypeError, math.acos) 270 self.ftest('acos(-1)', math.acos(-1), math.pi) 271 self.ftest('acos(0)', math.acos(0), math.pi/2) 272 self.ftest('acos(1)', math.acos(1), 0) 273 self.assertRaises(ValueError, math.acos, INF) 274 self.assertRaises(ValueError, math.acos, NINF) 275 self.assertRaises(ValueError, math.acos, 1 + eps) 276 self.assertRaises(ValueError, math.acos, -1 - eps) 277 self.assertTrue(math.isnan(math.acos(NAN))) 278 279 def testAcosh(self): 280 self.assertRaises(TypeError, math.acosh) 281 self.ftest('acosh(1)', math.acosh(1), 0) 282 self.ftest('acosh(2)', math.acosh(2), 1.3169578969248168) 283 self.assertRaises(ValueError, math.acosh, 0) 284 self.assertRaises(ValueError, math.acosh, -1) 285 self.assertEqual(math.acosh(INF), INF) 286 self.assertRaises(ValueError, math.acosh, NINF) 287 self.assertTrue(math.isnan(math.acosh(NAN))) 288 289 def testAsin(self): 290 self.assertRaises(TypeError, math.asin) 291 self.ftest('asin(-1)', math.asin(-1), -math.pi/2) 292 self.ftest('asin(0)', math.asin(0), 0) 293 self.ftest('asin(1)', math.asin(1), math.pi/2) 294 self.assertRaises(ValueError, math.asin, INF) 295 self.assertRaises(ValueError, math.asin, NINF) 296 self.assertRaises(ValueError, math.asin, 1 + eps) 297 self.assertRaises(ValueError, math.asin, -1 - eps) 298 self.assertTrue(math.isnan(math.asin(NAN))) 299 300 def testAsinh(self): 301 self.assertRaises(TypeError, math.asinh) 302 self.ftest('asinh(0)', math.asinh(0), 0) 303 self.ftest('asinh(1)', math.asinh(1), 0.88137358701954305) 304 self.ftest('asinh(-1)', math.asinh(-1), -0.88137358701954305) 305 self.assertEqual(math.asinh(INF), INF) 306 self.assertEqual(math.asinh(NINF), NINF) 307 self.assertTrue(math.isnan(math.asinh(NAN))) 308 309 def testAtan(self): 310 self.assertRaises(TypeError, math.atan) 311 self.ftest('atan(-1)', math.atan(-1), -math.pi/4) 312 self.ftest('atan(0)', math.atan(0), 0) 313 self.ftest('atan(1)', math.atan(1), math.pi/4) 314 self.ftest('atan(inf)', math.atan(INF), math.pi/2) 315 self.ftest('atan(-inf)', math.atan(NINF), -math.pi/2) 316 self.assertTrue(math.isnan(math.atan(NAN))) 317 318 def testAtanh(self): 319 self.assertRaises(TypeError, math.atan) 320 self.ftest('atanh(0)', math.atanh(0), 0) 321 self.ftest('atanh(0.5)', math.atanh(0.5), 0.54930614433405489) 322 self.ftest('atanh(-0.5)', math.atanh(-0.5), -0.54930614433405489) 323 self.assertRaises(ValueError, math.atanh, 1) 324 self.assertRaises(ValueError, math.atanh, -1) 325 self.assertRaises(ValueError, math.atanh, INF) 326 self.assertRaises(ValueError, math.atanh, NINF) 327 self.assertTrue(math.isnan(math.atanh(NAN))) 328 329 def testAtan2(self): 330 self.assertRaises(TypeError, math.atan2) 331 self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2) 332 self.ftest('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4) 333 self.ftest('atan2(0, 1)', math.atan2(0, 1), 0) 334 self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4) 335 self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2) 336 337 # math.atan2(0, x) 338 self.ftest('atan2(0., -inf)', math.atan2(0., NINF), math.pi) 339 self.ftest('atan2(0., -2.3)', math.atan2(0., -2.3), math.pi) 340 self.ftest('atan2(0., -0.)', math.atan2(0., -0.), math.pi) 341 self.assertEqual(math.atan2(0., 0.), 0.) 342 self.assertEqual(math.atan2(0., 2.3), 0.) 343 self.assertEqual(math.atan2(0., INF), 0.) 344 self.assertTrue(math.isnan(math.atan2(0., NAN))) 345 # math.atan2(-0, x) 346 self.ftest('atan2(-0., -inf)', math.atan2(-0., NINF), -math.pi) 347 self.ftest('atan2(-0., -2.3)', math.atan2(-0., -2.3), -math.pi) 348 self.ftest('atan2(-0., -0.)', math.atan2(-0., -0.), -math.pi) 349 self.assertEqual(math.atan2(-0., 0.), -0.) 350 self.assertEqual(math.atan2(-0., 2.3), -0.) 351 self.assertEqual(math.atan2(-0., INF), -0.) 352 self.assertTrue(math.isnan(math.atan2(-0., NAN))) 353 # math.atan2(INF, x) 354 self.ftest('atan2(inf, -inf)', math.atan2(INF, NINF), math.pi*3/4) 355 self.ftest('atan2(inf, -2.3)', math.atan2(INF, -2.3), math.pi/2) 356 self.ftest('atan2(inf, -0.)', math.atan2(INF, -0.0), math.pi/2) 357 self.ftest('atan2(inf, 0.)', math.atan2(INF, 0.0), math.pi/2) 358 self.ftest('atan2(inf, 2.3)', math.atan2(INF, 2.3), math.pi/2) 359 self.ftest('atan2(inf, inf)', math.atan2(INF, INF), math.pi/4) 360 self.assertTrue(math.isnan(math.atan2(INF, NAN))) 361 # math.atan2(NINF, x) 362 self.ftest('atan2(-inf, -inf)', math.atan2(NINF, NINF), -math.pi*3/4) 363 self.ftest('atan2(-inf, -2.3)', math.atan2(NINF, -2.3), -math.pi/2) 364 self.ftest('atan2(-inf, -0.)', math.atan2(NINF, -0.0), -math.pi/2) 365 self.ftest('atan2(-inf, 0.)', math.atan2(NINF, 0.0), -math.pi/2) 366 self.ftest('atan2(-inf, 2.3)', math.atan2(NINF, 2.3), -math.pi/2) 367 self.ftest('atan2(-inf, inf)', math.atan2(NINF, INF), -math.pi/4) 368 self.assertTrue(math.isnan(math.atan2(NINF, NAN))) 369 # math.atan2(+finite, x) 370 self.ftest('atan2(2.3, -inf)', math.atan2(2.3, NINF), math.pi) 371 self.ftest('atan2(2.3, -0.)', math.atan2(2.3, -0.), math.pi/2) 372 self.ftest('atan2(2.3, 0.)', math.atan2(2.3, 0.), math.pi/2) 373 self.assertEqual(math.atan2(2.3, INF), 0.) 374 self.assertTrue(math.isnan(math.atan2(2.3, NAN))) 375 # math.atan2(-finite, x) 376 self.ftest('atan2(-2.3, -inf)', math.atan2(-2.3, NINF), -math.pi) 377 self.ftest('atan2(-2.3, -0.)', math.atan2(-2.3, -0.), -math.pi/2) 378 self.ftest('atan2(-2.3, 0.)', math.atan2(-2.3, 0.), -math.pi/2) 379 self.assertEqual(math.atan2(-2.3, INF), -0.) 380 self.assertTrue(math.isnan(math.atan2(-2.3, NAN))) 381 # math.atan2(NAN, x) 382 self.assertTrue(math.isnan(math.atan2(NAN, NINF))) 383 self.assertTrue(math.isnan(math.atan2(NAN, -2.3))) 384 self.assertTrue(math.isnan(math.atan2(NAN, -0.))) 385 self.assertTrue(math.isnan(math.atan2(NAN, 0.))) 386 self.assertTrue(math.isnan(math.atan2(NAN, 2.3))) 387 self.assertTrue(math.isnan(math.atan2(NAN, INF))) 388 self.assertTrue(math.isnan(math.atan2(NAN, NAN))) 389 390 def testCeil(self): 391 self.assertRaises(TypeError, math.ceil) 392 self.assertEqual(int, type(math.ceil(0.5))) 393 self.ftest('ceil(0.5)', math.ceil(0.5), 1) 394 self.ftest('ceil(1.0)', math.ceil(1.0), 1) 395 self.ftest('ceil(1.5)', math.ceil(1.5), 2) 396 self.ftest('ceil(-0.5)', math.ceil(-0.5), 0) 397 self.ftest('ceil(-1.0)', math.ceil(-1.0), -1) 398 self.ftest('ceil(-1.5)', math.ceil(-1.5), -1) 399 #self.assertEqual(math.ceil(INF), INF) 400 #self.assertEqual(math.ceil(NINF), NINF) 401 #self.assertTrue(math.isnan(math.ceil(NAN))) 402 403 class TestCeil: 404 def __ceil__(self): 405 return 42 406 class TestNoCeil: 407 pass 408 self.ftest('ceil(TestCeil())', math.ceil(TestCeil()), 42) 409 self.assertRaises(TypeError, math.ceil, TestNoCeil()) 410 411 t = TestNoCeil() 412 t.__ceil__ = lambda *args: args 413 self.assertRaises(TypeError, math.ceil, t) 414 self.assertRaises(TypeError, math.ceil, t, 0) 415 416 @requires_IEEE_754 417 def testCopysign(self): 418 self.assertEqual(math.copysign(1, 42), 1.0) 419 self.assertEqual(math.copysign(0., 42), 0.0) 420 self.assertEqual(math.copysign(1., -42), -1.0) 421 self.assertEqual(math.copysign(3, 0.), 3.0) 422 self.assertEqual(math.copysign(4., -0.), -4.0) 423 424 self.assertRaises(TypeError, math.copysign) 425 # copysign should let us distinguish signs of zeros 426 self.assertEqual(math.copysign(1., 0.), 1.) 427 self.assertEqual(math.copysign(1., -0.), -1.) 428 self.assertEqual(math.copysign(INF, 0.), INF) 429 self.assertEqual(math.copysign(INF, -0.), NINF) 430 self.assertEqual(math.copysign(NINF, 0.), INF) 431 self.assertEqual(math.copysign(NINF, -0.), NINF) 432 # and of infinities 433 self.assertEqual(math.copysign(1., INF), 1.) 434 self.assertEqual(math.copysign(1., NINF), -1.) 435 self.assertEqual(math.copysign(INF, INF), INF) 436 self.assertEqual(math.copysign(INF, NINF), NINF) 437 self.assertEqual(math.copysign(NINF, INF), INF) 438 self.assertEqual(math.copysign(NINF, NINF), NINF) 439 self.assertTrue(math.isnan(math.copysign(NAN, 1.))) 440 self.assertTrue(math.isnan(math.copysign(NAN, INF))) 441 self.assertTrue(math.isnan(math.copysign(NAN, NINF))) 442 self.assertTrue(math.isnan(math.copysign(NAN, NAN))) 443 # copysign(INF, NAN) may be INF or it may be NINF, since 444 # we don't know whether the sign bit of NAN is set on any 445 # given platform. 446 self.assertTrue(math.isinf(math.copysign(INF, NAN))) 447 # similarly, copysign(2., NAN) could be 2. or -2. 448 self.assertEqual(abs(math.copysign(2., NAN)), 2.) 449 450 def testCos(self): 451 self.assertRaises(TypeError, math.cos) 452 self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0, abs_tol=ulp(1)) 453 self.ftest('cos(0)', math.cos(0), 1) 454 self.ftest('cos(pi/2)', math.cos(math.pi/2), 0, abs_tol=ulp(1)) 455 self.ftest('cos(pi)', math.cos(math.pi), -1) 456 try: 457 self.assertTrue(math.isnan(math.cos(INF))) 458 self.assertTrue(math.isnan(math.cos(NINF))) 459 except ValueError: 460 self.assertRaises(ValueError, math.cos, INF) 461 self.assertRaises(ValueError, math.cos, NINF) 462 self.assertTrue(math.isnan(math.cos(NAN))) 463 464 def testCosh(self): 465 self.assertRaises(TypeError, math.cosh) 466 self.ftest('cosh(0)', math.cosh(0), 1) 467 self.ftest('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert 468 self.assertEqual(math.cosh(INF), INF) 469 self.assertEqual(math.cosh(NINF), INF) 470 self.assertTrue(math.isnan(math.cosh(NAN))) 471 472 def testDegrees(self): 473 self.assertRaises(TypeError, math.degrees) 474 self.ftest('degrees(pi)', math.degrees(math.pi), 180.0) 475 self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0) 476 self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0) 477 self.ftest('degrees(0)', math.degrees(0), 0) 478 479 def testExp(self): 480 self.assertRaises(TypeError, math.exp) 481 self.ftest('exp(-1)', math.exp(-1), 1/math.e) 482 self.ftest('exp(0)', math.exp(0), 1) 483 self.ftest('exp(1)', math.exp(1), math.e) 484 self.assertEqual(math.exp(INF), INF) 485 self.assertEqual(math.exp(NINF), 0.) 486 self.assertTrue(math.isnan(math.exp(NAN))) 487 self.assertRaises(OverflowError, math.exp, 1000000) 488 489 def testFabs(self): 490 self.assertRaises(TypeError, math.fabs) 491 self.ftest('fabs(-1)', math.fabs(-1), 1) 492 self.ftest('fabs(0)', math.fabs(0), 0) 493 self.ftest('fabs(1)', math.fabs(1), 1) 494 495 def testFactorial(self): 496 self.assertEqual(math.factorial(0), 1) 497 self.assertEqual(math.factorial(0.0), 1) 498 total = 1 499 for i in range(1, 1000): 500 total *= i 501 self.assertEqual(math.factorial(i), total) 502 self.assertEqual(math.factorial(float(i)), total) 503 self.assertEqual(math.factorial(i), py_factorial(i)) 504 self.assertRaises(ValueError, math.factorial, -1) 505 self.assertRaises(ValueError, math.factorial, -1.0) 506 self.assertRaises(ValueError, math.factorial, -10**100) 507 self.assertRaises(ValueError, math.factorial, -1e100) 508 self.assertRaises(ValueError, math.factorial, math.pi) 509 510 # Other implementations may place different upper bounds. 511 @support.cpython_only 512 def testFactorialHugeInputs(self): 513 # Currently raises ValueError for inputs that are too large 514 # to fit into a C long. 515 self.assertRaises(OverflowError, math.factorial, 10**100) 516 self.assertRaises(OverflowError, math.factorial, 1e100) 517 518 def testFloor(self): 519 self.assertRaises(TypeError, math.floor) 520 self.assertEqual(int, type(math.floor(0.5))) 521 self.ftest('floor(0.5)', math.floor(0.5), 0) 522 self.ftest('floor(1.0)', math.floor(1.0), 1) 523 self.ftest('floor(1.5)', math.floor(1.5), 1) 524 self.ftest('floor(-0.5)', math.floor(-0.5), -1) 525 self.ftest('floor(-1.0)', math.floor(-1.0), -1) 526 self.ftest('floor(-1.5)', math.floor(-1.5), -2) 527 # pow() relies on floor() to check for integers 528 # This fails on some platforms - so check it here 529 self.ftest('floor(1.23e167)', math.floor(1.23e167), 1.23e167) 530 self.ftest('floor(-1.23e167)', math.floor(-1.23e167), -1.23e167) 531 #self.assertEqual(math.ceil(INF), INF) 532 #self.assertEqual(math.ceil(NINF), NINF) 533 #self.assertTrue(math.isnan(math.floor(NAN))) 534 535 class TestFloor: 536 def __floor__(self): 537 return 42 538 class TestNoFloor: 539 pass 540 self.ftest('floor(TestFloor())', math.floor(TestFloor()), 42) 541 self.assertRaises(TypeError, math.floor, TestNoFloor()) 542 543 t = TestNoFloor() 544 t.__floor__ = lambda *args: args 545 self.assertRaises(TypeError, math.floor, t) 546 self.assertRaises(TypeError, math.floor, t, 0) 547 548 def testFmod(self): 549 self.assertRaises(TypeError, math.fmod) 550 self.ftest('fmod(10, 1)', math.fmod(10, 1), 0.0) 551 self.ftest('fmod(10, 0.5)', math.fmod(10, 0.5), 0.0) 552 self.ftest('fmod(10, 1.5)', math.fmod(10, 1.5), 1.0) 553 self.ftest('fmod(-10, 1)', math.fmod(-10, 1), -0.0) 554 self.ftest('fmod(-10, 0.5)', math.fmod(-10, 0.5), -0.0) 555 self.ftest('fmod(-10, 1.5)', math.fmod(-10, 1.5), -1.0) 556 self.assertTrue(math.isnan(math.fmod(NAN, 1.))) 557 self.assertTrue(math.isnan(math.fmod(1., NAN))) 558 self.assertTrue(math.isnan(math.fmod(NAN, NAN))) 559 self.assertRaises(ValueError, math.fmod, 1., 0.) 560 self.assertRaises(ValueError, math.fmod, INF, 1.) 561 self.assertRaises(ValueError, math.fmod, NINF, 1.) 562 self.assertRaises(ValueError, math.fmod, INF, 0.) 563 self.assertEqual(math.fmod(3.0, INF), 3.0) 564 self.assertEqual(math.fmod(-3.0, INF), -3.0) 565 self.assertEqual(math.fmod(3.0, NINF), 3.0) 566 self.assertEqual(math.fmod(-3.0, NINF), -3.0) 567 self.assertEqual(math.fmod(0.0, 3.0), 0.0) 568 self.assertEqual(math.fmod(0.0, NINF), 0.0) 569 570 def testFrexp(self): 571 self.assertRaises(TypeError, math.frexp) 572 573 def testfrexp(name, result, expected): 574 (mant, exp), (emant, eexp) = result, expected 575 if abs(mant-emant) > eps or exp != eexp: 576 self.fail('%s returned %r, expected %r'%\ 577 (name, result, expected)) 578 579 testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1)) 580 testfrexp('frexp(0)', math.frexp(0), (0, 0)) 581 testfrexp('frexp(1)', math.frexp(1), (0.5, 1)) 582 testfrexp('frexp(2)', math.frexp(2), (0.5, 2)) 583 584 self.assertEqual(math.frexp(INF)[0], INF) 585 self.assertEqual(math.frexp(NINF)[0], NINF) 586 self.assertTrue(math.isnan(math.frexp(NAN)[0])) 587 588 @requires_IEEE_754 589 @unittest.skipIf(HAVE_DOUBLE_ROUNDING, 590 "fsum is not exact on machines with double rounding") 591 def testFsum(self): 592 # math.fsum relies on exact rounding for correct operation. 593 # There's a known problem with IA32 floating-point that causes 594 # inexact rounding in some situations, and will cause the 595 # math.fsum tests below to fail; see issue #2937. On non IEEE 596 # 754 platforms, and on IEEE 754 platforms that exhibit the 597 # problem described in issue #2937, we simply skip the whole 598 # test. 599 600 # Python version of math.fsum, for comparison. Uses a 601 # different algorithm based on frexp, ldexp and integer 602 # arithmetic. 603 from sys import float_info 604 mant_dig = float_info.mant_dig 605 etiny = float_info.min_exp - mant_dig 606 607 def msum(iterable): 608 """Full precision summation. Compute sum(iterable) without any 609 intermediate accumulation of error. Based on the 'lsum' function 610 at http://code.activestate.com/recipes/393090/ 611 612 """ 613 tmant, texp = 0, 0 614 for x in iterable: 615 mant, exp = math.frexp(x) 616 mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig 617 if texp > exp: 618 tmant <<= texp-exp 619 texp = exp 620 else: 621 mant <<= exp-texp 622 tmant += mant 623 # Round tmant * 2**texp to a float. The original recipe 624 # used float(str(tmant)) * 2.0**texp for this, but that's 625 # a little unsafe because str -> float conversion can't be 626 # relied upon to do correct rounding on all platforms. 627 tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp) 628 if tail > 0: 629 h = 1 << (tail-1) 630 tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1) 631 texp += tail 632 return math.ldexp(tmant, texp) 633 634 test_values = [ 635 ([], 0.0), 636 ([0.0], 0.0), 637 ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100), 638 ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0), 639 ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0), 640 ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0), 641 ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0), 642 ([1./n for n in range(1, 1001)], 643 float.fromhex('0x1.df11f45f4e61ap+2')), 644 ([(-1.)**n/n for n in range(1, 1001)], 645 float.fromhex('-0x1.62a2af1bd3624p-1')), 646 ([1.7**(i+1)-1.7**i for i in range(1000)] + [-1.7**1000], -1.0), 647 ([1e16, 1., 1e-16], 10000000000000002.0), 648 ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0), 649 # exercise code for resizing partials array 650 ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] + 651 [-2.**1022], 652 float.fromhex('0x1.5555555555555p+970')), 653 ] 654 655 for i, (vals, expected) in enumerate(test_values): 656 try: 657 actual = math.fsum(vals) 658 except OverflowError: 659 self.fail("test %d failed: got OverflowError, expected %r " 660 "for math.fsum(%.100r)" % (i, expected, vals)) 661 except ValueError: 662 self.fail("test %d failed: got ValueError, expected %r " 663 "for math.fsum(%.100r)" % (i, expected, vals)) 664 self.assertEqual(actual, expected) 665 666 from random import random, gauss, shuffle 667 for j in range(1000): 668 vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10 669 s = 0 670 for i in range(200): 671 v = gauss(0, random()) ** 7 - s 672 s += v 673 vals.append(v) 674 shuffle(vals) 675 676 s = msum(vals) 677 self.assertEqual(msum(vals), math.fsum(vals)) 678 679 def testGcd(self): 680 gcd = math.gcd 681 self.assertEqual(gcd(0, 0), 0) 682 self.assertEqual(gcd(1, 0), 1) 683 self.assertEqual(gcd(-1, 0), 1) 684 self.assertEqual(gcd(0, 1), 1) 685 self.assertEqual(gcd(0, -1), 1) 686 self.assertEqual(gcd(7, 1), 1) 687 self.assertEqual(gcd(7, -1), 1) 688 self.assertEqual(gcd(-23, 15), 1) 689 self.assertEqual(gcd(120, 84), 12) 690 self.assertEqual(gcd(84, -120), 12) 691 self.assertEqual(gcd(1216342683557601535506311712, 692 436522681849110124616458784), 32) 693 c = 652560 694 x = 434610456570399902378880679233098819019853229470286994367836600566 695 y = 1064502245825115327754847244914921553977 696 a = x * c 697 b = y * c 698 self.assertEqual(gcd(a, b), c) 699 self.assertEqual(gcd(b, a), c) 700 self.assertEqual(gcd(-a, b), c) 701 self.assertEqual(gcd(b, -a), c) 702 self.assertEqual(gcd(a, -b), c) 703 self.assertEqual(gcd(-b, a), c) 704 self.assertEqual(gcd(-a, -b), c) 705 self.assertEqual(gcd(-b, -a), c) 706 c = 576559230871654959816130551884856912003141446781646602790216406874 707 a = x * c 708 b = y * c 709 self.assertEqual(gcd(a, b), c) 710 self.assertEqual(gcd(b, a), c) 711 self.assertEqual(gcd(-a, b), c) 712 self.assertEqual(gcd(b, -a), c) 713 self.assertEqual(gcd(a, -b), c) 714 self.assertEqual(gcd(-b, a), c) 715 self.assertEqual(gcd(-a, -b), c) 716 self.assertEqual(gcd(-b, -a), c) 717 718 self.assertRaises(TypeError, gcd, 120.0, 84) 719 self.assertRaises(TypeError, gcd, 120, 84.0) 720 self.assertEqual(gcd(MyIndexable(120), MyIndexable(84)), 12) 721 722 def testHypot(self): 723 self.assertRaises(TypeError, math.hypot) 724 self.ftest('hypot(0,0)', math.hypot(0,0), 0) 725 self.ftest('hypot(3,4)', math.hypot(3,4), 5) 726 self.assertEqual(math.hypot(NAN, INF), INF) 727 self.assertEqual(math.hypot(INF, NAN), INF) 728 self.assertEqual(math.hypot(NAN, NINF), INF) 729 self.assertEqual(math.hypot(NINF, NAN), INF) 730 self.assertRaises(OverflowError, math.hypot, FLOAT_MAX, FLOAT_MAX) 731 self.assertTrue(math.isnan(math.hypot(1.0, NAN))) 732 self.assertTrue(math.isnan(math.hypot(NAN, -2.0))) 733 734 def testLdexp(self): 735 self.assertRaises(TypeError, math.ldexp) 736 self.ftest('ldexp(0,1)', math.ldexp(0,1), 0) 737 self.ftest('ldexp(1,1)', math.ldexp(1,1), 2) 738 self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5) 739 self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2) 740 self.assertRaises(OverflowError, math.ldexp, 1., 1000000) 741 self.assertRaises(OverflowError, math.ldexp, -1., 1000000) 742 self.assertEqual(math.ldexp(1., -1000000), 0.) 743 self.assertEqual(math.ldexp(-1., -1000000), -0.) 744 self.assertEqual(math.ldexp(INF, 30), INF) 745 self.assertEqual(math.ldexp(NINF, -213), NINF) 746 self.assertTrue(math.isnan(math.ldexp(NAN, 0))) 747 748 # large second argument 749 for n in [10**5, 10**10, 10**20, 10**40]: 750 self.assertEqual(math.ldexp(INF, -n), INF) 751 self.assertEqual(math.ldexp(NINF, -n), NINF) 752 self.assertEqual(math.ldexp(1., -n), 0.) 753 self.assertEqual(math.ldexp(-1., -n), -0.) 754 self.assertEqual(math.ldexp(0., -n), 0.) 755 self.assertEqual(math.ldexp(-0., -n), -0.) 756 self.assertTrue(math.isnan(math.ldexp(NAN, -n))) 757 758 self.assertRaises(OverflowError, math.ldexp, 1., n) 759 self.assertRaises(OverflowError, math.ldexp, -1., n) 760 self.assertEqual(math.ldexp(0., n), 0.) 761 self.assertEqual(math.ldexp(-0., n), -0.) 762 self.assertEqual(math.ldexp(INF, n), INF) 763 self.assertEqual(math.ldexp(NINF, n), NINF) 764 self.assertTrue(math.isnan(math.ldexp(NAN, n))) 765 766 def testLog(self): 767 self.assertRaises(TypeError, math.log) 768 self.ftest('log(1/e)', math.log(1/math.e), -1) 769 self.ftest('log(1)', math.log(1), 0) 770 self.ftest('log(e)', math.log(math.e), 1) 771 self.ftest('log(32,2)', math.log(32,2), 5) 772 self.ftest('log(10**40, 10)', math.log(10**40, 10), 40) 773 self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2) 774 self.ftest('log(10**1000)', math.log(10**1000), 775 2302.5850929940457) 776 self.assertRaises(ValueError, math.log, -1.5) 777 self.assertRaises(ValueError, math.log, -10**1000) 778 self.assertRaises(ValueError, math.log, NINF) 779 self.assertEqual(math.log(INF), INF) 780 self.assertTrue(math.isnan(math.log(NAN))) 781 782 def testLog1p(self): 783 self.assertRaises(TypeError, math.log1p) 784 for n in [2, 2**90, 2**300]: 785 self.assertAlmostEqual(math.log1p(n), math.log1p(float(n))) 786 self.assertRaises(ValueError, math.log1p, -1) 787 self.assertEqual(math.log1p(INF), INF) 788 789 @requires_IEEE_754 790 def testLog2(self): 791 self.assertRaises(TypeError, math.log2) 792 793 # Check some integer values 794 self.assertEqual(math.log2(1), 0.0) 795 self.assertEqual(math.log2(2), 1.0) 796 self.assertEqual(math.log2(4), 2.0) 797 798 # Large integer values 799 self.assertEqual(math.log2(2**1023), 1023.0) 800 self.assertEqual(math.log2(2**1024), 1024.0) 801 self.assertEqual(math.log2(2**2000), 2000.0) 802 803 self.assertRaises(ValueError, math.log2, -1.5) 804 self.assertRaises(ValueError, math.log2, NINF) 805 self.assertTrue(math.isnan(math.log2(NAN))) 806 807 @requires_IEEE_754 808 # log2() is not accurate enough on Mac OS X Tiger (10.4) 809 @support.requires_mac_ver(10, 5) 810 def testLog2Exact(self): 811 # Check that we get exact equality for log2 of powers of 2. 812 actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)] 813 expected = [float(n) for n in range(-1074, 1024)] 814 self.assertEqual(actual, expected) 815 816 def testLog10(self): 817 self.assertRaises(TypeError, math.log10) 818 self.ftest('log10(0.1)', math.log10(0.1), -1) 819 self.ftest('log10(1)', math.log10(1), 0) 820 self.ftest('log10(10)', math.log10(10), 1) 821 self.ftest('log10(10**1000)', math.log10(10**1000), 1000.0) 822 self.assertRaises(ValueError, math.log10, -1.5) 823 self.assertRaises(ValueError, math.log10, -10**1000) 824 self.assertRaises(ValueError, math.log10, NINF) 825 self.assertEqual(math.log(INF), INF) 826 self.assertTrue(math.isnan(math.log10(NAN))) 827 828 def testModf(self): 829 self.assertRaises(TypeError, math.modf) 830 831 def testmodf(name, result, expected): 832 (v1, v2), (e1, e2) = result, expected 833 if abs(v1-e1) > eps or abs(v2-e2): 834 self.fail('%s returned %r, expected %r'%\ 835 (name, result, expected)) 836 837 testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0)) 838 testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0)) 839 840 self.assertEqual(math.modf(INF), (0.0, INF)) 841 self.assertEqual(math.modf(NINF), (-0.0, NINF)) 842 843 modf_nan = math.modf(NAN) 844 self.assertTrue(math.isnan(modf_nan[0])) 845 self.assertTrue(math.isnan(modf_nan[1])) 846 847 def testPow(self): 848 self.assertRaises(TypeError, math.pow) 849 self.ftest('pow(0,1)', math.pow(0,1), 0) 850 self.ftest('pow(1,0)', math.pow(1,0), 1) 851 self.ftest('pow(2,1)', math.pow(2,1), 2) 852 self.ftest('pow(2,-1)', math.pow(2,-1), 0.5) 853 self.assertEqual(math.pow(INF, 1), INF) 854 self.assertEqual(math.pow(NINF, 1), NINF) 855 self.assertEqual((math.pow(1, INF)), 1.) 856 self.assertEqual((math.pow(1, NINF)), 1.) 857 self.assertTrue(math.isnan(math.pow(NAN, 1))) 858 self.assertTrue(math.isnan(math.pow(2, NAN))) 859 self.assertTrue(math.isnan(math.pow(0, NAN))) 860 self.assertEqual(math.pow(1, NAN), 1) 861 862 # pow(0., x) 863 self.assertEqual(math.pow(0., INF), 0.) 864 self.assertEqual(math.pow(0., 3.), 0.) 865 self.assertEqual(math.pow(0., 2.3), 0.) 866 self.assertEqual(math.pow(0., 2.), 0.) 867 self.assertEqual(math.pow(0., 0.), 1.) 868 self.assertEqual(math.pow(0., -0.), 1.) 869 self.assertRaises(ValueError, math.pow, 0., -2.) 870 self.assertRaises(ValueError, math.pow, 0., -2.3) 871 self.assertRaises(ValueError, math.pow, 0., -3.) 872 self.assertRaises(ValueError, math.pow, 0., NINF) 873 self.assertTrue(math.isnan(math.pow(0., NAN))) 874 875 # pow(INF, x) 876 self.assertEqual(math.pow(INF, INF), INF) 877 self.assertEqual(math.pow(INF, 3.), INF) 878 self.assertEqual(math.pow(INF, 2.3), INF) 879 self.assertEqual(math.pow(INF, 2.), INF) 880 self.assertEqual(math.pow(INF, 0.), 1.) 881 self.assertEqual(math.pow(INF, -0.), 1.) 882 self.assertEqual(math.pow(INF, -2.), 0.) 883 self.assertEqual(math.pow(INF, -2.3), 0.) 884 self.assertEqual(math.pow(INF, -3.), 0.) 885 self.assertEqual(math.pow(INF, NINF), 0.) 886 self.assertTrue(math.isnan(math.pow(INF, NAN))) 887 888 # pow(-0., x) 889 self.assertEqual(math.pow(-0., INF), 0.) 890 self.assertEqual(math.pow(-0., 3.), -0.) 891 self.assertEqual(math.pow(-0., 2.3), 0.) 892 self.assertEqual(math.pow(-0., 2.), 0.) 893 self.assertEqual(math.pow(-0., 0.), 1.) 894 self.assertEqual(math.pow(-0., -0.), 1.) 895 self.assertRaises(ValueError, math.pow, -0., -2.) 896 self.assertRaises(ValueError, math.pow, -0., -2.3) 897 self.assertRaises(ValueError, math.pow, -0., -3.) 898 self.assertRaises(ValueError, math.pow, -0., NINF) 899 self.assertTrue(math.isnan(math.pow(-0., NAN))) 900 901 # pow(NINF, x) 902 self.assertEqual(math.pow(NINF, INF), INF) 903 self.assertEqual(math.pow(NINF, 3.), NINF) 904 self.assertEqual(math.pow(NINF, 2.3), INF) 905 self.assertEqual(math.pow(NINF, 2.), INF) 906 self.assertEqual(math.pow(NINF, 0.), 1.) 907 self.assertEqual(math.pow(NINF, -0.), 1.) 908 self.assertEqual(math.pow(NINF, -2.), 0.) 909 self.assertEqual(math.pow(NINF, -2.3), 0.) 910 self.assertEqual(math.pow(NINF, -3.), -0.) 911 self.assertEqual(math.pow(NINF, NINF), 0.) 912 self.assertTrue(math.isnan(math.pow(NINF, NAN))) 913 914 # pow(-1, x) 915 self.assertEqual(math.pow(-1., INF), 1.) 916 self.assertEqual(math.pow(-1., 3.), -1.) 917 self.assertRaises(ValueError, math.pow, -1., 2.3) 918 self.assertEqual(math.pow(-1., 2.), 1.) 919 self.assertEqual(math.pow(-1., 0.), 1.) 920 self.assertEqual(math.pow(-1., -0.), 1.) 921 self.assertEqual(math.pow(-1., -2.), 1.) 922 self.assertRaises(ValueError, math.pow, -1., -2.3) 923 self.assertEqual(math.pow(-1., -3.), -1.) 924 self.assertEqual(math.pow(-1., NINF), 1.) 925 self.assertTrue(math.isnan(math.pow(-1., NAN))) 926 927 # pow(1, x) 928 self.assertEqual(math.pow(1., INF), 1.) 929 self.assertEqual(math.pow(1., 3.), 1.) 930 self.assertEqual(math.pow(1., 2.3), 1.) 931 self.assertEqual(math.pow(1., 2.), 1.) 932 self.assertEqual(math.pow(1., 0.), 1.) 933 self.assertEqual(math.pow(1., -0.), 1.) 934 self.assertEqual(math.pow(1., -2.), 1.) 935 self.assertEqual(math.pow(1., -2.3), 1.) 936 self.assertEqual(math.pow(1., -3.), 1.) 937 self.assertEqual(math.pow(1., NINF), 1.) 938 self.assertEqual(math.pow(1., NAN), 1.) 939 940 # pow(x, 0) should be 1 for any x 941 self.assertEqual(math.pow(2.3, 0.), 1.) 942 self.assertEqual(math.pow(-2.3, 0.), 1.) 943 self.assertEqual(math.pow(NAN, 0.), 1.) 944 self.assertEqual(math.pow(2.3, -0.), 1.) 945 self.assertEqual(math.pow(-2.3, -0.), 1.) 946 self.assertEqual(math.pow(NAN, -0.), 1.) 947 948 # pow(x, y) is invalid if x is negative and y is not integral 949 self.assertRaises(ValueError, math.pow, -1., 2.3) 950 self.assertRaises(ValueError, math.pow, -15., -3.1) 951 952 # pow(x, NINF) 953 self.assertEqual(math.pow(1.9, NINF), 0.) 954 self.assertEqual(math.pow(1.1, NINF), 0.) 955 self.assertEqual(math.pow(0.9, NINF), INF) 956 self.assertEqual(math.pow(0.1, NINF), INF) 957 self.assertEqual(math.pow(-0.1, NINF), INF) 958 self.assertEqual(math.pow(-0.9, NINF), INF) 959 self.assertEqual(math.pow(-1.1, NINF), 0.) 960 self.assertEqual(math.pow(-1.9, NINF), 0.) 961 962 # pow(x, INF) 963 self.assertEqual(math.pow(1.9, INF), INF) 964 self.assertEqual(math.pow(1.1, INF), INF) 965 self.assertEqual(math.pow(0.9, INF), 0.) 966 self.assertEqual(math.pow(0.1, INF), 0.) 967 self.assertEqual(math.pow(-0.1, INF), 0.) 968 self.assertEqual(math.pow(-0.9, INF), 0.) 969 self.assertEqual(math.pow(-1.1, INF), INF) 970 self.assertEqual(math.pow(-1.9, INF), INF) 971 972 # pow(x, y) should work for x negative, y an integer 973 self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0) 974 self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0) 975 self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0) 976 self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0) 977 self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0) 978 self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5) 979 self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25) 980 self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125) 981 self.assertRaises(ValueError, math.pow, -2.0, -0.5) 982 self.assertRaises(ValueError, math.pow, -2.0, 0.5) 983 984 # the following tests have been commented out since they don't 985 # really belong here: the implementation of ** for floats is 986 # independent of the implementation of math.pow 987 #self.assertEqual(1**NAN, 1) 988 #self.assertEqual(1**INF, 1) 989 #self.assertEqual(1**NINF, 1) 990 #self.assertEqual(1**0, 1) 991 #self.assertEqual(1.**NAN, 1) 992 #self.assertEqual(1.**INF, 1) 993 #self.assertEqual(1.**NINF, 1) 994 #self.assertEqual(1.**0, 1) 995 996 def testRadians(self): 997 self.assertRaises(TypeError, math.radians) 998 self.ftest('radians(180)', math.radians(180), math.pi) 999 self.ftest('radians(90)', math.radians(90), math.pi/2) 1000 self.ftest('radians(-45)', math.radians(-45), -math.pi/4) 1001 self.ftest('radians(0)', math.radians(0), 0) 1002 1003 def testSin(self): 1004 self.assertRaises(TypeError, math.sin) 1005 self.ftest('sin(0)', math.sin(0), 0) 1006 self.ftest('sin(pi/2)', math.sin(math.pi/2), 1) 1007 self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1) 1008 try: 1009 self.assertTrue(math.isnan(math.sin(INF))) 1010 self.assertTrue(math.isnan(math.sin(NINF))) 1011 except ValueError: 1012 self.assertRaises(ValueError, math.sin, INF) 1013 self.assertRaises(ValueError, math.sin, NINF) 1014 self.assertTrue(math.isnan(math.sin(NAN))) 1015 1016 def testSinh(self): 1017 self.assertRaises(TypeError, math.sinh) 1018 self.ftest('sinh(0)', math.sinh(0), 0) 1019 self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1) 1020 self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0) 1021 self.assertEqual(math.sinh(INF), INF) 1022 self.assertEqual(math.sinh(NINF), NINF) 1023 self.assertTrue(math.isnan(math.sinh(NAN))) 1024 1025 def testSqrt(self): 1026 self.assertRaises(TypeError, math.sqrt) 1027 self.ftest('sqrt(0)', math.sqrt(0), 0) 1028 self.ftest('sqrt(1)', math.sqrt(1), 1) 1029 self.ftest('sqrt(4)', math.sqrt(4), 2) 1030 self.assertEqual(math.sqrt(INF), INF) 1031 self.assertRaises(ValueError, math.sqrt, -1) 1032 self.assertRaises(ValueError, math.sqrt, NINF) 1033 self.assertTrue(math.isnan(math.sqrt(NAN))) 1034 1035 def testTan(self): 1036 self.assertRaises(TypeError, math.tan) 1037 self.ftest('tan(0)', math.tan(0), 0) 1038 self.ftest('tan(pi/4)', math.tan(math.pi/4), 1) 1039 self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1) 1040 try: 1041 self.assertTrue(math.isnan(math.tan(INF))) 1042 self.assertTrue(math.isnan(math.tan(NINF))) 1043 except: 1044 self.assertRaises(ValueError, math.tan, INF) 1045 self.assertRaises(ValueError, math.tan, NINF) 1046 self.assertTrue(math.isnan(math.tan(NAN))) 1047 1048 def testTanh(self): 1049 self.assertRaises(TypeError, math.tanh) 1050 self.ftest('tanh(0)', math.tanh(0), 0) 1051 self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0, 1052 abs_tol=ulp(1)) 1053 self.ftest('tanh(inf)', math.tanh(INF), 1) 1054 self.ftest('tanh(-inf)', math.tanh(NINF), -1) 1055 self.assertTrue(math.isnan(math.tanh(NAN))) 1056 1057 @requires_IEEE_754 1058 @unittest.skipIf(sysconfig.get_config_var('TANH_PRESERVES_ZERO_SIGN') == 0, 1059 "system tanh() function doesn't copy the sign") 1060 def testTanhSign(self): 1061 # check that tanh(-0.) == -0. on IEEE 754 systems 1062 self.assertEqual(math.tanh(-0.), -0.) 1063 self.assertEqual(math.copysign(1., math.tanh(-0.)), 1064 math.copysign(1., -0.)) 1065 1066 def test_trunc(self): 1067 self.assertEqual(math.trunc(1), 1) 1068 self.assertEqual(math.trunc(-1), -1) 1069 self.assertEqual(type(math.trunc(1)), int) 1070 self.assertEqual(type(math.trunc(1.5)), int) 1071 self.assertEqual(math.trunc(1.5), 1) 1072 self.assertEqual(math.trunc(-1.5), -1) 1073 self.assertEqual(math.trunc(1.999999), 1) 1074 self.assertEqual(math.trunc(-1.999999), -1) 1075 self.assertEqual(math.trunc(-0.999999), -0) 1076 self.assertEqual(math.trunc(-100.999), -100) 1077 1078 class TestTrunc(object): 1079 def __trunc__(self): 1080 return 23 1081 1082 class TestNoTrunc(object): 1083 pass 1084 1085 self.assertEqual(math.trunc(TestTrunc()), 23) 1086 1087 self.assertRaises(TypeError, math.trunc) 1088 self.assertRaises(TypeError, math.trunc, 1, 2) 1089 self.assertRaises(TypeError, math.trunc, TestNoTrunc()) 1090 1091 def testIsfinite(self): 1092 self.assertTrue(math.isfinite(0.0)) 1093 self.assertTrue(math.isfinite(-0.0)) 1094 self.assertTrue(math.isfinite(1.0)) 1095 self.assertTrue(math.isfinite(-1.0)) 1096 self.assertFalse(math.isfinite(float("nan"))) 1097 self.assertFalse(math.isfinite(float("inf"))) 1098 self.assertFalse(math.isfinite(float("-inf"))) 1099 1100 def testIsnan(self): 1101 self.assertTrue(math.isnan(float("nan"))) 1102 self.assertTrue(math.isnan(float("-nan"))) 1103 self.assertTrue(math.isnan(float("inf") * 0.)) 1104 self.assertFalse(math.isnan(float("inf"))) 1105 self.assertFalse(math.isnan(0.)) 1106 self.assertFalse(math.isnan(1.)) 1107 1108 def testIsinf(self): 1109 self.assertTrue(math.isinf(float("inf"))) 1110 self.assertTrue(math.isinf(float("-inf"))) 1111 self.assertTrue(math.isinf(1E400)) 1112 self.assertTrue(math.isinf(-1E400)) 1113 self.assertFalse(math.isinf(float("nan"))) 1114 self.assertFalse(math.isinf(0.)) 1115 self.assertFalse(math.isinf(1.)) 1116 1117 @requires_IEEE_754 1118 def test_nan_constant(self): 1119 self.assertTrue(math.isnan(math.nan)) 1120 1121 @requires_IEEE_754 1122 def test_inf_constant(self): 1123 self.assertTrue(math.isinf(math.inf)) 1124 self.assertGreater(math.inf, 0.0) 1125 self.assertEqual(math.inf, float("inf")) 1126 self.assertEqual(-math.inf, float("-inf")) 1127 1128 # RED_FLAG 16-Oct-2000 Tim 1129 # While 2.0 is more consistent about exceptions than previous releases, it 1130 # still fails this part of the test on some platforms. For now, we only 1131 # *run* test_exceptions() in verbose mode, so that this isn't normally 1132 # tested. 1133 @unittest.skipUnless(verbose, 'requires verbose mode') 1134 def test_exceptions(self): 1135 try: 1136 x = math.exp(-1000000000) 1137 except: 1138 # mathmodule.c is failing to weed out underflows from libm, or 1139 # we've got an fp format with huge dynamic range 1140 self.fail("underflowing exp() should not have raised " 1141 "an exception") 1142 if x != 0: 1143 self.fail("underflowing exp() should have returned 0") 1144 1145 # If this fails, probably using a strict IEEE-754 conforming libm, and x 1146 # is +Inf afterwards. But Python wants overflows detected by default. 1147 try: 1148 x = math.exp(1000000000) 1149 except OverflowError: 1150 pass 1151 else: 1152 self.fail("overflowing exp() didn't trigger OverflowError") 1153 1154 # If this fails, it could be a puzzle. One odd possibility is that 1155 # mathmodule.c's macros are getting confused while comparing 1156 # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE 1157 # as a result (and so raising OverflowError instead). 1158 try: 1159 x = math.sqrt(-1.0) 1160 except ValueError: 1161 pass 1162 else: 1163 self.fail("sqrt(-1) didn't raise ValueError") 1164 1165 @requires_IEEE_754 1166 def test_testfile(self): 1167 # Some tests need to be skipped on ancient OS X versions. 1168 # See issue #27953. 1169 SKIP_ON_TIGER = {'tan0064'} 1170 1171 osx_version = None 1172 if sys.platform == 'darwin': 1173 version_txt = platform.mac_ver()[0] 1174 try: 1175 osx_version = tuple(map(int, version_txt.split('.'))) 1176 except ValueError: 1177 pass 1178 1179 fail_fmt = "{}: {}({!r}): {}" 1180 1181 failures = [] 1182 for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file): 1183 # Skip if either the input or result is complex 1184 if ai != 0.0 or ei != 0.0: 1185 continue 1186 if fn in ['rect', 'polar']: 1187 # no real versions of rect, polar 1188 continue 1189 # Skip certain tests on OS X 10.4. 1190 if osx_version is not None and osx_version < (10, 5): 1191 if id in SKIP_ON_TIGER: 1192 continue 1193 1194 func = getattr(math, fn) 1195 1196 if 'invalid' in flags or 'divide-by-zero' in flags: 1197 er = 'ValueError' 1198 elif 'overflow' in flags: 1199 er = 'OverflowError' 1200 1201 try: 1202 result = func(ar) 1203 except ValueError: 1204 result = 'ValueError' 1205 except OverflowError: 1206 result = 'OverflowError' 1207 1208 # Default tolerances 1209 ulp_tol, abs_tol = 5, 0.0 1210 1211 failure = result_check(er, result, ulp_tol, abs_tol) 1212 if failure is None: 1213 continue 1214 1215 msg = fail_fmt.format(id, fn, ar, failure) 1216 failures.append(msg) 1217 1218 if failures: 1219 self.fail('Failures in test_testfile:\n ' + 1220 '\n '.join(failures)) 1221 1222 @requires_IEEE_754 1223 def test_mtestfile(self): 1224 fail_fmt = "{}: {}({!r}): {}" 1225 1226 failures = [] 1227 for id, fn, arg, expected, flags in parse_mtestfile(math_testcases): 1228 func = getattr(math, fn) 1229 1230 if 'invalid' in flags or 'divide-by-zero' in flags: 1231 expected = 'ValueError' 1232 elif 'overflow' in flags: 1233 expected = 'OverflowError' 1234 1235 try: 1236 got = func(arg) 1237 except ValueError: 1238 got = 'ValueError' 1239 except OverflowError: 1240 got = 'OverflowError' 1241 1242 # Default tolerances 1243 ulp_tol, abs_tol = 5, 0.0 1244 1245 # Exceptions to the defaults 1246 if fn == 'gamma': 1247 # Experimental results on one platform gave 1248 # an accuracy of <= 10 ulps across the entire float 1249 # domain. We weaken that to require 20 ulp accuracy. 1250 ulp_tol = 20 1251 1252 elif fn == 'lgamma': 1253 # we use a weaker accuracy test for lgamma; 1254 # lgamma only achieves an absolute error of 1255 # a few multiples of the machine accuracy, in 1256 # general. 1257 abs_tol = 1e-15 1258 1259 elif fn == 'erfc' and arg >= 0.0: 1260 # erfc has less-than-ideal accuracy for large 1261 # arguments (x ~ 25 or so), mainly due to the 1262 # error involved in computing exp(-x*x). 1263 # 1264 # Observed between CPython and mpmath at 25 dp: 1265 # x < 0 : err <= 2 ulp 1266 # 0 <= x < 1 : err <= 10 ulp 1267 # 1 <= x < 10 : err <= 100 ulp 1268 # 10 <= x < 20 : err <= 300 ulp 1269 # 20 <= x : < 600 ulp 1270 # 1271 if arg < 1.0: 1272 ulp_tol = 10 1273 elif arg < 10.0: 1274 ulp_tol = 100 1275 else: 1276 ulp_tol = 1000 1277 1278 failure = result_check(expected, got, ulp_tol, abs_tol) 1279 if failure is None: 1280 continue 1281 1282 msg = fail_fmt.format(id, fn, arg, failure) 1283 failures.append(msg) 1284 1285 if failures: 1286 self.fail('Failures in test_mtestfile:\n ' + 1287 '\n '.join(failures)) 1288 1289 1290class IsCloseTests(unittest.TestCase): 1291 isclose = math.isclose # sublcasses should override this 1292 1293 def assertIsClose(self, a, b, *args, **kwargs): 1294 self.assertTrue(self.isclose(a, b, *args, **kwargs), 1295 msg="%s and %s should be close!" % (a, b)) 1296 1297 def assertIsNotClose(self, a, b, *args, **kwargs): 1298 self.assertFalse(self.isclose(a, b, *args, **kwargs), 1299 msg="%s and %s should not be close!" % (a, b)) 1300 1301 def assertAllClose(self, examples, *args, **kwargs): 1302 for a, b in examples: 1303 self.assertIsClose(a, b, *args, **kwargs) 1304 1305 def assertAllNotClose(self, examples, *args, **kwargs): 1306 for a, b in examples: 1307 self.assertIsNotClose(a, b, *args, **kwargs) 1308 1309 def test_negative_tolerances(self): 1310 # ValueError should be raised if either tolerance is less than zero 1311 with self.assertRaises(ValueError): 1312 self.assertIsClose(1, 1, rel_tol=-1e-100) 1313 with self.assertRaises(ValueError): 1314 self.assertIsClose(1, 1, rel_tol=1e-100, abs_tol=-1e10) 1315 1316 def test_identical(self): 1317 # identical values must test as close 1318 identical_examples = [(2.0, 2.0), 1319 (0.1e200, 0.1e200), 1320 (1.123e-300, 1.123e-300), 1321 (12345, 12345.0), 1322 (0.0, -0.0), 1323 (345678, 345678)] 1324 self.assertAllClose(identical_examples, rel_tol=0.0, abs_tol=0.0) 1325 1326 def test_eight_decimal_places(self): 1327 # examples that are close to 1e-8, but not 1e-9 1328 eight_decimal_places_examples = [(1e8, 1e8 + 1), 1329 (-1e-8, -1.000000009e-8), 1330 (1.12345678, 1.12345679)] 1331 self.assertAllClose(eight_decimal_places_examples, rel_tol=1e-8) 1332 self.assertAllNotClose(eight_decimal_places_examples, rel_tol=1e-9) 1333 1334 def test_near_zero(self): 1335 # values close to zero 1336 near_zero_examples = [(1e-9, 0.0), 1337 (-1e-9, 0.0), 1338 (-1e-150, 0.0)] 1339 # these should not be close to any rel_tol 1340 self.assertAllNotClose(near_zero_examples, rel_tol=0.9) 1341 # these should be close to abs_tol=1e-8 1342 self.assertAllClose(near_zero_examples, abs_tol=1e-8) 1343 1344 def test_identical_infinite(self): 1345 # these are close regardless of tolerance -- i.e. they are equal 1346 self.assertIsClose(INF, INF) 1347 self.assertIsClose(INF, INF, abs_tol=0.0) 1348 self.assertIsClose(NINF, NINF) 1349 self.assertIsClose(NINF, NINF, abs_tol=0.0) 1350 1351 def test_inf_ninf_nan(self): 1352 # these should never be close (following IEEE 754 rules for equality) 1353 not_close_examples = [(NAN, NAN), 1354 (NAN, 1e-100), 1355 (1e-100, NAN), 1356 (INF, NAN), 1357 (NAN, INF), 1358 (INF, NINF), 1359 (INF, 1.0), 1360 (1.0, INF), 1361 (INF, 1e308), 1362 (1e308, INF)] 1363 # use largest reasonable tolerance 1364 self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999) 1365 1366 def test_zero_tolerance(self): 1367 # test with zero tolerance 1368 zero_tolerance_close_examples = [(1.0, 1.0), 1369 (-3.4, -3.4), 1370 (-1e-300, -1e-300)] 1371 self.assertAllClose(zero_tolerance_close_examples, rel_tol=0.0) 1372 1373 zero_tolerance_not_close_examples = [(1.0, 1.000000000000001), 1374 (0.99999999999999, 1.0), 1375 (1.0e200, .999999999999999e200)] 1376 self.assertAllNotClose(zero_tolerance_not_close_examples, rel_tol=0.0) 1377 1378 def test_asymmetry(self): 1379 # test the asymmetry example from PEP 485 1380 self.assertAllClose([(9, 10), (10, 9)], rel_tol=0.1) 1381 1382 def test_integers(self): 1383 # test with integer values 1384 integer_examples = [(100000001, 100000000), 1385 (123456789, 123456788)] 1386 1387 self.assertAllClose(integer_examples, rel_tol=1e-8) 1388 self.assertAllNotClose(integer_examples, rel_tol=1e-9) 1389 1390 def test_decimals(self): 1391 # test with Decimal values 1392 from decimal import Decimal 1393 1394 decimal_examples = [(Decimal('1.00000001'), Decimal('1.0')), 1395 (Decimal('1.00000001e-20'), Decimal('1.0e-20')), 1396 (Decimal('1.00000001e-100'), Decimal('1.0e-100')), 1397 (Decimal('1.00000001e20'), Decimal('1.0e20'))] 1398 self.assertAllClose(decimal_examples, rel_tol=1e-8) 1399 self.assertAllNotClose(decimal_examples, rel_tol=1e-9) 1400 1401 def test_fractions(self): 1402 # test with Fraction values 1403 from fractions import Fraction 1404 1405 fraction_examples = [ 1406 (Fraction(1, 100000000) + 1, Fraction(1)), 1407 (Fraction(100000001), Fraction(100000000)), 1408 (Fraction(10**8 + 1, 10**28), Fraction(1, 10**20))] 1409 self.assertAllClose(fraction_examples, rel_tol=1e-8) 1410 self.assertAllNotClose(fraction_examples, rel_tol=1e-9) 1411 1412 1413def test_main(): 1414 from doctest import DocFileSuite 1415 suite = unittest.TestSuite() 1416 suite.addTest(unittest.makeSuite(MathTests)) 1417 suite.addTest(unittest.makeSuite(IsCloseTests)) 1418 suite.addTest(DocFileSuite("ieee754.txt")) 1419 run_unittest(suite) 1420 1421if __name__ == '__main__': 1422 test_main() 1423