blob: f8afc9e80e19109d10f0e1f07c63a5890119fa46 [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
564 self.assertEqual(X()[-5L:7L], (-5, 7))
565 # use the clamping effect to test the smallest and largest longs
566 # that fit a Py_ssize_t
567 slicemin, slicemax = X()[-2L**100:2L**100]
568 self.assertEqual(X()[slicemin:slicemax], (slicemin, slicemax))
569
Tim Peters26c7fa32001-08-23 22:56:21 +0000570# ----------------------------------- tests of auto int->long conversion
571
Walter Dörwalda0021592005-06-13 21:44:48 +0000572 def test_auto_overflow(self):
573 import math, sys
Tim Peters26c7fa32001-08-23 22:56:21 +0000574
Walter Dörwalda0021592005-06-13 21:44:48 +0000575 special = [0, 1, 2, 3, sys.maxint-1, sys.maxint, sys.maxint+1]
576 sqrt = int(math.sqrt(sys.maxint))
577 special.extend([sqrt-1, sqrt, sqrt+1])
578 special.extend([-i for i in special])
Tim Peters26c7fa32001-08-23 22:56:21 +0000579
Walter Dörwalda0021592005-06-13 21:44:48 +0000580 def checkit(*args):
581 # Heavy use of nested scopes here!
582 self.assertEqual(got, expected,
583 Frm("for %r expected %r got %r", args, expected, got))
Tim Peters26c7fa32001-08-23 22:56:21 +0000584
Walter Dörwalda0021592005-06-13 21:44:48 +0000585 for x in special:
586 longx = long(x)
Tim Peters26c7fa32001-08-23 22:56:21 +0000587
Walter Dörwalda0021592005-06-13 21:44:48 +0000588 expected = -longx
589 got = -x
590 checkit('-', x)
Tim Peters26c7fa32001-08-23 22:56:21 +0000591
Walter Dörwalda0021592005-06-13 21:44:48 +0000592 for y in special:
593 longy = long(y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000594
Walter Dörwalda0021592005-06-13 21:44:48 +0000595 expected = longx + longy
596 got = x + y
597 checkit(x, '+', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000598
Walter Dörwalda0021592005-06-13 21:44:48 +0000599 expected = longx - longy
600 got = x - y
601 checkit(x, '-', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000602
Walter Dörwalda0021592005-06-13 21:44:48 +0000603 expected = longx * longy
604 got = x * y
605 checkit(x, '*', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000606
Walter Dörwalda0021592005-06-13 21:44:48 +0000607 if y:
608 expected = longx / longy
609 got = x / y
610 checkit(x, '/', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000611
Walter Dörwalda0021592005-06-13 21:44:48 +0000612 expected = longx // longy
613 got = x // y
614 checkit(x, '//', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000615
Walter Dörwalda0021592005-06-13 21:44:48 +0000616 expected = divmod(longx, longy)
617 got = divmod(longx, longy)
618 checkit(x, 'divmod', y)
Tim Petersa3653092001-08-23 23:02:57 +0000619
Walter Dörwalda0021592005-06-13 21:44:48 +0000620 if abs(y) < 5 and not (x == 0 and y < 0):
621 expected = longx ** longy
622 got = x ** y
623 checkit(x, '**', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000624
Walter Dörwalda0021592005-06-13 21:44:48 +0000625 for z in special:
626 if z != 0 :
627 if y >= 0:
628 expected = pow(longx, longy, long(z))
629 got = pow(x, y, z)
630 checkit('pow', x, y, '%', z)
Tim Peters32f453e2001-09-03 08:35:41 +0000631 else:
Walter Dörwalda0021592005-06-13 21:44:48 +0000632 self.assertRaises(TypeError, pow,longx, longy, long(z))
Tim Peters26c7fa32001-08-23 22:56:21 +0000633
Walter Dörwalda0021592005-06-13 21:44:48 +0000634 def test_float_overflow(self):
635 import math
Tim Peters9fffa3e2001-09-04 05:14:19 +0000636
Walter Dörwalda0021592005-06-13 21:44:48 +0000637 for x in -2.0, -1.0, 0.0, 1.0, 2.0:
638 self.assertEqual(float(long(x)), x)
Tim Peters9fffa3e2001-09-04 05:14:19 +0000639
Walter Dörwalda0021592005-06-13 21:44:48 +0000640 shuge = '12345' * 120
641 huge = 1L << 30000
642 mhuge = -huge
643 namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math}
644 for test in ["float(huge)", "float(mhuge)",
645 "complex(huge)", "complex(mhuge)",
646 "complex(huge, 1)", "complex(mhuge, 1)",
647 "complex(1, huge)", "complex(1, mhuge)",
648 "1. + huge", "huge + 1.", "1. + mhuge", "mhuge + 1.",
649 "1. - huge", "huge - 1.", "1. - mhuge", "mhuge - 1.",
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 "math.sin(huge)", "math.sin(mhuge)",
655 "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better
Jeffrey Yasskin9871d8f2008-01-05 08:47:13 +0000656 "math.floor(huge)", "math.floor(mhuge)"]:
Tim Peters9fffa3e2001-09-04 05:14:19 +0000657
Walter Dörwalda0021592005-06-13 21:44:48 +0000658 self.assertRaises(OverflowError, eval, test, namespace)
Tim Peters9fffa3e2001-09-04 05:14:19 +0000659
Walter Dörwalda0021592005-06-13 21:44:48 +0000660 # XXX Perhaps float(shuge) can raise OverflowError on some box?
661 # The comparison should not.
662 self.assertNotEqual(float(shuge), int(shuge),
663 "float(shuge) should not equal int(shuge)")
Tim Peters83e7ccc2001-09-04 06:37:28 +0000664
Walter Dörwalda0021592005-06-13 21:44:48 +0000665 def test_logs(self):
666 import math
Tim Peters78526162001-09-05 00:53:45 +0000667
Walter Dörwalda0021592005-06-13 21:44:48 +0000668 LOG10E = math.log10(math.e)
Tim Peters307fa782004-09-23 08:06:40 +0000669
Walter Dörwalda0021592005-06-13 21:44:48 +0000670 for exp in range(10) + [100, 1000, 10000]:
671 value = 10 ** exp
672 log10 = math.log10(value)
673 self.assertAlmostEqual(log10, exp)
Tim Peters78526162001-09-05 00:53:45 +0000674
Walter Dörwalda0021592005-06-13 21:44:48 +0000675 # log10(value) == exp, so log(value) == log10(value)/log10(e) ==
676 # exp/LOG10E
677 expected = exp / LOG10E
678 log = math.log(value)
679 self.assertAlmostEqual(log, expected)
Tim Peters78526162001-09-05 00:53:45 +0000680
Walter Dörwalda0021592005-06-13 21:44:48 +0000681 for bad in -(1L << 10000), -2L, 0L:
682 self.assertRaises(ValueError, math.log, bad)
683 self.assertRaises(ValueError, math.log10, bad)
Tim Peters78526162001-09-05 00:53:45 +0000684
Walter Dörwalda0021592005-06-13 21:44:48 +0000685 def test_mixed_compares(self):
686 eq = self.assertEqual
687 import math
Tim Peters78526162001-09-05 00:53:45 +0000688
Walter Dörwalda0021592005-06-13 21:44:48 +0000689 # We're mostly concerned with that mixing floats and longs does the
690 # right stuff, even when longs are too large to fit in a float.
691 # The safest way to check the results is to use an entirely different
692 # method, which we do here via a skeletal rational class (which
693 # represents all Python ints, longs and floats exactly).
694 class Rat:
695 def __init__(self, value):
696 if isinstance(value, (int, long)):
697 self.n = value
698 self.d = 1
699 elif isinstance(value, float):
700 # Convert to exact rational equivalent.
701 f, e = math.frexp(abs(value))
702 assert f == 0 or 0.5 <= f < 1.0
703 # |value| = f * 2**e exactly
Tim Peters78526162001-09-05 00:53:45 +0000704
Walter Dörwalda0021592005-06-13 21:44:48 +0000705 # Suck up CHUNK bits at a time; 28 is enough so that we suck
706 # up all bits in 2 iterations for all known binary double-
707 # precision formats, and small enough to fit in an int.
708 CHUNK = 28
709 top = 0
710 # invariant: |value| = (top + f) * 2**e exactly
711 while f:
712 f = math.ldexp(f, CHUNK)
713 digit = int(f)
714 assert digit >> CHUNK == 0
715 top = (top << CHUNK) | digit
716 f -= digit
717 assert 0.0 <= f < 1.0
718 e -= CHUNK
Tim Peters78526162001-09-05 00:53:45 +0000719
Walter Dörwalda0021592005-06-13 21:44:48 +0000720 # Now |value| = top * 2**e exactly.
721 if e >= 0:
722 n = top << e
723 d = 1
724 else:
725 n = top
726 d = 1 << -e
727 if value < 0:
728 n = -n
729 self.n = n
730 self.d = d
731 assert float(n) / float(d) == value
Tim Peters307fa782004-09-23 08:06:40 +0000732 else:
Georg Brandl708c4872010-02-07 12:01:19 +0000733 raise TypeError("can't deal with %r" % value)
Tim Peters307fa782004-09-23 08:06:40 +0000734
Walter Dörwalda0021592005-06-13 21:44:48 +0000735 def __cmp__(self, other):
736 if not isinstance(other, Rat):
737 other = Rat(other)
738 return cmp(self.n * other.d, self.d * other.n)
Tim Peters307fa782004-09-23 08:06:40 +0000739
Walter Dörwalda0021592005-06-13 21:44:48 +0000740 cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200]
741 # 2**48 is an important boundary in the internals. 2**53 is an
742 # important boundary for IEEE double precision.
743 for t in 2.0**48, 2.0**50, 2.0**53:
744 cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0,
745 long(t-1), long(t), long(t+1)])
746 cases.extend([0, 1, 2, sys.maxint, float(sys.maxint)])
747 # 1L<<20000 should exceed all double formats. long(1e200) is to
748 # check that we get equality with 1e200 above.
749 t = long(1e200)
750 cases.extend([0L, 1L, 2L, 1L << 20000, t-1, t, t+1])
751 cases.extend([-x for x in cases])
752 for x in cases:
753 Rx = Rat(x)
754 for y in cases:
755 Ry = Rat(y)
756 Rcmp = cmp(Rx, Ry)
757 xycmp = cmp(x, y)
758 eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp))
759 eq(x == y, Rcmp == 0, Frm("%r == %r %d", x, y, Rcmp))
760 eq(x != y, Rcmp != 0, Frm("%r != %r %d", x, y, Rcmp))
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))
Tim Peters307fa782004-09-23 08:06:40 +0000765
Christian Heimes8267d1d2008-01-04 00:37:34 +0000766 def test_nan_inf(self):
767 self.assertRaises(OverflowError, long, float('inf'))
Mark Dickinsonb6467572008-08-04 21:30:09 +0000768 self.assertRaises(OverflowError, long, float('-inf'))
769 self.assertRaises(ValueError, long, float('nan'))
Christian Heimes8267d1d2008-01-04 00:37:34 +0000770
Walter Dörwalda0021592005-06-13 21:44:48 +0000771def test_main():
772 test_support.run_unittest(LongTest)
Tim Peters307fa782004-09-23 08:06:40 +0000773
Walter Dörwalda0021592005-06-13 21:44:48 +0000774if __name__ == "__main__":
775 test_main()