blob: 5addd2e87584d004ec6e65eec6fb165bf0794a66 [file] [log] [blame]
Walter Dörwalda0021592005-06-13 21:44:48 +00001import unittest
2from test import test_support
Benjamin Peterson979395b2008-05-03 21:35:18 +00003import sys
Walter Dörwalda0021592005-06-13 21:44:48 +00004
5import random
6
7# Used for lazy formatting of failure messages
8class Frm(object):
9 def __init__(self, format, *args):
10 self.format = format
11 self.args = args
12
13 def __str__(self):
14 return self.format % self.args
Guido van Rossum4365cab1998-08-13 14:20:17 +000015
16# SHIFT should match the value in longintrepr.h for best testing.
17SHIFT = 15
18BASE = 2 ** SHIFT
19MASK = BASE - 1
Tim Petersdaec9612004-08-30 23:18:23 +000020KARATSUBA_CUTOFF = 70 # from longobject.c
Guido van Rossum4365cab1998-08-13 14:20:17 +000021
22# Max number of base BASE digits to use in test cases. Doubling
Tim Peters28b0e2a2002-08-13 02:17:11 +000023# this will more than double the runtime.
24MAXDIGITS = 15
Guido van Rossum4365cab1998-08-13 14:20:17 +000025
Guido van Rossum4581a0c1998-10-02 01:19:48 +000026# build some special values
27special = map(long, [0, 1, 2, BASE, BASE >> 1])
28special.append(0x5555555555555555L)
29special.append(0xaaaaaaaaaaaaaaaaL)
30# some solid strings of one bits
31p2 = 4L # 0 and 1 already added
32for i in range(2*SHIFT):
33 special.append(p2 - 1)
34 p2 = p2 << 1
35del p2
36# add complements & negations
37special = special + map(lambda x: ~x, special) + \
38 map(lambda x: -x, special)
39
Benjamin Peterson979395b2008-05-03 21:35:18 +000040L = [
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)
58]
59if 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),
78]
79
Guido van Rossum4365cab1998-08-13 14:20:17 +000080
Walter Dörwalda0021592005-06-13 21:44:48 +000081class LongTest(unittest.TestCase):
Guido van Rossum4365cab1998-08-13 14:20:17 +000082
Walter Dörwalda0021592005-06-13 21:44:48 +000083 # 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.
Guido van Rossum4365cab1998-08-13 14:20:17 +000088
Walter Dörwalda0021592005-06-13 21:44:48 +000089 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
Guido van Rossum4581a0c1998-10-02 01:19:48 +0000109
Walter Dörwalda0021592005-06-13 21:44:48 +0000110 # Get random long consisting of ndigits random digits (relative to base
111 # BASE). The sign bit is also random.
Guido van Rossum4581a0c1998-10-02 01:19:48 +0000112
Walter Dörwalda0021592005-06-13 21:44:48 +0000113 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
Guido van Rossum4365cab1998-08-13 14:20:17 +0000120
Walter Dörwalda0021592005-06-13 21:44:48 +0000121 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))
Guido van Rossum4365cab1998-08-13 14:20:17 +0000134
Walter Dörwalda0021592005-06-13 21:44:48 +0000135 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)
Guido van Rossum4365cab1998-08-13 14:20:17 +0000144
Walter Dörwalda0021592005-06-13 21:44:48 +0000145 def test_karatsuba(self):
146 digits = range(1, 5) + range(KARATSUBA_CUTOFF, KARATSUBA_CUTOFF + 10)
147 digits.extend([KARATSUBA_CUTOFF * 10, KARATSUBA_CUTOFF * 100])
Guido van Rossum4365cab1998-08-13 14:20:17 +0000148
Walter Dörwalda0021592005-06-13 21:44:48 +0000149 bits = [digit * SHIFT for digit in digits]
Guido van Rossum4365cab1998-08-13 14:20:17 +0000150
Walter Dörwalda0021592005-06-13 21:44:48 +0000151 # 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) +
163 1)
164 self.assertEqual(x, y,
165 Frm("bad result for a*b: a=%r, b=%r, x=%r, y=%r", a, b, x, y))
Tim Peters7f270ba2002-08-13 21:06:55 +0000166
Walter Dörwalda0021592005-06-13 21:44:48 +0000167 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)))
Tim Peters7f270ba2002-08-13 21:06:55 +0000196
Walter Dörwalda0021592005-06-13 21:44:48 +0000197 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)))
Tim Peters7f270ba2002-08-13 21:06:55 +0000211
Walter Dörwalda0021592005-06-13 21:44:48 +0000212 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)))
Tim Peters7f270ba2002-08-13 21:06:55 +0000224
Walter Dörwalda0021592005-06-13 21:44:48 +0000225 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))
Guido van Rossum4365cab1998-08-13 14:20:17 +0000236
Walter Dörwalda0021592005-06-13 21:44:48 +0000237 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] + \
Raymond Hettinger3296e692005-06-29 23:29:56 +0000252 "".join(map(lambda i: "0123456789abcdef"[i], digits)) + "L"
Guido van Rossum4365cab1998-08-13 14:20:17 +0000253
Walter Dörwalda0021592005-06-13 21:44:48 +0000254 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)
Guido van Rossum4365cab1998-08-13 14:20:17 +0000269
Walter Dörwalda0021592005-06-13 21:44:48 +0000270 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)
Guido van Rossum4365cab1998-08-13 14:20:17 +0000277
Benjamin Peterson979395b2008-05-03 21:35:18 +0000278 def test_long(self):
279 self.assertEqual(long(314), 314L)
280 self.assertEqual(long(3.14), 3L)
281 self.assertEqual(long(314L), 314L)
Amaury Forgeot d'Arcd3ffb892008-09-09 07:24:30 +0000282 # Check that long() of basic types actually returns a long
283 self.assertEqual(type(long(314)), long)
284 self.assertEqual(type(long(3.14)), long)
285 self.assertEqual(type(long(314L)), long)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000286 # Check that conversion from float truncates towards zero
287 self.assertEqual(long(-3.14), -3L)
288 self.assertEqual(long(3.9), 3L)
289 self.assertEqual(long(-3.9), -3L)
290 self.assertEqual(long(3.5), 3L)
291 self.assertEqual(long(-3.5), -3L)
292 self.assertEqual(long("-3"), -3L)
293 if test_support.have_unicode:
294 self.assertEqual(long(unicode("-3")), -3L)
295 # Different base:
296 self.assertEqual(long("10",16), 16L)
297 if test_support.have_unicode:
298 self.assertEqual(long(unicode("10"),16), 16L)
299 # Check conversions from string (same test set as for int(), and then some)
300 LL = [
301 ('1' + '0'*20, 10L**20),
302 ('1' + '0'*100, 10L**100)
303 ]
304 L2 = L[:]
305 if test_support.have_unicode:
306 L2 += [
307 (unicode('1') + unicode('0')*20, 10L**20),
308 (unicode('1') + unicode('0')*100, 10L**100),
309 ]
310 for s, v in L2 + LL:
311 for sign in "", "+", "-":
312 for prefix in "", " ", "\t", " \t\t ":
313 ss = prefix + sign + s
314 vv = v
315 if sign == "-" and v is not ValueError:
316 vv = -v
317 try:
318 self.assertEqual(long(ss), long(vv))
319 except v:
320 pass
321
322 self.assertRaises(ValueError, long, '123\0')
323 self.assertRaises(ValueError, long, '53', 40)
324 self.assertRaises(TypeError, long, 1, 12)
325
326 # SF patch #1638879: embedded NULs were not detected with
327 # explicit base
328 self.assertRaises(ValueError, long, '123\0', 10)
329 self.assertRaises(ValueError, long, '123\x00 245', 20)
330
331 self.assertEqual(long('100000000000000000000000000000000', 2),
332 4294967296)
333 self.assertEqual(long('102002022201221111211', 3), 4294967296)
334 self.assertEqual(long('10000000000000000', 4), 4294967296)
335 self.assertEqual(long('32244002423141', 5), 4294967296)
336 self.assertEqual(long('1550104015504', 6), 4294967296)
337 self.assertEqual(long('211301422354', 7), 4294967296)
338 self.assertEqual(long('40000000000', 8), 4294967296)
339 self.assertEqual(long('12068657454', 9), 4294967296)
340 self.assertEqual(long('4294967296', 10), 4294967296)
341 self.assertEqual(long('1904440554', 11), 4294967296)
342 self.assertEqual(long('9ba461594', 12), 4294967296)
343 self.assertEqual(long('535a79889', 13), 4294967296)
344 self.assertEqual(long('2ca5b7464', 14), 4294967296)
345 self.assertEqual(long('1a20dcd81', 15), 4294967296)
346 self.assertEqual(long('100000000', 16), 4294967296)
347 self.assertEqual(long('a7ffda91', 17), 4294967296)
348 self.assertEqual(long('704he7g4', 18), 4294967296)
349 self.assertEqual(long('4f5aff66', 19), 4294967296)
350 self.assertEqual(long('3723ai4g', 20), 4294967296)
351 self.assertEqual(long('281d55i4', 21), 4294967296)
352 self.assertEqual(long('1fj8b184', 22), 4294967296)
353 self.assertEqual(long('1606k7ic', 23), 4294967296)
354 self.assertEqual(long('mb994ag', 24), 4294967296)
355 self.assertEqual(long('hek2mgl', 25), 4294967296)
356 self.assertEqual(long('dnchbnm', 26), 4294967296)
357 self.assertEqual(long('b28jpdm', 27), 4294967296)
358 self.assertEqual(long('8pfgih4', 28), 4294967296)
359 self.assertEqual(long('76beigg', 29), 4294967296)
360 self.assertEqual(long('5qmcpqg', 30), 4294967296)
361 self.assertEqual(long('4q0jto4', 31), 4294967296)
362 self.assertEqual(long('4000000', 32), 4294967296)
363 self.assertEqual(long('3aokq94', 33), 4294967296)
364 self.assertEqual(long('2qhxjli', 34), 4294967296)
365 self.assertEqual(long('2br45qb', 35), 4294967296)
366 self.assertEqual(long('1z141z4', 36), 4294967296)
367
368 self.assertEqual(long('100000000000000000000000000000001', 2),
369 4294967297)
370 self.assertEqual(long('102002022201221111212', 3), 4294967297)
371 self.assertEqual(long('10000000000000001', 4), 4294967297)
372 self.assertEqual(long('32244002423142', 5), 4294967297)
373 self.assertEqual(long('1550104015505', 6), 4294967297)
374 self.assertEqual(long('211301422355', 7), 4294967297)
375 self.assertEqual(long('40000000001', 8), 4294967297)
376 self.assertEqual(long('12068657455', 9), 4294967297)
377 self.assertEqual(long('4294967297', 10), 4294967297)
378 self.assertEqual(long('1904440555', 11), 4294967297)
379 self.assertEqual(long('9ba461595', 12), 4294967297)
380 self.assertEqual(long('535a7988a', 13), 4294967297)
381 self.assertEqual(long('2ca5b7465', 14), 4294967297)
382 self.assertEqual(long('1a20dcd82', 15), 4294967297)
383 self.assertEqual(long('100000001', 16), 4294967297)
384 self.assertEqual(long('a7ffda92', 17), 4294967297)
385 self.assertEqual(long('704he7g5', 18), 4294967297)
386 self.assertEqual(long('4f5aff67', 19), 4294967297)
387 self.assertEqual(long('3723ai4h', 20), 4294967297)
388 self.assertEqual(long('281d55i5', 21), 4294967297)
389 self.assertEqual(long('1fj8b185', 22), 4294967297)
390 self.assertEqual(long('1606k7id', 23), 4294967297)
391 self.assertEqual(long('mb994ah', 24), 4294967297)
392 self.assertEqual(long('hek2mgm', 25), 4294967297)
393 self.assertEqual(long('dnchbnn', 26), 4294967297)
394 self.assertEqual(long('b28jpdn', 27), 4294967297)
395 self.assertEqual(long('8pfgih5', 28), 4294967297)
396 self.assertEqual(long('76beigh', 29), 4294967297)
397 self.assertEqual(long('5qmcpqh', 30), 4294967297)
398 self.assertEqual(long('4q0jto5', 31), 4294967297)
399 self.assertEqual(long('4000001', 32), 4294967297)
400 self.assertEqual(long('3aokq95', 33), 4294967297)
401 self.assertEqual(long('2qhxjlj', 34), 4294967297)
402 self.assertEqual(long('2br45qc', 35), 4294967297)
403 self.assertEqual(long('1z141z5', 36), 4294967297)
404
405
406 def test_conversion(self):
407 # Test __long__()
408 class ClassicMissingMethods:
409 pass
410 self.assertRaises(AttributeError, long, ClassicMissingMethods())
411
412 class MissingMethods(object):
413 pass
414 self.assertRaises(TypeError, long, MissingMethods())
415
416 class Foo0:
417 def __long__(self):
418 return 42L
419
420 class Foo1(object):
421 def __long__(self):
422 return 42L
423
424 class Foo2(long):
425 def __long__(self):
426 return 42L
427
428 class Foo3(long):
429 def __long__(self):
430 return self
431
432 class Foo4(long):
433 def __long__(self):
434 return 42
435
436 class Foo5(long):
437 def __long__(self):
438 return 42.
439
440 self.assertEqual(long(Foo0()), 42L)
441 self.assertEqual(long(Foo1()), 42L)
442 self.assertEqual(long(Foo2()), 42L)
443 self.assertEqual(long(Foo3()), 0)
444 self.assertEqual(long(Foo4()), 42)
445 self.assertRaises(TypeError, long, Foo5())
446
447 class Classic:
448 pass
449 for base in (object, Classic):
450 class LongOverridesTrunc(base):
451 def __long__(self):
452 return 42
453 def __trunc__(self):
454 return -12
455 self.assertEqual(long(LongOverridesTrunc()), 42)
456
457 class JustTrunc(base):
458 def __trunc__(self):
459 return 42
460 self.assertEqual(long(JustTrunc()), 42)
461
462 for trunc_result_base in (object, Classic):
463 class Integral(trunc_result_base):
464 def __int__(self):
465 return 42
466
467 class TruncReturnsNonLong(base):
468 def __trunc__(self):
469 return Integral()
470 self.assertEqual(long(TruncReturnsNonLong()), 42)
471
472 class NonIntegral(trunc_result_base):
473 def __trunc__(self):
474 # Check that we avoid infinite recursion.
475 return NonIntegral()
476
477 class TruncReturnsNonIntegral(base):
478 def __trunc__(self):
479 return NonIntegral()
480 try:
481 long(TruncReturnsNonIntegral())
482 except TypeError as e:
483 self.assertEquals(str(e),
484 "__trunc__ returned non-Integral"
485 " (type NonIntegral)")
486 else:
487 self.fail("Failed to raise TypeError with %s" %
488 ((base, trunc_result_base),))
489
Walter Dörwalda0021592005-06-13 21:44:48 +0000490 def test_misc(self):
Guido van Rossum4365cab1998-08-13 14:20:17 +0000491
Walter Dörwalda0021592005-06-13 21:44:48 +0000492 # check the extremes in int<->long conversion
493 hugepos = sys.maxint
494 hugeneg = -hugepos - 1
495 hugepos_aslong = long(hugepos)
496 hugeneg_aslong = long(hugeneg)
497 self.assertEqual(hugepos, hugepos_aslong, "long(sys.maxint) != sys.maxint")
498 self.assertEqual(hugeneg, hugeneg_aslong,
499 "long(-sys.maxint-1) != -sys.maxint-1")
Guido van Rossum4365cab1998-08-13 14:20:17 +0000500
Walter Dörwalda0021592005-06-13 21:44:48 +0000501 # long -> int should not fail for hugepos_aslong or hugeneg_aslong
Armin Rigo7ccbca92006-10-04 12:17:45 +0000502 x = int(hugepos_aslong)
Walter Dörwalda0021592005-06-13 21:44:48 +0000503 try:
Armin Rigo7ccbca92006-10-04 12:17:45 +0000504 self.assertEqual(x, hugepos,
Walter Dörwalda0021592005-06-13 21:44:48 +0000505 "converting sys.maxint to long and back to int fails")
506 except OverflowError:
507 self.fail("int(long(sys.maxint)) overflowed!")
Armin Rigo7ccbca92006-10-04 12:17:45 +0000508 if not isinstance(x, int):
509 raise TestFailed("int(long(sys.maxint)) should have returned int")
510 x = int(hugeneg_aslong)
Walter Dörwalda0021592005-06-13 21:44:48 +0000511 try:
Armin Rigo7ccbca92006-10-04 12:17:45 +0000512 self.assertEqual(x, hugeneg,
Walter Dörwalda0021592005-06-13 21:44:48 +0000513 "converting -sys.maxint-1 to long and back to int fails")
514 except OverflowError:
515 self.fail("int(long(-sys.maxint-1)) overflowed!")
Armin Rigo7ccbca92006-10-04 12:17:45 +0000516 if not isinstance(x, int):
517 raise TestFailed("int(long(-sys.maxint-1)) should have "
518 "returned int")
Walter Dörwalda0021592005-06-13 21:44:48 +0000519 # but long -> int should overflow for hugepos+1 and hugeneg-1
520 x = hugepos_aslong + 1
521 try:
522 y = int(x)
523 except OverflowError:
524 self.fail("int(long(sys.maxint) + 1) mustn't overflow")
525 self.assert_(isinstance(y, long),
526 "int(long(sys.maxint) + 1) should have returned long")
Guido van Rossum4365cab1998-08-13 14:20:17 +0000527
Walter Dörwalda0021592005-06-13 21:44:48 +0000528 x = hugeneg_aslong - 1
529 try:
530 y = int(x)
531 except OverflowError:
532 self.fail("int(long(-sys.maxint-1) - 1) mustn't overflow")
533 self.assert_(isinstance(y, long),
534 "int(long(-sys.maxint-1) - 1) should have returned long")
Guido van Rossum4365cab1998-08-13 14:20:17 +0000535
Walter Dörwalda0021592005-06-13 21:44:48 +0000536 class long2(long):
537 pass
538 x = long2(1L<<100)
Walter Dörwaldf1715402002-11-19 20:49:15 +0000539 y = int(x)
Walter Dörwalda0021592005-06-13 21:44:48 +0000540 self.assert_(type(y) is long,
541 "overflowing int conversion must return long not long subtype")
Guido van Rossum4581a0c1998-10-02 01:19:48 +0000542
Armin Rigo7ccbca92006-10-04 12:17:45 +0000543 # long -> Py_ssize_t conversion
544 class X(object):
545 def __getslice__(self, i, j):
546 return i, j
547
548 self.assertEqual(X()[-5L:7L], (-5, 7))
549 # use the clamping effect to test the smallest and largest longs
550 # that fit a Py_ssize_t
551 slicemin, slicemax = X()[-2L**100:2L**100]
552 self.assertEqual(X()[slicemin:slicemax], (slicemin, slicemax))
553
Tim Peters26c7fa32001-08-23 22:56:21 +0000554# ----------------------------------- tests of auto int->long conversion
555
Walter Dörwalda0021592005-06-13 21:44:48 +0000556 def test_auto_overflow(self):
557 import math, sys
Tim Peters26c7fa32001-08-23 22:56:21 +0000558
Walter Dörwalda0021592005-06-13 21:44:48 +0000559 special = [0, 1, 2, 3, sys.maxint-1, sys.maxint, sys.maxint+1]
560 sqrt = int(math.sqrt(sys.maxint))
561 special.extend([sqrt-1, sqrt, sqrt+1])
562 special.extend([-i for i in special])
Tim Peters26c7fa32001-08-23 22:56:21 +0000563
Walter Dörwalda0021592005-06-13 21:44:48 +0000564 def checkit(*args):
565 # Heavy use of nested scopes here!
566 self.assertEqual(got, expected,
567 Frm("for %r expected %r got %r", args, expected, got))
Tim Peters26c7fa32001-08-23 22:56:21 +0000568
Walter Dörwalda0021592005-06-13 21:44:48 +0000569 for x in special:
570 longx = long(x)
Tim Peters26c7fa32001-08-23 22:56:21 +0000571
Walter Dörwalda0021592005-06-13 21:44:48 +0000572 expected = -longx
573 got = -x
574 checkit('-', x)
Tim Peters26c7fa32001-08-23 22:56:21 +0000575
Walter Dörwalda0021592005-06-13 21:44:48 +0000576 for y in special:
577 longy = long(y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000578
Walter Dörwalda0021592005-06-13 21:44:48 +0000579 expected = longx + longy
580 got = x + y
581 checkit(x, '+', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000582
Walter Dörwalda0021592005-06-13 21:44:48 +0000583 expected = longx - longy
584 got = x - y
585 checkit(x, '-', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000586
Walter Dörwalda0021592005-06-13 21:44:48 +0000587 expected = longx * longy
588 got = x * y
589 checkit(x, '*', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000590
Walter Dörwalda0021592005-06-13 21:44:48 +0000591 if y:
592 expected = longx / longy
593 got = x / y
594 checkit(x, '/', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000595
Walter Dörwalda0021592005-06-13 21:44:48 +0000596 expected = longx // longy
597 got = x // y
598 checkit(x, '//', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000599
Walter Dörwalda0021592005-06-13 21:44:48 +0000600 expected = divmod(longx, longy)
601 got = divmod(longx, longy)
602 checkit(x, 'divmod', y)
Tim Petersa3653092001-08-23 23:02:57 +0000603
Walter Dörwalda0021592005-06-13 21:44:48 +0000604 if abs(y) < 5 and not (x == 0 and y < 0):
605 expected = longx ** longy
606 got = x ** y
607 checkit(x, '**', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000608
Walter Dörwalda0021592005-06-13 21:44:48 +0000609 for z in special:
610 if z != 0 :
611 if y >= 0:
612 expected = pow(longx, longy, long(z))
613 got = pow(x, y, z)
614 checkit('pow', x, y, '%', z)
Tim Peters32f453e2001-09-03 08:35:41 +0000615 else:
Walter Dörwalda0021592005-06-13 21:44:48 +0000616 self.assertRaises(TypeError, pow,longx, longy, long(z))
Tim Peters26c7fa32001-08-23 22:56:21 +0000617
Walter Dörwalda0021592005-06-13 21:44:48 +0000618 def test_float_overflow(self):
619 import math
Tim Peters9fffa3e2001-09-04 05:14:19 +0000620
Walter Dörwalda0021592005-06-13 21:44:48 +0000621 for x in -2.0, -1.0, 0.0, 1.0, 2.0:
622 self.assertEqual(float(long(x)), x)
Tim Peters9fffa3e2001-09-04 05:14:19 +0000623
Walter Dörwalda0021592005-06-13 21:44:48 +0000624 shuge = '12345' * 120
625 huge = 1L << 30000
626 mhuge = -huge
627 namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math}
628 for test in ["float(huge)", "float(mhuge)",
629 "complex(huge)", "complex(mhuge)",
630 "complex(huge, 1)", "complex(mhuge, 1)",
631 "complex(1, huge)", "complex(1, mhuge)",
632 "1. + huge", "huge + 1.", "1. + mhuge", "mhuge + 1.",
633 "1. - huge", "huge - 1.", "1. - mhuge", "mhuge - 1.",
634 "1. * huge", "huge * 1.", "1. * mhuge", "mhuge * 1.",
635 "1. // huge", "huge // 1.", "1. // mhuge", "mhuge // 1.",
636 "1. / huge", "huge / 1.", "1. / mhuge", "mhuge / 1.",
637 "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.",
638 "math.sin(huge)", "math.sin(mhuge)",
639 "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better
Jeffrey Yasskin9871d8f2008-01-05 08:47:13 +0000640 "math.floor(huge)", "math.floor(mhuge)"]:
Tim Peters9fffa3e2001-09-04 05:14:19 +0000641
Walter Dörwalda0021592005-06-13 21:44:48 +0000642 self.assertRaises(OverflowError, eval, test, namespace)
Tim Peters9fffa3e2001-09-04 05:14:19 +0000643
Walter Dörwalda0021592005-06-13 21:44:48 +0000644 # XXX Perhaps float(shuge) can raise OverflowError on some box?
645 # The comparison should not.
646 self.assertNotEqual(float(shuge), int(shuge),
647 "float(shuge) should not equal int(shuge)")
Tim Peters83e7ccc2001-09-04 06:37:28 +0000648
Walter Dörwalda0021592005-06-13 21:44:48 +0000649 def test_logs(self):
650 import math
Tim Peters78526162001-09-05 00:53:45 +0000651
Walter Dörwalda0021592005-06-13 21:44:48 +0000652 LOG10E = math.log10(math.e)
Tim Peters307fa782004-09-23 08:06:40 +0000653
Walter Dörwalda0021592005-06-13 21:44:48 +0000654 for exp in range(10) + [100, 1000, 10000]:
655 value = 10 ** exp
656 log10 = math.log10(value)
657 self.assertAlmostEqual(log10, exp)
Tim Peters78526162001-09-05 00:53:45 +0000658
Walter Dörwalda0021592005-06-13 21:44:48 +0000659 # log10(value) == exp, so log(value) == log10(value)/log10(e) ==
660 # exp/LOG10E
661 expected = exp / LOG10E
662 log = math.log(value)
663 self.assertAlmostEqual(log, expected)
Tim Peters78526162001-09-05 00:53:45 +0000664
Walter Dörwalda0021592005-06-13 21:44:48 +0000665 for bad in -(1L << 10000), -2L, 0L:
666 self.assertRaises(ValueError, math.log, bad)
667 self.assertRaises(ValueError, math.log10, bad)
Tim Peters78526162001-09-05 00:53:45 +0000668
Walter Dörwalda0021592005-06-13 21:44:48 +0000669 def test_mixed_compares(self):
670 eq = self.assertEqual
671 import math
Tim Peters78526162001-09-05 00:53:45 +0000672
Walter Dörwalda0021592005-06-13 21:44:48 +0000673 # We're mostly concerned with that mixing floats and longs does the
674 # right stuff, even when longs are too large to fit in a float.
675 # The safest way to check the results is to use an entirely different
676 # method, which we do here via a skeletal rational class (which
677 # represents all Python ints, longs and floats exactly).
678 class Rat:
679 def __init__(self, value):
680 if isinstance(value, (int, long)):
681 self.n = value
682 self.d = 1
683 elif isinstance(value, float):
684 # Convert to exact rational equivalent.
685 f, e = math.frexp(abs(value))
686 assert f == 0 or 0.5 <= f < 1.0
687 # |value| = f * 2**e exactly
Tim Peters78526162001-09-05 00:53:45 +0000688
Walter Dörwalda0021592005-06-13 21:44:48 +0000689 # Suck up CHUNK bits at a time; 28 is enough so that we suck
690 # up all bits in 2 iterations for all known binary double-
691 # precision formats, and small enough to fit in an int.
692 CHUNK = 28
693 top = 0
694 # invariant: |value| = (top + f) * 2**e exactly
695 while f:
696 f = math.ldexp(f, CHUNK)
697 digit = int(f)
698 assert digit >> CHUNK == 0
699 top = (top << CHUNK) | digit
700 f -= digit
701 assert 0.0 <= f < 1.0
702 e -= CHUNK
Tim Peters78526162001-09-05 00:53:45 +0000703
Walter Dörwalda0021592005-06-13 21:44:48 +0000704 # Now |value| = top * 2**e exactly.
705 if e >= 0:
706 n = top << e
707 d = 1
708 else:
709 n = top
710 d = 1 << -e
711 if value < 0:
712 n = -n
713 self.n = n
714 self.d = d
715 assert float(n) / float(d) == value
Tim Peters307fa782004-09-23 08:06:40 +0000716 else:
Walter Dörwalda0021592005-06-13 21:44:48 +0000717 raise TypeError("can't deal with %r" % val)
Tim Peters307fa782004-09-23 08:06:40 +0000718
Walter Dörwalda0021592005-06-13 21:44:48 +0000719 def __cmp__(self, other):
720 if not isinstance(other, Rat):
721 other = Rat(other)
722 return cmp(self.n * other.d, self.d * other.n)
Tim Peters307fa782004-09-23 08:06:40 +0000723
Walter Dörwalda0021592005-06-13 21:44:48 +0000724 cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200]
725 # 2**48 is an important boundary in the internals. 2**53 is an
726 # important boundary for IEEE double precision.
727 for t in 2.0**48, 2.0**50, 2.0**53:
728 cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0,
729 long(t-1), long(t), long(t+1)])
730 cases.extend([0, 1, 2, sys.maxint, float(sys.maxint)])
731 # 1L<<20000 should exceed all double formats. long(1e200) is to
732 # check that we get equality with 1e200 above.
733 t = long(1e200)
734 cases.extend([0L, 1L, 2L, 1L << 20000, t-1, t, t+1])
735 cases.extend([-x for x in cases])
736 for x in cases:
737 Rx = Rat(x)
738 for y in cases:
739 Ry = Rat(y)
740 Rcmp = cmp(Rx, Ry)
741 xycmp = cmp(x, y)
742 eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp))
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))
745 eq(x < y, Rcmp < 0, Frm("%r < %r %d", x, y, Rcmp))
746 eq(x <= y, Rcmp <= 0, Frm("%r <= %r %d", x, y, Rcmp))
747 eq(x > y, Rcmp > 0, Frm("%r > %r %d", x, y, Rcmp))
748 eq(x >= y, Rcmp >= 0, Frm("%r >= %r %d", x, y, Rcmp))
Tim Peters307fa782004-09-23 08:06:40 +0000749
Christian Heimes8267d1d2008-01-04 00:37:34 +0000750 def test_nan_inf(self):
751 self.assertRaises(OverflowError, long, float('inf'))
Mark Dickinsonb6467572008-08-04 21:30:09 +0000752 self.assertRaises(OverflowError, long, float('-inf'))
753 self.assertRaises(ValueError, long, float('nan'))
Christian Heimes8267d1d2008-01-04 00:37:34 +0000754
Walter Dörwalda0021592005-06-13 21:44:48 +0000755def test_main():
756 test_support.run_unittest(LongTest)
Tim Peters307fa782004-09-23 08:06:40 +0000757
Walter Dörwalda0021592005-06-13 21:44:48 +0000758if __name__ == "__main__":
759 test_main()