blob: a6ed1cb111ba2a208f23a5bfa69cc1127f5db904 [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
Mark Dickinson804b9d42010-05-26 19:07:12 +0000326 # tests with base 0
327 self.assertEqual(long(' 0123 ', 0), 83)
328 self.assertEqual(long(' 0123 ', 0), 83)
329 self.assertEqual(long('000', 0), 0)
330 self.assertEqual(long('0o123', 0), 83)
331 self.assertEqual(long('0x123', 0), 291)
332 self.assertEqual(long('0b100', 0), 4)
333 self.assertEqual(long(' 0O123 ', 0), 83)
334 self.assertEqual(long(' 0X123 ', 0), 291)
335 self.assertEqual(long(' 0B100 ', 0), 4)
336 self.assertEqual(long('0', 0), 0)
337 self.assertEqual(long('+0', 0), 0)
338 self.assertEqual(long('-0', 0), 0)
339 self.assertEqual(long('00', 0), 0)
340 self.assertRaises(ValueError, long, '08', 0)
341 self.assertRaises(ValueError, long, '-012395', 0)
342
Benjamin Peterson979395b2008-05-03 21:35:18 +0000343 # SF patch #1638879: embedded NULs were not detected with
344 # explicit base
345 self.assertRaises(ValueError, long, '123\0', 10)
346 self.assertRaises(ValueError, long, '123\x00 245', 20)
347
348 self.assertEqual(long('100000000000000000000000000000000', 2),
349 4294967296)
350 self.assertEqual(long('102002022201221111211', 3), 4294967296)
351 self.assertEqual(long('10000000000000000', 4), 4294967296)
352 self.assertEqual(long('32244002423141', 5), 4294967296)
353 self.assertEqual(long('1550104015504', 6), 4294967296)
354 self.assertEqual(long('211301422354', 7), 4294967296)
355 self.assertEqual(long('40000000000', 8), 4294967296)
356 self.assertEqual(long('12068657454', 9), 4294967296)
357 self.assertEqual(long('4294967296', 10), 4294967296)
358 self.assertEqual(long('1904440554', 11), 4294967296)
359 self.assertEqual(long('9ba461594', 12), 4294967296)
360 self.assertEqual(long('535a79889', 13), 4294967296)
361 self.assertEqual(long('2ca5b7464', 14), 4294967296)
362 self.assertEqual(long('1a20dcd81', 15), 4294967296)
363 self.assertEqual(long('100000000', 16), 4294967296)
364 self.assertEqual(long('a7ffda91', 17), 4294967296)
365 self.assertEqual(long('704he7g4', 18), 4294967296)
366 self.assertEqual(long('4f5aff66', 19), 4294967296)
367 self.assertEqual(long('3723ai4g', 20), 4294967296)
368 self.assertEqual(long('281d55i4', 21), 4294967296)
369 self.assertEqual(long('1fj8b184', 22), 4294967296)
370 self.assertEqual(long('1606k7ic', 23), 4294967296)
371 self.assertEqual(long('mb994ag', 24), 4294967296)
372 self.assertEqual(long('hek2mgl', 25), 4294967296)
373 self.assertEqual(long('dnchbnm', 26), 4294967296)
374 self.assertEqual(long('b28jpdm', 27), 4294967296)
375 self.assertEqual(long('8pfgih4', 28), 4294967296)
376 self.assertEqual(long('76beigg', 29), 4294967296)
377 self.assertEqual(long('5qmcpqg', 30), 4294967296)
378 self.assertEqual(long('4q0jto4', 31), 4294967296)
379 self.assertEqual(long('4000000', 32), 4294967296)
380 self.assertEqual(long('3aokq94', 33), 4294967296)
381 self.assertEqual(long('2qhxjli', 34), 4294967296)
382 self.assertEqual(long('2br45qb', 35), 4294967296)
383 self.assertEqual(long('1z141z4', 36), 4294967296)
384
385 self.assertEqual(long('100000000000000000000000000000001', 2),
386 4294967297)
387 self.assertEqual(long('102002022201221111212', 3), 4294967297)
388 self.assertEqual(long('10000000000000001', 4), 4294967297)
389 self.assertEqual(long('32244002423142', 5), 4294967297)
390 self.assertEqual(long('1550104015505', 6), 4294967297)
391 self.assertEqual(long('211301422355', 7), 4294967297)
392 self.assertEqual(long('40000000001', 8), 4294967297)
393 self.assertEqual(long('12068657455', 9), 4294967297)
394 self.assertEqual(long('4294967297', 10), 4294967297)
395 self.assertEqual(long('1904440555', 11), 4294967297)
396 self.assertEqual(long('9ba461595', 12), 4294967297)
397 self.assertEqual(long('535a7988a', 13), 4294967297)
398 self.assertEqual(long('2ca5b7465', 14), 4294967297)
399 self.assertEqual(long('1a20dcd82', 15), 4294967297)
400 self.assertEqual(long('100000001', 16), 4294967297)
401 self.assertEqual(long('a7ffda92', 17), 4294967297)
402 self.assertEqual(long('704he7g5', 18), 4294967297)
403 self.assertEqual(long('4f5aff67', 19), 4294967297)
404 self.assertEqual(long('3723ai4h', 20), 4294967297)
405 self.assertEqual(long('281d55i5', 21), 4294967297)
406 self.assertEqual(long('1fj8b185', 22), 4294967297)
407 self.assertEqual(long('1606k7id', 23), 4294967297)
408 self.assertEqual(long('mb994ah', 24), 4294967297)
409 self.assertEqual(long('hek2mgm', 25), 4294967297)
410 self.assertEqual(long('dnchbnn', 26), 4294967297)
411 self.assertEqual(long('b28jpdn', 27), 4294967297)
412 self.assertEqual(long('8pfgih5', 28), 4294967297)
413 self.assertEqual(long('76beigh', 29), 4294967297)
414 self.assertEqual(long('5qmcpqh', 30), 4294967297)
415 self.assertEqual(long('4q0jto5', 31), 4294967297)
416 self.assertEqual(long('4000001', 32), 4294967297)
417 self.assertEqual(long('3aokq95', 33), 4294967297)
418 self.assertEqual(long('2qhxjlj', 34), 4294967297)
419 self.assertEqual(long('2br45qc', 35), 4294967297)
420 self.assertEqual(long('1z141z5', 36), 4294967297)
421
422
423 def test_conversion(self):
424 # Test __long__()
425 class ClassicMissingMethods:
426 pass
427 self.assertRaises(AttributeError, long, ClassicMissingMethods())
428
429 class MissingMethods(object):
430 pass
431 self.assertRaises(TypeError, long, MissingMethods())
432
433 class Foo0:
434 def __long__(self):
435 return 42L
436
437 class Foo1(object):
438 def __long__(self):
439 return 42L
440
441 class Foo2(long):
442 def __long__(self):
443 return 42L
444
445 class Foo3(long):
446 def __long__(self):
447 return self
448
449 class Foo4(long):
450 def __long__(self):
451 return 42
452
453 class Foo5(long):
454 def __long__(self):
455 return 42.
456
457 self.assertEqual(long(Foo0()), 42L)
458 self.assertEqual(long(Foo1()), 42L)
459 self.assertEqual(long(Foo2()), 42L)
460 self.assertEqual(long(Foo3()), 0)
461 self.assertEqual(long(Foo4()), 42)
462 self.assertRaises(TypeError, long, Foo5())
463
464 class Classic:
465 pass
466 for base in (object, Classic):
467 class LongOverridesTrunc(base):
468 def __long__(self):
469 return 42
470 def __trunc__(self):
471 return -12
472 self.assertEqual(long(LongOverridesTrunc()), 42)
473
474 class JustTrunc(base):
475 def __trunc__(self):
476 return 42
477 self.assertEqual(long(JustTrunc()), 42)
478
479 for trunc_result_base in (object, Classic):
480 class Integral(trunc_result_base):
481 def __int__(self):
482 return 42
483
484 class TruncReturnsNonLong(base):
485 def __trunc__(self):
486 return Integral()
487 self.assertEqual(long(TruncReturnsNonLong()), 42)
488
489 class NonIntegral(trunc_result_base):
490 def __trunc__(self):
491 # Check that we avoid infinite recursion.
492 return NonIntegral()
493
494 class TruncReturnsNonIntegral(base):
495 def __trunc__(self):
496 return NonIntegral()
497 try:
498 long(TruncReturnsNonIntegral())
499 except TypeError as e:
500 self.assertEquals(str(e),
501 "__trunc__ returned non-Integral"
502 " (type NonIntegral)")
503 else:
504 self.fail("Failed to raise TypeError with %s" %
505 ((base, trunc_result_base),))
506
Walter Dörwalda0021592005-06-13 21:44:48 +0000507 def test_misc(self):
Guido van Rossum4365cab1998-08-13 14:20:17 +0000508
Walter Dörwalda0021592005-06-13 21:44:48 +0000509 # check the extremes in int<->long conversion
510 hugepos = sys.maxint
511 hugeneg = -hugepos - 1
512 hugepos_aslong = long(hugepos)
513 hugeneg_aslong = long(hugeneg)
514 self.assertEqual(hugepos, hugepos_aslong, "long(sys.maxint) != sys.maxint")
515 self.assertEqual(hugeneg, hugeneg_aslong,
516 "long(-sys.maxint-1) != -sys.maxint-1")
Guido van Rossum4365cab1998-08-13 14:20:17 +0000517
Walter Dörwalda0021592005-06-13 21:44:48 +0000518 # long -> int should not fail for hugepos_aslong or hugeneg_aslong
Armin Rigo7ccbca92006-10-04 12:17:45 +0000519 x = int(hugepos_aslong)
Walter Dörwalda0021592005-06-13 21:44:48 +0000520 try:
Armin Rigo7ccbca92006-10-04 12:17:45 +0000521 self.assertEqual(x, hugepos,
Walter Dörwalda0021592005-06-13 21:44:48 +0000522 "converting sys.maxint to long and back to int fails")
523 except OverflowError:
524 self.fail("int(long(sys.maxint)) overflowed!")
Armin Rigo7ccbca92006-10-04 12:17:45 +0000525 if not isinstance(x, int):
Georg Brandl708c4872010-02-07 12:01:19 +0000526 self.fail("int(long(sys.maxint)) should have returned int")
Armin Rigo7ccbca92006-10-04 12:17:45 +0000527 x = int(hugeneg_aslong)
Walter Dörwalda0021592005-06-13 21:44:48 +0000528 try:
Armin Rigo7ccbca92006-10-04 12:17:45 +0000529 self.assertEqual(x, hugeneg,
Walter Dörwalda0021592005-06-13 21:44:48 +0000530 "converting -sys.maxint-1 to long and back to int fails")
531 except OverflowError:
532 self.fail("int(long(-sys.maxint-1)) overflowed!")
Armin Rigo7ccbca92006-10-04 12:17:45 +0000533 if not isinstance(x, int):
Georg Brandl708c4872010-02-07 12:01:19 +0000534 self.fail("int(long(-sys.maxint-1)) should have returned int")
Walter Dörwalda0021592005-06-13 21:44:48 +0000535 # but long -> int should overflow for hugepos+1 and hugeneg-1
536 x = hugepos_aslong + 1
537 try:
538 y = int(x)
539 except OverflowError:
540 self.fail("int(long(sys.maxint) + 1) mustn't overflow")
541 self.assert_(isinstance(y, long),
542 "int(long(sys.maxint) + 1) should have returned long")
Guido van Rossum4365cab1998-08-13 14:20:17 +0000543
Walter Dörwalda0021592005-06-13 21:44:48 +0000544 x = hugeneg_aslong - 1
545 try:
546 y = int(x)
547 except OverflowError:
548 self.fail("int(long(-sys.maxint-1) - 1) mustn't overflow")
549 self.assert_(isinstance(y, long),
550 "int(long(-sys.maxint-1) - 1) should have returned long")
Guido van Rossum4365cab1998-08-13 14:20:17 +0000551
Walter Dörwalda0021592005-06-13 21:44:48 +0000552 class long2(long):
553 pass
554 x = long2(1L<<100)
Walter Dörwaldf1715402002-11-19 20:49:15 +0000555 y = int(x)
Walter Dörwalda0021592005-06-13 21:44:48 +0000556 self.assert_(type(y) is long,
557 "overflowing int conversion must return long not long subtype")
Guido van Rossum4581a0c1998-10-02 01:19:48 +0000558
Armin Rigo7ccbca92006-10-04 12:17:45 +0000559 # long -> Py_ssize_t conversion
560 class X(object):
561 def __getslice__(self, i, j):
562 return i, j
563
Ezio Melottia65e2af2010-08-02 19:56:05 +0000564 with test_support._check_py3k_warnings():
565 self.assertEqual(X()[-5L:7L], (-5, 7))
566 # use the clamping effect to test the smallest and largest longs
567 # that fit a Py_ssize_t
568 slicemin, slicemax = X()[-2L**100:2L**100]
569 self.assertEqual(X()[slicemin:slicemax], (slicemin, slicemax))
Armin Rigo7ccbca92006-10-04 12:17:45 +0000570
Tim Peters26c7fa32001-08-23 22:56:21 +0000571# ----------------------------------- tests of auto int->long conversion
572
Walter Dörwalda0021592005-06-13 21:44:48 +0000573 def test_auto_overflow(self):
574 import math, sys
Tim Peters26c7fa32001-08-23 22:56:21 +0000575
Walter Dörwalda0021592005-06-13 21:44:48 +0000576 special = [0, 1, 2, 3, sys.maxint-1, sys.maxint, sys.maxint+1]
577 sqrt = int(math.sqrt(sys.maxint))
578 special.extend([sqrt-1, sqrt, sqrt+1])
579 special.extend([-i for i in special])
Tim Peters26c7fa32001-08-23 22:56:21 +0000580
Walter Dörwalda0021592005-06-13 21:44:48 +0000581 def checkit(*args):
582 # Heavy use of nested scopes here!
583 self.assertEqual(got, expected,
584 Frm("for %r expected %r got %r", args, expected, got))
Tim Peters26c7fa32001-08-23 22:56:21 +0000585
Walter Dörwalda0021592005-06-13 21:44:48 +0000586 for x in special:
587 longx = long(x)
Tim Peters26c7fa32001-08-23 22:56:21 +0000588
Walter Dörwalda0021592005-06-13 21:44:48 +0000589 expected = -longx
590 got = -x
591 checkit('-', x)
Tim Peters26c7fa32001-08-23 22:56:21 +0000592
Walter Dörwalda0021592005-06-13 21:44:48 +0000593 for y in special:
594 longy = long(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 = longx - longy
601 got = x - y
602 checkit(x, '-', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000603
Walter Dörwalda0021592005-06-13 21:44:48 +0000604 expected = longx * longy
605 got = x * y
606 checkit(x, '*', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000607
Walter Dörwalda0021592005-06-13 21:44:48 +0000608 if y:
Ezio Melottia65e2af2010-08-02 19:56:05 +0000609 with test_support._check_py3k_warnings():
610 expected = longx / longy
611 got = x / y
Walter Dörwalda0021592005-06-13 21:44:48 +0000612 checkit(x, '/', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000613
Walter Dörwalda0021592005-06-13 21:44:48 +0000614 expected = longx // longy
615 got = x // y
616 checkit(x, '//', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000617
Walter Dörwalda0021592005-06-13 21:44:48 +0000618 expected = divmod(longx, longy)
619 got = divmod(longx, longy)
620 checkit(x, 'divmod', y)
Tim Petersa3653092001-08-23 23:02:57 +0000621
Walter Dörwalda0021592005-06-13 21:44:48 +0000622 if abs(y) < 5 and not (x == 0 and y < 0):
623 expected = longx ** longy
624 got = x ** y
625 checkit(x, '**', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000626
Walter Dörwalda0021592005-06-13 21:44:48 +0000627 for z in special:
628 if z != 0 :
629 if y >= 0:
630 expected = pow(longx, longy, long(z))
631 got = pow(x, y, z)
632 checkit('pow', x, y, '%', z)
Tim Peters32f453e2001-09-03 08:35:41 +0000633 else:
Walter Dörwalda0021592005-06-13 21:44:48 +0000634 self.assertRaises(TypeError, pow,longx, longy, long(z))
Tim Peters26c7fa32001-08-23 22:56:21 +0000635
Walter Dörwalda0021592005-06-13 21:44:48 +0000636 def test_float_overflow(self):
637 import math
Tim Peters9fffa3e2001-09-04 05:14:19 +0000638
Walter Dörwalda0021592005-06-13 21:44:48 +0000639 for x in -2.0, -1.0, 0.0, 1.0, 2.0:
640 self.assertEqual(float(long(x)), x)
Tim Peters9fffa3e2001-09-04 05:14:19 +0000641
Walter Dörwalda0021592005-06-13 21:44:48 +0000642 shuge = '12345' * 120
643 huge = 1L << 30000
644 mhuge = -huge
645 namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math}
646 for test in ["float(huge)", "float(mhuge)",
647 "complex(huge)", "complex(mhuge)",
648 "complex(huge, 1)", "complex(mhuge, 1)",
649 "complex(1, huge)", "complex(1, mhuge)",
650 "1. + huge", "huge + 1.", "1. + mhuge", "mhuge + 1.",
651 "1. - huge", "huge - 1.", "1. - mhuge", "mhuge - 1.",
652 "1. * huge", "huge * 1.", "1. * mhuge", "mhuge * 1.",
653 "1. // huge", "huge // 1.", "1. // mhuge", "mhuge // 1.",
654 "1. / huge", "huge / 1.", "1. / mhuge", "mhuge / 1.",
655 "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.",
656 "math.sin(huge)", "math.sin(mhuge)",
657 "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better
Jeffrey Yasskin9871d8f2008-01-05 08:47:13 +0000658 "math.floor(huge)", "math.floor(mhuge)"]:
Tim Peters9fffa3e2001-09-04 05:14:19 +0000659
Walter Dörwalda0021592005-06-13 21:44:48 +0000660 self.assertRaises(OverflowError, eval, test, namespace)
Tim Peters9fffa3e2001-09-04 05:14:19 +0000661
Walter Dörwalda0021592005-06-13 21:44:48 +0000662 # XXX Perhaps float(shuge) can raise OverflowError on some box?
663 # The comparison should not.
664 self.assertNotEqual(float(shuge), int(shuge),
665 "float(shuge) should not equal int(shuge)")
Tim Peters83e7ccc2001-09-04 06:37:28 +0000666
Walter Dörwalda0021592005-06-13 21:44:48 +0000667 def test_logs(self):
668 import math
Tim Peters78526162001-09-05 00:53:45 +0000669
Walter Dörwalda0021592005-06-13 21:44:48 +0000670 LOG10E = math.log10(math.e)
Tim Peters307fa782004-09-23 08:06:40 +0000671
Walter Dörwalda0021592005-06-13 21:44:48 +0000672 for exp in range(10) + [100, 1000, 10000]:
673 value = 10 ** exp
674 log10 = math.log10(value)
675 self.assertAlmostEqual(log10, exp)
Tim Peters78526162001-09-05 00:53:45 +0000676
Walter Dörwalda0021592005-06-13 21:44:48 +0000677 # log10(value) == exp, so log(value) == log10(value)/log10(e) ==
678 # exp/LOG10E
679 expected = exp / LOG10E
680 log = math.log(value)
681 self.assertAlmostEqual(log, expected)
Tim Peters78526162001-09-05 00:53:45 +0000682
Walter Dörwalda0021592005-06-13 21:44:48 +0000683 for bad in -(1L << 10000), -2L, 0L:
684 self.assertRaises(ValueError, math.log, bad)
685 self.assertRaises(ValueError, math.log10, bad)
Tim Peters78526162001-09-05 00:53:45 +0000686
Walter Dörwalda0021592005-06-13 21:44:48 +0000687 def test_mixed_compares(self):
688 eq = self.assertEqual
689 import math
Tim Peters78526162001-09-05 00:53:45 +0000690
Walter Dörwalda0021592005-06-13 21:44:48 +0000691 # We're mostly concerned with that mixing floats and longs does the
692 # right stuff, even when longs are too large to fit in a float.
693 # The safest way to check the results is to use an entirely different
694 # method, which we do here via a skeletal rational class (which
695 # represents all Python ints, longs and floats exactly).
696 class Rat:
697 def __init__(self, value):
698 if isinstance(value, (int, long)):
699 self.n = value
700 self.d = 1
701 elif isinstance(value, float):
702 # Convert to exact rational equivalent.
703 f, e = math.frexp(abs(value))
704 assert f == 0 or 0.5 <= f < 1.0
705 # |value| = f * 2**e exactly
Tim Peters78526162001-09-05 00:53:45 +0000706
Walter Dörwalda0021592005-06-13 21:44:48 +0000707 # Suck up CHUNK bits at a time; 28 is enough so that we suck
708 # up all bits in 2 iterations for all known binary double-
709 # precision formats, and small enough to fit in an int.
710 CHUNK = 28
711 top = 0
712 # invariant: |value| = (top + f) * 2**e exactly
713 while f:
714 f = math.ldexp(f, CHUNK)
715 digit = int(f)
716 assert digit >> CHUNK == 0
717 top = (top << CHUNK) | digit
718 f -= digit
719 assert 0.0 <= f < 1.0
720 e -= CHUNK
Tim Peters78526162001-09-05 00:53:45 +0000721
Walter Dörwalda0021592005-06-13 21:44:48 +0000722 # Now |value| = top * 2**e exactly.
723 if e >= 0:
724 n = top << e
725 d = 1
726 else:
727 n = top
728 d = 1 << -e
729 if value < 0:
730 n = -n
731 self.n = n
732 self.d = d
733 assert float(n) / float(d) == value
Tim Peters307fa782004-09-23 08:06:40 +0000734 else:
Georg Brandl708c4872010-02-07 12:01:19 +0000735 raise TypeError("can't deal with %r" % value)
Tim Peters307fa782004-09-23 08:06:40 +0000736
Walter Dörwalda0021592005-06-13 21:44:48 +0000737 def __cmp__(self, other):
738 if not isinstance(other, Rat):
739 other = Rat(other)
740 return cmp(self.n * other.d, self.d * other.n)
Tim Peters307fa782004-09-23 08:06:40 +0000741
Walter Dörwalda0021592005-06-13 21:44:48 +0000742 cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200]
743 # 2**48 is an important boundary in the internals. 2**53 is an
744 # important boundary for IEEE double precision.
745 for t in 2.0**48, 2.0**50, 2.0**53:
746 cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0,
747 long(t-1), long(t), long(t+1)])
748 cases.extend([0, 1, 2, sys.maxint, float(sys.maxint)])
749 # 1L<<20000 should exceed all double formats. long(1e200) is to
750 # check that we get equality with 1e200 above.
751 t = long(1e200)
752 cases.extend([0L, 1L, 2L, 1L << 20000, t-1, t, t+1])
753 cases.extend([-x for x in cases])
754 for x in cases:
755 Rx = Rat(x)
756 for y in cases:
757 Ry = Rat(y)
758 Rcmp = cmp(Rx, Ry)
759 xycmp = cmp(x, y)
760 eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp))
761 eq(x == y, Rcmp == 0, Frm("%r == %r %d", x, y, Rcmp))
762 eq(x != y, Rcmp != 0, Frm("%r != %r %d", x, y, Rcmp))
763 eq(x < y, Rcmp < 0, Frm("%r < %r %d", x, y, Rcmp))
764 eq(x <= y, Rcmp <= 0, Frm("%r <= %r %d", x, y, Rcmp))
765 eq(x > y, Rcmp > 0, Frm("%r > %r %d", x, y, Rcmp))
766 eq(x >= y, Rcmp >= 0, Frm("%r >= %r %d", x, y, Rcmp))
Tim Peters307fa782004-09-23 08:06:40 +0000767
Christian Heimes8267d1d2008-01-04 00:37:34 +0000768 def test_nan_inf(self):
769 self.assertRaises(OverflowError, long, float('inf'))
Mark Dickinsonb6467572008-08-04 21:30:09 +0000770 self.assertRaises(OverflowError, long, float('-inf'))
771 self.assertRaises(ValueError, long, float('nan'))
Christian Heimes8267d1d2008-01-04 00:37:34 +0000772
Walter Dörwalda0021592005-06-13 21:44:48 +0000773def test_main():
774 test_support.run_unittest(LongTest)
Tim Peters307fa782004-09-23 08:06:40 +0000775
Walter Dörwalda0021592005-06-13 21:44:48 +0000776if __name__ == "__main__":
777 test_main()