#1153769: document PEP 237 changes to string formatting.
[python.git] / Lib / test / test_long.py
blobb67c764ad50b1996a81f3ad00cef8f24e3659bf2
1 import unittest
2 from test import test_support
3 import sys
5 import random
7 # Used for lazy formatting of failure messages
8 class Frm(object):
9 def __init__(self, format, *args):
10 self.format = format
11 self.args = args
13 def __str__(self):
14 return self.format % self.args
16 # SHIFT should match the value in longintrepr.h for best testing.
17 SHIFT = 15
18 BASE = 2 ** SHIFT
19 MASK = BASE - 1
20 KARATSUBA_CUTOFF = 70 # from longobject.c
22 # Max number of base BASE digits to use in test cases. Doubling
23 # this will more than double the runtime.
24 MAXDIGITS = 15
26 # build some special values
27 special = map(long, [0, 1, 2, BASE, BASE >> 1])
28 special.append(0x5555555555555555L)
29 special.append(0xaaaaaaaaaaaaaaaaL)
30 # some solid strings of one bits
31 p2 = 4L # 0 and 1 already added
32 for i in range(2*SHIFT):
33 special.append(p2 - 1)
34 p2 = p2 << 1
35 del p2
36 # add complements & negations
37 special = special + map(lambda x: ~x, special) + \
38 map(lambda x: -x, special)
40 L = [
41 ('0', 0),
42 ('1', 1),
43 ('9', 9),
44 ('10', 10),
45 ('99', 99),
46 ('100', 100),
47 ('314', 314),
48 (' 314', 314),
49 ('314 ', 314),
50 (' \t\t 314 \t\t ', 314),
51 (repr(sys.maxint), sys.maxint),
52 (' 1x', ValueError),
53 (' 1 ', 1),
54 (' 1\02 ', ValueError),
55 ('', ValueError),
56 (' ', ValueError),
57 (' \t\t ', ValueError)
59 if test_support.have_unicode:
60 L += [
61 (unicode('0'), 0),
62 (unicode('1'), 1),
63 (unicode('9'), 9),
64 (unicode('10'), 10),
65 (unicode('99'), 99),
66 (unicode('100'), 100),
67 (unicode('314'), 314),
68 (unicode(' 314'), 314),
69 (unicode('\u0663\u0661\u0664 ','raw-unicode-escape'), 314),
70 (unicode(' \t\t 314 \t\t '), 314),
71 (unicode(' 1x'), ValueError),
72 (unicode(' 1 '), 1),
73 (unicode(' 1\02 '), ValueError),
74 (unicode(''), ValueError),
75 (unicode(' '), ValueError),
76 (unicode(' \t\t '), ValueError),
77 (unichr(0x200), ValueError),
81 class LongTest(unittest.TestCase):
83 # Get quasi-random long consisting of ndigits digits (in base BASE).
84 # quasi == the most-significant digit will not be 0, and the number
85 # is constructed to contain long strings of 0 and 1 bits. These are
86 # more likely than random bits to provoke digit-boundary errors.
87 # The sign of the number is also random.
89 def getran(self, ndigits):
90 self.assert_(ndigits > 0)
91 nbits_hi = ndigits * SHIFT
92 nbits_lo = nbits_hi - SHIFT + 1
93 answer = 0L
94 nbits = 0
95 r = int(random.random() * (SHIFT * 2)) | 1 # force 1 bits to start
96 while nbits < nbits_lo:
97 bits = (r >> 1) + 1
98 bits = min(bits, nbits_hi - nbits)
99 self.assert_(1 <= bits <= SHIFT)
100 nbits = nbits + bits
101 answer = answer << bits
102 if r & 1:
103 answer = answer | ((1 << bits) - 1)
104 r = int(random.random() * (SHIFT * 2))
105 self.assert_(nbits_lo <= nbits <= nbits_hi)
106 if random.random() < 0.5:
107 answer = -answer
108 return answer
110 # Get random long consisting of ndigits random digits (relative to base
111 # BASE). The sign bit is also random.
113 def getran2(ndigits):
114 answer = 0L
115 for i in xrange(ndigits):
116 answer = (answer << SHIFT) | random.randint(0, MASK)
117 if random.random() < 0.5:
118 answer = -answer
119 return answer
121 def check_division(self, x, y):
122 eq = self.assertEqual
123 q, r = divmod(x, y)
124 q2, r2 = x//y, x%y
125 pab, pba = x*y, y*x
126 eq(pab, pba, Frm("multiplication does not commute for %r and %r", x, y))
127 eq(q, q2, Frm("divmod returns different quotient than / for %r and %r", x, y))
128 eq(r, r2, Frm("divmod returns different mod than %% for %r and %r", x, y))
129 eq(x, q*y + r, Frm("x != q*y + r after divmod on x=%r, y=%r", x, y))
130 if y > 0:
131 self.assert_(0 <= r < y, Frm("bad mod from divmod on %r and %r", x, y))
132 else:
133 self.assert_(y < r <= 0, Frm("bad mod from divmod on %r and %r", x, y))
135 def test_division(self):
136 digits = range(1, MAXDIGITS+1) + range(KARATSUBA_CUTOFF,
137 KARATSUBA_CUTOFF + 14)
138 digits.append(KARATSUBA_CUTOFF * 3)
139 for lenx in digits:
140 x = self.getran(lenx)
141 for leny in digits:
142 y = self.getran(leny) or 1L
143 self.check_division(x, y)
145 def test_karatsuba(self):
146 digits = range(1, 5) + range(KARATSUBA_CUTOFF, KARATSUBA_CUTOFF + 10)
147 digits.extend([KARATSUBA_CUTOFF * 10, KARATSUBA_CUTOFF * 100])
149 bits = [digit * SHIFT for digit in digits]
151 # Test products of long strings of 1 bits -- (2**x-1)*(2**y-1) ==
152 # 2**(x+y) - 2**x - 2**y + 1, so the proper result is easy to check.
153 for abits in bits:
154 a = (1L << abits) - 1
155 for bbits in bits:
156 if bbits < abits:
157 continue
158 b = (1L << bbits) - 1
159 x = a * b
160 y = ((1L << (abits + bbits)) -
161 (1L << abits) -
162 (1L << bbits) +
164 self.assertEqual(x, y,
165 Frm("bad result for a*b: a=%r, b=%r, x=%r, y=%r", a, b, x, y))
167 def check_bitop_identities_1(self, x):
168 eq = self.assertEqual
169 eq(x & 0, 0, Frm("x & 0 != 0 for x=%r", x))
170 eq(x | 0, x, Frm("x | 0 != x for x=%r", x))
171 eq(x ^ 0, x, Frm("x ^ 0 != x for x=%r", x))
172 eq(x & -1, x, Frm("x & -1 != x for x=%r", x))
173 eq(x | -1, -1, Frm("x | -1 != -1 for x=%r", x))
174 eq(x ^ -1, ~x, Frm("x ^ -1 != ~x for x=%r", x))
175 eq(x, ~~x, Frm("x != ~~x for x=%r", x))
176 eq(x & x, x, Frm("x & x != x for x=%r", x))
177 eq(x | x, x, Frm("x | x != x for x=%r", x))
178 eq(x ^ x, 0, Frm("x ^ x != 0 for x=%r", x))
179 eq(x & ~x, 0, Frm("x & ~x != 0 for x=%r", x))
180 eq(x | ~x, -1, Frm("x | ~x != -1 for x=%r", x))
181 eq(x ^ ~x, -1, Frm("x ^ ~x != -1 for x=%r", x))
182 eq(-x, 1 + ~x, Frm("not -x == 1 + ~x for x=%r", x))
183 eq(-x, ~(x-1), Frm("not -x == ~(x-1) forx =%r", x))
184 for n in xrange(2*SHIFT):
185 p2 = 2L ** n
186 eq(x << n >> n, x,
187 Frm("x << n >> n != x for x=%r, n=%r", (x, n)))
188 eq(x // p2, x >> n,
189 Frm("x // p2 != x >> n for x=%r n=%r p2=%r", (x, n, p2)))
190 eq(x * p2, x << n,
191 Frm("x * p2 != x << n for x=%r n=%r p2=%r", (x, n, p2)))
192 eq(x & -p2, x >> n << n,
193 Frm("not x & -p2 == x >> n << n for x=%r n=%r p2=%r", (x, n, p2)))
194 eq(x & -p2, x & ~(p2 - 1),
195 Frm("not x & -p2 == x & ~(p2 - 1) for x=%r n=%r p2=%r", (x, n, p2)))
197 def check_bitop_identities_2(self, x, y):
198 eq = self.assertEqual
199 eq(x & y, y & x, Frm("x & y != y & x for x=%r, y=%r", (x, y)))
200 eq(x | y, y | x, Frm("x | y != y | x for x=%r, y=%r", (x, y)))
201 eq(x ^ y, y ^ x, Frm("x ^ y != y ^ x for x=%r, y=%r", (x, y)))
202 eq(x ^ y ^ x, y, Frm("x ^ y ^ x != y for x=%r, y=%r", (x, y)))
203 eq(x & y, ~(~x | ~y), Frm("x & y != ~(~x | ~y) for x=%r, y=%r", (x, y)))
204 eq(x | y, ~(~x & ~y), Frm("x | y != ~(~x & ~y) for x=%r, y=%r", (x, y)))
205 eq(x ^ y, (x | y) & ~(x & y),
206 Frm("x ^ y != (x | y) & ~(x & y) for x=%r, y=%r", (x, y)))
207 eq(x ^ y, (x & ~y) | (~x & y),
208 Frm("x ^ y == (x & ~y) | (~x & y) for x=%r, y=%r", (x, y)))
209 eq(x ^ y, (x | y) & (~x | ~y),
210 Frm("x ^ y == (x | y) & (~x | ~y) for x=%r, y=%r", (x, y)))
212 def check_bitop_identities_3(self, x, y, z):
213 eq = self.assertEqual
214 eq((x & y) & z, x & (y & z),
215 Frm("(x & y) & z != x & (y & z) for x=%r, y=%r, z=%r", (x, y, z)))
216 eq((x | y) | z, x | (y | z),
217 Frm("(x | y) | z != x | (y | z) for x=%r, y=%r, z=%r", (x, y, z)))
218 eq((x ^ y) ^ z, x ^ (y ^ z),
219 Frm("(x ^ y) ^ z != x ^ (y ^ z) for x=%r, y=%r, z=%r", (x, y, z)))
220 eq(x & (y | z), (x & y) | (x & z),
221 Frm("x & (y | z) != (x & y) | (x & z) for x=%r, y=%r, z=%r", (x, y, z)))
222 eq(x | (y & z), (x | y) & (x | z),
223 Frm("x | (y & z) != (x | y) & (x | z) for x=%r, y=%r, z=%r", (x, y, z)))
225 def test_bitop_identities(self):
226 for x in special:
227 self.check_bitop_identities_1(x)
228 digits = xrange(1, MAXDIGITS+1)
229 for lenx in digits:
230 x = self.getran(lenx)
231 self.check_bitop_identities_1(x)
232 for leny in digits:
233 y = self.getran(leny)
234 self.check_bitop_identities_2(x, y)
235 self.check_bitop_identities_3(x, y, self.getran((lenx + leny)//2))
237 def slow_format(self, x, base):
238 if (x, base) == (0, 8):
239 # this is an oddball!
240 return "0L"
241 digits = []
242 sign = 0
243 if x < 0:
244 sign, x = 1, -x
245 while x:
246 x, r = divmod(x, base)
247 digits.append(int(r))
248 digits.reverse()
249 digits = digits or [0]
250 return '-'[:sign] + \
251 {8: '0', 10: '', 16: '0x'}[base] + \
252 "".join(map(lambda i: "0123456789abcdef"[i], digits)) + "L"
254 def check_format_1(self, x):
255 for base, mapper in (8, oct), (10, repr), (16, hex):
256 got = mapper(x)
257 expected = self.slow_format(x, base)
258 msg = Frm("%s returned %r but expected %r for %r",
259 mapper.__name__, got, expected, x)
260 self.assertEqual(got, expected, msg)
261 self.assertEqual(long(got, 0), x, Frm('long("%s", 0) != %r', got, x))
262 # str() has to be checked a little differently since there's no
263 # trailing "L"
264 got = str(x)
265 expected = self.slow_format(x, 10)[:-1]
266 msg = Frm("%s returned %r but expected %r for %r",
267 mapper.__name__, got, expected, x)
268 self.assertEqual(got, expected, msg)
270 def test_format(self):
271 for x in special:
272 self.check_format_1(x)
273 for i in xrange(10):
274 for lenx in xrange(1, MAXDIGITS+1):
275 x = self.getran(lenx)
276 self.check_format_1(x)
278 def test_long(self):
279 self.assertEqual(long(314), 314L)
280 self.assertEqual(long(3.14), 3L)
281 self.assertEqual(long(314L), 314L)
282 # Check that conversion from float truncates towards zero
283 self.assertEqual(long(-3.14), -3L)
284 self.assertEqual(long(3.9), 3L)
285 self.assertEqual(long(-3.9), -3L)
286 self.assertEqual(long(3.5), 3L)
287 self.assertEqual(long(-3.5), -3L)
288 self.assertEqual(long("-3"), -3L)
289 if test_support.have_unicode:
290 self.assertEqual(long(unicode("-3")), -3L)
291 # Different base:
292 self.assertEqual(long("10",16), 16L)
293 if test_support.have_unicode:
294 self.assertEqual(long(unicode("10"),16), 16L)
295 # Check conversions from string (same test set as for int(), and then some)
296 LL = [
297 ('1' + '0'*20, 10L**20),
298 ('1' + '0'*100, 10L**100)
300 L2 = L[:]
301 if test_support.have_unicode:
302 L2 += [
303 (unicode('1') + unicode('0')*20, 10L**20),
304 (unicode('1') + unicode('0')*100, 10L**100),
306 for s, v in L2 + LL:
307 for sign in "", "+", "-":
308 for prefix in "", " ", "\t", " \t\t ":
309 ss = prefix + sign + s
310 vv = v
311 if sign == "-" and v is not ValueError:
312 vv = -v
313 try:
314 self.assertEqual(long(ss), long(vv))
315 except v:
316 pass
318 self.assertRaises(ValueError, long, '123\0')
319 self.assertRaises(ValueError, long, '53', 40)
320 self.assertRaises(TypeError, long, 1, 12)
322 # SF patch #1638879: embedded NULs were not detected with
323 # explicit base
324 self.assertRaises(ValueError, long, '123\0', 10)
325 self.assertRaises(ValueError, long, '123\x00 245', 20)
327 self.assertEqual(long('100000000000000000000000000000000', 2),
328 4294967296)
329 self.assertEqual(long('102002022201221111211', 3), 4294967296)
330 self.assertEqual(long('10000000000000000', 4), 4294967296)
331 self.assertEqual(long('32244002423141', 5), 4294967296)
332 self.assertEqual(long('1550104015504', 6), 4294967296)
333 self.assertEqual(long('211301422354', 7), 4294967296)
334 self.assertEqual(long('40000000000', 8), 4294967296)
335 self.assertEqual(long('12068657454', 9), 4294967296)
336 self.assertEqual(long('4294967296', 10), 4294967296)
337 self.assertEqual(long('1904440554', 11), 4294967296)
338 self.assertEqual(long('9ba461594', 12), 4294967296)
339 self.assertEqual(long('535a79889', 13), 4294967296)
340 self.assertEqual(long('2ca5b7464', 14), 4294967296)
341 self.assertEqual(long('1a20dcd81', 15), 4294967296)
342 self.assertEqual(long('100000000', 16), 4294967296)
343 self.assertEqual(long('a7ffda91', 17), 4294967296)
344 self.assertEqual(long('704he7g4', 18), 4294967296)
345 self.assertEqual(long('4f5aff66', 19), 4294967296)
346 self.assertEqual(long('3723ai4g', 20), 4294967296)
347 self.assertEqual(long('281d55i4', 21), 4294967296)
348 self.assertEqual(long('1fj8b184', 22), 4294967296)
349 self.assertEqual(long('1606k7ic', 23), 4294967296)
350 self.assertEqual(long('mb994ag', 24), 4294967296)
351 self.assertEqual(long('hek2mgl', 25), 4294967296)
352 self.assertEqual(long('dnchbnm', 26), 4294967296)
353 self.assertEqual(long('b28jpdm', 27), 4294967296)
354 self.assertEqual(long('8pfgih4', 28), 4294967296)
355 self.assertEqual(long('76beigg', 29), 4294967296)
356 self.assertEqual(long('5qmcpqg', 30), 4294967296)
357 self.assertEqual(long('4q0jto4', 31), 4294967296)
358 self.assertEqual(long('4000000', 32), 4294967296)
359 self.assertEqual(long('3aokq94', 33), 4294967296)
360 self.assertEqual(long('2qhxjli', 34), 4294967296)
361 self.assertEqual(long('2br45qb', 35), 4294967296)
362 self.assertEqual(long('1z141z4', 36), 4294967296)
364 self.assertEqual(long('100000000000000000000000000000001', 2),
365 4294967297)
366 self.assertEqual(long('102002022201221111212', 3), 4294967297)
367 self.assertEqual(long('10000000000000001', 4), 4294967297)
368 self.assertEqual(long('32244002423142', 5), 4294967297)
369 self.assertEqual(long('1550104015505', 6), 4294967297)
370 self.assertEqual(long('211301422355', 7), 4294967297)
371 self.assertEqual(long('40000000001', 8), 4294967297)
372 self.assertEqual(long('12068657455', 9), 4294967297)
373 self.assertEqual(long('4294967297', 10), 4294967297)
374 self.assertEqual(long('1904440555', 11), 4294967297)
375 self.assertEqual(long('9ba461595', 12), 4294967297)
376 self.assertEqual(long('535a7988a', 13), 4294967297)
377 self.assertEqual(long('2ca5b7465', 14), 4294967297)
378 self.assertEqual(long('1a20dcd82', 15), 4294967297)
379 self.assertEqual(long('100000001', 16), 4294967297)
380 self.assertEqual(long('a7ffda92', 17), 4294967297)
381 self.assertEqual(long('704he7g5', 18), 4294967297)
382 self.assertEqual(long('4f5aff67', 19), 4294967297)
383 self.assertEqual(long('3723ai4h', 20), 4294967297)
384 self.assertEqual(long('281d55i5', 21), 4294967297)
385 self.assertEqual(long('1fj8b185', 22), 4294967297)
386 self.assertEqual(long('1606k7id', 23), 4294967297)
387 self.assertEqual(long('mb994ah', 24), 4294967297)
388 self.assertEqual(long('hek2mgm', 25), 4294967297)
389 self.assertEqual(long('dnchbnn', 26), 4294967297)
390 self.assertEqual(long('b28jpdn', 27), 4294967297)
391 self.assertEqual(long('8pfgih5', 28), 4294967297)
392 self.assertEqual(long('76beigh', 29), 4294967297)
393 self.assertEqual(long('5qmcpqh', 30), 4294967297)
394 self.assertEqual(long('4q0jto5', 31), 4294967297)
395 self.assertEqual(long('4000001', 32), 4294967297)
396 self.assertEqual(long('3aokq95', 33), 4294967297)
397 self.assertEqual(long('2qhxjlj', 34), 4294967297)
398 self.assertEqual(long('2br45qc', 35), 4294967297)
399 self.assertEqual(long('1z141z5', 36), 4294967297)
402 def test_conversion(self):
403 # Test __long__()
404 class ClassicMissingMethods:
405 pass
406 self.assertRaises(AttributeError, long, ClassicMissingMethods())
408 class MissingMethods(object):
409 pass
410 self.assertRaises(TypeError, long, MissingMethods())
412 class Foo0:
413 def __long__(self):
414 return 42L
416 class Foo1(object):
417 def __long__(self):
418 return 42L
420 class Foo2(long):
421 def __long__(self):
422 return 42L
424 class Foo3(long):
425 def __long__(self):
426 return self
428 class Foo4(long):
429 def __long__(self):
430 return 42
432 class Foo5(long):
433 def __long__(self):
434 return 42.
436 self.assertEqual(long(Foo0()), 42L)
437 self.assertEqual(long(Foo1()), 42L)
438 self.assertEqual(long(Foo2()), 42L)
439 self.assertEqual(long(Foo3()), 0)
440 self.assertEqual(long(Foo4()), 42)
441 self.assertRaises(TypeError, long, Foo5())
443 class Classic:
444 pass
445 for base in (object, Classic):
446 class LongOverridesTrunc(base):
447 def __long__(self):
448 return 42
449 def __trunc__(self):
450 return -12
451 self.assertEqual(long(LongOverridesTrunc()), 42)
453 class JustTrunc(base):
454 def __trunc__(self):
455 return 42
456 self.assertEqual(long(JustTrunc()), 42)
458 for trunc_result_base in (object, Classic):
459 class Integral(trunc_result_base):
460 def __int__(self):
461 return 42
463 class TruncReturnsNonLong(base):
464 def __trunc__(self):
465 return Integral()
466 self.assertEqual(long(TruncReturnsNonLong()), 42)
468 class NonIntegral(trunc_result_base):
469 def __trunc__(self):
470 # Check that we avoid infinite recursion.
471 return NonIntegral()
473 class TruncReturnsNonIntegral(base):
474 def __trunc__(self):
475 return NonIntegral()
476 try:
477 long(TruncReturnsNonIntegral())
478 except TypeError as e:
479 self.assertEquals(str(e),
480 "__trunc__ returned non-Integral"
481 " (type NonIntegral)")
482 else:
483 self.fail("Failed to raise TypeError with %s" %
484 ((base, trunc_result_base),))
486 def test_misc(self):
488 # check the extremes in int<->long conversion
489 hugepos = sys.maxint
490 hugeneg = -hugepos - 1
491 hugepos_aslong = long(hugepos)
492 hugeneg_aslong = long(hugeneg)
493 self.assertEqual(hugepos, hugepos_aslong, "long(sys.maxint) != sys.maxint")
494 self.assertEqual(hugeneg, hugeneg_aslong,
495 "long(-sys.maxint-1) != -sys.maxint-1")
497 # long -> int should not fail for hugepos_aslong or hugeneg_aslong
498 x = int(hugepos_aslong)
499 try:
500 self.assertEqual(x, hugepos,
501 "converting sys.maxint to long and back to int fails")
502 except OverflowError:
503 self.fail("int(long(sys.maxint)) overflowed!")
504 if not isinstance(x, int):
505 raise TestFailed("int(long(sys.maxint)) should have returned int")
506 x = int(hugeneg_aslong)
507 try:
508 self.assertEqual(x, hugeneg,
509 "converting -sys.maxint-1 to long and back to int fails")
510 except OverflowError:
511 self.fail("int(long(-sys.maxint-1)) overflowed!")
512 if not isinstance(x, int):
513 raise TestFailed("int(long(-sys.maxint-1)) should have "
514 "returned int")
515 # but long -> int should overflow for hugepos+1 and hugeneg-1
516 x = hugepos_aslong + 1
517 try:
518 y = int(x)
519 except OverflowError:
520 self.fail("int(long(sys.maxint) + 1) mustn't overflow")
521 self.assert_(isinstance(y, long),
522 "int(long(sys.maxint) + 1) should have returned long")
524 x = hugeneg_aslong - 1
525 try:
526 y = int(x)
527 except OverflowError:
528 self.fail("int(long(-sys.maxint-1) - 1) mustn't overflow")
529 self.assert_(isinstance(y, long),
530 "int(long(-sys.maxint-1) - 1) should have returned long")
532 class long2(long):
533 pass
534 x = long2(1L<<100)
535 y = int(x)
536 self.assert_(type(y) is long,
537 "overflowing int conversion must return long not long subtype")
539 # long -> Py_ssize_t conversion
540 class X(object):
541 def __getslice__(self, i, j):
542 return i, j
544 self.assertEqual(X()[-5L:7L], (-5, 7))
545 # use the clamping effect to test the smallest and largest longs
546 # that fit a Py_ssize_t
547 slicemin, slicemax = X()[-2L**100:2L**100]
548 self.assertEqual(X()[slicemin:slicemax], (slicemin, slicemax))
550 # ----------------------------------- tests of auto int->long conversion
552 def test_auto_overflow(self):
553 import math, sys
555 special = [0, 1, 2, 3, sys.maxint-1, sys.maxint, sys.maxint+1]
556 sqrt = int(math.sqrt(sys.maxint))
557 special.extend([sqrt-1, sqrt, sqrt+1])
558 special.extend([-i for i in special])
560 def checkit(*args):
561 # Heavy use of nested scopes here!
562 self.assertEqual(got, expected,
563 Frm("for %r expected %r got %r", args, expected, got))
565 for x in special:
566 longx = long(x)
568 expected = -longx
569 got = -x
570 checkit('-', x)
572 for y in special:
573 longy = long(y)
575 expected = longx + longy
576 got = x + y
577 checkit(x, '+', y)
579 expected = longx - longy
580 got = x - y
581 checkit(x, '-', y)
583 expected = longx * longy
584 got = x * y
585 checkit(x, '*', y)
587 if y:
588 expected = longx / longy
589 got = x / y
590 checkit(x, '/', y)
592 expected = longx // longy
593 got = x // y
594 checkit(x, '//', y)
596 expected = divmod(longx, longy)
597 got = divmod(longx, longy)
598 checkit(x, 'divmod', y)
600 if abs(y) < 5 and not (x == 0 and y < 0):
601 expected = longx ** longy
602 got = x ** y
603 checkit(x, '**', y)
605 for z in special:
606 if z != 0 :
607 if y >= 0:
608 expected = pow(longx, longy, long(z))
609 got = pow(x, y, z)
610 checkit('pow', x, y, '%', z)
611 else:
612 self.assertRaises(TypeError, pow,longx, longy, long(z))
614 def test_float_overflow(self):
615 import math
617 for x in -2.0, -1.0, 0.0, 1.0, 2.0:
618 self.assertEqual(float(long(x)), x)
620 shuge = '12345' * 120
621 huge = 1L << 30000
622 mhuge = -huge
623 namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math}
624 for test in ["float(huge)", "float(mhuge)",
625 "complex(huge)", "complex(mhuge)",
626 "complex(huge, 1)", "complex(mhuge, 1)",
627 "complex(1, huge)", "complex(1, mhuge)",
628 "1. + huge", "huge + 1.", "1. + mhuge", "mhuge + 1.",
629 "1. - huge", "huge - 1.", "1. - mhuge", "mhuge - 1.",
630 "1. * huge", "huge * 1.", "1. * mhuge", "mhuge * 1.",
631 "1. // huge", "huge // 1.", "1. // mhuge", "mhuge // 1.",
632 "1. / huge", "huge / 1.", "1. / mhuge", "mhuge / 1.",
633 "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.",
634 "math.sin(huge)", "math.sin(mhuge)",
635 "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better
636 "math.floor(huge)", "math.floor(mhuge)"]:
638 self.assertRaises(OverflowError, eval, test, namespace)
640 # XXX Perhaps float(shuge) can raise OverflowError on some box?
641 # The comparison should not.
642 self.assertNotEqual(float(shuge), int(shuge),
643 "float(shuge) should not equal int(shuge)")
645 def test_logs(self):
646 import math
648 LOG10E = math.log10(math.e)
650 for exp in range(10) + [100, 1000, 10000]:
651 value = 10 ** exp
652 log10 = math.log10(value)
653 self.assertAlmostEqual(log10, exp)
655 # log10(value) == exp, so log(value) == log10(value)/log10(e) ==
656 # exp/LOG10E
657 expected = exp / LOG10E
658 log = math.log(value)
659 self.assertAlmostEqual(log, expected)
661 for bad in -(1L << 10000), -2L, 0L:
662 self.assertRaises(ValueError, math.log, bad)
663 self.assertRaises(ValueError, math.log10, bad)
665 def test_mixed_compares(self):
666 eq = self.assertEqual
667 import math
669 # We're mostly concerned with that mixing floats and longs does the
670 # right stuff, even when longs are too large to fit in a float.
671 # The safest way to check the results is to use an entirely different
672 # method, which we do here via a skeletal rational class (which
673 # represents all Python ints, longs and floats exactly).
674 class Rat:
675 def __init__(self, value):
676 if isinstance(value, (int, long)):
677 self.n = value
678 self.d = 1
679 elif isinstance(value, float):
680 # Convert to exact rational equivalent.
681 f, e = math.frexp(abs(value))
682 assert f == 0 or 0.5 <= f < 1.0
683 # |value| = f * 2**e exactly
685 # Suck up CHUNK bits at a time; 28 is enough so that we suck
686 # up all bits in 2 iterations for all known binary double-
687 # precision formats, and small enough to fit in an int.
688 CHUNK = 28
689 top = 0
690 # invariant: |value| = (top + f) * 2**e exactly
691 while f:
692 f = math.ldexp(f, CHUNK)
693 digit = int(f)
694 assert digit >> CHUNK == 0
695 top = (top << CHUNK) | digit
696 f -= digit
697 assert 0.0 <= f < 1.0
698 e -= CHUNK
700 # Now |value| = top * 2**e exactly.
701 if e >= 0:
702 n = top << e
703 d = 1
704 else:
705 n = top
706 d = 1 << -e
707 if value < 0:
708 n = -n
709 self.n = n
710 self.d = d
711 assert float(n) / float(d) == value
712 else:
713 raise TypeError("can't deal with %r" % val)
715 def __cmp__(self, other):
716 if not isinstance(other, Rat):
717 other = Rat(other)
718 return cmp(self.n * other.d, self.d * other.n)
720 cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200]
721 # 2**48 is an important boundary in the internals. 2**53 is an
722 # important boundary for IEEE double precision.
723 for t in 2.0**48, 2.0**50, 2.0**53:
724 cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0,
725 long(t-1), long(t), long(t+1)])
726 cases.extend([0, 1, 2, sys.maxint, float(sys.maxint)])
727 # 1L<<20000 should exceed all double formats. long(1e200) is to
728 # check that we get equality with 1e200 above.
729 t = long(1e200)
730 cases.extend([0L, 1L, 2L, 1L << 20000, t-1, t, t+1])
731 cases.extend([-x for x in cases])
732 for x in cases:
733 Rx = Rat(x)
734 for y in cases:
735 Ry = Rat(y)
736 Rcmp = cmp(Rx, Ry)
737 xycmp = cmp(x, y)
738 eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp))
739 eq(x == y, Rcmp == 0, Frm("%r == %r %d", x, y, Rcmp))
740 eq(x != y, Rcmp != 0, Frm("%r != %r %d", x, y, Rcmp))
741 eq(x < y, Rcmp < 0, Frm("%r < %r %d", x, y, Rcmp))
742 eq(x <= y, Rcmp <= 0, Frm("%r <= %r %d", x, y, Rcmp))
743 eq(x > y, Rcmp > 0, Frm("%r > %r %d", x, y, Rcmp))
744 eq(x >= y, Rcmp >= 0, Frm("%r >= %r %d", x, y, Rcmp))
746 def test_nan_inf(self):
747 self.assertRaises(OverflowError, long, float('inf'))
748 self.assertEqual(long(float('nan')), 0L)
750 def test_main():
751 test_support.run_unittest(LongTest)
753 if __name__ == "__main__":
754 test_main()