blob: 21881c97c9f9e8cf9601d40a62b0f2411fc93925 [file] [log] [blame]
Walter Dörwalda0021592005-06-13 21:44:48 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Christian Heimes81ee3ef2008-05-04 22:42:01 +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
Guido van Rossumc1f779c2007-07-03 08:25:58 +000027special = [0, 1, 2, BASE, BASE >> 1, 0x5555555555555555, 0xaaaaaaaaaaaaaaaa]
Guido van Rossum4581a0c1998-10-02 01:19:48 +000028# some solid strings of one bits
Guido van Rossume2a383d2007-01-15 16:59:06 +000029p2 = 4 # 0 and 1 already added
Guido van Rossum4581a0c1998-10-02 01:19:48 +000030for i in range(2*SHIFT):
31 special.append(p2 - 1)
32 p2 = p2 << 1
33del p2
34# add complements & negations
Guido van Rossumc1f779c2007-07-03 08:25:58 +000035special += [~x for x in special] + [-x for x in special]
Guido van Rossum4581a0c1998-10-02 01:19:48 +000036
Christian Heimes81ee3ef2008-05-04 22:42:01 +000037L = [
38 ('0', 0),
39 ('1', 1),
40 ('9', 9),
41 ('10', 10),
42 ('99', 99),
43 ('100', 100),
44 ('314', 314),
45 (' 314', 314),
46 ('314 ', 314),
47 (' \t\t 314 \t\t ', 314),
48 (repr(sys.maxsize), sys.maxsize),
49 (' 1x', ValueError),
50 (' 1 ', 1),
51 (' 1\02 ', ValueError),
52 ('', ValueError),
53 (' ', ValueError),
54 (' \t\t ', ValueError)
55]
56
Guido van Rossum4365cab1998-08-13 14:20:17 +000057
Walter Dörwalda0021592005-06-13 21:44:48 +000058class LongTest(unittest.TestCase):
Guido van Rossum4365cab1998-08-13 14:20:17 +000059
Walter Dörwalda0021592005-06-13 21:44:48 +000060 # Get quasi-random long consisting of ndigits digits (in base BASE).
61 # quasi == the most-significant digit will not be 0, and the number
62 # is constructed to contain long strings of 0 and 1 bits. These are
63 # more likely than random bits to provoke digit-boundary errors.
64 # The sign of the number is also random.
Guido van Rossum4365cab1998-08-13 14:20:17 +000065
Walter Dörwalda0021592005-06-13 21:44:48 +000066 def getran(self, ndigits):
67 self.assert_(ndigits > 0)
68 nbits_hi = ndigits * SHIFT
69 nbits_lo = nbits_hi - SHIFT + 1
Guido van Rossume2a383d2007-01-15 16:59:06 +000070 answer = 0
Walter Dörwalda0021592005-06-13 21:44:48 +000071 nbits = 0
72 r = int(random.random() * (SHIFT * 2)) | 1 # force 1 bits to start
73 while nbits < nbits_lo:
74 bits = (r >> 1) + 1
75 bits = min(bits, nbits_hi - nbits)
76 self.assert_(1 <= bits <= SHIFT)
77 nbits = nbits + bits
78 answer = answer << bits
79 if r & 1:
80 answer = answer | ((1 << bits) - 1)
81 r = int(random.random() * (SHIFT * 2))
82 self.assert_(nbits_lo <= nbits <= nbits_hi)
83 if random.random() < 0.5:
84 answer = -answer
85 return answer
Guido van Rossum4581a0c1998-10-02 01:19:48 +000086
Walter Dörwalda0021592005-06-13 21:44:48 +000087 # Get random long consisting of ndigits random digits (relative to base
88 # BASE). The sign bit is also random.
Guido van Rossum4581a0c1998-10-02 01:19:48 +000089
Walter Dörwalda0021592005-06-13 21:44:48 +000090 def getran2(ndigits):
Guido van Rossume2a383d2007-01-15 16:59:06 +000091 answer = 0
Guido van Rossum805365e2007-05-07 22:24:25 +000092 for i in range(ndigits):
Walter Dörwalda0021592005-06-13 21:44:48 +000093 answer = (answer << SHIFT) | random.randint(0, MASK)
94 if random.random() < 0.5:
95 answer = -answer
96 return answer
Guido van Rossum4365cab1998-08-13 14:20:17 +000097
Walter Dörwalda0021592005-06-13 21:44:48 +000098 def check_division(self, x, y):
99 eq = self.assertEqual
100 q, r = divmod(x, y)
101 q2, r2 = x//y, x%y
102 pab, pba = x*y, y*x
103 eq(pab, pba, Frm("multiplication does not commute for %r and %r", x, y))
104 eq(q, q2, Frm("divmod returns different quotient than / for %r and %r", x, y))
105 eq(r, r2, Frm("divmod returns different mod than %% for %r and %r", x, y))
106 eq(x, q*y + r, Frm("x != q*y + r after divmod on x=%r, y=%r", x, y))
107 if y > 0:
108 self.assert_(0 <= r < y, Frm("bad mod from divmod on %r and %r", x, y))
109 else:
110 self.assert_(y < r <= 0, Frm("bad mod from divmod on %r and %r", x, y))
Guido van Rossum4365cab1998-08-13 14:20:17 +0000111
Walter Dörwalda0021592005-06-13 21:44:48 +0000112 def test_division(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000113 digits = list(range(1, MAXDIGITS+1)) + list(range(KARATSUBA_CUTOFF,
114 KARATSUBA_CUTOFF + 14))
Walter Dörwalda0021592005-06-13 21:44:48 +0000115 digits.append(KARATSUBA_CUTOFF * 3)
116 for lenx in digits:
117 x = self.getran(lenx)
118 for leny in digits:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000119 y = self.getran(leny) or 1
Walter Dörwalda0021592005-06-13 21:44:48 +0000120 self.check_division(x, y)
Guido van Rossum4365cab1998-08-13 14:20:17 +0000121
Walter Dörwalda0021592005-06-13 21:44:48 +0000122 def test_karatsuba(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000123 digits = list(range(1, 5)) + list(range(KARATSUBA_CUTOFF,
124 KARATSUBA_CUTOFF + 10))
Walter Dörwalda0021592005-06-13 21:44:48 +0000125 digits.extend([KARATSUBA_CUTOFF * 10, KARATSUBA_CUTOFF * 100])
Guido van Rossum4365cab1998-08-13 14:20:17 +0000126
Walter Dörwalda0021592005-06-13 21:44:48 +0000127 bits = [digit * SHIFT for digit in digits]
Guido van Rossum4365cab1998-08-13 14:20:17 +0000128
Walter Dörwalda0021592005-06-13 21:44:48 +0000129 # Test products of long strings of 1 bits -- (2**x-1)*(2**y-1) ==
130 # 2**(x+y) - 2**x - 2**y + 1, so the proper result is easy to check.
131 for abits in bits:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000132 a = (1 << abits) - 1
Walter Dörwalda0021592005-06-13 21:44:48 +0000133 for bbits in bits:
134 if bbits < abits:
135 continue
Guido van Rossume2a383d2007-01-15 16:59:06 +0000136 b = (1 << bbits) - 1
Walter Dörwalda0021592005-06-13 21:44:48 +0000137 x = a * b
Guido van Rossume2a383d2007-01-15 16:59:06 +0000138 y = ((1 << (abits + bbits)) -
139 (1 << abits) -
140 (1 << bbits) +
Walter Dörwalda0021592005-06-13 21:44:48 +0000141 1)
142 self.assertEqual(x, y,
143 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 +0000144
Walter Dörwalda0021592005-06-13 21:44:48 +0000145 def check_bitop_identities_1(self, x):
146 eq = self.assertEqual
147 eq(x & 0, 0, Frm("x & 0 != 0 for x=%r", x))
148 eq(x | 0, x, Frm("x | 0 != x for x=%r", x))
149 eq(x ^ 0, x, Frm("x ^ 0 != x for x=%r", x))
150 eq(x & -1, x, Frm("x & -1 != x for x=%r", x))
151 eq(x | -1, -1, Frm("x | -1 != -1 for x=%r", x))
152 eq(x ^ -1, ~x, Frm("x ^ -1 != ~x for x=%r", x))
153 eq(x, ~~x, Frm("x != ~~x for x=%r", x))
154 eq(x & x, x, Frm("x & x != x for x=%r", x))
155 eq(x | x, x, Frm("x | x != x for x=%r", x))
156 eq(x ^ x, 0, Frm("x ^ x != 0 for x=%r", x))
157 eq(x & ~x, 0, Frm("x & ~x != 0 for x=%r", x))
158 eq(x | ~x, -1, Frm("x | ~x != -1 for x=%r", x))
159 eq(x ^ ~x, -1, Frm("x ^ ~x != -1 for x=%r", x))
160 eq(-x, 1 + ~x, Frm("not -x == 1 + ~x for x=%r", x))
161 eq(-x, ~(x-1), Frm("not -x == ~(x-1) forx =%r", x))
Guido van Rossum805365e2007-05-07 22:24:25 +0000162 for n in range(2*SHIFT):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000163 p2 = 2 ** n
Walter Dörwalda0021592005-06-13 21:44:48 +0000164 eq(x << n >> n, x,
165 Frm("x << n >> n != x for x=%r, n=%r", (x, n)))
166 eq(x // p2, x >> n,
167 Frm("x // p2 != x >> n for x=%r n=%r p2=%r", (x, n, p2)))
168 eq(x * p2, x << n,
169 Frm("x * p2 != x << n for x=%r n=%r p2=%r", (x, n, p2)))
170 eq(x & -p2, x >> n << n,
171 Frm("not x & -p2 == x >> n << n for x=%r n=%r p2=%r", (x, n, p2)))
172 eq(x & -p2, x & ~(p2 - 1),
173 Frm("not x & -p2 == x & ~(p2 - 1) for x=%r n=%r p2=%r", (x, n, p2)))
Tim Peters7f270ba2002-08-13 21:06:55 +0000174
Walter Dörwalda0021592005-06-13 21:44:48 +0000175 def check_bitop_identities_2(self, x, y):
176 eq = self.assertEqual
177 eq(x & y, y & x, Frm("x & y != y & x for x=%r, y=%r", (x, y)))
178 eq(x | y, y | x, Frm("x | y != y | x for x=%r, y=%r", (x, y)))
179 eq(x ^ y, y ^ x, Frm("x ^ y != y ^ x for x=%r, y=%r", (x, y)))
180 eq(x ^ y ^ x, y, Frm("x ^ y ^ x != y for x=%r, y=%r", (x, y)))
181 eq(x & y, ~(~x | ~y), Frm("x & y != ~(~x | ~y) for x=%r, y=%r", (x, y)))
182 eq(x | y, ~(~x & ~y), Frm("x | y != ~(~x & ~y) for x=%r, y=%r", (x, y)))
183 eq(x ^ y, (x | y) & ~(x & y),
184 Frm("x ^ y != (x | y) & ~(x & y) for x=%r, y=%r", (x, y)))
185 eq(x ^ y, (x & ~y) | (~x & y),
186 Frm("x ^ y == (x & ~y) | (~x & y) for x=%r, y=%r", (x, y)))
187 eq(x ^ y, (x | y) & (~x | ~y),
188 Frm("x ^ y == (x | y) & (~x | ~y) for x=%r, y=%r", (x, y)))
Tim Peters7f270ba2002-08-13 21:06:55 +0000189
Walter Dörwalda0021592005-06-13 21:44:48 +0000190 def check_bitop_identities_3(self, x, y, z):
191 eq = self.assertEqual
192 eq((x & y) & z, x & (y & z),
193 Frm("(x & y) & z != x & (y & z) for x=%r, y=%r, z=%r", (x, y, z)))
194 eq((x | y) | z, x | (y | z),
195 Frm("(x | y) | z != x | (y | z) for x=%r, y=%r, z=%r", (x, y, z)))
196 eq((x ^ y) ^ z, x ^ (y ^ z),
197 Frm("(x ^ y) ^ z != x ^ (y ^ z) for x=%r, y=%r, z=%r", (x, y, z)))
198 eq(x & (y | z), (x & y) | (x & z),
199 Frm("x & (y | z) != (x & y) | (x & z) for x=%r, y=%r, z=%r", (x, y, z)))
200 eq(x | (y & z), (x | y) & (x | z),
201 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 +0000202
Walter Dörwalda0021592005-06-13 21:44:48 +0000203 def test_bitop_identities(self):
204 for x in special:
205 self.check_bitop_identities_1(x)
Guido van Rossum805365e2007-05-07 22:24:25 +0000206 digits = range(1, MAXDIGITS+1)
Walter Dörwalda0021592005-06-13 21:44:48 +0000207 for lenx in digits:
208 x = self.getran(lenx)
209 self.check_bitop_identities_1(x)
210 for leny in digits:
211 y = self.getran(leny)
212 self.check_bitop_identities_2(x, y)
213 self.check_bitop_identities_3(x, y, self.getran((lenx + leny)//2))
Guido van Rossum4365cab1998-08-13 14:20:17 +0000214
Walter Dörwalda0021592005-06-13 21:44:48 +0000215 def slow_format(self, x, base):
Walter Dörwalda0021592005-06-13 21:44:48 +0000216 digits = []
217 sign = 0
218 if x < 0:
219 sign, x = 1, -x
220 while x:
221 x, r = divmod(x, base)
222 digits.append(int(r))
223 digits.reverse()
224 digits = digits or [0]
225 return '-'[:sign] + \
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000226 {2: '0b', 8: '0o', 10: '', 16: '0x'}[base] + \
Guido van Rossumd2dbecb2006-08-18 16:29:54 +0000227 "".join(map(lambda i: "0123456789abcdef"[i], digits))
Guido van Rossum4365cab1998-08-13 14:20:17 +0000228
Walter Dörwalda0021592005-06-13 21:44:48 +0000229 def check_format_1(self, x):
230 for base, mapper in (8, oct), (10, repr), (16, hex):
231 got = mapper(x)
232 expected = self.slow_format(x, base)
233 msg = Frm("%s returned %r but expected %r for %r",
234 mapper.__name__, got, expected, x)
235 self.assertEqual(got, expected, msg)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000236 self.assertEqual(int(got, 0), x, Frm('long("%s", 0) != %r', got, x))
Walter Dörwalda0021592005-06-13 21:44:48 +0000237 # str() has to be checked a little differently since there's no
238 # trailing "L"
239 got = str(x)
Guido van Rossumd2dbecb2006-08-18 16:29:54 +0000240 expected = self.slow_format(x, 10)
Walter Dörwalda0021592005-06-13 21:44:48 +0000241 msg = Frm("%s returned %r but expected %r for %r",
242 mapper.__name__, got, expected, x)
243 self.assertEqual(got, expected, msg)
Guido van Rossum4365cab1998-08-13 14:20:17 +0000244
Walter Dörwalda0021592005-06-13 21:44:48 +0000245 def test_format(self):
246 for x in special:
247 self.check_format_1(x)
Guido van Rossum805365e2007-05-07 22:24:25 +0000248 for i in range(10):
249 for lenx in range(1, MAXDIGITS+1):
Walter Dörwalda0021592005-06-13 21:44:48 +0000250 x = self.getran(lenx)
251 self.check_format_1(x)
Guido van Rossum4365cab1998-08-13 14:20:17 +0000252
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000253 def test_long(self):
254 self.assertEqual(int(314), 314)
255 self.assertEqual(int(3.14), 3)
256 self.assertEqual(int(314), 314)
257 # Check that conversion from float truncates towards zero
258 self.assertEqual(int(-3.14), -3)
259 self.assertEqual(int(3.9), 3)
260 self.assertEqual(int(-3.9), -3)
261 self.assertEqual(int(3.5), 3)
262 self.assertEqual(int(-3.5), -3)
263 self.assertEqual(int("-3"), -3)
264 # Different base:
265 self.assertEqual(int("10",16), 16)
266 # Check conversions from string (same test set as for int(), and then some)
267 LL = [
268 ('1' + '0'*20, 10**20),
269 ('1' + '0'*100, 10**100)
270 ]
271 L2 = L[:]
272 for s, v in L2 + LL:
273 for sign in "", "+", "-":
274 for prefix in "", " ", "\t", " \t\t ":
275 ss = prefix + sign + s
276 vv = v
277 if sign == "-" and v is not ValueError:
278 vv = -v
279 try:
280 self.assertEqual(int(ss), int(vv))
281 except ValueError:
282 pass
283
284 self.assertRaises(ValueError, int, '123\0')
285 self.assertRaises(ValueError, int, '53', 40)
286 self.assertRaises(TypeError, int, 1, 12)
287
288 # SF patch #1638879: embedded NULs were not detected with
289 # explicit base
290 self.assertRaises(ValueError, int, '123\0', 10)
291 self.assertRaises(ValueError, int, '123\x00 245', 20)
292
293 self.assertEqual(int('100000000000000000000000000000000', 2),
294 4294967296)
295 self.assertEqual(int('102002022201221111211', 3), 4294967296)
296 self.assertEqual(int('10000000000000000', 4), 4294967296)
297 self.assertEqual(int('32244002423141', 5), 4294967296)
298 self.assertEqual(int('1550104015504', 6), 4294967296)
299 self.assertEqual(int('211301422354', 7), 4294967296)
300 self.assertEqual(int('40000000000', 8), 4294967296)
301 self.assertEqual(int('12068657454', 9), 4294967296)
302 self.assertEqual(int('4294967296', 10), 4294967296)
303 self.assertEqual(int('1904440554', 11), 4294967296)
304 self.assertEqual(int('9ba461594', 12), 4294967296)
305 self.assertEqual(int('535a79889', 13), 4294967296)
306 self.assertEqual(int('2ca5b7464', 14), 4294967296)
307 self.assertEqual(int('1a20dcd81', 15), 4294967296)
308 self.assertEqual(int('100000000', 16), 4294967296)
309 self.assertEqual(int('a7ffda91', 17), 4294967296)
310 self.assertEqual(int('704he7g4', 18), 4294967296)
311 self.assertEqual(int('4f5aff66', 19), 4294967296)
312 self.assertEqual(int('3723ai4g', 20), 4294967296)
313 self.assertEqual(int('281d55i4', 21), 4294967296)
314 self.assertEqual(int('1fj8b184', 22), 4294967296)
315 self.assertEqual(int('1606k7ic', 23), 4294967296)
316 self.assertEqual(int('mb994ag', 24), 4294967296)
317 self.assertEqual(int('hek2mgl', 25), 4294967296)
318 self.assertEqual(int('dnchbnm', 26), 4294967296)
319 self.assertEqual(int('b28jpdm', 27), 4294967296)
320 self.assertEqual(int('8pfgih4', 28), 4294967296)
321 self.assertEqual(int('76beigg', 29), 4294967296)
322 self.assertEqual(int('5qmcpqg', 30), 4294967296)
323 self.assertEqual(int('4q0jto4', 31), 4294967296)
324 self.assertEqual(int('4000000', 32), 4294967296)
325 self.assertEqual(int('3aokq94', 33), 4294967296)
326 self.assertEqual(int('2qhxjli', 34), 4294967296)
327 self.assertEqual(int('2br45qb', 35), 4294967296)
328 self.assertEqual(int('1z141z4', 36), 4294967296)
329
330 self.assertEqual(int('100000000000000000000000000000001', 2),
331 4294967297)
332 self.assertEqual(int('102002022201221111212', 3), 4294967297)
333 self.assertEqual(int('10000000000000001', 4), 4294967297)
334 self.assertEqual(int('32244002423142', 5), 4294967297)
335 self.assertEqual(int('1550104015505', 6), 4294967297)
336 self.assertEqual(int('211301422355', 7), 4294967297)
337 self.assertEqual(int('40000000001', 8), 4294967297)
338 self.assertEqual(int('12068657455', 9), 4294967297)
339 self.assertEqual(int('4294967297', 10), 4294967297)
340 self.assertEqual(int('1904440555', 11), 4294967297)
341 self.assertEqual(int('9ba461595', 12), 4294967297)
342 self.assertEqual(int('535a7988a', 13), 4294967297)
343 self.assertEqual(int('2ca5b7465', 14), 4294967297)
344 self.assertEqual(int('1a20dcd82', 15), 4294967297)
345 self.assertEqual(int('100000001', 16), 4294967297)
346 self.assertEqual(int('a7ffda92', 17), 4294967297)
347 self.assertEqual(int('704he7g5', 18), 4294967297)
348 self.assertEqual(int('4f5aff67', 19), 4294967297)
349 self.assertEqual(int('3723ai4h', 20), 4294967297)
350 self.assertEqual(int('281d55i5', 21), 4294967297)
351 self.assertEqual(int('1fj8b185', 22), 4294967297)
352 self.assertEqual(int('1606k7id', 23), 4294967297)
353 self.assertEqual(int('mb994ah', 24), 4294967297)
354 self.assertEqual(int('hek2mgm', 25), 4294967297)
355 self.assertEqual(int('dnchbnn', 26), 4294967297)
356 self.assertEqual(int('b28jpdn', 27), 4294967297)
357 self.assertEqual(int('8pfgih5', 28), 4294967297)
358 self.assertEqual(int('76beigh', 29), 4294967297)
359 self.assertEqual(int('5qmcpqh', 30), 4294967297)
360 self.assertEqual(int('4q0jto5', 31), 4294967297)
361 self.assertEqual(int('4000001', 32), 4294967297)
362 self.assertEqual(int('3aokq95', 33), 4294967297)
363 self.assertEqual(int('2qhxjlj', 34), 4294967297)
364 self.assertEqual(int('2br45qc', 35), 4294967297)
365 self.assertEqual(int('1z141z5', 36), 4294967297)
366
367
368 def test_conversion(self):
369 # Test __long__()
370 class ClassicMissingMethods:
371 pass
372 self.assertRaises(TypeError, int, ClassicMissingMethods())
373
374 class MissingMethods(object):
375 pass
376 self.assertRaises(TypeError, int, MissingMethods())
377
378 class Foo0:
379 def __int__(self):
380 return 42
381
382 class Foo1(object):
383 def __int__(self):
384 return 42
385
386 class Foo2(int):
387 def __int__(self):
388 return 42
389
390 class Foo3(int):
391 def __int__(self):
392 return self
393
394 class Foo4(int):
395 def __int__(self):
396 return 42
397
398 class Foo5(int):
399 def __int__(self):
400 return 42.
401
402 self.assertEqual(int(Foo0()), 42)
403 self.assertEqual(int(Foo1()), 42)
404 self.assertEqual(int(Foo2()), 42)
405 self.assertEqual(int(Foo3()), 0)
406 self.assertEqual(int(Foo4()), 42)
407 self.assertRaises(TypeError, int, Foo5())
408
409 class Classic:
410 pass
411 for base in (object, Classic):
412 class LongOverridesTrunc(base):
413 def __long__(self):
414 return 42
415 def __trunc__(self):
416 return -12
417 self.assertEqual(int(LongOverridesTrunc()), 42)
418
419 class JustTrunc(base):
420 def __trunc__(self):
421 return 42
422 self.assertEqual(int(JustTrunc()), 42)
423
424 for trunc_result_base in (object, Classic):
425 class Integral(trunc_result_base):
426 def __int__(self):
427 return 42
428
429 class TruncReturnsNonLong(base):
430 def __trunc__(self):
431 return Integral()
432 self.assertEqual(int(TruncReturnsNonLong()), 42)
433
434 class NonIntegral(trunc_result_base):
435 def __trunc__(self):
436 # Check that we avoid infinite recursion.
437 return NonIntegral()
438
439 class TruncReturnsNonIntegral(base):
440 def __trunc__(self):
441 return NonIntegral()
442 try:
443 int(TruncReturnsNonIntegral())
444 except TypeError as e:
445 self.assertEquals(str(e),
446 "__trunc__ returned non-Integral"
447 " (type NonIntegral)")
448 else:
449 self.fail("Failed to raise TypeError with %s" %
450 ((base, trunc_result_base),))
451
Walter Dörwalda0021592005-06-13 21:44:48 +0000452 def test_misc(self):
Guido van Rossum4365cab1998-08-13 14:20:17 +0000453
Walter Dörwalda0021592005-06-13 21:44:48 +0000454 # check the extremes in int<->long conversion
Christian Heimesa37d4c62007-12-04 23:02:19 +0000455 hugepos = sys.maxsize
Walter Dörwalda0021592005-06-13 21:44:48 +0000456 hugeneg = -hugepos - 1
Guido van Rossume2a383d2007-01-15 16:59:06 +0000457 hugepos_aslong = int(hugepos)
458 hugeneg_aslong = int(hugeneg)
Christian Heimesa37d4c62007-12-04 23:02:19 +0000459 self.assertEqual(hugepos, hugepos_aslong, "long(sys.maxsize) != sys.maxsize")
Walter Dörwalda0021592005-06-13 21:44:48 +0000460 self.assertEqual(hugeneg, hugeneg_aslong,
Christian Heimesa37d4c62007-12-04 23:02:19 +0000461 "long(-sys.maxsize-1) != -sys.maxsize-1")
Guido van Rossum4365cab1998-08-13 14:20:17 +0000462
Walter Dörwalda0021592005-06-13 21:44:48 +0000463 # long -> int should not fail for hugepos_aslong or hugeneg_aslong
Thomas Wouters89f507f2006-12-13 04:49:30 +0000464 x = int(hugepos_aslong)
Walter Dörwalda0021592005-06-13 21:44:48 +0000465 try:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000466 self.assertEqual(x, hugepos,
Christian Heimesa37d4c62007-12-04 23:02:19 +0000467 "converting sys.maxsize to long and back to int fails")
Walter Dörwalda0021592005-06-13 21:44:48 +0000468 except OverflowError:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000469 self.fail("int(long(sys.maxsize)) overflowed!")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000470 if not isinstance(x, int):
Christian Heimesa37d4c62007-12-04 23:02:19 +0000471 raise TestFailed("int(long(sys.maxsize)) should have returned int")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000472 x = int(hugeneg_aslong)
Walter Dörwalda0021592005-06-13 21:44:48 +0000473 try:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000474 self.assertEqual(x, hugeneg,
Christian Heimesa37d4c62007-12-04 23:02:19 +0000475 "converting -sys.maxsize-1 to long and back to int fails")
Walter Dörwalda0021592005-06-13 21:44:48 +0000476 except OverflowError:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000477 self.fail("int(long(-sys.maxsize-1)) overflowed!")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000478 if not isinstance(x, int):
Christian Heimesa37d4c62007-12-04 23:02:19 +0000479 raise TestFailed("int(long(-sys.maxsize-1)) should have "
Thomas Wouters89f507f2006-12-13 04:49:30 +0000480 "returned int")
Walter Dörwalda0021592005-06-13 21:44:48 +0000481 # but long -> int should overflow for hugepos+1 and hugeneg-1
482 x = hugepos_aslong + 1
483 try:
484 y = int(x)
485 except OverflowError:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000486 self.fail("int(long(sys.maxsize) + 1) mustn't overflow")
Guido van Rossume2a383d2007-01-15 16:59:06 +0000487 self.assert_(isinstance(y, int),
Christian Heimesa37d4c62007-12-04 23:02:19 +0000488 "int(long(sys.maxsize) + 1) should have returned long")
Guido van Rossum4365cab1998-08-13 14:20:17 +0000489
Walter Dörwalda0021592005-06-13 21:44:48 +0000490 x = hugeneg_aslong - 1
491 try:
492 y = int(x)
493 except OverflowError:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000494 self.fail("int(long(-sys.maxsize-1) - 1) mustn't overflow")
Guido van Rossume2a383d2007-01-15 16:59:06 +0000495 self.assert_(isinstance(y, int),
Christian Heimesa37d4c62007-12-04 23:02:19 +0000496 "int(long(-sys.maxsize-1) - 1) should have returned long")
Guido van Rossum4365cab1998-08-13 14:20:17 +0000497
Guido van Rossume2a383d2007-01-15 16:59:06 +0000498 class long2(int):
Walter Dörwalda0021592005-06-13 21:44:48 +0000499 pass
Guido van Rossume2a383d2007-01-15 16:59:06 +0000500 x = long2(1<<100)
Walter Dörwaldf1715402002-11-19 20:49:15 +0000501 y = int(x)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000502 self.assert_(type(y) is int,
Walter Dörwalda0021592005-06-13 21:44:48 +0000503 "overflowing int conversion must return long not long subtype")
Guido van Rossum4581a0c1998-10-02 01:19:48 +0000504
Tim Peters26c7fa32001-08-23 22:56:21 +0000505# ----------------------------------- tests of auto int->long conversion
506
Walter Dörwalda0021592005-06-13 21:44:48 +0000507 def test_auto_overflow(self):
508 import math, sys
Tim Peters26c7fa32001-08-23 22:56:21 +0000509
Christian Heimesa37d4c62007-12-04 23:02:19 +0000510 special = [0, 1, 2, 3, sys.maxsize-1, sys.maxsize, sys.maxsize+1]
511 sqrt = int(math.sqrt(sys.maxsize))
Walter Dörwalda0021592005-06-13 21:44:48 +0000512 special.extend([sqrt-1, sqrt, sqrt+1])
513 special.extend([-i for i in special])
Tim Peters26c7fa32001-08-23 22:56:21 +0000514
Walter Dörwalda0021592005-06-13 21:44:48 +0000515 def checkit(*args):
516 # Heavy use of nested scopes here!
517 self.assertEqual(got, expected,
518 Frm("for %r expected %r got %r", args, expected, got))
Tim Peters26c7fa32001-08-23 22:56:21 +0000519
Walter Dörwalda0021592005-06-13 21:44:48 +0000520 for x in special:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000521 longx = int(x)
Tim Peters26c7fa32001-08-23 22:56:21 +0000522
Walter Dörwalda0021592005-06-13 21:44:48 +0000523 expected = -longx
524 got = -x
525 checkit('-', x)
Tim Peters26c7fa32001-08-23 22:56:21 +0000526
Walter Dörwalda0021592005-06-13 21:44:48 +0000527 for y in special:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000528 longy = int(y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000529
Walter Dörwalda0021592005-06-13 21:44:48 +0000530 expected = longx + longy
531 got = x + y
532 checkit(x, '+', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000533
Walter Dörwalda0021592005-06-13 21:44:48 +0000534 expected = longx - longy
535 got = x - y
536 checkit(x, '-', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000537
Walter Dörwalda0021592005-06-13 21:44:48 +0000538 expected = longx * longy
539 got = x * y
540 checkit(x, '*', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000541
Walter Dörwalda0021592005-06-13 21:44:48 +0000542 if y:
543 expected = longx / longy
544 got = x / y
545 checkit(x, '/', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000546
Walter Dörwalda0021592005-06-13 21:44:48 +0000547 expected = longx // longy
548 got = x // y
549 checkit(x, '//', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000550
Walter Dörwalda0021592005-06-13 21:44:48 +0000551 expected = divmod(longx, longy)
552 got = divmod(longx, longy)
553 checkit(x, 'divmod', y)
Tim Petersa3653092001-08-23 23:02:57 +0000554
Walter Dörwalda0021592005-06-13 21:44:48 +0000555 if abs(y) < 5 and not (x == 0 and y < 0):
556 expected = longx ** longy
557 got = x ** y
558 checkit(x, '**', y)
Tim Peters26c7fa32001-08-23 22:56:21 +0000559
Walter Dörwalda0021592005-06-13 21:44:48 +0000560 for z in special:
561 if z != 0 :
562 if y >= 0:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000563 expected = pow(longx, longy, int(z))
Walter Dörwalda0021592005-06-13 21:44:48 +0000564 got = pow(x, y, z)
565 checkit('pow', x, y, '%', z)
Tim Peters32f453e2001-09-03 08:35:41 +0000566 else:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000567 self.assertRaises(TypeError, pow,longx, longy, int(z))
Tim Peters26c7fa32001-08-23 22:56:21 +0000568
Walter Dörwalda0021592005-06-13 21:44:48 +0000569 def test_float_overflow(self):
570 import math
Tim Peters9fffa3e2001-09-04 05:14:19 +0000571
Walter Dörwalda0021592005-06-13 21:44:48 +0000572 for x in -2.0, -1.0, 0.0, 1.0, 2.0:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000573 self.assertEqual(float(int(x)), x)
Tim Peters9fffa3e2001-09-04 05:14:19 +0000574
Walter Dörwalda0021592005-06-13 21:44:48 +0000575 shuge = '12345' * 120
Guido van Rossume2a383d2007-01-15 16:59:06 +0000576 huge = 1 << 30000
Walter Dörwalda0021592005-06-13 21:44:48 +0000577 mhuge = -huge
578 namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math}
579 for test in ["float(huge)", "float(mhuge)",
580 "complex(huge)", "complex(mhuge)",
581 "complex(huge, 1)", "complex(mhuge, 1)",
582 "complex(1, huge)", "complex(1, mhuge)",
583 "1. + huge", "huge + 1.", "1. + mhuge", "mhuge + 1.",
584 "1. - huge", "huge - 1.", "1. - mhuge", "mhuge - 1.",
585 "1. * huge", "huge * 1.", "1. * mhuge", "mhuge * 1.",
586 "1. // huge", "huge // 1.", "1. // mhuge", "mhuge // 1.",
587 "1. / huge", "huge / 1.", "1. / mhuge", "mhuge / 1.",
588 "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.",
589 "math.sin(huge)", "math.sin(mhuge)",
590 "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better
Guido van Rossum28bbe422007-08-24 03:46:30 +0000591 # math.floor() of an int returns an int now
592 ##"math.floor(huge)", "math.floor(mhuge)",
593 ]:
Tim Peters9fffa3e2001-09-04 05:14:19 +0000594
Walter Dörwalda0021592005-06-13 21:44:48 +0000595 self.assertRaises(OverflowError, eval, test, namespace)
Tim Peters9fffa3e2001-09-04 05:14:19 +0000596
Walter Dörwalda0021592005-06-13 21:44:48 +0000597 # XXX Perhaps float(shuge) can raise OverflowError on some box?
598 # The comparison should not.
599 self.assertNotEqual(float(shuge), int(shuge),
600 "float(shuge) should not equal int(shuge)")
Tim Peters83e7ccc2001-09-04 06:37:28 +0000601
Walter Dörwalda0021592005-06-13 21:44:48 +0000602 def test_logs(self):
603 import math
Tim Peters78526162001-09-05 00:53:45 +0000604
Walter Dörwalda0021592005-06-13 21:44:48 +0000605 LOG10E = math.log10(math.e)
Tim Peters307fa782004-09-23 08:06:40 +0000606
Guido van Rossum805365e2007-05-07 22:24:25 +0000607 for exp in list(range(10)) + [100, 1000, 10000]:
Walter Dörwalda0021592005-06-13 21:44:48 +0000608 value = 10 ** exp
609 log10 = math.log10(value)
610 self.assertAlmostEqual(log10, exp)
Tim Peters78526162001-09-05 00:53:45 +0000611
Walter Dörwalda0021592005-06-13 21:44:48 +0000612 # log10(value) == exp, so log(value) == log10(value)/log10(e) ==
613 # exp/LOG10E
614 expected = exp / LOG10E
615 log = math.log(value)
616 self.assertAlmostEqual(log, expected)
Tim Peters78526162001-09-05 00:53:45 +0000617
Guido van Rossume2a383d2007-01-15 16:59:06 +0000618 for bad in -(1 << 10000), -2, 0:
Walter Dörwalda0021592005-06-13 21:44:48 +0000619 self.assertRaises(ValueError, math.log, bad)
620 self.assertRaises(ValueError, math.log10, bad)
Tim Peters78526162001-09-05 00:53:45 +0000621
Walter Dörwalda0021592005-06-13 21:44:48 +0000622 def test_mixed_compares(self):
623 eq = self.assertEqual
624 import math
Tim Peters78526162001-09-05 00:53:45 +0000625
Walter Dörwalda0021592005-06-13 21:44:48 +0000626 # We're mostly concerned with that mixing floats and longs does the
627 # right stuff, even when longs are too large to fit in a float.
628 # The safest way to check the results is to use an entirely different
629 # method, which we do here via a skeletal rational class (which
630 # represents all Python ints, longs and floats exactly).
631 class Rat:
632 def __init__(self, value):
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000633 if isinstance(value, int):
Walter Dörwalda0021592005-06-13 21:44:48 +0000634 self.n = value
635 self.d = 1
636 elif isinstance(value, float):
637 # Convert to exact rational equivalent.
638 f, e = math.frexp(abs(value))
639 assert f == 0 or 0.5 <= f < 1.0
640 # |value| = f * 2**e exactly
Tim Peters78526162001-09-05 00:53:45 +0000641
Walter Dörwalda0021592005-06-13 21:44:48 +0000642 # Suck up CHUNK bits at a time; 28 is enough so that we suck
643 # up all bits in 2 iterations for all known binary double-
644 # precision formats, and small enough to fit in an int.
645 CHUNK = 28
646 top = 0
647 # invariant: |value| = (top + f) * 2**e exactly
648 while f:
649 f = math.ldexp(f, CHUNK)
650 digit = int(f)
651 assert digit >> CHUNK == 0
652 top = (top << CHUNK) | digit
653 f -= digit
654 assert 0.0 <= f < 1.0
655 e -= CHUNK
Tim Peters78526162001-09-05 00:53:45 +0000656
Walter Dörwalda0021592005-06-13 21:44:48 +0000657 # Now |value| = top * 2**e exactly.
658 if e >= 0:
659 n = top << e
660 d = 1
661 else:
662 n = top
663 d = 1 << -e
664 if value < 0:
665 n = -n
666 self.n = n
667 self.d = d
668 assert float(n) / float(d) == value
Tim Peters307fa782004-09-23 08:06:40 +0000669 else:
Walter Dörwalda0021592005-06-13 21:44:48 +0000670 raise TypeError("can't deal with %r" % val)
Tim Peters307fa782004-09-23 08:06:40 +0000671
Walter Dörwalda0021592005-06-13 21:44:48 +0000672 def __cmp__(self, other):
673 if not isinstance(other, Rat):
674 other = Rat(other)
675 return cmp(self.n * other.d, self.d * other.n)
Tim Peters307fa782004-09-23 08:06:40 +0000676
Walter Dörwalda0021592005-06-13 21:44:48 +0000677 cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200]
678 # 2**48 is an important boundary in the internals. 2**53 is an
679 # important boundary for IEEE double precision.
680 for t in 2.0**48, 2.0**50, 2.0**53:
681 cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0,
Guido van Rossume2a383d2007-01-15 16:59:06 +0000682 int(t-1), int(t), int(t+1)])
Christian Heimesa37d4c62007-12-04 23:02:19 +0000683 cases.extend([0, 1, 2, sys.maxsize, float(sys.maxsize)])
Walter Dörwalda0021592005-06-13 21:44:48 +0000684 # 1L<<20000 should exceed all double formats. long(1e200) is to
685 # check that we get equality with 1e200 above.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000686 t = int(1e200)
687 cases.extend([0, 1, 2, 1 << 20000, t-1, t, t+1])
Walter Dörwalda0021592005-06-13 21:44:48 +0000688 cases.extend([-x for x in cases])
689 for x in cases:
690 Rx = Rat(x)
691 for y in cases:
692 Ry = Rat(y)
693 Rcmp = cmp(Rx, Ry)
694 xycmp = cmp(x, y)
695 eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp))
696 eq(x == y, Rcmp == 0, Frm("%r == %r %d", x, y, Rcmp))
697 eq(x != y, Rcmp != 0, Frm("%r != %r %d", x, y, Rcmp))
698 eq(x < y, Rcmp < 0, Frm("%r < %r %d", x, y, Rcmp))
699 eq(x <= y, Rcmp <= 0, Frm("%r <= %r %d", x, y, Rcmp))
700 eq(x > y, Rcmp > 0, Frm("%r > %r %d", x, y, Rcmp))
701 eq(x >= y, Rcmp >= 0, Frm("%r >= %r %d", x, y, Rcmp))
Tim Peters307fa782004-09-23 08:06:40 +0000702
Eric Smith0dd1b632008-02-11 17:55:01 +0000703 def test__format__(self):
Eric Smith8c663262007-08-25 02:26:07 +0000704 self.assertEqual(format(123456789, 'd'), '123456789')
705 self.assertEqual(format(123456789, 'd'), '123456789')
706
Eric Smith185e30c2007-08-30 22:23:08 +0000707 # sign and aligning are interdependent
708 self.assertEqual(format(1, "-"), '1')
709 self.assertEqual(format(-1, "-"), '-1')
710 self.assertEqual(format(1, "-3"), ' 1')
711 self.assertEqual(format(-1, "-3"), ' -1')
712 self.assertEqual(format(1, "+3"), ' +1')
713 self.assertEqual(format(-1, "+3"), ' -1')
714 self.assertEqual(format(1, " 3"), ' 1')
715 self.assertEqual(format(-1, " 3"), ' -1')
716 self.assertEqual(format(1, " "), ' 1')
717 self.assertEqual(format(-1, " "), '-1')
718
Eric Smith8c663262007-08-25 02:26:07 +0000719 # hex
720 self.assertEqual(format(3, "x"), "3")
721 self.assertEqual(format(3, "X"), "3")
722 self.assertEqual(format(1234, "x"), "4d2")
723 self.assertEqual(format(-1234, "x"), "-4d2")
724 self.assertEqual(format(1234, "8x"), " 4d2")
Eric Smith185e30c2007-08-30 22:23:08 +0000725 self.assertEqual(format(-1234, "8x"), " -4d2")
Eric Smith8c663262007-08-25 02:26:07 +0000726 self.assertEqual(format(1234, "x"), "4d2")
727 self.assertEqual(format(-1234, "x"), "-4d2")
728 self.assertEqual(format(-3, "x"), "-3")
729 self.assertEqual(format(-3, "X"), "-3")
730 self.assertEqual(format(int('be', 16), "x"), "be")
731 self.assertEqual(format(int('be', 16), "X"), "BE")
732 self.assertEqual(format(-int('be', 16), "x"), "-be")
733 self.assertEqual(format(-int('be', 16), "X"), "-BE")
734
735 # octal
736 self.assertEqual(format(3, "b"), "11")
737 self.assertEqual(format(-3, "b"), "-11")
738 self.assertEqual(format(1234, "b"), "10011010010")
739 self.assertEqual(format(-1234, "b"), "-10011010010")
740 self.assertEqual(format(1234, "-b"), "10011010010")
741 self.assertEqual(format(-1234, "-b"), "-10011010010")
742 self.assertEqual(format(1234, " b"), " 10011010010")
743 self.assertEqual(format(-1234, " b"), "-10011010010")
744 self.assertEqual(format(1234, "+b"), "+10011010010")
745 self.assertEqual(format(-1234, "+b"), "-10011010010")
746
Eric Smith8c663262007-08-25 02:26:07 +0000747 # make sure these are errors
748 self.assertRaises(ValueError, format, 3, "1.3") # precision disallowed
Eric Smith8c663262007-08-25 02:26:07 +0000749 self.assertRaises(ValueError, format, 3, "+c") # sign not allowed
750 # with 'c'
Eric Smithfa767ef2008-01-28 10:59:27 +0000751
752 # ensure that only int and float type specifiers work
Eric Smith7b69c6c2008-01-27 21:07:59 +0000753 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
754 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
Eric Smithfa767ef2008-01-28 10:59:27 +0000755 if not format_spec in 'bcdoxXeEfFgGn%':
Eric Smith7b69c6c2008-01-27 21:07:59 +0000756 self.assertRaises(ValueError, format, 0, format_spec)
757 self.assertRaises(ValueError, format, 1, format_spec)
758 self.assertRaises(ValueError, format, -1, format_spec)
759 self.assertRaises(ValueError, format, 2**100, format_spec)
760 self.assertRaises(ValueError, format, -(2**100), format_spec)
761
Eric Smithfa767ef2008-01-28 10:59:27 +0000762 # ensure that float type specifiers work; format converts
763 # the int to a float
Eric Smith5807c412008-05-11 21:00:57 +0000764 for format_spec in 'eEfFgG%':
Eric Smithfa767ef2008-01-28 10:59:27 +0000765 for value in [0, 1, -1, 100, -100, 1234567890, -1234567890]:
766 self.assertEqual(format(value, format_spec),
767 format(float(value), format_spec))
Eric Smith8c663262007-08-25 02:26:07 +0000768
Christian Heimesa34706f2008-01-04 03:06:10 +0000769 def test_nan_inf(self):
Christian Heimes1aa7b302008-01-04 03:22:53 +0000770 self.assertRaises(OverflowError, int, float('inf'))
Christian Heimes386cd1e2008-01-15 02:01:20 +0000771 self.assertRaises(OverflowError, int, float('nan'))
Christian Heimesa34706f2008-01-04 03:06:10 +0000772
Walter Dörwalda0021592005-06-13 21:44:48 +0000773def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000774 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()