symbian-qemu-0.9.1-12/python-2.6.1/Lib/test/test_long.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 import unittest
       
     2 from test import test_support
       
     3 import sys
       
     4 
       
     5 import random
       
     6 
       
     7 # Used for lazy formatting of failure messages
       
     8 class 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
       
    15 
       
    16 # SHIFT should match the value in longintrepr.h for best testing.
       
    17 SHIFT = 15
       
    18 BASE = 2 ** SHIFT
       
    19 MASK = BASE - 1
       
    20 KARATSUBA_CUTOFF = 70   # from longobject.c
       
    21 
       
    22 # Max number of base BASE digits to use in test cases.  Doubling
       
    23 # this will more than double the runtime.
       
    24 MAXDIGITS = 15
       
    25 
       
    26 # build some special values
       
    27 special = map(long, [0, 1, 2, BASE, BASE >> 1])
       
    28 special.append(0x5555555555555555L)
       
    29 special.append(0xaaaaaaaaaaaaaaaaL)
       
    30 #  some solid strings of one bits
       
    31 p2 = 4L  # 0 and 1 already added
       
    32 for i in range(2*SHIFT):
       
    33     special.append(p2 - 1)
       
    34     p2 = p2 << 1
       
    35 del p2
       
    36 # add complements & negations
       
    37 special = special + map(lambda x: ~x, special) + \
       
    38                     map(lambda x: -x, special)
       
    39 
       
    40 L = [
       
    41         ('0', 0),
       
    42         ('1', 1),
       
    43         ('9', 9),
       
    44         ('10', 10),
       
    45         ('99', 99),
       
    46         ('100', 100),
       
    47         ('314', 314),
       
    48         (' 314', 314),
       
    49         ('314 ', 314),
       
    50         ('  \t\t  314  \t\t  ', 314),
       
    51         (repr(sys.maxint), sys.maxint),
       
    52         ('  1x', ValueError),
       
    53         ('  1  ', 1),
       
    54         ('  1\02  ', ValueError),
       
    55         ('', ValueError),
       
    56         (' ', ValueError),
       
    57         ('  \t\t  ', ValueError)
       
    58 ]
       
    59 if test_support.have_unicode:
       
    60     L += [
       
    61         (unicode('0'), 0),
       
    62         (unicode('1'), 1),
       
    63         (unicode('9'), 9),
       
    64         (unicode('10'), 10),
       
    65         (unicode('99'), 99),
       
    66         (unicode('100'), 100),
       
    67         (unicode('314'), 314),
       
    68         (unicode(' 314'), 314),
       
    69         (unicode('\u0663\u0661\u0664 ','raw-unicode-escape'), 314),
       
    70         (unicode('  \t\t  314  \t\t  '), 314),
       
    71         (unicode('  1x'), ValueError),
       
    72         (unicode('  1  '), 1),
       
    73         (unicode('  1\02  '), ValueError),
       
    74         (unicode(''), ValueError),
       
    75         (unicode(' '), ValueError),
       
    76         (unicode('  \t\t  '), ValueError),
       
    77         (unichr(0x200), ValueError),
       
    78 ]
       
    79 
       
    80 
       
    81 class LongTest(unittest.TestCase):
       
    82 
       
    83     # Get quasi-random long consisting of ndigits digits (in base BASE).
       
    84     # quasi == the most-significant digit will not be 0, and the number
       
    85     # is constructed to contain long strings of 0 and 1 bits.  These are
       
    86     # more likely than random bits to provoke digit-boundary errors.
       
    87     # The sign of the number is also random.
       
    88 
       
    89     def getran(self, ndigits):
       
    90         self.assert_(ndigits > 0)
       
    91         nbits_hi = ndigits * SHIFT
       
    92         nbits_lo = nbits_hi - SHIFT + 1
       
    93         answer = 0L
       
    94         nbits = 0
       
    95         r = int(random.random() * (SHIFT * 2)) | 1  # force 1 bits to start
       
    96         while nbits < nbits_lo:
       
    97             bits = (r >> 1) + 1
       
    98             bits = min(bits, nbits_hi - nbits)
       
    99             self.assert_(1 <= bits <= SHIFT)
       
   100             nbits = nbits + bits
       
   101             answer = answer << bits
       
   102             if r & 1:
       
   103                 answer = answer | ((1 << bits) - 1)
       
   104             r = int(random.random() * (SHIFT * 2))
       
   105         self.assert_(nbits_lo <= nbits <= nbits_hi)
       
   106         if random.random() < 0.5:
       
   107             answer = -answer
       
   108         return answer
       
   109 
       
   110     # Get random long consisting of ndigits random digits (relative to base
       
   111     # BASE).  The sign bit is also random.
       
   112 
       
   113     def getran2(ndigits):
       
   114         answer = 0L
       
   115         for i in xrange(ndigits):
       
   116             answer = (answer << SHIFT) | random.randint(0, MASK)
       
   117         if random.random() < 0.5:
       
   118             answer = -answer
       
   119         return answer
       
   120 
       
   121     def check_division(self, x, y):
       
   122         eq = self.assertEqual
       
   123         q, r = divmod(x, y)
       
   124         q2, r2 = x//y, x%y
       
   125         pab, pba = x*y, y*x
       
   126         eq(pab, pba, Frm("multiplication does not commute for %r and %r", x, y))
       
   127         eq(q, q2, Frm("divmod returns different quotient than / for %r and %r", x, y))
       
   128         eq(r, r2, Frm("divmod returns different mod than %% for %r and %r", x, y))
       
   129         eq(x, q*y + r, Frm("x != q*y + r after divmod on x=%r, y=%r", x, y))
       
   130         if y > 0:
       
   131             self.assert_(0 <= r < y, Frm("bad mod from divmod on %r and %r", x, y))
       
   132         else:
       
   133             self.assert_(y < r <= 0, Frm("bad mod from divmod on %r and %r", x, y))
       
   134 
       
   135     def test_division(self):
       
   136         digits = range(1, MAXDIGITS+1) + range(KARATSUBA_CUTOFF,
       
   137                                                KARATSUBA_CUTOFF + 14)
       
   138         digits.append(KARATSUBA_CUTOFF * 3)
       
   139         for lenx in digits:
       
   140             x = self.getran(lenx)
       
   141             for leny in digits:
       
   142                 y = self.getran(leny) or 1L
       
   143                 self.check_division(x, y)
       
   144 
       
   145     def test_karatsuba(self):
       
   146         digits = range(1, 5) + range(KARATSUBA_CUTOFF, KARATSUBA_CUTOFF + 10)
       
   147         digits.extend([KARATSUBA_CUTOFF * 10, KARATSUBA_CUTOFF * 100])
       
   148 
       
   149         bits = [digit * SHIFT for digit in digits]
       
   150 
       
   151         # Test products of long strings of 1 bits -- (2**x-1)*(2**y-1) ==
       
   152         # 2**(x+y) - 2**x - 2**y + 1, so the proper result is easy to check.
       
   153         for abits in bits:
       
   154             a = (1L << abits) - 1
       
   155             for bbits in bits:
       
   156                 if bbits < abits:
       
   157                     continue
       
   158                 b = (1L << bbits) - 1
       
   159                 x = a * b
       
   160                 y = ((1L << (abits + bbits)) -
       
   161                      (1L << abits) -
       
   162                      (1L << bbits) +
       
   163                      1)
       
   164                 self.assertEqual(x, y,
       
   165                     Frm("bad result for a*b: a=%r, b=%r, x=%r, y=%r", a, b, x, y))
       
   166 
       
   167     def check_bitop_identities_1(self, x):
       
   168         eq = self.assertEqual
       
   169         eq(x & 0, 0, Frm("x & 0 != 0 for x=%r", x))
       
   170         eq(x | 0, x, Frm("x | 0 != x for x=%r", x))
       
   171         eq(x ^ 0, x, Frm("x ^ 0 != x for x=%r", x))
       
   172         eq(x & -1, x, Frm("x & -1 != x for x=%r", x))
       
   173         eq(x | -1, -1, Frm("x | -1 != -1 for x=%r", x))
       
   174         eq(x ^ -1, ~x, Frm("x ^ -1 != ~x for x=%r", x))
       
   175         eq(x, ~~x, Frm("x != ~~x for x=%r", x))
       
   176         eq(x & x, x, Frm("x & x != x for x=%r", x))
       
   177         eq(x | x, x, Frm("x | x != x for x=%r", x))
       
   178         eq(x ^ x, 0, Frm("x ^ x != 0 for x=%r", x))
       
   179         eq(x & ~x, 0, Frm("x & ~x != 0 for x=%r", x))
       
   180         eq(x | ~x, -1, Frm("x | ~x != -1 for x=%r", x))
       
   181         eq(x ^ ~x, -1, Frm("x ^ ~x != -1 for x=%r", x))
       
   182         eq(-x, 1 + ~x, Frm("not -x == 1 + ~x for x=%r", x))
       
   183         eq(-x, ~(x-1), Frm("not -x == ~(x-1) forx =%r", x))
       
   184         for n in xrange(2*SHIFT):
       
   185             p2 = 2L ** n
       
   186             eq(x << n >> n, x,
       
   187                 Frm("x << n >> n != x for x=%r, n=%r", (x, n)))
       
   188             eq(x // p2, x >> n,
       
   189                 Frm("x // p2 != x >> n for x=%r n=%r p2=%r", (x, n, p2)))
       
   190             eq(x * p2, x << n,
       
   191                 Frm("x * p2 != x << n for x=%r n=%r p2=%r", (x, n, p2)))
       
   192             eq(x & -p2, x >> n << n,
       
   193                 Frm("not x & -p2 == x >> n << n for x=%r n=%r p2=%r", (x, n, p2)))
       
   194             eq(x & -p2, x & ~(p2 - 1),
       
   195                 Frm("not x & -p2 == x & ~(p2 - 1) for x=%r n=%r p2=%r", (x, n, p2)))
       
   196 
       
   197     def check_bitop_identities_2(self, x, y):
       
   198         eq = self.assertEqual
       
   199         eq(x & y, y & x, Frm("x & y != y & x for x=%r, y=%r", (x, y)))
       
   200         eq(x | y, y | x, Frm("x | y != y | x for x=%r, y=%r", (x, y)))
       
   201         eq(x ^ y, y ^ x, Frm("x ^ y != y ^ x for x=%r, y=%r", (x, y)))
       
   202         eq(x ^ y ^ x, y, Frm("x ^ y ^ x != y for x=%r, y=%r", (x, y)))
       
   203         eq(x & y, ~(~x | ~y), Frm("x & y != ~(~x | ~y) for x=%r, y=%r", (x, y)))
       
   204         eq(x | y, ~(~x & ~y), Frm("x | y != ~(~x & ~y) for x=%r, y=%r", (x, y)))
       
   205         eq(x ^ y, (x | y) & ~(x & y),
       
   206              Frm("x ^ y != (x | y) & ~(x & y) for x=%r, y=%r", (x, y)))
       
   207         eq(x ^ y, (x & ~y) | (~x & y),
       
   208              Frm("x ^ y == (x & ~y) | (~x & y) for x=%r, y=%r", (x, y)))
       
   209         eq(x ^ y, (x | y) & (~x | ~y),
       
   210              Frm("x ^ y == (x | y) & (~x | ~y) for x=%r, y=%r", (x, y)))
       
   211 
       
   212     def check_bitop_identities_3(self, x, y, z):
       
   213         eq = self.assertEqual
       
   214         eq((x & y) & z, x & (y & z),
       
   215              Frm("(x & y) & z != x & (y & z) for x=%r, y=%r, z=%r", (x, y, z)))
       
   216         eq((x | y) | z, x | (y | z),
       
   217              Frm("(x | y) | z != x | (y | z) for x=%r, y=%r, z=%r", (x, y, z)))
       
   218         eq((x ^ y) ^ z, x ^ (y ^ z),
       
   219              Frm("(x ^ y) ^ z != x ^ (y ^ z) for x=%r, y=%r, z=%r", (x, y, z)))
       
   220         eq(x & (y | z), (x & y) | (x & z),
       
   221              Frm("x & (y | z) != (x & y) | (x & z) for x=%r, y=%r, z=%r", (x, y, z)))
       
   222         eq(x | (y & z), (x | y) & (x | z),
       
   223              Frm("x | (y & z) != (x | y) & (x | z) for x=%r, y=%r, z=%r", (x, y, z)))
       
   224 
       
   225     def test_bitop_identities(self):
       
   226         for x in special:
       
   227             self.check_bitop_identities_1(x)
       
   228         digits = xrange(1, MAXDIGITS+1)
       
   229         for lenx in digits:
       
   230             x = self.getran(lenx)
       
   231             self.check_bitop_identities_1(x)
       
   232             for leny in digits:
       
   233                 y = self.getran(leny)
       
   234                 self.check_bitop_identities_2(x, y)
       
   235                 self.check_bitop_identities_3(x, y, self.getran((lenx + leny)//2))
       
   236 
       
   237     def slow_format(self, x, base):
       
   238         if (x, base) == (0, 8):
       
   239             # this is an oddball!
       
   240             return "0L"
       
   241         digits = []
       
   242         sign = 0
       
   243         if x < 0:
       
   244             sign, x = 1, -x
       
   245         while x:
       
   246             x, r = divmod(x, base)
       
   247             digits.append(int(r))
       
   248         digits.reverse()
       
   249         digits = digits or [0]
       
   250         return '-'[:sign] + \
       
   251                {8: '0', 10: '', 16: '0x'}[base] + \
       
   252                "".join(map(lambda i: "0123456789abcdef"[i], digits)) + "L"
       
   253 
       
   254     def check_format_1(self, x):
       
   255         for base, mapper in (8, oct), (10, repr), (16, hex):
       
   256             got = mapper(x)
       
   257             expected = self.slow_format(x, base)
       
   258             msg = Frm("%s returned %r but expected %r for %r",
       
   259                 mapper.__name__, got, expected, x)
       
   260             self.assertEqual(got, expected, msg)
       
   261             self.assertEqual(long(got, 0), x, Frm('long("%s", 0) != %r', got, x))
       
   262         # str() has to be checked a little differently since there's no
       
   263         # trailing "L"
       
   264         got = str(x)
       
   265         expected = self.slow_format(x, 10)[:-1]
       
   266         msg = Frm("%s returned %r but expected %r for %r",
       
   267             mapper.__name__, got, expected, x)
       
   268         self.assertEqual(got, expected, msg)
       
   269 
       
   270     def test_format(self):
       
   271         for x in special:
       
   272             self.check_format_1(x)
       
   273         for i in xrange(10):
       
   274             for lenx in xrange(1, MAXDIGITS+1):
       
   275                 x = self.getran(lenx)
       
   276                 self.check_format_1(x)
       
   277 
       
   278     def test_long(self):
       
   279         self.assertEqual(long(314), 314L)
       
   280         self.assertEqual(long(3.14), 3L)
       
   281         self.assertEqual(long(314L), 314L)
       
   282         # Check that long() of basic types actually returns a long
       
   283         self.assertEqual(type(long(314)), long)
       
   284         self.assertEqual(type(long(3.14)), long)
       
   285         self.assertEqual(type(long(314L)), long)
       
   286         # Check that conversion from float truncates towards zero
       
   287         self.assertEqual(long(-3.14), -3L)
       
   288         self.assertEqual(long(3.9), 3L)
       
   289         self.assertEqual(long(-3.9), -3L)
       
   290         self.assertEqual(long(3.5), 3L)
       
   291         self.assertEqual(long(-3.5), -3L)
       
   292         self.assertEqual(long("-3"), -3L)
       
   293         if test_support.have_unicode:
       
   294             self.assertEqual(long(unicode("-3")), -3L)
       
   295         # Different base:
       
   296         self.assertEqual(long("10",16), 16L)
       
   297         if test_support.have_unicode:
       
   298             self.assertEqual(long(unicode("10"),16), 16L)
       
   299         # Check conversions from string (same test set as for int(), and then some)
       
   300         LL = [
       
   301                 ('1' + '0'*20, 10L**20),
       
   302                 ('1' + '0'*100, 10L**100)
       
   303         ]
       
   304         L2 = L[:]
       
   305         if test_support.have_unicode:
       
   306             L2 += [
       
   307                 (unicode('1') + unicode('0')*20, 10L**20),
       
   308                 (unicode('1') + unicode('0')*100, 10L**100),
       
   309         ]
       
   310         for s, v in L2 + LL:
       
   311             for sign in "", "+", "-":
       
   312                 for prefix in "", " ", "\t", "  \t\t  ":
       
   313                     ss = prefix + sign + s
       
   314                     vv = v
       
   315                     if sign == "-" and v is not ValueError:
       
   316                         vv = -v
       
   317                     try:
       
   318                         self.assertEqual(long(ss), long(vv))
       
   319                     except v:
       
   320                         pass
       
   321 
       
   322         self.assertRaises(ValueError, long, '123\0')
       
   323         self.assertRaises(ValueError, long, '53', 40)
       
   324         self.assertRaises(TypeError, long, 1, 12)
       
   325 
       
   326         # SF patch #1638879: embedded NULs were not detected with
       
   327         # explicit base
       
   328         self.assertRaises(ValueError, long, '123\0', 10)
       
   329         self.assertRaises(ValueError, long, '123\x00 245', 20)
       
   330 
       
   331         self.assertEqual(long('100000000000000000000000000000000', 2),
       
   332                          4294967296)
       
   333         self.assertEqual(long('102002022201221111211', 3), 4294967296)
       
   334         self.assertEqual(long('10000000000000000', 4), 4294967296)
       
   335         self.assertEqual(long('32244002423141', 5), 4294967296)
       
   336         self.assertEqual(long('1550104015504', 6), 4294967296)
       
   337         self.assertEqual(long('211301422354', 7), 4294967296)
       
   338         self.assertEqual(long('40000000000', 8), 4294967296)
       
   339         self.assertEqual(long('12068657454', 9), 4294967296)
       
   340         self.assertEqual(long('4294967296', 10), 4294967296)
       
   341         self.assertEqual(long('1904440554', 11), 4294967296)
       
   342         self.assertEqual(long('9ba461594', 12), 4294967296)
       
   343         self.assertEqual(long('535a79889', 13), 4294967296)
       
   344         self.assertEqual(long('2ca5b7464', 14), 4294967296)
       
   345         self.assertEqual(long('1a20dcd81', 15), 4294967296)
       
   346         self.assertEqual(long('100000000', 16), 4294967296)
       
   347         self.assertEqual(long('a7ffda91', 17), 4294967296)
       
   348         self.assertEqual(long('704he7g4', 18), 4294967296)
       
   349         self.assertEqual(long('4f5aff66', 19), 4294967296)
       
   350         self.assertEqual(long('3723ai4g', 20), 4294967296)
       
   351         self.assertEqual(long('281d55i4', 21), 4294967296)
       
   352         self.assertEqual(long('1fj8b184', 22), 4294967296)
       
   353         self.assertEqual(long('1606k7ic', 23), 4294967296)
       
   354         self.assertEqual(long('mb994ag', 24), 4294967296)
       
   355         self.assertEqual(long('hek2mgl', 25), 4294967296)
       
   356         self.assertEqual(long('dnchbnm', 26), 4294967296)
       
   357         self.assertEqual(long('b28jpdm', 27), 4294967296)
       
   358         self.assertEqual(long('8pfgih4', 28), 4294967296)
       
   359         self.assertEqual(long('76beigg', 29), 4294967296)
       
   360         self.assertEqual(long('5qmcpqg', 30), 4294967296)
       
   361         self.assertEqual(long('4q0jto4', 31), 4294967296)
       
   362         self.assertEqual(long('4000000', 32), 4294967296)
       
   363         self.assertEqual(long('3aokq94', 33), 4294967296)
       
   364         self.assertEqual(long('2qhxjli', 34), 4294967296)
       
   365         self.assertEqual(long('2br45qb', 35), 4294967296)
       
   366         self.assertEqual(long('1z141z4', 36), 4294967296)
       
   367 
       
   368         self.assertEqual(long('100000000000000000000000000000001', 2),
       
   369                          4294967297)
       
   370         self.assertEqual(long('102002022201221111212', 3), 4294967297)
       
   371         self.assertEqual(long('10000000000000001', 4), 4294967297)
       
   372         self.assertEqual(long('32244002423142', 5), 4294967297)
       
   373         self.assertEqual(long('1550104015505', 6), 4294967297)
       
   374         self.assertEqual(long('211301422355', 7), 4294967297)
       
   375         self.assertEqual(long('40000000001', 8), 4294967297)
       
   376         self.assertEqual(long('12068657455', 9), 4294967297)
       
   377         self.assertEqual(long('4294967297', 10), 4294967297)
       
   378         self.assertEqual(long('1904440555', 11), 4294967297)
       
   379         self.assertEqual(long('9ba461595', 12), 4294967297)
       
   380         self.assertEqual(long('535a7988a', 13), 4294967297)
       
   381         self.assertEqual(long('2ca5b7465', 14), 4294967297)
       
   382         self.assertEqual(long('1a20dcd82', 15), 4294967297)
       
   383         self.assertEqual(long('100000001', 16), 4294967297)
       
   384         self.assertEqual(long('a7ffda92', 17), 4294967297)
       
   385         self.assertEqual(long('704he7g5', 18), 4294967297)
       
   386         self.assertEqual(long('4f5aff67', 19), 4294967297)
       
   387         self.assertEqual(long('3723ai4h', 20), 4294967297)
       
   388         self.assertEqual(long('281d55i5', 21), 4294967297)
       
   389         self.assertEqual(long('1fj8b185', 22), 4294967297)
       
   390         self.assertEqual(long('1606k7id', 23), 4294967297)
       
   391         self.assertEqual(long('mb994ah', 24), 4294967297)
       
   392         self.assertEqual(long('hek2mgm', 25), 4294967297)
       
   393         self.assertEqual(long('dnchbnn', 26), 4294967297)
       
   394         self.assertEqual(long('b28jpdn', 27), 4294967297)
       
   395         self.assertEqual(long('8pfgih5', 28), 4294967297)
       
   396         self.assertEqual(long('76beigh', 29), 4294967297)
       
   397         self.assertEqual(long('5qmcpqh', 30), 4294967297)
       
   398         self.assertEqual(long('4q0jto5', 31), 4294967297)
       
   399         self.assertEqual(long('4000001', 32), 4294967297)
       
   400         self.assertEqual(long('3aokq95', 33), 4294967297)
       
   401         self.assertEqual(long('2qhxjlj', 34), 4294967297)
       
   402         self.assertEqual(long('2br45qc', 35), 4294967297)
       
   403         self.assertEqual(long('1z141z5', 36), 4294967297)
       
   404 
       
   405 
       
   406     def test_conversion(self):
       
   407         # Test __long__()
       
   408         class ClassicMissingMethods:
       
   409             pass
       
   410         self.assertRaises(AttributeError, long, ClassicMissingMethods())
       
   411 
       
   412         class MissingMethods(object):
       
   413             pass
       
   414         self.assertRaises(TypeError, long, MissingMethods())
       
   415 
       
   416         class Foo0:
       
   417             def __long__(self):
       
   418                 return 42L
       
   419 
       
   420         class Foo1(object):
       
   421             def __long__(self):
       
   422                 return 42L
       
   423 
       
   424         class Foo2(long):
       
   425             def __long__(self):
       
   426                 return 42L
       
   427 
       
   428         class Foo3(long):
       
   429             def __long__(self):
       
   430                 return self
       
   431 
       
   432         class Foo4(long):
       
   433             def __long__(self):
       
   434                 return 42
       
   435 
       
   436         class Foo5(long):
       
   437             def __long__(self):
       
   438                 return 42.
       
   439 
       
   440         self.assertEqual(long(Foo0()), 42L)
       
   441         self.assertEqual(long(Foo1()), 42L)
       
   442         self.assertEqual(long(Foo2()), 42L)
       
   443         self.assertEqual(long(Foo3()), 0)
       
   444         self.assertEqual(long(Foo4()), 42)
       
   445         self.assertRaises(TypeError, long, Foo5())
       
   446 
       
   447         class Classic:
       
   448             pass
       
   449         for base in (object, Classic):
       
   450             class LongOverridesTrunc(base):
       
   451                 def __long__(self):
       
   452                     return 42
       
   453                 def __trunc__(self):
       
   454                     return -12
       
   455             self.assertEqual(long(LongOverridesTrunc()), 42)
       
   456 
       
   457             class JustTrunc(base):
       
   458                 def __trunc__(self):
       
   459                     return 42
       
   460             self.assertEqual(long(JustTrunc()), 42)
       
   461 
       
   462             for trunc_result_base in (object, Classic):
       
   463                 class Integral(trunc_result_base):
       
   464                     def __int__(self):
       
   465                         return 42
       
   466 
       
   467                 class TruncReturnsNonLong(base):
       
   468                     def __trunc__(self):
       
   469                         return Integral()
       
   470                 self.assertEqual(long(TruncReturnsNonLong()), 42)
       
   471 
       
   472                 class NonIntegral(trunc_result_base):
       
   473                     def __trunc__(self):
       
   474                         # Check that we avoid infinite recursion.
       
   475                         return NonIntegral()
       
   476 
       
   477                 class TruncReturnsNonIntegral(base):
       
   478                     def __trunc__(self):
       
   479                         return NonIntegral()
       
   480                 try:
       
   481                     long(TruncReturnsNonIntegral())
       
   482                 except TypeError as e:
       
   483                     self.assertEquals(str(e),
       
   484                                       "__trunc__ returned non-Integral"
       
   485                                       " (type NonIntegral)")
       
   486                 else:
       
   487                     self.fail("Failed to raise TypeError with %s" %
       
   488                               ((base, trunc_result_base),))
       
   489 
       
   490     def test_misc(self):
       
   491 
       
   492         # check the extremes in int<->long conversion
       
   493         hugepos = sys.maxint
       
   494         hugeneg = -hugepos - 1
       
   495         hugepos_aslong = long(hugepos)
       
   496         hugeneg_aslong = long(hugeneg)
       
   497         self.assertEqual(hugepos, hugepos_aslong, "long(sys.maxint) != sys.maxint")
       
   498         self.assertEqual(hugeneg, hugeneg_aslong,
       
   499             "long(-sys.maxint-1) != -sys.maxint-1")
       
   500 
       
   501         # long -> int should not fail for hugepos_aslong or hugeneg_aslong
       
   502         x = int(hugepos_aslong)
       
   503         try:
       
   504             self.assertEqual(x, hugepos,
       
   505                   "converting sys.maxint to long and back to int fails")
       
   506         except OverflowError:
       
   507             self.fail("int(long(sys.maxint)) overflowed!")
       
   508         if not isinstance(x, int):
       
   509             raise TestFailed("int(long(sys.maxint)) should have returned int")
       
   510         x = int(hugeneg_aslong)
       
   511         try:
       
   512             self.assertEqual(x, hugeneg,
       
   513                   "converting -sys.maxint-1 to long and back to int fails")
       
   514         except OverflowError:
       
   515             self.fail("int(long(-sys.maxint-1)) overflowed!")
       
   516         if not isinstance(x, int):
       
   517             raise TestFailed("int(long(-sys.maxint-1)) should have "
       
   518                              "returned int")
       
   519         # but long -> int should overflow for hugepos+1 and hugeneg-1
       
   520         x = hugepos_aslong + 1
       
   521         try:
       
   522             y = int(x)
       
   523         except OverflowError:
       
   524             self.fail("int(long(sys.maxint) + 1) mustn't overflow")
       
   525         self.assert_(isinstance(y, long),
       
   526             "int(long(sys.maxint) + 1) should have returned long")
       
   527 
       
   528         x = hugeneg_aslong - 1
       
   529         try:
       
   530             y = int(x)
       
   531         except OverflowError:
       
   532             self.fail("int(long(-sys.maxint-1) - 1) mustn't overflow")
       
   533         self.assert_(isinstance(y, long),
       
   534                "int(long(-sys.maxint-1) - 1) should have returned long")
       
   535 
       
   536         class long2(long):
       
   537             pass
       
   538         x = long2(1L<<100)
       
   539         y = int(x)
       
   540         self.assert_(type(y) is long,
       
   541             "overflowing int conversion must return long not long subtype")
       
   542 
       
   543         # long -> Py_ssize_t conversion
       
   544         class X(object):
       
   545             def __getslice__(self, i, j):
       
   546                 return i, j
       
   547 
       
   548         self.assertEqual(X()[-5L:7L], (-5, 7))
       
   549         # use the clamping effect to test the smallest and largest longs
       
   550         # that fit a Py_ssize_t
       
   551         slicemin, slicemax = X()[-2L**100:2L**100]
       
   552         self.assertEqual(X()[slicemin:slicemax], (slicemin, slicemax))
       
   553 
       
   554 # ----------------------------------- tests of auto int->long conversion
       
   555 
       
   556     def test_auto_overflow(self):
       
   557         import math, sys
       
   558 
       
   559         special = [0, 1, 2, 3, sys.maxint-1, sys.maxint, sys.maxint+1]
       
   560         sqrt = int(math.sqrt(sys.maxint))
       
   561         special.extend([sqrt-1, sqrt, sqrt+1])
       
   562         special.extend([-i for i in special])
       
   563 
       
   564         def checkit(*args):
       
   565             # Heavy use of nested scopes here!
       
   566             self.assertEqual(got, expected,
       
   567                 Frm("for %r expected %r got %r", args, expected, got))
       
   568 
       
   569         for x in special:
       
   570             longx = long(x)
       
   571 
       
   572             expected = -longx
       
   573             got = -x
       
   574             checkit('-', x)
       
   575 
       
   576             for y in special:
       
   577                 longy = long(y)
       
   578 
       
   579                 expected = longx + longy
       
   580                 got = x + y
       
   581                 checkit(x, '+', y)
       
   582 
       
   583                 expected = longx - longy
       
   584                 got = x - y
       
   585                 checkit(x, '-', y)
       
   586 
       
   587                 expected = longx * longy
       
   588                 got = x * y
       
   589                 checkit(x, '*', y)
       
   590 
       
   591                 if y:
       
   592                     expected = longx / longy
       
   593                     got = x / y
       
   594                     checkit(x, '/', y)
       
   595 
       
   596                     expected = longx // longy
       
   597                     got = x // y
       
   598                     checkit(x, '//', y)
       
   599 
       
   600                     expected = divmod(longx, longy)
       
   601                     got = divmod(longx, longy)
       
   602                     checkit(x, 'divmod', y)
       
   603 
       
   604                 if abs(y) < 5 and not (x == 0 and y < 0):
       
   605                     expected = longx ** longy
       
   606                     got = x ** y
       
   607                     checkit(x, '**', y)
       
   608 
       
   609                     for z in special:
       
   610                         if z != 0 :
       
   611                             if y >= 0:
       
   612                                 expected = pow(longx, longy, long(z))
       
   613                                 got = pow(x, y, z)
       
   614                                 checkit('pow', x, y, '%', z)
       
   615                             else:
       
   616                                 self.assertRaises(TypeError, pow,longx, longy, long(z))
       
   617 
       
   618     def test_float_overflow(self):
       
   619         import math
       
   620 
       
   621         for x in -2.0, -1.0, 0.0, 1.0, 2.0:
       
   622             self.assertEqual(float(long(x)), x)
       
   623 
       
   624         shuge = '12345' * 120
       
   625         huge = 1L << 30000
       
   626         mhuge = -huge
       
   627         namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math}
       
   628         for test in ["float(huge)", "float(mhuge)",
       
   629                      "complex(huge)", "complex(mhuge)",
       
   630                      "complex(huge, 1)", "complex(mhuge, 1)",
       
   631                      "complex(1, huge)", "complex(1, mhuge)",
       
   632                      "1. + huge", "huge + 1.", "1. + mhuge", "mhuge + 1.",
       
   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                      "math.sin(huge)", "math.sin(mhuge)",
       
   639                      "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better
       
   640                      "math.floor(huge)", "math.floor(mhuge)"]:
       
   641 
       
   642             self.assertRaises(OverflowError, eval, test, namespace)
       
   643 
       
   644             # XXX Perhaps float(shuge) can raise OverflowError on some box?
       
   645             # The comparison should not.
       
   646             self.assertNotEqual(float(shuge), int(shuge),
       
   647                 "float(shuge) should not equal int(shuge)")
       
   648 
       
   649     def test_logs(self):
       
   650         import math
       
   651 
       
   652         LOG10E = math.log10(math.e)
       
   653 
       
   654         for exp in range(10) + [100, 1000, 10000]:
       
   655             value = 10 ** exp
       
   656             log10 = math.log10(value)
       
   657             self.assertAlmostEqual(log10, exp)
       
   658 
       
   659             # log10(value) == exp, so log(value) == log10(value)/log10(e) ==
       
   660             # exp/LOG10E
       
   661             expected = exp / LOG10E
       
   662             log = math.log(value)
       
   663             self.assertAlmostEqual(log, expected)
       
   664 
       
   665         for bad in -(1L << 10000), -2L, 0L:
       
   666             self.assertRaises(ValueError, math.log, bad)
       
   667             self.assertRaises(ValueError, math.log10, bad)
       
   668 
       
   669     def test_mixed_compares(self):
       
   670         eq = self.assertEqual
       
   671         import math
       
   672 
       
   673         # We're mostly concerned with that mixing floats and longs does the
       
   674         # right stuff, even when longs are too large to fit in a float.
       
   675         # The safest way to check the results is to use an entirely different
       
   676         # method, which we do here via a skeletal rational class (which
       
   677         # represents all Python ints, longs and floats exactly).
       
   678         class Rat:
       
   679             def __init__(self, value):
       
   680                 if isinstance(value, (int, long)):
       
   681                     self.n = value
       
   682                     self.d = 1
       
   683                 elif isinstance(value, float):
       
   684                     # Convert to exact rational equivalent.
       
   685                     f, e = math.frexp(abs(value))
       
   686                     assert f == 0 or 0.5 <= f < 1.0
       
   687                     # |value| = f * 2**e exactly
       
   688 
       
   689                     # Suck up CHUNK bits at a time; 28 is enough so that we suck
       
   690                     # up all bits in 2 iterations for all known binary double-
       
   691                     # precision formats, and small enough to fit in an int.
       
   692                     CHUNK = 28
       
   693                     top = 0
       
   694                     # invariant: |value| = (top + f) * 2**e exactly
       
   695                     while f:
       
   696                         f = math.ldexp(f, CHUNK)
       
   697                         digit = int(f)
       
   698                         assert digit >> CHUNK == 0
       
   699                         top = (top << CHUNK) | digit
       
   700                         f -= digit
       
   701                         assert 0.0 <= f < 1.0
       
   702                         e -= CHUNK
       
   703 
       
   704                     # Now |value| = top * 2**e exactly.
       
   705                     if e >= 0:
       
   706                         n = top << e
       
   707                         d = 1
       
   708                     else:
       
   709                         n = top
       
   710                         d = 1 << -e
       
   711                     if value < 0:
       
   712                         n = -n
       
   713                     self.n = n
       
   714                     self.d = d
       
   715                     assert float(n) / float(d) == value
       
   716                 else:
       
   717                     raise TypeError("can't deal with %r" % val)
       
   718 
       
   719             def __cmp__(self, other):
       
   720                 if not isinstance(other, Rat):
       
   721                     other = Rat(other)
       
   722                 return cmp(self.n * other.d, self.d * other.n)
       
   723 
       
   724         cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200]
       
   725         # 2**48 is an important boundary in the internals.  2**53 is an
       
   726         # important boundary for IEEE double precision.
       
   727         for t in 2.0**48, 2.0**50, 2.0**53:
       
   728             cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0,
       
   729                           long(t-1), long(t), long(t+1)])
       
   730         cases.extend([0, 1, 2, sys.maxint, float(sys.maxint)])
       
   731         # 1L<<20000 should exceed all double formats.  long(1e200) is to
       
   732         # check that we get equality with 1e200 above.
       
   733         t = long(1e200)
       
   734         cases.extend([0L, 1L, 2L, 1L << 20000, t-1, t, t+1])
       
   735         cases.extend([-x for x in cases])
       
   736         for x in cases:
       
   737             Rx = Rat(x)
       
   738             for y in cases:
       
   739                 Ry = Rat(y)
       
   740                 Rcmp = cmp(Rx, Ry)
       
   741                 xycmp = cmp(x, y)
       
   742                 eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp))
       
   743                 eq(x == y, Rcmp == 0, Frm("%r == %r %d", x, y, Rcmp))
       
   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 
       
   750     def test_nan_inf(self):
       
   751         self.assertRaises(OverflowError, long, float('inf'))
       
   752         self.assertRaises(OverflowError, long, float('-inf'))
       
   753         self.assertRaises(ValueError, long, float('nan'))
       
   754 
       
   755 def test_main():
       
   756     test_support.run_unittest(LongTest)
       
   757 
       
   758 if __name__ == "__main__":
       
   759     test_main()