1 # Python test set -- math module 2 # XXXX Should not do tests around zero only 3 4 from test.support import run_unittest, verbose, requires_IEEE_754 5 from test import support 6 import unittest 7 import math 8 import os 9 import platform 10 import struct 11 import sys 12 import sysconfig 13 14 eps = 1E-05 15 NAN = float('nan') 16 INF = float('inf') 17 NINF = float('-inf') 18 FLOAT_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. 22 x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer 23 HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4) 24 25 # locate file with test values 26 if __name__ == '__main__': 27 file = sys.argv[0] 28 else: 29 file = __file__ 30 test_dir = os.path.dirname(file) or os.curdir 31 math_testcases = os.path.join(test_dir, 'math_testcases.txt') 32 test_file = os.path.join(test_dir, 'cmath_testcases.txt') 33 34 35 def 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 52 def 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 97 def 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 101 def 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 115 def 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 126 def 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 144 def 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 170 def 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 194 def 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. 240 class MyIndexable(object): 241 def __init__(self, value): 242 self.value = value 243 244 def __index__(self): 245 return self.value 246 247 class 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 @requires_IEEE_754 1004 def testRemainder(self): 1005 from fractions import Fraction 1006 1007 def validate_spec(x, y, r): 1008 """ 1009 Check that r matches remainder(x, y) according to the IEEE 754 1010 specification. Assumes that x, y and r are finite and y is nonzero. 1011 """ 1012 fx, fy, fr = Fraction(x), Fraction(y), Fraction(r) 1013 # r should not exceed y/2 in absolute value 1014 self.assertLessEqual(abs(fr), abs(fy/2)) 1015 # x - r should be an exact integer multiple of y 1016 n = (fx - fr) / fy 1017 self.assertEqual(n, int(n)) 1018 if abs(fr) == abs(fy/2): 1019 # If |r| == |y/2|, n should be even. 1020 self.assertEqual(n/2, int(n/2)) 1021 1022 # triples (x, y, remainder(x, y)) in hexadecimal form. 1023 testcases = [ 1024 # Remainders modulo 1, showing the ties-to-even behaviour. 1025 '-4.0 1 -0.0', 1026 '-3.8 1 0.8', 1027 '-3.0 1 -0.0', 1028 '-2.8 1 -0.8', 1029 '-2.0 1 -0.0', 1030 '-1.8 1 0.8', 1031 '-1.0 1 -0.0', 1032 '-0.8 1 -0.8', 1033 '-0.0 1 -0.0', 1034 ' 0.0 1 0.0', 1035 ' 0.8 1 0.8', 1036 ' 1.0 1 0.0', 1037 ' 1.8 1 -0.8', 1038 ' 2.0 1 0.0', 1039 ' 2.8 1 0.8', 1040 ' 3.0 1 0.0', 1041 ' 3.8 1 -0.8', 1042 ' 4.0 1 0.0', 1043 1044 # Reductions modulo 2*pi 1045 '0x0.0p+0 0x1.921fb54442d18p+2 0x0.0p+0', 1046 '0x1.921fb54442d18p+0 0x1.921fb54442d18p+2 0x1.921fb54442d18p+0', 1047 '0x1.921fb54442d17p+1 0x1.921fb54442d18p+2 0x1.921fb54442d17p+1', 1048 '0x1.921fb54442d18p+1 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1', 1049 '0x1.921fb54442d19p+1 0x1.921fb54442d18p+2 -0x1.921fb54442d17p+1', 1050 '0x1.921fb54442d17p+2 0x1.921fb54442d18p+2 -0x0.0000000000001p+2', 1051 '0x1.921fb54442d18p+2 0x1.921fb54442d18p+2 0x0p0', 1052 '0x1.921fb54442d19p+2 0x1.921fb54442d18p+2 0x0.0000000000001p+2', 1053 '0x1.2d97c7f3321d1p+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1', 1054 '0x1.2d97c7f3321d2p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d18p+1', 1055 '0x1.2d97c7f3321d3p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1', 1056 '0x1.921fb54442d17p+3 0x1.921fb54442d18p+2 -0x0.0000000000001p+3', 1057 '0x1.921fb54442d18p+3 0x1.921fb54442d18p+2 0x0p0', 1058 '0x1.921fb54442d19p+3 0x1.921fb54442d18p+2 0x0.0000000000001p+3', 1059 '0x1.f6a7a2955385dp+3 0x1.921fb54442d18p+2 0x1.921fb54442d14p+1', 1060 '0x1.f6a7a2955385ep+3 0x1.921fb54442d18p+2 0x1.921fb54442d18p+1', 1061 '0x1.f6a7a2955385fp+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1', 1062 '0x1.1475cc9eedf00p+5 0x1.921fb54442d18p+2 0x1.921fb54442d10p+1', 1063 '0x1.1475cc9eedf01p+5 0x1.921fb54442d18p+2 -0x1.921fb54442d10p+1', 1064 1065 # Symmetry with respect to signs. 1066 ' 1 0.c 0.4', 1067 '-1 0.c -0.4', 1068 ' 1 -0.c 0.4', 1069 '-1 -0.c -0.4', 1070 ' 1.4 0.c -0.4', 1071 '-1.4 0.c 0.4', 1072 ' 1.4 -0.c -0.4', 1073 '-1.4 -0.c 0.4', 1074 1075 # Huge modulus, to check that the underlying algorithm doesn't 1076 # rely on 2.0 * modulus being representable. 1077 '0x1.dp+1023 0x1.4p+1023 0x0.9p+1023', 1078 '0x1.ep+1023 0x1.4p+1023 -0x0.ap+1023', 1079 '0x1.fp+1023 0x1.4p+1023 -0x0.9p+1023', 1080 ] 1081 1082 for case in testcases: 1083 with self.subTest(case=case): 1084 x_hex, y_hex, expected_hex = case.split() 1085 x = float.fromhex(x_hex) 1086 y = float.fromhex(y_hex) 1087 expected = float.fromhex(expected_hex) 1088 validate_spec(x, y, expected) 1089 actual = math.remainder(x, y) 1090 # Cheap way of checking that the floats are 1091 # as identical as we need them to be. 1092 self.assertEqual(actual.hex(), expected.hex()) 1093 1094 # Test tiny subnormal modulus: there's potential for 1095 # getting the implementation wrong here (for example, 1096 # by assuming that modulus/2 is exactly representable). 1097 tiny = float.fromhex('1p-1074') # min +ve subnormal 1098 for n in range(-25, 25): 1099 if n == 0: 1100 continue 1101 y = n * tiny 1102 for m in range(100): 1103 x = m * tiny 1104 actual = math.remainder(x, y) 1105 validate_spec(x, y, actual) 1106 actual = math.remainder(-x, y) 1107 validate_spec(-x, y, actual) 1108 1109 # Special values. 1110 # NaNs should propagate as usual. 1111 for value in [NAN, 0.0, -0.0, 2.0, -2.3, NINF, INF]: 1112 self.assertIsNaN(math.remainder(NAN, value)) 1113 self.assertIsNaN(math.remainder(value, NAN)) 1114 1115 # remainder(x, inf) is x, for non-nan non-infinite x. 1116 for value in [-2.3, -0.0, 0.0, 2.3]: 1117 self.assertEqual(math.remainder(value, INF), value) 1118 self.assertEqual(math.remainder(value, NINF), value) 1119 1120 # remainder(x, 0) and remainder(infinity, x) for non-NaN x are invalid 1121 # operations according to IEEE 754-2008 7.2(f), and should raise. 1122 for value in [NINF, -2.3, -0.0, 0.0, 2.3, INF]: 1123 with self.assertRaises(ValueError): 1124 math.remainder(INF, value) 1125 with self.assertRaises(ValueError): 1126 math.remainder(NINF, value) 1127 with self.assertRaises(ValueError): 1128 math.remainder(value, 0.0) 1129 with self.assertRaises(ValueError): 1130 math.remainder(value, -0.0) 1131 1132 def testSin(self): 1133 self.assertRaises(TypeError, math.sin) 1134 self.ftest('sin(0)', math.sin(0), 0) 1135 self.ftest('sin(pi/2)', math.sin(math.pi/2), 1) 1136 self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1) 1137 try: 1138 self.assertTrue(math.isnan(math.sin(INF))) 1139 self.assertTrue(math.isnan(math.sin(NINF))) 1140 except ValueError: 1141 self.assertRaises(ValueError, math.sin, INF) 1142 self.assertRaises(ValueError, math.sin, NINF) 1143 self.assertTrue(math.isnan(math.sin(NAN))) 1144 1145 def testSinh(self): 1146 self.assertRaises(TypeError, math.sinh) 1147 self.ftest('sinh(0)', math.sinh(0), 0) 1148 self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1) 1149 self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0) 1150 self.assertEqual(math.sinh(INF), INF) 1151 self.assertEqual(math.sinh(NINF), NINF) 1152 self.assertTrue(math.isnan(math.sinh(NAN))) 1153 1154 def testSqrt(self): 1155 self.assertRaises(TypeError, math.sqrt) 1156 self.ftest('sqrt(0)', math.sqrt(0), 0) 1157 self.ftest('sqrt(1)', math.sqrt(1), 1) 1158 self.ftest('sqrt(4)', math.sqrt(4), 2) 1159 self.assertEqual(math.sqrt(INF), INF) 1160 self.assertRaises(ValueError, math.sqrt, -1) 1161 self.assertRaises(ValueError, math.sqrt, NINF) 1162 self.assertTrue(math.isnan(math.sqrt(NAN))) 1163 1164 def testTan(self): 1165 self.assertRaises(TypeError, math.tan) 1166 self.ftest('tan(0)', math.tan(0), 0) 1167 self.ftest('tan(pi/4)', math.tan(math.pi/4), 1) 1168 self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1) 1169 try: 1170 self.assertTrue(math.isnan(math.tan(INF))) 1171 self.assertTrue(math.isnan(math.tan(NINF))) 1172 except: 1173 self.assertRaises(ValueError, math.tan, INF) 1174 self.assertRaises(ValueError, math.tan, NINF) 1175 self.assertTrue(math.isnan(math.tan(NAN))) 1176 1177 def testTanh(self): 1178 self.assertRaises(TypeError, math.tanh) 1179 self.ftest('tanh(0)', math.tanh(0), 0) 1180 self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0, 1181 abs_tol=ulp(1)) 1182 self.ftest('tanh(inf)', math.tanh(INF), 1) 1183 self.ftest('tanh(-inf)', math.tanh(NINF), -1) 1184 self.assertTrue(math.isnan(math.tanh(NAN))) 1185 1186 @requires_IEEE_754 1187 @unittest.skipIf(sysconfig.get_config_var('TANH_PRESERVES_ZERO_SIGN') == 0, 1188 "system tanh() function doesn't copy the sign") 1189 def testTanhSign(self): 1190 # check that tanh(-0.) == -0. on IEEE 754 systems 1191 self.assertEqual(math.tanh(-0.), -0.) 1192 self.assertEqual(math.copysign(1., math.tanh(-0.)), 1193 math.copysign(1., -0.)) 1194 1195 def test_trunc(self): 1196 self.assertEqual(math.trunc(1), 1) 1197 self.assertEqual(math.trunc(-1), -1) 1198 self.assertEqual(type(math.trunc(1)), int) 1199 self.assertEqual(type(math.trunc(1.5)), int) 1200 self.assertEqual(math.trunc(1.5), 1) 1201 self.assertEqual(math.trunc(-1.5), -1) 1202 self.assertEqual(math.trunc(1.999999), 1) 1203 self.assertEqual(math.trunc(-1.999999), -1) 1204 self.assertEqual(math.trunc(-0.999999), -0) 1205 self.assertEqual(math.trunc(-100.999), -100) 1206 1207 class TestTrunc(object): 1208 def __trunc__(self): 1209 return 23 1210 1211 class TestNoTrunc(object): 1212 pass 1213 1214 self.assertEqual(math.trunc(TestTrunc()), 23) 1215 1216 self.assertRaises(TypeError, math.trunc) 1217 self.assertRaises(TypeError, math.trunc, 1, 2) 1218 self.assertRaises(TypeError, math.trunc, TestNoTrunc()) 1219 1220 def testIsfinite(self): 1221 self.assertTrue(math.isfinite(0.0)) 1222 self.assertTrue(math.isfinite(-0.0)) 1223 self.assertTrue(math.isfinite(1.0)) 1224 self.assertTrue(math.isfinite(-1.0)) 1225 self.assertFalse(math.isfinite(float("nan"))) 1226 self.assertFalse(math.isfinite(float("inf"))) 1227 self.assertFalse(math.isfinite(float("-inf"))) 1228 1229 def testIsnan(self): 1230 self.assertTrue(math.isnan(float("nan"))) 1231 self.assertTrue(math.isnan(float("-nan"))) 1232 self.assertTrue(math.isnan(float("inf") * 0.)) 1233 self.assertFalse(math.isnan(float("inf"))) 1234 self.assertFalse(math.isnan(0.)) 1235 self.assertFalse(math.isnan(1.)) 1236 1237 def testIsinf(self): 1238 self.assertTrue(math.isinf(float("inf"))) 1239 self.assertTrue(math.isinf(float("-inf"))) 1240 self.assertTrue(math.isinf(1E400)) 1241 self.assertTrue(math.isinf(-1E400)) 1242 self.assertFalse(math.isinf(float("nan"))) 1243 self.assertFalse(math.isinf(0.)) 1244 self.assertFalse(math.isinf(1.)) 1245 1246 @requires_IEEE_754 1247 def test_nan_constant(self): 1248 self.assertTrue(math.isnan(math.nan)) 1249 1250 @requires_IEEE_754 1251 def test_inf_constant(self): 1252 self.assertTrue(math.isinf(math.inf)) 1253 self.assertGreater(math.inf, 0.0) 1254 self.assertEqual(math.inf, float("inf")) 1255 self.assertEqual(-math.inf, float("-inf")) 1256 1257 # RED_FLAG 16-Oct-2000 Tim 1258 # While 2.0 is more consistent about exceptions than previous releases, it 1259 # still fails this part of the test on some platforms. For now, we only 1260 # *run* test_exceptions() in verbose mode, so that this isn't normally 1261 # tested. 1262 @unittest.skipUnless(verbose, 'requires verbose mode') 1263 def test_exceptions(self): 1264 try: 1265 x = math.exp(-1000000000) 1266 except: 1267 # mathmodule.c is failing to weed out underflows from libm, or 1268 # we've got an fp format with huge dynamic range 1269 self.fail("underflowing exp() should not have raised " 1270 "an exception") 1271 if x != 0: 1272 self.fail("underflowing exp() should have returned 0") 1273 1274 # If this fails, probably using a strict IEEE-754 conforming libm, and x 1275 # is +Inf afterwards. But Python wants overflows detected by default. 1276 try: 1277 x = math.exp(1000000000) 1278 except OverflowError: 1279 pass 1280 else: 1281 self.fail("overflowing exp() didn't trigger OverflowError") 1282 1283 # If this fails, it could be a puzzle. One odd possibility is that 1284 # mathmodule.c's macros are getting confused while comparing 1285 # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE 1286 # as a result (and so raising OverflowError instead). 1287 try: 1288 x = math.sqrt(-1.0) 1289 except ValueError: 1290 pass 1291 else: 1292 self.fail("sqrt(-1) didn't raise ValueError") 1293 1294 @requires_IEEE_754 1295 def test_testfile(self): 1296 # Some tests need to be skipped on ancient OS X versions. 1297 # See issue #27953. 1298 SKIP_ON_TIGER = {'tan0064'} 1299 1300 osx_version = None 1301 if sys.platform == 'darwin': 1302 version_txt = platform.mac_ver()[0] 1303 try: 1304 osx_version = tuple(map(int, version_txt.split('.'))) 1305 except ValueError: 1306 pass 1307 1308 fail_fmt = "{}: {}({!r}): {}" 1309 1310 failures = [] 1311 for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file): 1312 # Skip if either the input or result is complex 1313 if ai != 0.0 or ei != 0.0: 1314 continue 1315 if fn in ['rect', 'polar']: 1316 # no real versions of rect, polar 1317 continue 1318 # Skip certain tests on OS X 10.4. 1319 if osx_version is not None and osx_version < (10, 5): 1320 if id in SKIP_ON_TIGER: 1321 continue 1322 1323 func = getattr(math, fn) 1324 1325 if 'invalid' in flags or 'divide-by-zero' in flags: 1326 er = 'ValueError' 1327 elif 'overflow' in flags: 1328 er = 'OverflowError' 1329 1330 try: 1331 result = func(ar) 1332 except ValueError: 1333 result = 'ValueError' 1334 except OverflowError: 1335 result = 'OverflowError' 1336 1337 # Default tolerances 1338 ulp_tol, abs_tol = 5, 0.0 1339 1340 failure = result_check(er, result, ulp_tol, abs_tol) 1341 if failure is None: 1342 continue 1343 1344 msg = fail_fmt.format(id, fn, ar, failure) 1345 failures.append(msg) 1346 1347 if failures: 1348 self.fail('Failures in test_testfile:\n ' + 1349 '\n '.join(failures)) 1350 1351 @requires_IEEE_754 1352 def test_mtestfile(self): 1353 fail_fmt = "{}: {}({!r}): {}" 1354 1355 failures = [] 1356 for id, fn, arg, expected, flags in parse_mtestfile(math_testcases): 1357 func = getattr(math, fn) 1358 1359 if 'invalid' in flags or 'divide-by-zero' in flags: 1360 expected = 'ValueError' 1361 elif 'overflow' in flags: 1362 expected = 'OverflowError' 1363 1364 try: 1365 got = func(arg) 1366 except ValueError: 1367 got = 'ValueError' 1368 except OverflowError: 1369 got = 'OverflowError' 1370 1371 # Default tolerances 1372 ulp_tol, abs_tol = 5, 0.0 1373 1374 # Exceptions to the defaults 1375 if fn == 'gamma': 1376 # Experimental results on one platform gave 1377 # an accuracy of <= 10 ulps across the entire float 1378 # domain. We weaken that to require 20 ulp accuracy. 1379 ulp_tol = 20 1380 1381 elif fn == 'lgamma': 1382 # we use a weaker accuracy test for lgamma; 1383 # lgamma only achieves an absolute error of 1384 # a few multiples of the machine accuracy, in 1385 # general. 1386 abs_tol = 1e-15 1387 1388 elif fn == 'erfc' and arg >= 0.0: 1389 # erfc has less-than-ideal accuracy for large 1390 # arguments (x ~ 25 or so), mainly due to the 1391 # error involved in computing exp(-x*x). 1392 # 1393 # Observed between CPython and mpmath at 25 dp: 1394 # x < 0 : err <= 2 ulp 1395 # 0 <= x < 1 : err <= 10 ulp 1396 # 1 <= x < 10 : err <= 100 ulp 1397 # 10 <= x < 20 : err <= 300 ulp 1398 # 20 <= x : < 600 ulp 1399 # 1400 if arg < 1.0: 1401 ulp_tol = 10 1402 elif arg < 10.0: 1403 ulp_tol = 100 1404 else: 1405 ulp_tol = 1000 1406 1407 failure = result_check(expected, got, ulp_tol, abs_tol) 1408 if failure is None: 1409 continue 1410 1411 msg = fail_fmt.format(id, fn, arg, failure) 1412 failures.append(msg) 1413 1414 if failures: 1415 self.fail('Failures in test_mtestfile:\n ' + 1416 '\n '.join(failures)) 1417 1418 # Custom assertions. 1419 1420 def assertIsNaN(self, value): 1421 if not math.isnan(value): 1422 self.fail("Expected a NaN, got {!r}.".format(value)) 1423 1424 1425 class IsCloseTests(unittest.TestCase): 1426 isclose = math.isclose # subclasses should override this 1427 1428 def assertIsClose(self, a, b, *args, **kwargs): 1429 self.assertTrue(self.isclose(a, b, *args, **kwargs), 1430 msg="%s and %s should be close!" % (a, b)) 1431 1432 def assertIsNotClose(self, a, b, *args, **kwargs): 1433 self.assertFalse(self.isclose(a, b, *args, **kwargs), 1434 msg="%s and %s should not be close!" % (a, b)) 1435 1436 def assertAllClose(self, examples, *args, **kwargs): 1437 for a, b in examples: 1438 self.assertIsClose(a, b, *args, **kwargs) 1439 1440 def assertAllNotClose(self, examples, *args, **kwargs): 1441 for a, b in examples: 1442 self.assertIsNotClose(a, b, *args, **kwargs) 1443 1444 def test_negative_tolerances(self): 1445 # ValueError should be raised if either tolerance is less than zero 1446 with self.assertRaises(ValueError): 1447 self.assertIsClose(1, 1, rel_tol=-1e-100) 1448 with self.assertRaises(ValueError): 1449 self.assertIsClose(1, 1, rel_tol=1e-100, abs_tol=-1e10) 1450 1451 def test_identical(self): 1452 # identical values must test as close 1453 identical_examples = [(2.0, 2.0), 1454 (0.1e200, 0.1e200), 1455 (1.123e-300, 1.123e-300), 1456 (12345, 12345.0), 1457 (0.0, -0.0), 1458 (345678, 345678)] 1459 self.assertAllClose(identical_examples, rel_tol=0.0, abs_tol=0.0) 1460 1461 def test_eight_decimal_places(self): 1462 # examples that are close to 1e-8, but not 1e-9 1463 eight_decimal_places_examples = [(1e8, 1e8 + 1), 1464 (-1e-8, -1.000000009e-8), 1465 (1.12345678, 1.12345679)] 1466 self.assertAllClose(eight_decimal_places_examples, rel_tol=1e-8) 1467 self.assertAllNotClose(eight_decimal_places_examples, rel_tol=1e-9) 1468 1469 def test_near_zero(self): 1470 # values close to zero 1471 near_zero_examples = [(1e-9, 0.0), 1472 (-1e-9, 0.0), 1473 (-1e-150, 0.0)] 1474 # these should not be close to any rel_tol 1475 self.assertAllNotClose(near_zero_examples, rel_tol=0.9) 1476 # these should be close to abs_tol=1e-8 1477 self.assertAllClose(near_zero_examples, abs_tol=1e-8) 1478 1479 def test_identical_infinite(self): 1480 # these are close regardless of tolerance -- i.e. they are equal 1481 self.assertIsClose(INF, INF) 1482 self.assertIsClose(INF, INF, abs_tol=0.0) 1483 self.assertIsClose(NINF, NINF) 1484 self.assertIsClose(NINF, NINF, abs_tol=0.0) 1485 1486 def test_inf_ninf_nan(self): 1487 # these should never be close (following IEEE 754 rules for equality) 1488 not_close_examples = [(NAN, NAN), 1489 (NAN, 1e-100), 1490 (1e-100, NAN), 1491 (INF, NAN), 1492 (NAN, INF), 1493 (INF, NINF), 1494 (INF, 1.0), 1495 (1.0, INF), 1496 (INF, 1e308), 1497 (1e308, INF)] 1498 # use largest reasonable tolerance 1499 self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999) 1500 1501 def test_zero_tolerance(self): 1502 # test with zero tolerance 1503 zero_tolerance_close_examples = [(1.0, 1.0), 1504 (-3.4, -3.4), 1505 (-1e-300, -1e-300)] 1506 self.assertAllClose(zero_tolerance_close_examples, rel_tol=0.0) 1507 1508 zero_tolerance_not_close_examples = [(1.0, 1.000000000000001), 1509 (0.99999999999999, 1.0), 1510 (1.0e200, .999999999999999e200)] 1511 self.assertAllNotClose(zero_tolerance_not_close_examples, rel_tol=0.0) 1512 1513 def test_asymmetry(self): 1514 # test the asymmetry example from PEP 485 1515 self.assertAllClose([(9, 10), (10, 9)], rel_tol=0.1) 1516 1517 def test_integers(self): 1518 # test with integer values 1519 integer_examples = [(100000001, 100000000), 1520 (123456789, 123456788)] 1521 1522 self.assertAllClose(integer_examples, rel_tol=1e-8) 1523 self.assertAllNotClose(integer_examples, rel_tol=1e-9) 1524 1525 def test_decimals(self): 1526 # test with Decimal values 1527 from decimal import Decimal 1528 1529 decimal_examples = [(Decimal('1.00000001'), Decimal('1.0')), 1530 (Decimal('1.00000001e-20'), Decimal('1.0e-20')), 1531 (Decimal('1.00000001e-100'), Decimal('1.0e-100')), 1532 (Decimal('1.00000001e20'), Decimal('1.0e20'))] 1533 self.assertAllClose(decimal_examples, rel_tol=1e-8) 1534 self.assertAllNotClose(decimal_examples, rel_tol=1e-9) 1535 1536 def test_fractions(self): 1537 # test with Fraction values 1538 from fractions import Fraction 1539 1540 fraction_examples = [ 1541 (Fraction(1, 100000000) + 1, Fraction(1)), 1542 (Fraction(100000001), Fraction(100000000)), 1543 (Fraction(10**8 + 1, 10**28), Fraction(1, 10**20))] 1544 self.assertAllClose(fraction_examples, rel_tol=1e-8) 1545 self.assertAllNotClose(fraction_examples, rel_tol=1e-9) 1546 1547 1548 def test_main(): 1549 from doctest import DocFileSuite 1550 suite = unittest.TestSuite() 1551 suite.addTest(unittest.makeSuite(MathTests)) 1552 suite.addTest(unittest.makeSuite(IsCloseTests)) 1553 suite.addTest(DocFileSuite("ieee754.txt")) 1554 run_unittest(suite) 1555 1556 if __name__ == '__main__': 1557 test_main() 1558