source: python/trunk/Lib/test/test_long.py

Last change on this file was 391, checked in by dmik, 11 years ago

python: Merge vendor 2.7.6 to trunk.

  • Property svn:eol-style set to native
File size: 36.4 KB
Line 
1import unittest
2import sys
3
4import random
5import math
6
7from test import test_int, test_support
8
9# Used for lazy formatting of failure messages
10class Frm(object):
11 def __init__(self, format, *args):
12 self.format = format
13 self.args = args
14
15 def __str__(self):
16 return self.format % self.args
17
18# SHIFT should match the value in longintrepr.h for best testing.
19SHIFT = sys.long_info.bits_per_digit
20BASE = 2 ** SHIFT
21MASK = BASE - 1
22KARATSUBA_CUTOFF = 70 # from longobject.c
23
24# Max number of base BASE digits to use in test cases. Doubling
25# this will more than double the runtime.
26MAXDIGITS = 15
27
28# build some special values
29special = map(long, [0, 1, 2, BASE, BASE >> 1])
30special.append(0x5555555555555555L)
31special.append(0xaaaaaaaaaaaaaaaaL)
32# some solid strings of one bits
33p2 = 4L # 0 and 1 already added
34for i in range(2*SHIFT):
35 special.append(p2 - 1)
36 p2 = p2 << 1
37del p2
38# add complements & negations
39special = special + map(lambda x: ~x, special) + \
40 map(lambda x: -x, special)
41
42L = [
43 ('0', 0),
44 ('1', 1),
45 ('9', 9),
46 ('10', 10),
47 ('99', 99),
48 ('100', 100),
49 ('314', 314),
50 (' 314', 314),
51 ('314 ', 314),
52 (' \t\t 314 \t\t ', 314),
53 (repr(sys.maxint), sys.maxint),
54 (' 1x', ValueError),
55 (' 1 ', 1),
56 (' 1\02 ', ValueError),
57 ('', ValueError),
58 (' ', ValueError),
59 (' \t\t ', ValueError)
60]
61if test_support.have_unicode:
62 L += [
63 (unicode('0'), 0),
64 (unicode('1'), 1),
65 (unicode('9'), 9),
66 (unicode('10'), 10),
67 (unicode('99'), 99),
68 (unicode('100'), 100),
69 (unicode('314'), 314),
70 (unicode(' 314'), 314),
71 (unicode('\u0663\u0661\u0664 ','raw-unicode-escape'), 314),
72 (unicode(' \t\t 314 \t\t '), 314),
73 (unicode(' 1x'), ValueError),
74 (unicode(' 1 '), 1),
75 (unicode(' 1\02 '), ValueError),
76 (unicode(''), ValueError),
77 (unicode(' '), ValueError),
78 (unicode(' \t\t '), ValueError),
79 (unichr(0x200), ValueError),
80]
81
82class LongTest(test_int.IntLongCommonTests, unittest.TestCase):
83
84 ntype = long
85
86 # Get quasi-random long consisting of ndigits digits (in base BASE).
87 # quasi == the most-significant digit will not be 0, and the number
88 # is constructed to contain long strings of 0 and 1 bits. These are
89 # more likely than random bits to provoke digit-boundary errors.
90 # The sign of the number is also random.
91
92 def getran(self, ndigits):
93 self.assertTrue(ndigits > 0)
94 nbits_hi = ndigits * SHIFT
95 nbits_lo = nbits_hi - SHIFT + 1
96 answer = 0L
97 nbits = 0
98 r = int(random.random() * (SHIFT * 2)) | 1 # force 1 bits to start
99 while nbits < nbits_lo:
100 bits = (r >> 1) + 1
101 bits = min(bits, nbits_hi - nbits)
102 self.assertTrue(1 <= bits <= SHIFT)
103 nbits = nbits + bits
104 answer = answer << bits
105 if r & 1:
106 answer = answer | ((1 << bits) - 1)
107 r = int(random.random() * (SHIFT * 2))
108 self.assertTrue(nbits_lo <= nbits <= nbits_hi)
109 if random.random() < 0.5:
110 answer = -answer
111 return answer
112
113 # Get random long consisting of ndigits random digits (relative to base
114 # BASE). The sign bit is also random.
115
116 def getran2(ndigits):
117 answer = 0L
118 for i in xrange(ndigits):
119 answer = (answer << SHIFT) | random.randint(0, MASK)
120 if random.random() < 0.5:
121 answer = -answer
122 return answer
123
124 def check_division(self, x, y):
125 eq = self.assertEqual
126 q, r = divmod(x, y)
127 q2, r2 = x//y, x%y
128 pab, pba = x*y, y*x
129 eq(pab, pba, Frm("multiplication does not commute for %r and %r", x, y))
130 eq(q, q2, Frm("divmod returns different quotient than / for %r and %r", x, y))
131 eq(r, r2, Frm("divmod returns different mod than %% for %r and %r", x, y))
132 eq(x, q*y + r, Frm("x != q*y + r after divmod on x=%r, y=%r", x, y))
133 if y > 0:
134 self.assertTrue(0 <= r < y, Frm("bad mod from divmod on %r and %r", x, y))
135 else:
136 self.assertTrue(y < r <= 0, Frm("bad mod from divmod on %r and %r", x, y))
137
138 def test_division(self):
139 digits = range(1, MAXDIGITS+1) + range(KARATSUBA_CUTOFF,
140 KARATSUBA_CUTOFF + 14)
141 digits.append(KARATSUBA_CUTOFF * 3)
142 for lenx in digits:
143 x = self.getran(lenx)
144 for leny in digits:
145 y = self.getran(leny) or 1L
146 self.check_division(x, y)
147
148 # specific numbers chosen to exercise corner cases of the
149 # current long division implementation
150
151 # 30-bit cases involving a quotient digit estimate of BASE+1
152 self.check_division(1231948412290879395966702881L,
153 1147341367131428698L)
154 self.check_division(815427756481275430342312021515587883L,
155 707270836069027745L)
156 self.check_division(627976073697012820849443363563599041L,
157 643588798496057020L)
158 self.check_division(1115141373653752303710932756325578065L,
159 1038556335171453937726882627L)
160 # 30-bit cases that require the post-subtraction correction step
161 self.check_division(922498905405436751940989320930368494L,
162 949985870686786135626943396L)
163 self.check_division(768235853328091167204009652174031844L,
164 1091555541180371554426545266L)
165
166 # 15-bit cases involving a quotient digit estimate of BASE+1
167 self.check_division(20172188947443L, 615611397L)
168 self.check_division(1020908530270155025L, 950795710L)
169 self.check_division(128589565723112408L, 736393718L)
170 self.check_division(609919780285761575L, 18613274546784L)
171 # 15-bit cases that require the post-subtraction correction step
172 self.check_division(710031681576388032L, 26769404391308L)
173 self.check_division(1933622614268221L, 30212853348836L)
174
175
176
177 def test_karatsuba(self):
178 digits = range(1, 5) + range(KARATSUBA_CUTOFF, KARATSUBA_CUTOFF + 10)
179 digits.extend([KARATSUBA_CUTOFF * 10, KARATSUBA_CUTOFF * 100])
180
181 bits = [digit * SHIFT for digit in digits]
182
183 # Test products of long strings of 1 bits -- (2**x-1)*(2**y-1) ==
184 # 2**(x+y) - 2**x - 2**y + 1, so the proper result is easy to check.
185 for abits in bits:
186 a = (1L << abits) - 1
187 for bbits in bits:
188 if bbits < abits:
189 continue
190 b = (1L << bbits) - 1
191 x = a * b
192 y = ((1L << (abits + bbits)) -
193 (1L << abits) -
194 (1L << bbits) +
195 1)
196 self.assertEqual(x, y,
197 Frm("bad result for a*b: a=%r, b=%r, x=%r, y=%r", a, b, x, y))
198
199 def check_bitop_identities_1(self, x):
200 eq = self.assertEqual
201 eq(x & 0, 0, Frm("x & 0 != 0 for x=%r", x))
202 eq(x | 0, x, Frm("x | 0 != x for x=%r", x))
203 eq(x ^ 0, x, Frm("x ^ 0 != x for x=%r", x))
204 eq(x & -1, x, Frm("x & -1 != x for x=%r", x))
205 eq(x | -1, -1, Frm("x | -1 != -1 for x=%r", x))
206 eq(x ^ -1, ~x, Frm("x ^ -1 != ~x for x=%r", x))
207 eq(x, ~~x, Frm("x != ~~x for x=%r", x))
208 eq(x & x, x, Frm("x & x != x for x=%r", x))
209 eq(x | x, x, Frm("x | x != x for x=%r", x))
210 eq(x ^ x, 0, Frm("x ^ x != 0 for x=%r", x))
211 eq(x & ~x, 0, Frm("x & ~x != 0 for x=%r", x))
212 eq(x | ~x, -1, Frm("x | ~x != -1 for x=%r", x))
213 eq(x ^ ~x, -1, Frm("x ^ ~x != -1 for x=%r", x))
214 eq(-x, 1 + ~x, Frm("not -x == 1 + ~x for x=%r", x))
215 eq(-x, ~(x-1), Frm("not -x == ~(x-1) forx =%r", x))
216 for n in xrange(2*SHIFT):
217 p2 = 2L ** n
218 eq(x << n >> n, x,
219 Frm("x << n >> n != x for x=%r, n=%r", (x, n)))
220 eq(x // p2, x >> n,
221 Frm("x // p2 != x >> n for x=%r n=%r p2=%r", (x, n, p2)))
222 eq(x * p2, x << n,
223 Frm("x * p2 != x << n for x=%r n=%r p2=%r", (x, n, p2)))
224 eq(x & -p2, x >> n << n,
225 Frm("not x & -p2 == x >> n << n for x=%r n=%r p2=%r", (x, n, p2)))
226 eq(x & -p2, x & ~(p2 - 1),
227 Frm("not x & -p2 == x & ~(p2 - 1) for x=%r n=%r p2=%r", (x, n, p2)))
228
229 def check_bitop_identities_2(self, x, y):
230 eq = self.assertEqual
231 eq(x & y, y & x, Frm("x & y != y & x for x=%r, y=%r", (x, y)))
232 eq(x | y, y | x, Frm("x | y != y | x for x=%r, y=%r", (x, y)))
233 eq(x ^ y, y ^ x, Frm("x ^ y != y ^ x for x=%r, y=%r", (x, y)))
234 eq(x ^ y ^ x, y, Frm("x ^ y ^ x != y for x=%r, y=%r", (x, y)))
235 eq(x & y, ~(~x | ~y), Frm("x & y != ~(~x | ~y) for x=%r, y=%r", (x, y)))
236 eq(x | y, ~(~x & ~y), Frm("x | y != ~(~x & ~y) for x=%r, y=%r", (x, y)))
237 eq(x ^ y, (x | y) & ~(x & y),
238 Frm("x ^ y != (x | y) & ~(x & y) for x=%r, y=%r", (x, y)))
239 eq(x ^ y, (x & ~y) | (~x & y),
240 Frm("x ^ y == (x & ~y) | (~x & y) for x=%r, y=%r", (x, y)))
241 eq(x ^ y, (x | y) & (~x | ~y),
242 Frm("x ^ y == (x | y) & (~x | ~y) for x=%r, y=%r", (x, y)))
243
244 def check_bitop_identities_3(self, x, y, z):
245 eq = self.assertEqual
246 eq((x & y) & z, x & (y & z),
247 Frm("(x & y) & z != x & (y & z) for x=%r, y=%r, z=%r", (x, y, z)))
248 eq((x | y) | z, x | (y | z),
249 Frm("(x | y) | z != x | (y | z) for x=%r, y=%r, z=%r", (x, y, z)))
250 eq((x ^ y) ^ z, x ^ (y ^ z),
251 Frm("(x ^ y) ^ z != x ^ (y ^ z) for x=%r, y=%r, z=%r", (x, y, z)))
252 eq(x & (y | z), (x & y) | (x & z),
253 Frm("x & (y | z) != (x & y) | (x & z) for x=%r, y=%r, z=%r", (x, y, z)))
254 eq(x | (y & z), (x | y) & (x | z),
255 Frm("x | (y & z) != (x | y) & (x | z) for x=%r, y=%r, z=%r", (x, y, z)))
256
257 def test_bitop_identities(self):
258 for x in special:
259 self.check_bitop_identities_1(x)
260 digits = xrange(1, MAXDIGITS+1)
261 for lenx in digits:
262 x = self.getran(lenx)
263 self.check_bitop_identities_1(x)
264 for leny in digits:
265 y = self.getran(leny)
266 self.check_bitop_identities_2(x, y)
267 self.check_bitop_identities_3(x, y, self.getran((lenx + leny)//2))
268
269 def slow_format(self, x, base):
270 if (x, base) == (0, 8):
271 # this is an oddball!
272 return "0L"
273 digits = []
274 sign = 0
275 if x < 0:
276 sign, x = 1, -x
277 while x:
278 x, r = divmod(x, base)
279 digits.append(int(r))
280 digits.reverse()
281 digits = digits or [0]
282 return '-'[:sign] + \
283 {8: '0', 10: '', 16: '0x'}[base] + \
284 "".join(map(lambda i: "0123456789abcdef"[i], digits)) + "L"
285
286 def check_format_1(self, x):
287 for base, mapper in (8, oct), (10, repr), (16, hex):
288 got = mapper(x)
289 expected = self.slow_format(x, base)
290 msg = Frm("%s returned %r but expected %r for %r",
291 mapper.__name__, got, expected, x)
292 self.assertEqual(got, expected, msg)
293 self.assertEqual(long(got, 0), x, Frm('long("%s", 0) != %r', got, x))
294 # str() has to be checked a little differently since there's no
295 # trailing "L"
296 got = str(x)
297 expected = self.slow_format(x, 10)[:-1]
298 msg = Frm("%s returned %r but expected %r for %r",
299 mapper.__name__, got, expected, x)
300 self.assertEqual(got, expected, msg)
301
302 def test_format(self):
303 for x in special:
304 self.check_format_1(x)
305 for i in xrange(10):
306 for lenx in xrange(1, MAXDIGITS+1):
307 x = self.getran(lenx)
308 self.check_format_1(x)
309
310 def test_long(self):
311 self.assertEqual(long(314), 314L)
312 self.assertEqual(long(3.14), 3L)
313 self.assertEqual(long(314L), 314L)
314 # Check that long() of basic types actually returns a long
315 self.assertEqual(type(long(314)), long)
316 self.assertEqual(type(long(3.14)), long)
317 self.assertEqual(type(long(314L)), long)
318 # Check that conversion from float truncates towards zero
319 self.assertEqual(long(-3.14), -3L)
320 self.assertEqual(long(3.9), 3L)
321 self.assertEqual(long(-3.9), -3L)
322 self.assertEqual(long(3.5), 3L)
323 self.assertEqual(long(-3.5), -3L)
324 self.assertEqual(long("-3"), -3L)
325 self.assertEqual(long("0b10", 2), 2L)
326 self.assertEqual(long("0o10", 8), 8L)
327 self.assertEqual(long("0x10", 16), 16L)
328 if test_support.have_unicode:
329 self.assertEqual(long(unicode("-3")), -3L)
330 # Different base:
331 self.assertEqual(long("10",16), 16L)
332 if test_support.have_unicode:
333 self.assertEqual(long(unicode("10"),16), 16L)
334 # Check conversions from string (same test set as for int(), and then some)
335 LL = [
336 ('1' + '0'*20, 10L**20),
337 ('1' + '0'*100, 10L**100)
338 ]
339 L2 = L[:]
340 if test_support.have_unicode:
341 L2 += [
342 (unicode('1') + unicode('0')*20, 10L**20),
343 (unicode('1') + unicode('0')*100, 10L**100),
344 ]
345 for s, v in L2 + LL:
346 for sign in "", "+", "-":
347 for prefix in "", " ", "\t", " \t\t ":
348 ss = prefix + sign + s
349 vv = v
350 if sign == "-" and v is not ValueError:
351 vv = -v
352 try:
353 self.assertEqual(long(ss), long(vv))
354 except v:
355 pass
356
357 self.assertRaises(ValueError, long, '123\0')
358 self.assertRaises(ValueError, long, '53', 40)
359 self.assertRaises(TypeError, long, 1, 12)
360
361 # tests with base 0
362 self.assertEqual(long(' 0123 ', 0), 83)
363 self.assertEqual(long(' 0123 ', 0), 83)
364 self.assertEqual(long('000', 0), 0)
365 self.assertEqual(long('0o123', 0), 83)
366 self.assertEqual(long('0x123', 0), 291)
367 self.assertEqual(long('0b100', 0), 4)
368 self.assertEqual(long(' 0O123 ', 0), 83)
369 self.assertEqual(long(' 0X123 ', 0), 291)
370 self.assertEqual(long(' 0B100 ', 0), 4)
371 self.assertEqual(long('0', 0), 0)
372 self.assertEqual(long('+0', 0), 0)
373 self.assertEqual(long('-0', 0), 0)
374 self.assertEqual(long('00', 0), 0)
375 self.assertRaises(ValueError, long, '08', 0)
376 self.assertRaises(ValueError, long, '-012395', 0)
377
378 # SF patch #1638879: embedded NULs were not detected with
379 # explicit base
380 self.assertRaises(ValueError, long, '123\0', 10)
381 self.assertRaises(ValueError, long, '123\x00 245', 20)
382
383 self.assertEqual(long('100000000000000000000000000000000', 2),
384 4294967296)
385 self.assertEqual(long('102002022201221111211', 3), 4294967296)
386 self.assertEqual(long('10000000000000000', 4), 4294967296)
387 self.assertEqual(long('32244002423141', 5), 4294967296)
388 self.assertEqual(long('1550104015504', 6), 4294967296)
389 self.assertEqual(long('211301422354', 7), 4294967296)
390 self.assertEqual(long('40000000000', 8), 4294967296)
391 self.assertEqual(long('12068657454', 9), 4294967296)
392 self.assertEqual(long('4294967296', 10), 4294967296)
393 self.assertEqual(long('1904440554', 11), 4294967296)
394 self.assertEqual(long('9ba461594', 12), 4294967296)
395 self.assertEqual(long('535a79889', 13), 4294967296)
396 self.assertEqual(long('2ca5b7464', 14), 4294967296)
397 self.assertEqual(long('1a20dcd81', 15), 4294967296)
398 self.assertEqual(long('100000000', 16), 4294967296)
399 self.assertEqual(long('a7ffda91', 17), 4294967296)
400 self.assertEqual(long('704he7g4', 18), 4294967296)
401 self.assertEqual(long('4f5aff66', 19), 4294967296)
402 self.assertEqual(long('3723ai4g', 20), 4294967296)
403 self.assertEqual(long('281d55i4', 21), 4294967296)
404 self.assertEqual(long('1fj8b184', 22), 4294967296)
405 self.assertEqual(long('1606k7ic', 23), 4294967296)
406 self.assertEqual(long('mb994ag', 24), 4294967296)
407 self.assertEqual(long('hek2mgl', 25), 4294967296)
408 self.assertEqual(long('dnchbnm', 26), 4294967296)
409 self.assertEqual(long('b28jpdm', 27), 4294967296)
410 self.assertEqual(long('8pfgih4', 28), 4294967296)
411 self.assertEqual(long('76beigg', 29), 4294967296)
412 self.assertEqual(long('5qmcpqg', 30), 4294967296)
413 self.assertEqual(long('4q0jto4', 31), 4294967296)
414 self.assertEqual(long('4000000', 32), 4294967296)
415 self.assertEqual(long('3aokq94', 33), 4294967296)
416 self.assertEqual(long('2qhxjli', 34), 4294967296)
417 self.assertEqual(long('2br45qb', 35), 4294967296)
418 self.assertEqual(long('1z141z4', 36), 4294967296)
419
420 self.assertEqual(long('100000000000000000000000000000001', 2),
421 4294967297)
422 self.assertEqual(long('102002022201221111212', 3), 4294967297)
423 self.assertEqual(long('10000000000000001', 4), 4294967297)
424 self.assertEqual(long('32244002423142', 5), 4294967297)
425 self.assertEqual(long('1550104015505', 6), 4294967297)
426 self.assertEqual(long('211301422355', 7), 4294967297)
427 self.assertEqual(long('40000000001', 8), 4294967297)
428 self.assertEqual(long('12068657455', 9), 4294967297)
429 self.assertEqual(long('4294967297', 10), 4294967297)
430 self.assertEqual(long('1904440555', 11), 4294967297)
431 self.assertEqual(long('9ba461595', 12), 4294967297)
432 self.assertEqual(long('535a7988a', 13), 4294967297)
433 self.assertEqual(long('2ca5b7465', 14), 4294967297)
434 self.assertEqual(long('1a20dcd82', 15), 4294967297)
435 self.assertEqual(long('100000001', 16), 4294967297)
436 self.assertEqual(long('a7ffda92', 17), 4294967297)
437 self.assertEqual(long('704he7g5', 18), 4294967297)
438 self.assertEqual(long('4f5aff67', 19), 4294967297)
439 self.assertEqual(long('3723ai4h', 20), 4294967297)
440 self.assertEqual(long('281d55i5', 21), 4294967297)
441 self.assertEqual(long('1fj8b185', 22), 4294967297)
442 self.assertEqual(long('1606k7id', 23), 4294967297)
443 self.assertEqual(long('mb994ah', 24), 4294967297)
444 self.assertEqual(long('hek2mgm', 25), 4294967297)
445 self.assertEqual(long('dnchbnn', 26), 4294967297)
446 self.assertEqual(long('b28jpdn', 27), 4294967297)
447 self.assertEqual(long('8pfgih5', 28), 4294967297)
448 self.assertEqual(long('76beigh', 29), 4294967297)
449 self.assertEqual(long('5qmcpqh', 30), 4294967297)
450 self.assertEqual(long('4q0jto5', 31), 4294967297)
451 self.assertEqual(long('4000001', 32), 4294967297)
452 self.assertEqual(long('3aokq95', 33), 4294967297)
453 self.assertEqual(long('2qhxjlj', 34), 4294967297)
454 self.assertEqual(long('2br45qc', 35), 4294967297)
455 self.assertEqual(long('1z141z5', 36), 4294967297)
456
457
458 def test_conversion(self):
459 # Test __long__()
460 class ClassicMissingMethods:
461 pass
462 self.assertRaises(AttributeError, long, ClassicMissingMethods())
463
464 class MissingMethods(object):
465 pass
466 self.assertRaises(TypeError, long, MissingMethods())
467
468 class Foo0:
469 def __long__(self):
470 return 42L
471
472 class Foo1(object):
473 def __long__(self):
474 return 42L
475
476 class Foo2(long):
477 def __long__(self):
478 return 42L
479
480 class Foo3(long):
481 def __long__(self):
482 return self
483
484 class Foo4(long):
485 def __long__(self):
486 return 42
487
488 class Foo5(long):
489 def __long__(self):
490 return 42.
491
492 self.assertEqual(long(Foo0()), 42L)
493 self.assertEqual(long(Foo1()), 42L)
494 self.assertEqual(long(Foo2()), 42L)
495 self.assertEqual(long(Foo3()), 0)
496 self.assertEqual(long(Foo4()), 42)
497 self.assertRaises(TypeError, long, Foo5())
498
499 class Classic:
500 pass
501 for base in (object, Classic):
502 class LongOverridesTrunc(base):
503 def __long__(self):
504 return 42
505 def __trunc__(self):
506 return -12
507 self.assertEqual(long(LongOverridesTrunc()), 42)
508
509 class JustTrunc(base):
510 def __trunc__(self):
511 return 42
512 self.assertEqual(long(JustTrunc()), 42)
513
514 for trunc_result_base in (object, Classic):
515 class Integral(trunc_result_base):
516 def __int__(self):
517 return 42
518
519 class TruncReturnsNonLong(base):
520 def __trunc__(self):
521 return Integral()
522 self.assertEqual(long(TruncReturnsNonLong()), 42)
523
524 class NonIntegral(trunc_result_base):
525 def __trunc__(self):
526 # Check that we avoid infinite recursion.
527 return NonIntegral()
528
529 class TruncReturnsNonIntegral(base):
530 def __trunc__(self):
531 return NonIntegral()
532 try:
533 long(TruncReturnsNonIntegral())
534 except TypeError as e:
535 self.assertEqual(str(e),
536 "__trunc__ returned non-Integral"
537 " (type NonIntegral)")
538 else:
539 self.fail("Failed to raise TypeError with %s" %
540 ((base, trunc_result_base),))
541
542 def test_misc(self):
543
544 # check the extremes in int<->long conversion
545 hugepos = sys.maxint
546 hugeneg = -hugepos - 1
547 hugepos_aslong = long(hugepos)
548 hugeneg_aslong = long(hugeneg)
549 self.assertEqual(hugepos, hugepos_aslong, "long(sys.maxint) != sys.maxint")
550 self.assertEqual(hugeneg, hugeneg_aslong,
551 "long(-sys.maxint-1) != -sys.maxint-1")
552
553 # long -> int should not fail for hugepos_aslong or hugeneg_aslong
554 x = int(hugepos_aslong)
555 try:
556 self.assertEqual(x, hugepos,
557 "converting sys.maxint to long and back to int fails")
558 except OverflowError:
559 self.fail("int(long(sys.maxint)) overflowed!")
560 if not isinstance(x, int):
561 self.fail("int(long(sys.maxint)) should have returned int")
562 x = int(hugeneg_aslong)
563 try:
564 self.assertEqual(x, hugeneg,
565 "converting -sys.maxint-1 to long and back to int fails")
566 except OverflowError:
567 self.fail("int(long(-sys.maxint-1)) overflowed!")
568 if not isinstance(x, int):
569 self.fail("int(long(-sys.maxint-1)) should have returned int")
570 # but long -> int should overflow for hugepos+1 and hugeneg-1
571 x = hugepos_aslong + 1
572 try:
573 y = int(x)
574 except OverflowError:
575 self.fail("int(long(sys.maxint) + 1) mustn't overflow")
576 self.assertIsInstance(y, long,
577 "int(long(sys.maxint) + 1) should have returned long")
578
579 x = hugeneg_aslong - 1
580 try:
581 y = int(x)
582 except OverflowError:
583 self.fail("int(long(-sys.maxint-1) - 1) mustn't overflow")
584 self.assertIsInstance(y, long,
585 "int(long(-sys.maxint-1) - 1) should have returned long")
586
587 class long2(long):
588 pass
589 x = long2(1L<<100)
590 y = int(x)
591 self.assertTrue(type(y) is long,
592 "overflowing int conversion must return long not long subtype")
593
594 # long -> Py_ssize_t conversion
595 class X(object):
596 def __getslice__(self, i, j):
597 return i, j
598
599 with test_support.check_py3k_warnings():
600 self.assertEqual(X()[-5L:7L], (-5, 7))
601 # use the clamping effect to test the smallest and largest longs
602 # that fit a Py_ssize_t
603 slicemin, slicemax = X()[-2L**100:2L**100]
604 self.assertEqual(X()[slicemin:slicemax], (slicemin, slicemax))
605
606 def test_issue9869(self):
607 # Issue 9869: Interpreter crash when initializing an instance
608 # of a long subclass from an object whose __long__ method returns
609 # a plain int.
610 class BadLong(object):
611 def __long__(self):
612 return 1000000
613
614 class MyLong(long):
615 pass
616
617 x = MyLong(BadLong())
618 self.assertIsInstance(x, long)
619 self.assertEqual(x, 1000000)
620
621
622# ----------------------------------- tests of auto int->long conversion
623
624 def test_auto_overflow(self):
625 special = [0, 1, 2, 3, sys.maxint-1, sys.maxint, sys.maxint+1]
626 sqrt = int(math.sqrt(sys.maxint))
627 special.extend([sqrt-1, sqrt, sqrt+1])
628 special.extend([-i for i in special])
629
630 def checkit(*args):
631 # Heavy use of nested scopes here!
632 self.assertEqual(got, expected,
633 Frm("for %r expected %r got %r", args, expected, got))
634
635 for x in special:
636 longx = long(x)
637
638 expected = -longx
639 got = -x
640 checkit('-', x)
641
642 for y in special:
643 longy = long(y)
644
645 expected = longx + longy
646 got = x + y
647 checkit(x, '+', y)
648
649 expected = longx - longy
650 got = x - y
651 checkit(x, '-', y)
652
653 expected = longx * longy
654 got = x * y
655 checkit(x, '*', y)
656
657 if y:
658 with test_support.check_py3k_warnings():
659 expected = longx / longy
660 got = x / y
661 checkit(x, '/', y)
662
663 expected = longx // longy
664 got = x // y
665 checkit(x, '//', y)
666
667 expected = divmod(longx, longy)
668 got = divmod(longx, longy)
669 checkit(x, 'divmod', y)
670
671 if abs(y) < 5 and not (x == 0 and y < 0):
672 expected = longx ** longy
673 got = x ** y
674 checkit(x, '**', y)
675
676 for z in special:
677 if z != 0 :
678 if y >= 0:
679 expected = pow(longx, longy, long(z))
680 got = pow(x, y, z)
681 checkit('pow', x, y, '%', z)
682 else:
683 self.assertRaises(TypeError, pow,longx, longy, long(z))
684
685 @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
686 "test requires IEEE 754 doubles")
687 def test_float_conversion(self):
688 import sys
689 DBL_MAX = sys.float_info.max
690 DBL_MAX_EXP = sys.float_info.max_exp
691 DBL_MANT_DIG = sys.float_info.mant_dig
692
693 exact_values = [0L, 1L, 2L,
694 long(2**53-3),
695 long(2**53-2),
696 long(2**53-1),
697 long(2**53),
698 long(2**53+2),
699 long(2**54-4),
700 long(2**54-2),
701 long(2**54),
702 long(2**54+4)]
703 for x in exact_values:
704 self.assertEqual(long(float(x)), x)
705 self.assertEqual(long(float(-x)), -x)
706
707 # test round-half-even
708 for x, y in [(1, 0), (2, 2), (3, 4), (4, 4), (5, 4), (6, 6), (7, 8)]:
709 for p in xrange(15):
710 self.assertEqual(long(float(2L**p*(2**53+x))), 2L**p*(2**53+y))
711
712 for x, y in [(0, 0), (1, 0), (2, 0), (3, 4), (4, 4), (5, 4), (6, 8),
713 (7, 8), (8, 8), (9, 8), (10, 8), (11, 12), (12, 12),
714 (13, 12), (14, 16), (15, 16)]:
715 for p in xrange(15):
716 self.assertEqual(long(float(2L**p*(2**54+x))), 2L**p*(2**54+y))
717
718 # behaviour near extremes of floating-point range
719 long_dbl_max = long(DBL_MAX)
720 top_power = 2**DBL_MAX_EXP
721 halfway = (long_dbl_max + top_power)//2
722 self.assertEqual(float(long_dbl_max), DBL_MAX)
723 self.assertEqual(float(long_dbl_max+1), DBL_MAX)
724 self.assertEqual(float(halfway-1), DBL_MAX)
725 self.assertRaises(OverflowError, float, halfway)
726 self.assertEqual(float(1-halfway), -DBL_MAX)
727 self.assertRaises(OverflowError, float, -halfway)
728 self.assertRaises(OverflowError, float, top_power-1)
729 self.assertRaises(OverflowError, float, top_power)
730 self.assertRaises(OverflowError, float, top_power+1)
731 self.assertRaises(OverflowError, float, 2*top_power-1)
732 self.assertRaises(OverflowError, float, 2*top_power)
733 self.assertRaises(OverflowError, float, top_power*top_power)
734
735 for p in xrange(100):
736 x = long(2**p * (2**53 + 1) + 1)
737 y = long(2**p * (2**53+ 2))
738 self.assertEqual(long(float(x)), y)
739
740 x = long(2**p * (2**53 + 1))
741 y = long(2**p * 2**53)
742 self.assertEqual(long(float(x)), y)
743
744 def test_float_overflow(self):
745 for x in -2.0, -1.0, 0.0, 1.0, 2.0:
746 self.assertEqual(float(long(x)), x)
747
748 shuge = '12345' * 120
749 huge = 1L << 30000
750 mhuge = -huge
751 namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math}
752 for test in ["float(huge)", "float(mhuge)",
753 "complex(huge)", "complex(mhuge)",
754 "complex(huge, 1)", "complex(mhuge, 1)",
755 "complex(1, huge)", "complex(1, mhuge)",
756 "1. + huge", "huge + 1.", "1. + mhuge", "mhuge + 1.",
757 "1. - huge", "huge - 1.", "1. - mhuge", "mhuge - 1.",
758 "1. * huge", "huge * 1.", "1. * mhuge", "mhuge * 1.",
759 "1. // huge", "huge // 1.", "1. // mhuge", "mhuge // 1.",
760 "1. / huge", "huge / 1.", "1. / mhuge", "mhuge / 1.",
761 "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.",
762 "math.sin(huge)", "math.sin(mhuge)",
763 "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better
764 "math.floor(huge)", "math.floor(mhuge)"]:
765
766 self.assertRaises(OverflowError, eval, test, namespace)
767
768 # XXX Perhaps float(shuge) can raise OverflowError on some box?
769 # The comparison should not.
770 self.assertNotEqual(float(shuge), int(shuge),
771 "float(shuge) should not equal int(shuge)")
772
773 def test_logs(self):
774 LOG10E = math.log10(math.e)
775
776 for exp in range(10) + [100, 1000, 10000]:
777 value = 10 ** exp
778 log10 = math.log10(value)
779 self.assertAlmostEqual(log10, exp)
780
781 # log10(value) == exp, so log(value) == log10(value)/log10(e) ==
782 # exp/LOG10E
783 expected = exp / LOG10E
784 log = math.log(value)
785 self.assertAlmostEqual(log, expected)
786
787 for bad in -(1L << 10000), -2L, 0L:
788 self.assertRaises(ValueError, math.log, bad)
789 self.assertRaises(ValueError, math.log10, bad)
790
791 def test_mixed_compares(self):
792 eq = self.assertEqual
793
794 # We're mostly concerned with that mixing floats and longs does the
795 # right stuff, even when longs are too large to fit in a float.
796 # The safest way to check the results is to use an entirely different
797 # method, which we do here via a skeletal rational class (which
798 # represents all Python ints, longs and floats exactly).
799 class Rat:
800 def __init__(self, value):
801 if isinstance(value, (int, long)):
802 self.n = value
803 self.d = 1
804 elif isinstance(value, float):
805 # Convert to exact rational equivalent.
806 f, e = math.frexp(abs(value))
807 assert f == 0 or 0.5 <= f < 1.0
808 # |value| = f * 2**e exactly
809
810 # Suck up CHUNK bits at a time; 28 is enough so that we suck
811 # up all bits in 2 iterations for all known binary double-
812 # precision formats, and small enough to fit in an int.
813 CHUNK = 28
814 top = 0
815 # invariant: |value| = (top + f) * 2**e exactly
816 while f:
817 f = math.ldexp(f, CHUNK)
818 digit = int(f)
819 assert digit >> CHUNK == 0
820 top = (top << CHUNK) | digit
821 f -= digit
822 assert 0.0 <= f < 1.0
823 e -= CHUNK
824
825 # Now |value| = top * 2**e exactly.
826 if e >= 0:
827 n = top << e
828 d = 1
829 else:
830 n = top
831 d = 1 << -e
832 if value < 0:
833 n = -n
834 self.n = n
835 self.d = d
836 assert float(n) / float(d) == value
837 else:
838 raise TypeError("can't deal with %r" % value)
839
840 def __cmp__(self, other):
841 if not isinstance(other, Rat):
842 other = Rat(other)
843 return cmp(self.n * other.d, self.d * other.n)
844
845 cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200]
846 # 2**48 is an important boundary in the internals. 2**53 is an
847 # important boundary for IEEE double precision.
848 for t in 2.0**48, 2.0**50, 2.0**53:
849 cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0,
850 long(t-1), long(t), long(t+1)])
851 cases.extend([0, 1, 2, sys.maxint, float(sys.maxint)])
852 # 1L<<20000 should exceed all double formats. long(1e200) is to
853 # check that we get equality with 1e200 above.
854 t = long(1e200)
855 cases.extend([0L, 1L, 2L, 1L << 20000, t-1, t, t+1])
856 cases.extend([-x for x in cases])
857 for x in cases:
858 Rx = Rat(x)
859 for y in cases:
860 Ry = Rat(y)
861 Rcmp = cmp(Rx, Ry)
862 xycmp = cmp(x, y)
863 eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp))
864 eq(x == y, Rcmp == 0, Frm("%r == %r %d", x, y, Rcmp))
865 eq(x != y, Rcmp != 0, Frm("%r != %r %d", x, y, Rcmp))
866 eq(x < y, Rcmp < 0, Frm("%r < %r %d", x, y, Rcmp))
867 eq(x <= y, Rcmp <= 0, Frm("%r <= %r %d", x, y, Rcmp))
868 eq(x > y, Rcmp > 0, Frm("%r > %r %d", x, y, Rcmp))
869 eq(x >= y, Rcmp >= 0, Frm("%r >= %r %d", x, y, Rcmp))
870
871 def test_nan_inf(self):
872 self.assertRaises(OverflowError, long, float('inf'))
873 self.assertRaises(OverflowError, long, float('-inf'))
874 self.assertRaises(ValueError, long, float('nan'))
875
876 def test_bit_length(self):
877 tiny = 1e-10
878 for x in xrange(-65000, 65000):
879 x = long(x)
880 k = x.bit_length()
881 # Check equivalence with Python version
882 self.assertEqual(k, len(bin(x).lstrip('-0b')))
883 # Behaviour as specified in the docs
884 if x != 0:
885 self.assertTrue(2**(k-1) <= abs(x) < 2**k)
886 else:
887 self.assertEqual(k, 0)
888 # Alternative definition: x.bit_length() == 1 + floor(log_2(x))
889 if x != 0:
890 # When x is an exact power of 2, numeric errors can
891 # cause floor(log(x)/log(2)) to be one too small; for
892 # small x this can be fixed by adding a small quantity
893 # to the quotient before taking the floor.
894 self.assertEqual(k, 1 + math.floor(
895 math.log(abs(x))/math.log(2) + tiny))
896
897 self.assertEqual((0L).bit_length(), 0)
898 self.assertEqual((1L).bit_length(), 1)
899 self.assertEqual((-1L).bit_length(), 1)
900 self.assertEqual((2L).bit_length(), 2)
901 self.assertEqual((-2L).bit_length(), 2)
902 for i in [2, 3, 15, 16, 17, 31, 32, 33, 63, 64, 234]:
903 a = 2L**i
904 self.assertEqual((a-1).bit_length(), i)
905 self.assertEqual((1-a).bit_length(), i)
906 self.assertEqual((a).bit_length(), i+1)
907 self.assertEqual((-a).bit_length(), i+1)
908 self.assertEqual((a+1).bit_length(), i+1)
909 self.assertEqual((-a-1).bit_length(), i+1)
910
911
912def test_main():
913 test_support.run_unittest(LongTest)
914
915if __name__ == "__main__":
916 test_main()
Note: See TracBrowser for help on using the repository browser.