blob: e648c0fa1606c2d7471fa66ca649b28e25270bf9 [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
Mark Dickinson1a707982008-12-17 16:14:37 +00006import math
Walter Dörwalda0021592005-06-13 21:44:48 +00007
8# Used for lazy formatting of failure messages
9class Frm(object):
10 def __init__(self, format, *args):
11 self.format = format
12 self.args = args
13
14 def __str__(self):
15 return self.format % self.args
Guido van Rossum4365cab1998-08-13 14:20:17 +000016
17# SHIFT should match the value in longintrepr.h for best testing.
18SHIFT = 15
19BASE = 2 ** SHIFT
20MASK = BASE - 1
Tim Petersdaec9612004-08-30 23:18:23 +000021KARATSUBA_CUTOFF = 70 # from longobject.c
Guido van Rossum4365cab1998-08-13 14:20:17 +000022
23# Max number of base BASE digits to use in test cases. Doubling
Tim Peters28b0e2a2002-08-13 02:17:11 +000024# this will more than double the runtime.
25MAXDIGITS = 15
Guido van Rossum4365cab1998-08-13 14:20:17 +000026
Guido van Rossum4581a0c1998-10-02 01:19:48 +000027# build some special values
28special = map(long, [0, 1, 2, BASE, BASE >> 1])
29special.append(0x5555555555555555L)
30special.append(0xaaaaaaaaaaaaaaaaL)
31# some solid strings of one bits
32p2 = 4L # 0 and 1 already added
33for i in range(2*SHIFT):
34 special.append(p2 - 1)
35 p2 = p2 << 1
36del p2
37# add complements & negations
38special = special + map(lambda x: ~x, special) + \
39 map(lambda x: -x, special)
40
Benjamin Peterson979395b2008-05-03 21:35:18 +000041L = [
42 ('0', 0),
43 ('1', 1),
44 ('9', 9),
45 ('10', 10),
46 ('99', 99),
47 ('100', 100),
48 ('314', 314),
49 (' 314', 314),
50 ('314 ', 314),
51 (' \t\t 314 \t\t ', 314),
52 (repr(sys.maxint), sys.maxint),
53 (' 1x', ValueError),
54 (' 1 ', 1),
55 (' 1\02 ', ValueError),
56 ('', ValueError),
57 (' ', ValueError),
58 (' \t\t ', ValueError)
59]
60if test_support.have_unicode:
61 L += [
62 (unicode('0'), 0),
63 (unicode('1'), 1),
64 (unicode('9'), 9),
65 (unicode('10'), 10),
66 (unicode('99'), 99),
67 (unicode('100'), 100),
68 (unicode('314'), 314),
69 (unicode(' 314'), 314),
70 (unicode('\u0663\u0661\u0664 ','raw-unicode-escape'), 314),
71 (unicode(' \t\t 314 \t\t '), 314),
72 (unicode(' 1x'), ValueError),
73 (unicode(' 1 '), 1),
74 (unicode(' 1\02 '), ValueError),
75 (unicode(''), ValueError),
76 (unicode(' '), ValueError),
77 (unicode(' \t\t '), ValueError),
78 (unichr(0x200), ValueError),
79]
80
Guido van Rossum4365cab1998-08-13 14:20:17 +000081
Walter Dörwalda0021592005-06-13 21:44:48 +000082class LongTest(unittest.TestCase):
Guido van Rossum4365cab1998-08-13 14:20:17 +000083
Walter Dörwalda0021592005-06-13 21:44:48 +000084 # Get quasi-random long consisting of ndigits digits (in base BASE).
85 # quasi == the most-significant digit will not be 0, and the number
86 # is constructed to contain long strings of 0 and 1 bits. These are
87 # more likely than random bits to provoke digit-boundary errors.
88 # The sign of the number is also random.
Guido van Rossum4365cab1998-08-13 14:20:17 +000089
Walter Dörwalda0021592005-06-13 21:44:48 +000090 def getran(self, ndigits):
91 self.assert_(ndigits > 0)
92 nbits_hi = ndigits * SHIFT
93 nbits_lo = nbits_hi - SHIFT + 1
94 answer = 0L
95 nbits = 0
96 r = int(random.random() * (SHIFT * 2)) | 1 # force 1 bits to start
97 while nbits < nbits_lo:
98 bits = (r >> 1) + 1
99 bits = min(bits, nbits_hi - nbits)
100 self.assert_(1 <= bits <= SHIFT)
101 nbits = nbits + bits
102 answer = answer << bits
103 if r & 1:
104 answer = answer | ((1 << bits) - 1)
105 r = int(random.random() * (SHIFT * 2))
106 self.assert_(nbits_lo <= nbits <= nbits_hi)
107 if random.random() < 0.5:
108 answer = -answer
109 return answer
Guido van Rossum4581a0c1998-10-02 01:19:48 +0000110
Walter Dörwalda0021592005-06-13 21:44:48 +0000111 # Get random long consisting of ndigits random digits (relative to base
112 # BASE). The sign bit is also random.
Guido van Rossum4581a0c1998-10-02 01:19:48 +0000113
Walter Dörwalda0021592005-06-13 21:44:48 +0000114 def getran2(ndigits):
115 answer = 0L
116 for i in xrange(ndigits):
117 answer = (answer << SHIFT) | random.randint(0, MASK)
118 if random.random() < 0.5:
119 answer = -answer
120 return answer
Guido van Rossum4365cab1998-08-13 14:20:17 +0000121
Walter Dörwalda0021592005-06-13 21:44:48 +0000122 def check_division(self, x, y):
123 eq = self.assertEqual
124 q, r = divmod(x, y)
125 q2, r2 = x//y, x%y
126 pab, pba = x*y, y*x
127 eq(pab, pba, Frm("multiplication does not commute for %r and %r", x, y))
128 eq(q, q2, Frm("divmod returns different quotient than / for %r and %r", x, y))
129 eq(r, r2, Frm("divmod returns different mod than %% for %r and %r", x, y))
130 eq(x, q*y + r, Frm("x != q*y + r after divmod on x=%r, y=%r", x, y))
131 if y > 0:
132 self.assert_(0 <= r < y, Frm("bad mod from divmod on %r and %r", x, y))
133 else:
134 self.assert_(y < r <= 0, Frm("bad mod from divmod on %r and %r", x, y))
Guido van Rossum4365cab1998-08-13 14:20:17 +0000135
Walter Dörwalda0021592005-06-13 21:44:48 +0000136 def test_division(self):
137 digits = range(1, MAXDIGITS+1) + range(KARATSUBA_CUTOFF,
138 KARATSUBA_CUTOFF + 14)
139 digits.append(KARATSUBA_CUTOFF * 3)
140 for lenx in digits:
141 x = self.getran(lenx)
142 for leny in digits:
143 y = self.getran(leny) or 1L
144 self.check_division(x, y)
Guido van Rossum4365cab1998-08-13 14:20:17 +0000145
Walter Dörwalda0021592005-06-13 21:44:48 +0000146 def test_karatsuba(self):
147 digits = range(1, 5) + range(KARATSUBA_CUTOFF, KARATSUBA_CUTOFF + 10)
148 digits.extend([KARATSUBA_CUTOFF * 10, KARATSUBA_CUTOFF * 100])
Guido van Rossum4365cab1998-08-13 14:20:17 +0000149
Walter Dörwalda0021592005-06-13 21:44:48 +0000150 bits = [digit * SHIFT for digit in digits]
Guido van Rossum4365cab1998-08-13 14:20:17 +0000151
Walter Dörwalda0021592005-06-13 21:44:48 +0000152 # Test products of long strings of 1 bits -- (2**x-1)*(2**y-1) ==
153 # 2**(x+y) - 2**x - 2**y + 1, so the proper result is easy to check.
154 for abits in bits:
155 a = (1L << abits) - 1
156 for bbits in bits:
157 if bbits < abits:
158 continue
159 b = (1L << bbits) - 1
160 x = a * b
161 y = ((1L << (abits + bbits)) -
162 (1L << abits) -
163 (1L << bbits) +
164 1)
165 self.assertEqual(x, y,
166 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 +0000167
Walter Dörwalda0021592005-06-13 21:44:48 +0000168 def check_bitop_identities_1(self, x):
169 eq = self.assertEqual
170 eq(x & 0, 0, Frm("x & 0 != 0 for x=%r", x))
171 eq(x | 0, x, Frm("x | 0 != x for x=%r", x))
172 eq(x ^ 0, x, Frm("x ^ 0 != x for x=%r", x))
173 eq(x & -1, x, Frm("x & -1 != x for x=%r", x))
174 eq(x | -1, -1, Frm("x | -1 != -1 for x=%r", x))
175 eq(x ^ -1, ~x, Frm("x ^ -1 != ~x for x=%r", x))
176 eq(x, ~~x, Frm("x != ~~x for x=%r", x))
177 eq(x & x, x, Frm("x & x != x for x=%r", x))
178 eq(x | x, x, Frm("x | x != x for x=%r", x))
179 eq(x ^ x, 0, Frm("x ^ x != 0 for x=%r", x))
180 eq(x & ~x, 0, Frm("x & ~x != 0 for x=%r", x))
181 eq(x | ~x, -1, Frm("x | ~x != -1 for x=%r", x))
182 eq(x ^ ~x, -1, Frm("x ^ ~x != -1 for x=%r", x))
183 eq(-x, 1 + ~x, Frm("not -x == 1 + ~x for x=%r", x))
184 eq(-x, ~(x-1), Frm("not -x == ~(x-1) forx =%r", x))
185 for n in xrange(2*SHIFT):
186 p2 = 2L ** n
187 eq(x << n >> n, x,
188 Frm("x << n >> n != x for x=%r, n=%r", (x, n)))
189 eq(x // p2, x >> n,
190 Frm("x // p2 != x >> n for x=%r n=%r p2=%r", (x, n, p2)))
191 eq(x * p2, x << n,
192 Frm("x * p2 != x << n for x=%r n=%r p2=%r", (x, n, p2)))
193 eq(x & -p2, x >> n << n,
194 Frm("not x & -p2 == x >> n << n for x=%r n=%r p2=%r", (x, n, p2)))
195 eq(x & -p2, x & ~(p2 - 1),
196 Frm("not x & -p2 == x & ~(p2 - 1) for x=%r n=%r p2=%r", (x, n, p2)))
Tim Peters7f270ba2002-08-13 21:06:55 +0000197
Walter Dörwalda0021592005-06-13 21:44:48 +0000198 def check_bitop_identities_2(self, x, y):
199 eq = self.assertEqual
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, y ^ x, Frm("x ^ y != y ^ x 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), Frm("x | y != ~(~x & ~y) for x=%r, y=%r", (x, y)))
206 eq(x ^ y, (x | y) & ~(x & y),
207 Frm("x ^ y != (x | y) & ~(x & y) for x=%r, y=%r", (x, y)))
208 eq(x ^ y, (x & ~y) | (~x & y),
209 Frm("x ^ y == (x & ~y) | (~x & y) for x=%r, y=%r", (x, y)))
210 eq(x ^ y, (x | y) & (~x | ~y),
211 Frm("x ^ y == (x | y) & (~x | ~y) for x=%r, y=%r", (x, y)))
Tim Peters7f270ba2002-08-13 21:06:55 +0000212
Walter Dörwalda0021592005-06-13 21:44:48 +0000213 def check_bitop_identities_3(self, x, y, z):
214 eq = self.assertEqual
215 eq((x & y) & z, x & (y & z),
216 Frm("(x & y) & z != x & (y & z) for x=%r, y=%r, z=%r", (x, y, z)))
217 eq((x | y) | z, x | (y | z),
218 Frm("(x | y) | z != x | (y | z) for x=%r, y=%r, z=%r", (x, y, z)))
219 eq((x ^ y) ^ z, x ^ (y ^ z),
220 Frm("(x ^ y) ^ z != x ^ (y ^ z) for x=%r, y=%r, z=%r", (x, y, z)))
221 eq(x & (y | z), (x & y) | (x & z),
222 Frm("x & (y | z) != (x & y) | (x & z) for x=%r, y=%r, z=%r", (x, y, z)))
223 eq(x | (y & z), (x | y) & (x | z),
224 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 +0000225
Walter Dörwalda0021592005-06-13 21:44:48 +0000226 def test_bitop_identities(self):
227 for x in special:
228 self.check_bitop_identities_1(x)
229 digits = xrange(1, MAXDIGITS+1)
230 for lenx in digits:
231 x = self.getran(lenx)
232 self.check_bitop_identities_1(x)
233 for leny in digits:
234 y = self.getran(leny)
235 self.check_bitop_identities_2(x, y)
236 self.check_bitop_identities_3(x, y, self.getran((lenx + leny)//2))
Guido van Rossum4365cab1998-08-13 14:20:17 +0000237
Walter Dörwalda0021592005-06-13 21:44:48 +0000238 def slow_format(self, x, base):
239 if (x, base) == (0, 8):
240 # this is an oddball!
241 return "0L"
242 digits = []
243 sign = 0
244 if x < 0:
245 sign, x = 1, -x
246 while x:
247 x, r = divmod(x, base)
248 digits.append(int(r))
249 digits.reverse()
250 digits = digits or [0]
251 return '-'[:sign] + \
252 {8: '0', 10: '', 16: '0x'}[base] + \
Raymond Hettinger3296e692005-06-29 23:29:56 +0000253 "".join(map(lambda i: "0123456789abcdef"[i], digits)) + "L"
Guido van Rossum4365cab1998-08-13 14:20:17 +0000254
Walter Dörwalda0021592005-06-13 21:44:48 +0000255 def check_format_1(self, x):
256 for base, mapper in (8, oct), (10, repr), (16, hex):
257 got = mapper(x)
258 expected = self.slow_format(x, base)
259 msg = Frm("%s returned %r but expected %r for %r",
260 mapper.__name__, got, expected, x)
261 self.assertEqual(got, expected, msg)
262 self.assertEqual(long(got, 0), x, Frm('long("%s", 0) != %r', got, x))
263 # str() has to be checked a little differently since there's no
264 # trailing "L"
265 got = str(x)
266 expected = self.slow_format(x, 10)[:-1]
267 msg = Frm("%s returned %r but expected %r for %r",
268 mapper.__name__, got, expected, x)
269 self.assertEqual(got, expected, msg)
Guido van Rossum4365cab1998-08-13 14:20:17 +0000270
Walter Dörwalda0021592005-06-13 21:44:48 +0000271 def test_format(self):
272 for x in special:
273 self.check_format_1(x)
274 for i in xrange(10):
275 for lenx in xrange(1, MAXDIGITS+1):
276 x = self.getran(lenx)
277 self.check_format_1(x)
Guido van Rossum4365cab1998-08-13 14:20:17 +0000278
Benjamin Peterson979395b2008-05-03 21:35:18 +0000279 def test_long(self):
280 self.assertEqual(long(314), 314L)
281 self.assertEqual(long(3.14), 3L)
282 self.assertEqual(long(314L), 314L)
Amaury Forgeot d'Arcd3ffb892008-09-09 07:24:30 +0000283 # Check that long() of basic types actually returns a long
284 self.assertEqual(type(long(314)), long)
285 self.assertEqual(type(long(3.14)), long)
286 self.assertEqual(type(long(314L)), long)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000287 # Check that conversion from float truncates towards zero
288 self.assertEqual(long(-3.14), -3L)
289 self.assertEqual(long(3.9), 3L)
290 self.assertEqual(long(-3.9), -3L)
291 self.assertEqual(long(3.5), 3L)
292 self.assertEqual(long(-3.5), -3L)
293 self.assertEqual(long("-3"), -3L)
294 if test_support.have_unicode:
295 self.assertEqual(long(unicode("-3")), -3L)
296 # Different base:
297 self.assertEqual(long("10",16), 16L)
298 if test_support.have_unicode:
299 self.assertEqual(long(unicode("10"),16), 16L)
300 # Check conversions from string (same test set as for int(), and then some)
301 LL = [
302 ('1' + '0'*20, 10L**20),
303 ('1' + '0'*100, 10L**100)
304 ]
305 L2 = L[:]
306 if test_support.have_unicode:
307 L2 += [
308 (unicode('1') + unicode('0')*20, 10L**20),
309 (unicode('1') + unicode('0')*100, 10L**100),
310 ]
311 for s, v in L2 + LL:
312 for sign in "", "+", "-":
313 for prefix in "", " ", "\t", " \t\t ":
314 ss = prefix + sign + s
315 vv = v
316 if sign == "-" and v is not ValueError:
317 vv = -v
318 try:
319 self.assertEqual(long(ss), long(vv))
320 except v:
321 pass
322
323 self.assertRaises(ValueError, long, '123\0')
324 self.assertRaises(ValueError, long, '53', 40)
325 self.assertRaises(TypeError, long, 1, 12)
326
327 # SF patch #1638879: embedded NULs were not detected with
328 # explicit base
329 self.assertRaises(ValueError, long, '123\0', 10)
330 self.assertRaises(ValueError, long, '123\x00 245', 20)
331
332 self.assertEqual(long('100000000000000000000000000000000', 2),
333 4294967296)
334 self.assertEqual(long('102002022201221111211', 3), 4294967296)
335 self.assertEqual(long('10000000000000000', 4), 4294967296)
336 self.assertEqual(long('32244002423141', 5), 4294967296)
337 self.assertEqual(long('1550104015504', 6), 4294967296)
338 self.assertEqual(long('211301422354', 7), 4294967296)
339 self.assertEqual(long('40000000000', 8), 4294967296)
340 self.assertEqual(long('12068657454', 9), 4294967296)
341 self.assertEqual(long('4294967296', 10), 4294967296)
342 self.assertEqual(long('1904440554', 11), 4294967296)
343 self.assertEqual(long('9ba461594', 12), 4294967296)
344 self.assertEqual(long('535a79889', 13), 4294967296)
345 self.assertEqual(long('2ca5b7464', 14), 4294967296)
346 self.assertEqual(long('1a20dcd81', 15), 4294967296)
347 self.assertEqual(long('100000000', 16), 4294967296)
348 self.assertEqual(long('a7ffda91', 17), 4294967296)
349 self.assertEqual(long('704he7g4', 18), 4294967296)
350 self.assertEqual(long('4f5aff66', 19), 4294967296)
351 self.assertEqual(long('3723ai4g', 20), 4294967296)
352 self.assertEqual(long('281d55i4', 21), 4294967296)
353 self.assertEqual(long('1fj8b184', 22), 4294967296)
354 self.assertEqual(long('1606k7ic', 23), 4294967296)
355 self.assertEqual(long('mb994ag', 24), 4294967296)
356 self.assertEqual(long('hek2mgl', 25), 4294967296)
357 self.assertEqual(long('dnchbnm', 26), 4294967296)
358 self.assertEqual(long('b28jpdm', 27), 4294967296)
359 self.assertEqual(long('8pfgih4', 28), 4294967296)
360 self.assertEqual(long('76beigg', 29), 4294967296)
361 self.assertEqual(long('5qmcpqg', 30), 4294967296)
362 self.assertEqual(long('4q0jto4', 31), 4294967296)
363 self.assertEqual(long('4000000', 32), 4294967296)
364 self.assertEqual(long('3aokq94', 33), 4294967296)
365 self.assertEqual(long('2qhxjli', 34), 4294967296)
366 self.assertEqual(long('2br45qb', 35), 4294967296)
367 self.assertEqual(long('1z141z4', 36), 4294967296)
368
369 self.assertEqual(long('100000000000000000000000000000001', 2),
370 4294967297)
371 self.assertEqual(long('102002022201221111212', 3), 4294967297)
372 self.assertEqual(long('10000000000000001', 4), 4294967297)
373 self.assertEqual(long('32244002423142', 5), 4294967297)
374 self.assertEqual(long('1550104015505', 6), 4294967297)
375 self.assertEqual(long('211301422355', 7), 4294967297)
376 self.assertEqual(long('40000000001', 8), 4294967297)
377 self.assertEqual(long('12068657455', 9), 4294967297)
378 self.assertEqual(long('4294967297', 10), 4294967297)
379 self.assertEqual(long('1904440555', 11), 4294967297)
380 self.assertEqual(long('9ba461595', 12), 4294967297)
381 self.assertEqual(long('535a7988a', 13), 4294967297)
382 self.assertEqual(long('2ca5b7465', 14), 4294967297)
383 self.assertEqual(long('1a20dcd82', 15), 4294967297)
384 self.assertEqual(long('100000001', 16), 4294967297)
385 self.assertEqual(long('a7ffda92', 17), 4294967297)
386 self.assertEqual(long('704he7g5', 18), 4294967297)
387 self.assertEqual(long('4f5aff67', 19), 4294967297)
388 self.assertEqual(long('3723ai4h', 20), 4294967297)
389 self.assertEqual(long('281d55i5', 21), 4294967297)
390 self.assertEqual(long('1fj8b185', 22), 4294967297)
391 self.assertEqual(long('1606k7id', 23), 4294967297)
392 self.assertEqual(long('mb994ah', 24), 4294967297)
393 self.assertEqual(long('hek2mgm', 25), 4294967297)
394 self.assertEqual(long('dnchbnn', 26), 4294967297)
395 self.assertEqual(long('b28jpdn', 27), 4294967297)
396 self.assertEqual(long('8pfgih5', 28), 4294967297)
397 self.assertEqual(long('76beigh', 29), 4294967297)
398 self.assertEqual(long('5qmcpqh', 30), 4294967297)
399 self.assertEqual(long('4q0jto5', 31), 4294967297)
400 self.assertEqual(long('4000001', 32), 4294967297)
401 self.assertEqual(long('3aokq95', 33), 4294967297)
402 self.assertEqual(long('2qhxjlj', 34), 4294967297)
403 self.assertEqual(long('2br45qc', 35), 4294967297)
404 self.assertEqual(long('1z141z5', 36), 4294967297)
405
406
407 def test_conversion(self):
408 # Test __long__()
409 class ClassicMissingMethods:
410 pass
411 self.assertRaises(AttributeError, long, ClassicMissingMethods())
412
413 class MissingMethods(object):
414 pass
415 self.assertRaises(TypeError, long, MissingMethods())
416
417 class Foo0:
418 def __long__(self):
419 return 42L
420
421 class Foo1(object):
422 def __long__(self):
423 return 42L
424
425 class Foo2(long):
426 def __long__(self):
427 return 42L
428
429 class Foo3(long):
430 def __long__(self):
431 return self
432
433 class Foo4(long):
434 def __long__(self):
435 return 42
436
437 class Foo5(long):
438 def __long__(self):
439 return 42.
440
441 self.assertEqual(long(Foo0()), 42L)
442 self.assertEqual(long(Foo1()), 42L)
443 self.assertEqual(long(Foo2()), 42L)
444 self.assertEqual(long(Foo3()), 0)
445 self.assertEqual(long(Foo4()), 42)
446 self.assertRaises(TypeError, long, Foo5())
447
448 class Classic:
449 pass
450 for base in (object, Classic):
451 class LongOverridesTrunc(base):
452 def __long__(self):
453 return 42
454 def __trunc__(self):
455 return -12
456 self.assertEqual(long(LongOverridesTrunc()), 42)
457
458 class JustTrunc(base):
459 def __trunc__(self):
460 return 42
461 self.assertEqual(long(JustTrunc()), 42)
462
463 for trunc_result_base in (object, Classic):
464 class Integral(trunc_result_base):
465 def __int__(self):
466 return 42
467
468 class TruncReturnsNonLong(base):
469 def __trunc__(self):
470 return Integral()
471 self.assertEqual(long(TruncReturnsNonLong()), 42)
472
473 class NonIntegral(trunc_result_base):
474 def __trunc__(self):
475 # Check that we avoid infinite recursion.
476 return NonIntegral()
477
478 class TruncReturnsNonIntegral(base):
479 def __trunc__(self):
480 return NonIntegral()
481 try:
482 long(TruncReturnsNonIntegral())
483 except TypeError as e:
484 self.assertEquals(str(e),
485 "__trunc__ returned non-Integral"
486 " (type NonIntegral)")
487 else:
488 self.fail("Failed to raise TypeError with %s" %
489 ((base, trunc_result_base),))
490
Walter Dörwalda0021592005-06-13 21:44:48 +0000491 def test_misc(self):
Guido van Rossum4365cab1998-08-13 14:20:17 +0000492
Walter Dörwalda0021592005-06-13 21:44:48 +0000493 # check the extremes in int<->long conversion
494 hugepos = sys.maxint
495 hugeneg = -hugepos - 1
496 hugepos_aslong = long(hugepos)
497 hugeneg_aslong = long(hugeneg)
498 self.assertEqual(hugepos, hugepos_aslong, "long(sys.maxint) != sys.maxint")
499 self.assertEqual(hugeneg, hugeneg_aslong,
500 "long(-sys.maxint-1) != -sys.maxint-1")
Guido van Rossum4365cab1998-08-13 14:20:17 +0000501
Walter Dörwalda0021592005-06-13 21:44:48 +0000502 # long -> int should not fail for hugepos_aslong or hugeneg_aslong
Armin Rigo7ccbca92006-10-04 12:17:45 +0000503 x = int(hugepos_aslong)
Walter Dörwalda0021592005-06-13 21:44:48 +0000504 try:
Armin Rigo7ccbca92006-10-04 12:17:45 +0000505 self.assertEqual(x, hugepos,
Walter Dörwalda0021592005-06-13 21:44:48 +0000506 "converting sys.maxint to long and back to int fails")
507 except OverflowError:
508 self.fail("int(long(sys.maxint)) overflowed!")
Armin Rigo7ccbca92006-10-04 12:17:45 +0000509 if not isinstance(x, int):
510 raise TestFailed("int(long(sys.maxint)) should have returned int")
511 x = int(hugeneg_aslong)
Walter Dörwalda0021592005-06-13 21:44:48 +0000512 try:
Armin Rigo7ccbca92006-10-04 12:17:45 +0000513 self.assertEqual(x, hugeneg,
Walter Dörwalda0021592005-06-13 21:44:48 +0000514 "converting -sys.maxint-1 to long and back to int fails")
515 except OverflowError:
516 self.fail("int(long(-sys.maxint-1)) overflowed!")
Armin Rigo7ccbca92006-10-04 12:17:45 +0000517 if not isinstance(x, int):
518 raise TestFailed("int(long(-sys.maxint-1)) should have "
519 "returned int")
Walter Dörwalda0021592005-06-13 21:44:48 +0000520 # but long -> int should overflow for hugepos+1 and hugeneg-1
521 x = hugepos_aslong + 1
522 try:
523 y = int(x)
524 except OverflowError:
525 self.fail("int(long(sys.maxint) + 1) mustn't overflow")
526 self.assert_(isinstance(y, long),
527 "int(long(sys.maxint) + 1) should have returned long")
Guido van Rossum4365cab1998-08-13 14:20:17 +0000528
Walter Dörwalda0021592005-06-13 21:44:48 +0000529 x = hugeneg_aslong - 1
530 try:
531 y = int(x)
532 except OverflowError:
533 self.fail("int(long(-sys.maxint-1) - 1) mustn't overflow")
534 self.assert_(isinstance(y, long),
535 "int(long(-sys.maxint-1) - 1) should have returned long")
Guido van Rossum4365cab1998-08-13 14:20:17 +0000536
Walter Dörwalda0021592005-06-13 21:44:48 +0000537 class long2(long):
538 pass
539 x = long2(1L<<100)
Walter Dörwaldf1715402002-11-19 20:49:15 +0000540 y = int(x)
Walter Dörwalda0021592005-06-13 21:44:48 +0000541 self.assert_(type(y) is long,
542 "overflowing int conversion must return long not long subtype")
Guido van Rossum4581a0c1998-10-02 01:19:48 +0000543
Armin Rigo7ccbca92006-10-04 12:17:45 +0000544 # long -> Py_ssize_t conversion
545 class X(object):
546 def __getslice__(self, i, j):
547 return i, j
548
549 self.assertEqual(X()[-5L:7L], (-5, 7))
550 # use the clamping effect to test the smallest and largest longs
551 # that fit a Py_ssize_t
552 slicemin, slicemax = X()[-2L**100:2L**100]
553 self.assertEqual(X()[slicemin:slicemax], (slicemin, slicemax))
554
Tim Peters26c7fa32001-08-23 22:56:21 +0000555# ----------------------------------- tests of auto int->long conversion
556
Walter Dörwalda0021592005-06-13 21:44:48 +0000557 def test_auto_overflow(self):
558 import math, sys
Tim Peters26c7fa32001-08-23 22:56:21 +0000559
Walter Dörwalda0021592005-06-13 21:44:48 +0000560 special = [0, 1, 2, 3, sys.maxint-1, sys.maxint, sys.maxint+1]
561 sqrt = int(math.sqrt(sys.maxint))
562 special.extend([sqrt-1, sqrt, sqrt+1])
563 special.extend([-i for i in special])
Tim Peters26c7fa32001-08-23 22:56:21 +0000564
Walter Dörwalda0021592005-06-13 21:44:48 +0000565 def checkit(*args):
566 # Heavy use of nested scopes here!
567 self.assertEqual(got, expected,
568 Frm("for %r expected %r got %r", args, expected, got))
Tim Peters26c7fa32001-08-23 22:56:21 +0000569
Walter Dörwalda0021592005-06-13 21:44:48 +0000570 for x in special:
571 longx = long(x)
Tim Peters26c7fa32001-08-23 22:56:21 +0000572
Walter Dörwalda0021592005-06-13 21:44:48 +0000573 expected = -longx
574 got = -x
575 checkit('-', x)
Tim Peters26c7fa32001-08-23 22:56:21 +0000576
Walter Dörwalda0021592005-06-13 21:44:48 +0000577 for y in special:
578 longy = long(y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000579
Walter Dörwalda0021592005-06-13 21:44:48 +0000580 expected = longx + longy
581 got = x + y
582 checkit(x, '+', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000583
Walter Dörwalda0021592005-06-13 21:44:48 +0000584 expected = longx - longy
585 got = x - y
586 checkit(x, '-', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000587
Walter Dörwalda0021592005-06-13 21:44:48 +0000588 expected = longx * longy
589 got = x * y
590 checkit(x, '*', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000591
Walter Dörwalda0021592005-06-13 21:44:48 +0000592 if y:
593 expected = longx / longy
594 got = x / y
595 checkit(x, '/', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000596
Walter Dörwalda0021592005-06-13 21:44:48 +0000597 expected = longx // longy
598 got = x // y
599 checkit(x, '//', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000600
Walter Dörwalda0021592005-06-13 21:44:48 +0000601 expected = divmod(longx, longy)
602 got = divmod(longx, longy)
603 checkit(x, 'divmod', y)
Tim Petersa3653092001-08-23 23:02:57 +0000604
Walter Dörwalda0021592005-06-13 21:44:48 +0000605 if abs(y) < 5 and not (x == 0 and y < 0):
606 expected = longx ** longy
607 got = x ** y
608 checkit(x, '**', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000609
Walter Dörwalda0021592005-06-13 21:44:48 +0000610 for z in special:
611 if z != 0 :
612 if y >= 0:
613 expected = pow(longx, longy, long(z))
614 got = pow(x, y, z)
615 checkit('pow', x, y, '%', z)
Tim Peters32f453e2001-09-03 08:35:41 +0000616 else:
Walter Dörwalda0021592005-06-13 21:44:48 +0000617 self.assertRaises(TypeError, pow,longx, longy, long(z))
Tim Peters26c7fa32001-08-23 22:56:21 +0000618
Walter Dörwalda0021592005-06-13 21:44:48 +0000619 def test_float_overflow(self):
620 import math
Tim Peters9fffa3e2001-09-04 05:14:19 +0000621
Walter Dörwalda0021592005-06-13 21:44:48 +0000622 for x in -2.0, -1.0, 0.0, 1.0, 2.0:
623 self.assertEqual(float(long(x)), x)
Tim Peters9fffa3e2001-09-04 05:14:19 +0000624
Walter Dörwalda0021592005-06-13 21:44:48 +0000625 shuge = '12345' * 120
626 huge = 1L << 30000
627 mhuge = -huge
628 namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math}
629 for test in ["float(huge)", "float(mhuge)",
630 "complex(huge)", "complex(mhuge)",
631 "complex(huge, 1)", "complex(mhuge, 1)",
632 "complex(1, huge)", "complex(1, mhuge)",
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 "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.",
639 "math.sin(huge)", "math.sin(mhuge)",
640 "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better
Jeffrey Yasskin9871d8f2008-01-05 08:47:13 +0000641 "math.floor(huge)", "math.floor(mhuge)"]:
Tim Peters9fffa3e2001-09-04 05:14:19 +0000642
Walter Dörwalda0021592005-06-13 21:44:48 +0000643 self.assertRaises(OverflowError, eval, test, namespace)
Tim Peters9fffa3e2001-09-04 05:14:19 +0000644
Walter Dörwalda0021592005-06-13 21:44:48 +0000645 # XXX Perhaps float(shuge) can raise OverflowError on some box?
646 # The comparison should not.
647 self.assertNotEqual(float(shuge), int(shuge),
648 "float(shuge) should not equal int(shuge)")
Tim Peters83e7ccc2001-09-04 06:37:28 +0000649
Walter Dörwalda0021592005-06-13 21:44:48 +0000650 def test_logs(self):
651 import math
Tim Peters78526162001-09-05 00:53:45 +0000652
Walter Dörwalda0021592005-06-13 21:44:48 +0000653 LOG10E = math.log10(math.e)
Tim Peters307fa782004-09-23 08:06:40 +0000654
Walter Dörwalda0021592005-06-13 21:44:48 +0000655 for exp in range(10) + [100, 1000, 10000]:
656 value = 10 ** exp
657 log10 = math.log10(value)
658 self.assertAlmostEqual(log10, exp)
Tim Peters78526162001-09-05 00:53:45 +0000659
Walter Dörwalda0021592005-06-13 21:44:48 +0000660 # log10(value) == exp, so log(value) == log10(value)/log10(e) ==
661 # exp/LOG10E
662 expected = exp / LOG10E
663 log = math.log(value)
664 self.assertAlmostEqual(log, expected)
Tim Peters78526162001-09-05 00:53:45 +0000665
Walter Dörwalda0021592005-06-13 21:44:48 +0000666 for bad in -(1L << 10000), -2L, 0L:
667 self.assertRaises(ValueError, math.log, bad)
668 self.assertRaises(ValueError, math.log10, bad)
Tim Peters78526162001-09-05 00:53:45 +0000669
Walter Dörwalda0021592005-06-13 21:44:48 +0000670 def test_mixed_compares(self):
671 eq = self.assertEqual
672 import math
Tim Peters78526162001-09-05 00:53:45 +0000673
Walter Dörwalda0021592005-06-13 21:44:48 +0000674 # We're mostly concerned with that mixing floats and longs does the
675 # right stuff, even when longs are too large to fit in a float.
676 # The safest way to check the results is to use an entirely different
677 # method, which we do here via a skeletal rational class (which
678 # represents all Python ints, longs and floats exactly).
679 class Rat:
680 def __init__(self, value):
681 if isinstance(value, (int, long)):
682 self.n = value
683 self.d = 1
684 elif isinstance(value, float):
685 # Convert to exact rational equivalent.
686 f, e = math.frexp(abs(value))
687 assert f == 0 or 0.5 <= f < 1.0
688 # |value| = f * 2**e exactly
Tim Peters78526162001-09-05 00:53:45 +0000689
Walter Dörwalda0021592005-06-13 21:44:48 +0000690 # Suck up CHUNK bits at a time; 28 is enough so that we suck
691 # up all bits in 2 iterations for all known binary double-
692 # precision formats, and small enough to fit in an int.
693 CHUNK = 28
694 top = 0
695 # invariant: |value| = (top + f) * 2**e exactly
696 while f:
697 f = math.ldexp(f, CHUNK)
698 digit = int(f)
699 assert digit >> CHUNK == 0
700 top = (top << CHUNK) | digit
701 f -= digit
702 assert 0.0 <= f < 1.0
703 e -= CHUNK
Tim Peters78526162001-09-05 00:53:45 +0000704
Walter Dörwalda0021592005-06-13 21:44:48 +0000705 # Now |value| = top * 2**e exactly.
706 if e >= 0:
707 n = top << e
708 d = 1
709 else:
710 n = top
711 d = 1 << -e
712 if value < 0:
713 n = -n
714 self.n = n
715 self.d = d
716 assert float(n) / float(d) == value
Tim Peters307fa782004-09-23 08:06:40 +0000717 else:
Walter Dörwalda0021592005-06-13 21:44:48 +0000718 raise TypeError("can't deal with %r" % val)
Tim Peters307fa782004-09-23 08:06:40 +0000719
Walter Dörwalda0021592005-06-13 21:44:48 +0000720 def __cmp__(self, other):
721 if not isinstance(other, Rat):
722 other = Rat(other)
723 return cmp(self.n * other.d, self.d * other.n)
Tim Peters307fa782004-09-23 08:06:40 +0000724
Walter Dörwalda0021592005-06-13 21:44:48 +0000725 cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200]
726 # 2**48 is an important boundary in the internals. 2**53 is an
727 # important boundary for IEEE double precision.
728 for t in 2.0**48, 2.0**50, 2.0**53:
729 cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0,
730 long(t-1), long(t), long(t+1)])
731 cases.extend([0, 1, 2, sys.maxint, float(sys.maxint)])
732 # 1L<<20000 should exceed all double formats. long(1e200) is to
733 # check that we get equality with 1e200 above.
734 t = long(1e200)
735 cases.extend([0L, 1L, 2L, 1L << 20000, t-1, t, t+1])
736 cases.extend([-x for x in cases])
737 for x in cases:
738 Rx = Rat(x)
739 for y in cases:
740 Ry = Rat(y)
741 Rcmp = cmp(Rx, Ry)
742 xycmp = cmp(x, y)
743 eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp))
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))
749 eq(x >= y, Rcmp >= 0, Frm("%r >= %r %d", x, y, Rcmp))
Tim Peters307fa782004-09-23 08:06:40 +0000750
Christian Heimes8267d1d2008-01-04 00:37:34 +0000751 def test_nan_inf(self):
752 self.assertRaises(OverflowError, long, float('inf'))
Mark Dickinsonb6467572008-08-04 21:30:09 +0000753 self.assertRaises(OverflowError, long, float('-inf'))
754 self.assertRaises(ValueError, long, float('nan'))
Christian Heimes8267d1d2008-01-04 00:37:34 +0000755
Mark Dickinson1a707982008-12-17 16:14:37 +0000756 def test_bit_length(self):
757 tiny = 1e-10
758 for x in xrange(-65000, 65000):
759 x = long(x)
760 k = x.bit_length()
761 # Check equivalence with Python version
762 self.assertEqual(k, len(bin(x).lstrip('-0b')))
763 # Behaviour as specified in the docs
764 if x != 0:
765 self.assert_(2**(k-1) <= abs(x) < 2**k)
766 else:
767 self.assertEqual(k, 0)
768 # Alternative definition: x.bit_length() == 1 + floor(log_2(x))
769 if x != 0:
770 # When x is an exact power of 2, numeric errors can
771 # cause floor(log(x)/log(2)) to be one too small; for
772 # small x this can be fixed by adding a small quantity
773 # to the quotient before taking the floor.
774 self.assertEqual(k, 1 + math.floor(
775 math.log(abs(x))/math.log(2) + tiny))
776
777 self.assertEqual((0L).bit_length(), 0)
778 self.assertEqual((1L).bit_length(), 1)
779 self.assertEqual((-1L).bit_length(), 1)
780 self.assertEqual((2L).bit_length(), 2)
781 self.assertEqual((-2L).bit_length(), 2)
782 for i in [2, 3, 15, 16, 17, 31, 32, 33, 63, 64, 234]:
783 a = 2L**i
784 self.assertEqual((a-1).bit_length(), i)
785 self.assertEqual((1-a).bit_length(), i)
786 self.assertEqual((a).bit_length(), i+1)
787 self.assertEqual((-a).bit_length(), i+1)
788 self.assertEqual((a+1).bit_length(), i+1)
789 self.assertEqual((-a-1).bit_length(), i+1)
790
791
Walter Dörwalda0021592005-06-13 21:44:48 +0000792def test_main():
793 test_support.run_unittest(LongTest)
Tim Peters307fa782004-09-23 08:06:40 +0000794
Walter Dörwalda0021592005-06-13 21:44:48 +0000795if __name__ == "__main__":
796 test_main()