1 import unittest 2 import sys 3 4 import random 5 import math 6 7 from test import test_int, test_support 8 9 # Used for lazy formatting of failure messages 10 class Frm(object): 11 def __init__(self, format, *args): 12 self.format = format 13 self.args = args 14 15 def __str__(self): 16 return self.format % self.args 17 18 # SHIFT should match the value in longintrepr.h for best testing. 19 SHIFT = sys.long_info.bits_per_digit 20 BASE = 2 ** SHIFT 21 MASK = BASE - 1 22 KARATSUBA_CUTOFF = 70 # from longobject.c 23 24 # Max number of base BASE digits to use in test cases. Doubling 25 # this will more than double the runtime. 26 MAXDIGITS = 15 27 28 # build some special values 29 special = map(long, [0, 1, 2, BASE, BASE >> 1]) 30 special.append(0x5555555555555555L) 31 special.append(0xaaaaaaaaaaaaaaaaL) 32 # some solid strings of one bits 33 p2 = 4L # 0 and 1 already added 34 for i in range(2*SHIFT): 35 special.append(p2 - 1) 36 p2 = p2 << 1 37 del p2 38 # add complements & negations 39 special = special + map(lambda x: ~x, special) + \ 40 map(lambda x: -x, special) 41 42 L = [ 43 ('0', 0), 44 ('1', 1), 45 ('9', 9), 46 ('10', 10), 47 ('99', 99), 48 ('100', 100), 49 ('314', 314), 50 (' 314', 314), 51 ('314 ', 314), 52 (' \t\t 314 \t\t ', 314), 53 (repr(sys.maxint), sys.maxint), 54 (' 1x', ValueError), 55 (' 1 ', 1), 56 (' 1\02 ', ValueError), 57 ('', ValueError), 58 (' ', ValueError), 59 (' \t\t ', ValueError) 60 ] 61 if test_support.have_unicode: 62 L += [ 63 (unicode('0'), 0), 64 (unicode('1'), 1), 65 (unicode('9'), 9), 66 (unicode('10'), 10), 67 (unicode('99'), 99), 68 (unicode('100'), 100), 69 (unicode('314'), 314), 70 (unicode(' 314'), 314), 71 (unicode('\u0663\u0661\u0664 ','raw-unicode-escape'), 314), 72 (unicode(' \t\t 314 \t\t '), 314), 73 (unicode(' 1x'), ValueError), 74 (unicode(' 1 '), 1), 75 (unicode(' 1\02 '), ValueError), 76 (unicode(''), ValueError), 77 (unicode(' '), ValueError), 78 (unicode(' \t\t '), ValueError), 79 (unichr(0x200), ValueError), 80 ] 81 82 class LongTest(test_int.IntLongCommonTests, unittest.TestCase): 83 84 ntype = long 85 86 # Get quasi-random long consisting of ndigits digits (in base BASE). 87 # quasi == the most-significant digit will not be 0, and the number 88 # is constructed to contain long strings of 0 and 1 bits. These are 89 # more likely than random bits to provoke digit-boundary errors. 90 # The sign of the number is also random. 91 92 def getran(self, ndigits): 93 self.assertTrue(ndigits > 0) 94 nbits_hi = ndigits * SHIFT 95 nbits_lo = nbits_hi - SHIFT + 1 96 answer = 0L 97 nbits = 0 98 r = int(random.random() * (SHIFT * 2)) | 1 # force 1 bits to start 99 while nbits < nbits_lo: 100 bits = (r >> 1) + 1 101 bits = min(bits, nbits_hi - nbits) 102 self.assertTrue(1 <= bits <= SHIFT) 103 nbits = nbits + bits 104 answer = answer << bits 105 if r & 1: 106 answer = answer | ((1 << bits) - 1) 107 r = int(random.random() * (SHIFT * 2)) 108 self.assertTrue(nbits_lo <= nbits <= nbits_hi) 109 if random.random() < 0.5: 110 answer = -answer 111 return answer 112 113 # Get random long consisting of ndigits random digits (relative to base 114 # BASE). The sign bit is also random. 115 116 def getran2(ndigits): 117 answer = 0L 118 for i in xrange(ndigits): 119 answer = (answer << SHIFT) | random.randint(0, MASK) 120 if random.random() < 0.5: 121 answer = -answer 122 return answer 123 124 def check_division(self, x, y): 125 eq = self.assertEqual 126 q, r = divmod(x, y) 127 q2, r2 = x//y, x%y 128 pab, pba = x*y, y*x 129 eq(pab, pba, Frm("multiplication does not commute for %r and %r", x, y)) 130 eq(q, q2, Frm("divmod returns different quotient than / for %r and %r", x, y)) 131 eq(r, r2, Frm("divmod returns different mod than %% for %r and %r", x, y)) 132 eq(x, q*y + r, Frm("x != q*y + r after divmod on x=%r, y=%r", x, y)) 133 if y > 0: 134 self.assertTrue(0 <= r < y, Frm("bad mod from divmod on %r and %r", x, y)) 135 else: 136 self.assertTrue(y < r <= 0, Frm("bad mod from divmod on %r and %r", x, y)) 137 138 def test_division(self): 139 digits = range(1, MAXDIGITS+1) + range(KARATSUBA_CUTOFF, 140 KARATSUBA_CUTOFF + 14) 141 digits.append(KARATSUBA_CUTOFF * 3) 142 for lenx in digits: 143 x = self.getran(lenx) 144 for leny in digits: 145 y = self.getran(leny) or 1L 146 self.check_division(x, y) 147 148 # specific numbers chosen to exercise corner cases of the 149 # current long division implementation 150 151 # 30-bit cases involving a quotient digit estimate of BASE+1 152 self.check_division(1231948412290879395966702881L, 153 1147341367131428698L) 154 self.check_division(815427756481275430342312021515587883L, 155 707270836069027745L) 156 self.check_division(627976073697012820849443363563599041L, 157 643588798496057020L) 158 self.check_division(1115141373653752303710932756325578065L, 159 1038556335171453937726882627L) 160 # 30-bit cases that require the post-subtraction correction step 161 self.check_division(922498905405436751940989320930368494L, 162 949985870686786135626943396L) 163 self.check_division(768235853328091167204009652174031844L, 164 1091555541180371554426545266L) 165 166 # 15-bit cases involving a quotient digit estimate of BASE+1 167 self.check_division(20172188947443L, 615611397L) 168 self.check_division(1020908530270155025L, 950795710L) 169 self.check_division(128589565723112408L, 736393718L) 170 self.check_division(609919780285761575L, 18613274546784L) 171 # 15-bit cases that require the post-subtraction correction step 172 self.check_division(710031681576388032L, 26769404391308L) 173 self.check_division(1933622614268221L, 30212853348836L) 174 175 176 177 def test_karatsuba(self): 178 digits = range(1, 5) + range(KARATSUBA_CUTOFF, KARATSUBA_CUTOFF + 10) 179 digits.extend([KARATSUBA_CUTOFF * 10, KARATSUBA_CUTOFF * 100]) 180 181 bits = [digit * SHIFT for digit in digits] 182 183 # Test products of long strings of 1 bits -- (2**x-1)*(2**y-1) == 184 # 2**(x+y) - 2**x - 2**y + 1, so the proper result is easy to check. 185 for abits in bits: 186 a = (1L << abits) - 1 187 for bbits in bits: 188 if bbits < abits: 189 continue 190 b = (1L << bbits) - 1 191 x = a * b 192 y = ((1L << (abits + bbits)) - 193 (1L << abits) - 194 (1L << bbits) + 195 1) 196 self.assertEqual(x, y, 197 Frm("bad result for a*b: a=%r, b=%r, x=%r, y=%r", a, b, x, y)) 198 199 def check_bitop_identities_1(self, x): 200 eq = self.assertEqual 201 eq(x & 0, 0, Frm("x & 0 != 0 for x=%r", x)) 202 eq(x | 0, x, Frm("x | 0 != x for x=%r", x)) 203 eq(x ^ 0, x, Frm("x ^ 0 != x for x=%r", x)) 204 eq(x & -1, x, Frm("x & -1 != x for x=%r", x)) 205 eq(x | -1, -1, Frm("x | -1 != -1 for x=%r", x)) 206 eq(x ^ -1, ~x, Frm("x ^ -1 != ~x for x=%r", x)) 207 eq(x, ~~x, Frm("x != ~~x for x=%r", x)) 208 eq(x & x, x, Frm("x & x != x for x=%r", x)) 209 eq(x | x, x, Frm("x | x != x for x=%r", x)) 210 eq(x ^ x, 0, Frm("x ^ x != 0 for x=%r", x)) 211 eq(x & ~x, 0, Frm("x & ~x != 0 for x=%r", x)) 212 eq(x | ~x, -1, Frm("x | ~x != -1 for x=%r", x)) 213 eq(x ^ ~x, -1, Frm("x ^ ~x != -1 for x=%r", x)) 214 eq(-x, 1 + ~x, Frm("not -x == 1 + ~x for x=%r", x)) 215 eq(-x, ~(x-1), Frm("not -x == ~(x-1) forx =%r", x)) 216 for n in xrange(2*SHIFT): 217 p2 = 2L ** n 218 eq(x << n >> n, x, 219 Frm("x << n >> n != x for x=%r, n=%r", (x, n))) 220 eq(x // p2, x >> n, 221 Frm("x // p2 != x >> n for x=%r n=%r p2=%r", (x, n, p2))) 222 eq(x * p2, x << n, 223 Frm("x * p2 != x << n for x=%r n=%r p2=%r", (x, n, p2))) 224 eq(x & -p2, x >> n << n, 225 Frm("not x & -p2 == x >> n << n for x=%r n=%r p2=%r", (x, n, p2))) 226 eq(x & -p2, x & ~(p2 - 1), 227 Frm("not x & -p2 == x & ~(p2 - 1) for x=%r n=%r p2=%r", (x, n, p2))) 228 229 def check_bitop_identities_2(self, x, y): 230 eq = self.assertEqual 231 eq(x & y, y & x, Frm("x & y != y & x for x=%r, y=%r", (x, y))) 232 eq(x | y, y | x, Frm("x | y != y | x for x=%r, y=%r", (x, y))) 233 eq(x ^ y, y ^ x, Frm("x ^ y != y ^ x for x=%r, y=%r", (x, y))) 234 eq(x ^ y ^ x, y, Frm("x ^ y ^ x != y for x=%r, y=%r", (x, y))) 235 eq(x & y, ~(~x | ~y), Frm("x & y != ~(~x | ~y) for x=%r, y=%r", (x, y))) 236 eq(x | y, ~(~x & ~y), Frm("x | y != ~(~x & ~y) for x=%r, y=%r", (x, y))) 237 eq(x ^ y, (x | y) & ~(x & y), 238 Frm("x ^ y != (x | y) & ~(x & y) for x=%r, y=%r", (x, y))) 239 eq(x ^ y, (x & ~y) | (~x & y), 240 Frm("x ^ y == (x & ~y) | (~x & y) for x=%r, y=%r", (x, y))) 241 eq(x ^ y, (x | y) & (~x | ~y), 242 Frm("x ^ y == (x | y) & (~x | ~y) for x=%r, y=%r", (x, y))) 243 244 def check_bitop_identities_3(self, x, y, z): 245 eq = self.assertEqual 246 eq((x & y) & z, x & (y & z), 247 Frm("(x & y) & z != x & (y & z) for x=%r, y=%r, z=%r", (x, y, z))) 248 eq((x | y) | z, x | (y | z), 249 Frm("(x | y) | z != x | (y | z) for x=%r, y=%r, z=%r", (x, y, z))) 250 eq((x ^ y) ^ z, x ^ (y ^ z), 251 Frm("(x ^ y) ^ z != x ^ (y ^ z) for x=%r, y=%r, z=%r", (x, y, z))) 252 eq(x & (y | z), (x & y) | (x & z), 253 Frm("x & (y | z) != (x & y) | (x & z) for x=%r, y=%r, z=%r", (x, y, z))) 254 eq(x | (y & z), (x | y) & (x | z), 255 Frm("x | (y & z) != (x | y) & (x | z) for x=%r, y=%r, z=%r", (x, y, z))) 256 257 def test_bitop_identities(self): 258 for x in special: 259 self.check_bitop_identities_1(x) 260 digits = xrange(1, MAXDIGITS+1) 261 for lenx in digits: 262 x = self.getran(lenx) 263 self.check_bitop_identities_1(x) 264 for leny in digits: 265 y = self.getran(leny) 266 self.check_bitop_identities_2(x, y) 267 self.check_bitop_identities_3(x, y, self.getran((lenx + leny)//2)) 268 269 def slow_format(self, x, base): 270 if (x, base) == (0, 8): 271 # this is an oddball! 272 return "0L" 273 digits = [] 274 sign = 0 275 if x < 0: 276 sign, x = 1, -x 277 while x: 278 x, r = divmod(x, base) 279 digits.append(int(r)) 280 digits.reverse() 281 digits = digits or [0] 282 return '-'[:sign] + \ 283 {8: '0', 10: '', 16: '0x'}[base] + \ 284 "".join(map(lambda i: "0123456789abcdef"[i], digits)) + "L" 285 286 def check_format_1(self, x): 287 for base, mapper in (8, oct), (10, repr), (16, hex): 288 got = mapper(x) 289 expected = self.slow_format(x, base) 290 msg = Frm("%s returned %r but expected %r for %r", 291 mapper.__name__, got, expected, x) 292 self.assertEqual(got, expected, msg) 293 self.assertEqual(long(got, 0), x, Frm('long("%s", 0) != %r', got, x)) 294 # str() has to be checked a little differently since there's no 295 # trailing "L" 296 got = str(x) 297 expected = self.slow_format(x, 10)[:-1] 298 msg = Frm("%s returned %r but expected %r for %r", 299 mapper.__name__, got, expected, x) 300 self.assertEqual(got, expected, msg) 301 302 def test_format(self): 303 for x in special: 304 self.check_format_1(x) 305 for i in xrange(10): 306 for lenx in xrange(1, MAXDIGITS+1): 307 x = self.getran(lenx) 308 self.check_format_1(x) 309 310 def test_long(self): 311 self.assertEqual(long(314), 314L) 312 self.assertEqual(long(3.14), 3L) 313 self.assertEqual(long(314L), 314L) 314 # Check that long() of basic types actually returns a long 315 self.assertEqual(type(long(314)), long) 316 self.assertEqual(type(long(3.14)), long) 317 self.assertEqual(type(long(314L)), long) 318 # Check that conversion from float truncates towards zero 319 self.assertEqual(long(-3.14), -3L) 320 self.assertEqual(long(3.9), 3L) 321 self.assertEqual(long(-3.9), -3L) 322 self.assertEqual(long(3.5), 3L) 323 self.assertEqual(long(-3.5), -3L) 324 self.assertEqual(long("-3"), -3L) 325 self.assertEqual(long("0b10", 2), 2L) 326 self.assertEqual(long("0o10", 8), 8L) 327 self.assertEqual(long("0x10", 16), 16L) 328 if test_support.have_unicode: 329 self.assertEqual(long(unicode("-3")), -3L) 330 # Different base: 331 self.assertEqual(long("10",16), 16L) 332 if test_support.have_unicode: 333 self.assertEqual(long(unicode("10"),16), 16L) 334 # Check conversions from string (same test set as for int(), and then some) 335 LL = [ 336 ('1' + '0'*20, 10L**20), 337 ('1' + '0'*100, 10L**100) 338 ] 339 L2 = L[:] 340 if test_support.have_unicode: 341 L2 += [ 342 (unicode('1') + unicode('0')*20, 10L**20), 343 (unicode('1') + unicode('0')*100, 10L**100), 344 ] 345 for s, v in L2 + LL: 346 for sign in "", "+", "-": 347 for prefix in "", " ", "\t", " \t\t ": 348 ss = prefix + sign + s 349 vv = v 350 if sign == "-" and v is not ValueError: 351 vv = -v 352 try: 353 self.assertEqual(long(ss), long(vv)) 354 except v: 355 pass 356 357 self.assertRaises(ValueError, long, '123\0') 358 self.assertRaises(ValueError, long, '53', 40) 359 self.assertRaises(TypeError, long, 1, 12) 360 361 # tests with base 0 362 self.assertEqual(long(' 0123 ', 0), 83) 363 self.assertEqual(long(' 0123 ', 0), 83) 364 self.assertEqual(long('000', 0), 0) 365 self.assertEqual(long('0o123', 0), 83) 366 self.assertEqual(long('0x123', 0), 291) 367 self.assertEqual(long('0b100', 0), 4) 368 self.assertEqual(long(' 0O123 ', 0), 83) 369 self.assertEqual(long(' 0X123 ', 0), 291) 370 self.assertEqual(long(' 0B100 ', 0), 4) 371 self.assertEqual(long('0', 0), 0) 372 self.assertEqual(long('+0', 0), 0) 373 self.assertEqual(long('-0', 0), 0) 374 self.assertEqual(long('00', 0), 0) 375 self.assertRaises(ValueError, long, '08', 0) 376 self.assertRaises(ValueError, long, '-012395', 0) 377 378 # SF patch #1638879: embedded NULs were not detected with 379 # explicit base 380 self.assertRaises(ValueError, long, '123\0', 10) 381 self.assertRaises(ValueError, long, '123\x00 245', 20) 382 383 self.assertEqual(long('100000000000000000000000000000000', 2), 384 4294967296) 385 self.assertEqual(long('102002022201221111211', 3), 4294967296) 386 self.assertEqual(long('10000000000000000', 4), 4294967296) 387 self.assertEqual(long('32244002423141', 5), 4294967296) 388 self.assertEqual(long('1550104015504', 6), 4294967296) 389 self.assertEqual(long('211301422354', 7), 4294967296) 390 self.assertEqual(long('40000000000', 8), 4294967296) 391 self.assertEqual(long('12068657454', 9), 4294967296) 392 self.assertEqual(long('4294967296', 10), 4294967296) 393 self.assertEqual(long('1904440554', 11), 4294967296) 394 self.assertEqual(long('9ba461594', 12), 4294967296) 395 self.assertEqual(long('535a79889', 13), 4294967296) 396 self.assertEqual(long('2ca5b7464', 14), 4294967296) 397 self.assertEqual(long('1a20dcd81', 15), 4294967296) 398 self.assertEqual(long('100000000', 16), 4294967296) 399 self.assertEqual(long('a7ffda91', 17), 4294967296) 400 self.assertEqual(long('704he7g4', 18), 4294967296) 401 self.assertEqual(long('4f5aff66', 19), 4294967296) 402 self.assertEqual(long('3723ai4g', 20), 4294967296) 403 self.assertEqual(long('281d55i4', 21), 4294967296) 404 self.assertEqual(long('1fj8b184', 22), 4294967296) 405 self.assertEqual(long('1606k7ic', 23), 4294967296) 406 self.assertEqual(long('mb994ag', 24), 4294967296) 407 self.assertEqual(long('hek2mgl', 25), 4294967296) 408 self.assertEqual(long('dnchbnm', 26), 4294967296) 409 self.assertEqual(long('b28jpdm', 27), 4294967296) 410 self.assertEqual(long('8pfgih4', 28), 4294967296) 411 self.assertEqual(long('76beigg', 29), 4294967296) 412 self.assertEqual(long('5qmcpqg', 30), 4294967296) 413 self.assertEqual(long('4q0jto4', 31), 4294967296) 414 self.assertEqual(long('4000000', 32), 4294967296) 415 self.assertEqual(long('3aokq94', 33), 4294967296) 416 self.assertEqual(long('2qhxjli', 34), 4294967296) 417 self.assertEqual(long('2br45qb', 35), 4294967296) 418 self.assertEqual(long('1z141z4', 36), 4294967296) 419 420 self.assertEqual(long('100000000000000000000000000000001', 2), 421 4294967297) 422 self.assertEqual(long('102002022201221111212', 3), 4294967297) 423 self.assertEqual(long('10000000000000001', 4), 4294967297) 424 self.assertEqual(long('32244002423142', 5), 4294967297) 425 self.assertEqual(long('1550104015505', 6), 4294967297) 426 self.assertEqual(long('211301422355', 7), 4294967297) 427 self.assertEqual(long('40000000001', 8), 4294967297) 428 self.assertEqual(long('12068657455', 9), 4294967297) 429 self.assertEqual(long('4294967297', 10), 4294967297) 430 self.assertEqual(long('1904440555', 11), 4294967297) 431 self.assertEqual(long('9ba461595', 12), 4294967297) 432 self.assertEqual(long('535a7988a', 13), 4294967297) 433 self.assertEqual(long('2ca5b7465', 14), 4294967297) 434 self.assertEqual(long('1a20dcd82', 15), 4294967297) 435 self.assertEqual(long('100000001', 16), 4294967297) 436 self.assertEqual(long('a7ffda92', 17), 4294967297) 437 self.assertEqual(long('704he7g5', 18), 4294967297) 438 self.assertEqual(long('4f5aff67', 19), 4294967297) 439 self.assertEqual(long('3723ai4h', 20), 4294967297) 440 self.assertEqual(long('281d55i5', 21), 4294967297) 441 self.assertEqual(long('1fj8b185', 22), 4294967297) 442 self.assertEqual(long('1606k7id', 23), 4294967297) 443 self.assertEqual(long('mb994ah', 24), 4294967297) 444 self.assertEqual(long('hek2mgm', 25), 4294967297) 445 self.assertEqual(long('dnchbnn', 26), 4294967297) 446 self.assertEqual(long('b28jpdn', 27), 4294967297) 447 self.assertEqual(long('8pfgih5', 28), 4294967297) 448 self.assertEqual(long('76beigh', 29), 4294967297) 449 self.assertEqual(long('5qmcpqh', 30), 4294967297) 450 self.assertEqual(long('4q0jto5', 31), 4294967297) 451 self.assertEqual(long('4000001', 32), 4294967297) 452 self.assertEqual(long('3aokq95', 33), 4294967297) 453 self.assertEqual(long('2qhxjlj', 34), 4294967297) 454 self.assertEqual(long('2br45qc', 35), 4294967297) 455 self.assertEqual(long('1z141z5', 36), 4294967297) 456 457 458 def test_conversion(self): 459 # Test __long__() 460 class ClassicMissingMethods: 461 pass 462 self.assertRaises(AttributeError, long, ClassicMissingMethods()) 463 464 class MissingMethods(object): 465 pass 466 self.assertRaises(TypeError, long, MissingMethods()) 467 468 class Foo0: 469 def __long__(self): 470 return 42L 471 472 class Foo1(object): 473 def __long__(self): 474 return 42L 475 476 class Foo2(long): 477 def __long__(self): 478 return 42L 479 480 class Foo3(long): 481 def __long__(self): 482 return self 483 484 class Foo4(long): 485 def __long__(self): 486 return 42 487 488 class Foo5(long): 489 def __long__(self): 490 return 42. 491 492 self.assertEqual(long(Foo0()), 42L) 493 self.assertEqual(long(Foo1()), 42L) 494 self.assertEqual(long(Foo2()), 42L) 495 self.assertEqual(long(Foo3()), 0) 496 self.assertEqual(long(Foo4()), 42) 497 self.assertRaises(TypeError, long, Foo5()) 498 499 class Classic: 500 pass 501 for base in (object, Classic): 502 class LongOverridesTrunc(base): 503 def __long__(self): 504 return 42 505 def __trunc__(self): 506 return -12 507 self.assertEqual(long(LongOverridesTrunc()), 42) 508 509 class JustTrunc(base): 510 def __trunc__(self): 511 return 42 512 self.assertEqual(long(JustTrunc()), 42) 513 514 for trunc_result_base in (object, Classic): 515 class Integral(trunc_result_base): 516 def __int__(self): 517 return 42 518 519 class TruncReturnsNonLong(base): 520 def __trunc__(self): 521 return Integral() 522 self.assertEqual(long(TruncReturnsNonLong()), 42) 523 524 class NonIntegral(trunc_result_base): 525 def __trunc__(self): 526 # Check that we avoid infinite recursion. 527 return NonIntegral() 528 529 class TruncReturnsNonIntegral(base): 530 def __trunc__(self): 531 return NonIntegral() 532 try: 533 long(TruncReturnsNonIntegral()) 534 except TypeError as e: 535 self.assertEqual(str(e), 536 "__trunc__ returned non-Integral" 537 " (type NonIntegral)") 538 else: 539 self.fail("Failed to raise TypeError with %s" % 540 ((base, trunc_result_base),)) 541 542 def test_misc(self): 543 544 # check the extremes in int<->long conversion 545 hugepos = sys.maxint 546 hugeneg = -hugepos - 1 547 hugepos_aslong = long(hugepos) 548 hugeneg_aslong = long(hugeneg) 549 self.assertEqual(hugepos, hugepos_aslong, "long(sys.maxint) != sys.maxint") 550 self.assertEqual(hugeneg, hugeneg_aslong, 551 "long(-sys.maxint-1) != -sys.maxint-1") 552 553 # long -> int should not fail for hugepos_aslong or hugeneg_aslong 554 x = int(hugepos_aslong) 555 try: 556 self.assertEqual(x, hugepos, 557 "converting sys.maxint to long and back to int fails") 558 except OverflowError: 559 self.fail("int(long(sys.maxint)) overflowed!") 560 if not isinstance(x, int): 561 self.fail("int(long(sys.maxint)) should have returned int") 562 x = int(hugeneg_aslong) 563 try: 564 self.assertEqual(x, hugeneg, 565 "converting -sys.maxint-1 to long and back to int fails") 566 except OverflowError: 567 self.fail("int(long(-sys.maxint-1)) overflowed!") 568 if not isinstance(x, int): 569 self.fail("int(long(-sys.maxint-1)) should have returned int") 570 # but long -> int should overflow for hugepos+1 and hugeneg-1 571 x = hugepos_aslong + 1 572 try: 573 y = int(x) 574 except OverflowError: 575 self.fail("int(long(sys.maxint) + 1) mustn't overflow") 576 self.assertIsInstance(y, long, 577 "int(long(sys.maxint) + 1) should have returned long") 578 579 x = hugeneg_aslong - 1 580 try: 581 y = int(x) 582 except OverflowError: 583 self.fail("int(long(-sys.maxint-1) - 1) mustn't overflow") 584 self.assertIsInstance(y, long, 585 "int(long(-sys.maxint-1) - 1) should have returned long") 586 587 class long2(long): 588 pass 589 x = long2(1L<<100) 590 y = int(x) 591 self.assertTrue(type(y) is long, 592 "overflowing int conversion must return long not long subtype") 593 594 # long -> Py_ssize_t conversion 595 class X(object): 596 def __getslice__(self, i, j): 597 return i, j 598 599 with test_support.check_py3k_warnings(): 600 self.assertEqual(X()[-5L:7L], (-5, 7)) 601 # use the clamping effect to test the smallest and largest longs 602 # that fit a Py_ssize_t 603 slicemin, slicemax = X()[-2L**100:2L**100] 604 self.assertEqual(X()[slicemin:slicemax], (slicemin, slicemax)) 605 606 def test_issue9869(self): 607 # Issue 9869: Interpreter crash when initializing an instance 608 # of a long subclass from an object whose __long__ method returns 609 # a plain int. 610 class BadLong(object): 611 def __long__(self): 612 return 1000000 613 614 class MyLong(long): 615 pass 616 617 x = MyLong(BadLong()) 618 self.assertIsInstance(x, long) 619 self.assertEqual(x, 1000000) 620 621 622 # ----------------------------------- tests of auto int->long conversion 623 624 def test_auto_overflow(self): 625 special = [0, 1, 2, 3, sys.maxint-1, sys.maxint, sys.maxint+1] 626 sqrt = int(math.sqrt(sys.maxint)) 627 special.extend([sqrt-1, sqrt, sqrt+1]) 628 special.extend([-i for i in special]) 629 630 def checkit(*args): 631 # Heavy use of nested scopes here! 632 self.assertEqual(got, expected, 633 Frm("for %r expected %r got %r", args, expected, got)) 634 635 for x in special: 636 longx = long(x) 637 638 expected = -longx 639 got = -x 640 checkit('-', x) 641 642 for y in special: 643 longy = long(y) 644 645 expected = longx + longy 646 got = x + y 647 checkit(x, '+', y) 648 649 expected = longx - longy 650 got = x - y 651 checkit(x, '-', y) 652 653 expected = longx * longy 654 got = x * y 655 checkit(x, '*', y) 656 657 if y: 658 with test_support.check_py3k_warnings(): 659 expected = longx / longy 660 got = x / y 661 checkit(x, '/', y) 662 663 expected = longx // longy 664 got = x // y 665 checkit(x, '//', y) 666 667 expected = divmod(longx, longy) 668 got = divmod(longx, longy) 669 checkit(x, 'divmod', y) 670 671 if abs(y) < 5 and not (x == 0 and y < 0): 672 expected = longx ** longy 673 got = x ** y 674 checkit(x, '**', y) 675 676 for z in special: 677 if z != 0 : 678 if y >= 0: 679 expected = pow(longx, longy, long(z)) 680 got = pow(x, y, z) 681 checkit('pow', x, y, '%', z) 682 else: 683 self.assertRaises(TypeError, pow,longx, longy, long(z)) 684 685 @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), 686 "test requires IEEE 754 doubles") 687 def test_float_conversion(self): 688 import sys 689 DBL_MAX = sys.float_info.max 690 DBL_MAX_EXP = sys.float_info.max_exp 691 DBL_MANT_DIG = sys.float_info.mant_dig 692 693 exact_values = [0L, 1L, 2L, 694 long(2**53-3), 695 long(2**53-2), 696 long(2**53-1), 697 long(2**53), 698 long(2**53+2), 699 long(2**54-4), 700 long(2**54-2), 701 long(2**54), 702 long(2**54+4)] 703 for x in exact_values: 704 self.assertEqual(long(float(x)), x) 705 self.assertEqual(long(float(-x)), -x) 706 707 # test round-half-even 708 for x, y in [(1, 0), (2, 2), (3, 4), (4, 4), (5, 4), (6, 6), (7, 8)]: 709 for p in xrange(15): 710 self.assertEqual(long(float(2L**p*(2**53+x))), 2L**p*(2**53+y)) 711 712 for x, y in [(0, 0), (1, 0), (2, 0), (3, 4), (4, 4), (5, 4), (6, 8), 713 (7, 8), (8, 8), (9, 8), (10, 8), (11, 12), (12, 12), 714 (13, 12), (14, 16), (15, 16)]: 715 for p in xrange(15): 716 self.assertEqual(long(float(2L**p*(2**54+x))), 2L**p*(2**54+y)) 717 718 # behaviour near extremes of floating-point range 719 long_dbl_max = long(DBL_MAX) 720 top_power = 2**DBL_MAX_EXP 721 halfway = (long_dbl_max + top_power)//2 722 self.assertEqual(float(long_dbl_max), DBL_MAX) 723 self.assertEqual(float(long_dbl_max+1), DBL_MAX) 724 self.assertEqual(float(halfway-1), DBL_MAX) 725 self.assertRaises(OverflowError, float, halfway) 726 self.assertEqual(float(1-halfway), -DBL_MAX) 727 self.assertRaises(OverflowError, float, -halfway) 728 self.assertRaises(OverflowError, float, top_power-1) 729 self.assertRaises(OverflowError, float, top_power) 730 self.assertRaises(OverflowError, float, top_power+1) 731 self.assertRaises(OverflowError, float, 2*top_power-1) 732 self.assertRaises(OverflowError, float, 2*top_power) 733 self.assertRaises(OverflowError, float, top_power*top_power) 734 735 for p in xrange(100): 736 x = long(2**p * (2**53 + 1) + 1) 737 y = long(2**p * (2**53+ 2)) 738 self.assertEqual(long(float(x)), y) 739 740 x = long(2**p * (2**53 + 1)) 741 y = long(2**p * 2**53) 742 self.assertEqual(long(float(x)), y) 743 744 def test_float_overflow(self): 745 for x in -2.0, -1.0, 0.0, 1.0, 2.0: 746 self.assertEqual(float(long(x)), x) 747 748 shuge = '12345' * 120 749 huge = 1L << 30000 750 mhuge = -huge 751 namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math} 752 for test in ["float(huge)", "float(mhuge)", 753 "complex(huge)", "complex(mhuge)", 754 "complex(huge, 1)", "complex(mhuge, 1)", 755 "complex(1, huge)", "complex(1, mhuge)", 756 "1. + huge", "huge + 1.", "1. + mhuge", "mhuge + 1.", 757 "1. - huge", "huge - 1.", "1. - mhuge", "mhuge - 1.", 758 "1. * huge", "huge * 1.", "1. * mhuge", "mhuge * 1.", 759 "1. // huge", "huge // 1.", "1. // mhuge", "mhuge // 1.", 760 "1. / huge", "huge / 1.", "1. / mhuge", "mhuge / 1.", 761 "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.", 762 "math.sin(huge)", "math.sin(mhuge)", 763 "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better 764 "math.floor(huge)", "math.floor(mhuge)"]: 765 766 self.assertRaises(OverflowError, eval, test, namespace) 767 768 # XXX Perhaps float(shuge) can raise OverflowError on some box? 769 # The comparison should not. 770 self.assertNotEqual(float(shuge), int(shuge), 771 "float(shuge) should not equal int(shuge)") 772 773 def test_logs(self): 774 LOG10E = math.log10(math.e) 775 776 for exp in range(10) + [100, 1000, 10000]: 777 value = 10 ** exp 778 log10 = math.log10(value) 779 self.assertAlmostEqual(log10, exp) 780 781 # log10(value) == exp, so log(value) == log10(value)/log10(e) == 782 # exp/LOG10E 783 expected = exp / LOG10E 784 log = math.log(value) 785 self.assertAlmostEqual(log, expected) 786 787 for bad in -(1L << 10000), -2L, 0L: 788 self.assertRaises(ValueError, math.log, bad) 789 self.assertRaises(ValueError, math.log10, bad) 790 791 def test_mixed_compares(self): 792 eq = self.assertEqual 793 794 # We're mostly concerned with that mixing floats and longs does the 795 # right stuff, even when longs are too large to fit in a float. 796 # The safest way to check the results is to use an entirely different 797 # method, which we do here via a skeletal rational class (which 798 # represents all Python ints, longs and floats exactly). 799 class Rat: 800 def __init__(self, value): 801 if isinstance(value, (int, long)): 802 self.n = value 803 self.d = 1 804 elif isinstance(value, float): 805 # Convert to exact rational equivalent. 806 f, e = math.frexp(abs(value)) 807 assert f == 0 or 0.5 <= f < 1.0 808 # |value| = f * 2**e exactly 809 810 # Suck up CHUNK bits at a time; 28 is enough so that we suck 811 # up all bits in 2 iterations for all known binary double- 812 # precision formats, and small enough to fit in an int. 813 CHUNK = 28 814 top = 0 815 # invariant: |value| = (top + f) * 2**e exactly 816 while f: 817 f = math.ldexp(f, CHUNK) 818 digit = int(f) 819 assert digit >> CHUNK == 0 820 top = (top << CHUNK) | digit 821 f -= digit 822 assert 0.0 <= f < 1.0 823 e -= CHUNK 824 825 # Now |value| = top * 2**e exactly. 826 if e >= 0: 827 n = top << e 828 d = 1 829 else: 830 n = top 831 d = 1 << -e 832 if value < 0: 833 n = -n 834 self.n = n 835 self.d = d 836 assert float(n) / float(d) == value 837 else: 838 raise TypeError("can't deal with %r" % value) 839 840 def __cmp__(self, other): 841 if not isinstance(other, Rat): 842 other = Rat(other) 843 return cmp(self.n * other.d, self.d * other.n) 844 845 cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200] 846 # 2**48 is an important boundary in the internals. 2**53 is an 847 # important boundary for IEEE double precision. 848 for t in 2.0**48, 2.0**50, 2.0**53: 849 cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0, 850 long(t-1), long(t), long(t+1)]) 851 cases.extend([0, 1, 2, sys.maxint, float(sys.maxint)]) 852 # 1L<<20000 should exceed all double formats. long(1e200) is to 853 # check that we get equality with 1e200 above. 854 t = long(1e200) 855 cases.extend([0L, 1L, 2L, 1L << 20000, t-1, t, t+1]) 856 cases.extend([-x for x in cases]) 857 for x in cases: 858 Rx = Rat(x) 859 for y in cases: 860 Ry = Rat(y) 861 Rcmp = cmp(Rx, Ry) 862 xycmp = cmp(x, y) 863 eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp)) 864 eq(x == y, Rcmp == 0, Frm("%r == %r %d", x, y, Rcmp)) 865 eq(x != y, Rcmp != 0, Frm("%r != %r %d", x, y, Rcmp)) 866 eq(x < y, Rcmp < 0, Frm("%r < %r %d", x, y, Rcmp)) 867 eq(x <= y, Rcmp <= 0, Frm("%r <= %r %d", x, y, Rcmp)) 868 eq(x > y, Rcmp > 0, Frm("%r > %r %d", x, y, Rcmp)) 869 eq(x >= y, Rcmp >= 0, Frm("%r >= %r %d", x, y, Rcmp)) 870 871 def test_nan_inf(self): 872 self.assertRaises(OverflowError, long, float('inf')) 873 self.assertRaises(OverflowError, long, float('-inf')) 874 self.assertRaises(ValueError, long, float('nan')) 875 876 def test_bit_length(self): 877 tiny = 1e-10 878 for x in xrange(-65000, 65000): 879 x = long(x) 880 k = x.bit_length() 881 # Check equivalence with Python version 882 self.assertEqual(k, len(bin(x).lstrip('-0b'))) 883 # Behaviour as specified in the docs 884 if x != 0: 885 self.assertTrue(2**(k-1) <= abs(x) < 2**k) 886 else: 887 self.assertEqual(k, 0) 888 # Alternative definition: x.bit_length() == 1 + floor(log_2(x)) 889 if x != 0: 890 # When x is an exact power of 2, numeric errors can 891 # cause floor(log(x)/log(2)) to be one too small; for 892 # small x this can be fixed by adding a small quantity 893 # to the quotient before taking the floor. 894 self.assertEqual(k, 1 + math.floor( 895 math.log(abs(x))/math.log(2) + tiny)) 896 897 self.assertEqual((0L).bit_length(), 0) 898 self.assertEqual((1L).bit_length(), 1) 899 self.assertEqual((-1L).bit_length(), 1) 900 self.assertEqual((2L).bit_length(), 2) 901 self.assertEqual((-2L).bit_length(), 2) 902 for i in [2, 3, 15, 16, 17, 31, 32, 33, 63, 64, 234]: 903 a = 2L**i 904 self.assertEqual((a-1).bit_length(), i) 905 self.assertEqual((1-a).bit_length(), i) 906 self.assertEqual((a).bit_length(), i+1) 907 self.assertEqual((-a).bit_length(), i+1) 908 self.assertEqual((a+1).bit_length(), i+1) 909 self.assertEqual((-a-1).bit_length(), i+1) 910 911 912 def test_main(): 913 test_support.run_unittest(LongTest) 914 915 if __name__ == "__main__": 916 test_main() 917