blob: 9974a5fa9f80c11f73aa5ebc1207d6ab0666c6f6 [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
Mark Dickinson54bc1ec2008-12-17 16:19:07 +00006import math
Walter Dörwalda0021592005-06-13 21:44:48 +00007
8# Used for lazy formatting of failure messages
9class Frm(object):
10 def __init__(self, format, *args):
11 self.format = format
12 self.args = args
13
14 def __str__(self):
15 return self.format % self.args
Guido van Rossum4365cab1998-08-13 14:20:17 +000016
Mark Dickinsoncbb62742009-12-27 15:09:50 +000017# decorator for skipping tests on non-IEEE 754 platforms
18requires_IEEE_754 = unittest.skipUnless(
19 float.__getformat__("double").startswith("IEEE"),
20 "test requires IEEE 754 doubles")
21
Guido van Rossum4365cab1998-08-13 14:20:17 +000022# SHIFT should match the value in longintrepr.h for best testing.
Mark Dickinsonbd792642009-03-18 20:06:12 +000023SHIFT = sys.int_info.bits_per_digit
Guido van Rossum4365cab1998-08-13 14:20:17 +000024BASE = 2 ** SHIFT
25MASK = BASE - 1
Tim Petersdaec9612004-08-30 23:18:23 +000026KARATSUBA_CUTOFF = 70 # from longobject.c
Guido van Rossum4365cab1998-08-13 14:20:17 +000027
28# Max number of base BASE digits to use in test cases. Doubling
Tim Peters28b0e2a2002-08-13 02:17:11 +000029# this will more than double the runtime.
30MAXDIGITS = 15
Guido van Rossum4365cab1998-08-13 14:20:17 +000031
Guido van Rossum4581a0c1998-10-02 01:19:48 +000032# build some special values
Guido van Rossumc1f779c2007-07-03 08:25:58 +000033special = [0, 1, 2, BASE, BASE >> 1, 0x5555555555555555, 0xaaaaaaaaaaaaaaaa]
Guido van Rossum4581a0c1998-10-02 01:19:48 +000034# some solid strings of one bits
Guido van Rossume2a383d2007-01-15 16:59:06 +000035p2 = 4 # 0 and 1 already added
Guido van Rossum4581a0c1998-10-02 01:19:48 +000036for i in range(2*SHIFT):
37 special.append(p2 - 1)
38 p2 = p2 << 1
39del p2
40# add complements & negations
Guido van Rossumc1f779c2007-07-03 08:25:58 +000041special += [~x for x in special] + [-x for x in special]
Guido van Rossum4581a0c1998-10-02 01:19:48 +000042
Mark Dickinsoncbb62742009-12-27 15:09:50 +000043DBL_MAX = sys.float_info.max
44DBL_MAX_EXP = sys.float_info.max_exp
45DBL_MIN_EXP = sys.float_info.min_exp
46DBL_MANT_DIG = sys.float_info.mant_dig
47DBL_MIN_OVERFLOW = 2**DBL_MAX_EXP - 2**(DBL_MAX_EXP - DBL_MANT_DIG - 1)
48
49# pure Python version of correctly-rounded true division
50def truediv(a, b):
51 """Correctly-rounded true division for integers."""
52 negative = a^b < 0
53 a, b = abs(a), abs(b)
54
55 # exceptions: division by zero, overflow
56 if not b:
57 raise ZeroDivisionError("division by zero")
58 if a >= DBL_MIN_OVERFLOW * b:
59 raise OverflowError("int/int too large to represent as a float")
60
61 # find integer d satisfying 2**(d - 1) <= a/b < 2**d
62 d = a.bit_length() - b.bit_length()
63 if d >= 0 and a >= 2**d * b or d < 0 and a * 2**-d >= b:
64 d += 1
65
66 # compute 2**-exp * a / b for suitable exp
67 exp = max(d, DBL_MIN_EXP) - DBL_MANT_DIG
68 a, b = a << max(-exp, 0), b << max(exp, 0)
69 q, r = divmod(a, b)
70
71 # round-half-to-even: fractional part is r/b, which is > 0.5 iff
72 # 2*r > b, and == 0.5 iff 2*r == b.
73 if 2*r > b or 2*r == b and q % 2 == 1:
74 q += 1
75
Mark Dickinsona4e15062009-12-27 19:03:31 +000076 result = math.ldexp(q, exp)
Mark Dickinsoncbb62742009-12-27 15:09:50 +000077 return -result if negative else result
78
79
Walter Dörwalda0021592005-06-13 21:44:48 +000080class LongTest(unittest.TestCase):
Guido van Rossum4365cab1998-08-13 14:20:17 +000081
Walter Dörwalda0021592005-06-13 21:44:48 +000082 # Get quasi-random long consisting of ndigits digits (in base BASE).
83 # quasi == the most-significant digit will not be 0, and the number
84 # is constructed to contain long strings of 0 and 1 bits. These are
85 # more likely than random bits to provoke digit-boundary errors.
86 # The sign of the number is also random.
Guido van Rossum4365cab1998-08-13 14:20:17 +000087
Walter Dörwalda0021592005-06-13 21:44:48 +000088 def getran(self, ndigits):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000089 self.assertTrue(ndigits > 0)
Walter Dörwalda0021592005-06-13 21:44:48 +000090 nbits_hi = ndigits * SHIFT
91 nbits_lo = nbits_hi - SHIFT + 1
Guido van Rossume2a383d2007-01-15 16:59:06 +000092 answer = 0
Walter Dörwalda0021592005-06-13 21:44:48 +000093 nbits = 0
94 r = int(random.random() * (SHIFT * 2)) | 1 # force 1 bits to start
95 while nbits < nbits_lo:
96 bits = (r >> 1) + 1
97 bits = min(bits, nbits_hi - nbits)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000098 self.assertTrue(1 <= bits <= SHIFT)
Walter Dörwalda0021592005-06-13 21:44:48 +000099 nbits = nbits + bits
100 answer = answer << bits
101 if r & 1:
102 answer = answer | ((1 << bits) - 1)
103 r = int(random.random() * (SHIFT * 2))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000104 self.assertTrue(nbits_lo <= nbits <= nbits_hi)
Walter Dörwalda0021592005-06-13 21:44:48 +0000105 if random.random() < 0.5:
106 answer = -answer
107 return answer
Guido van Rossum4581a0c1998-10-02 01:19:48 +0000108
Walter Dörwalda0021592005-06-13 21:44:48 +0000109 # Get random long consisting of ndigits random digits (relative to base
110 # BASE). The sign bit is also random.
Guido van Rossum4581a0c1998-10-02 01:19:48 +0000111
Walter Dörwalda0021592005-06-13 21:44:48 +0000112 def getran2(ndigits):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000113 answer = 0
Guido van Rossum805365e2007-05-07 22:24:25 +0000114 for i in range(ndigits):
Walter Dörwalda0021592005-06-13 21:44:48 +0000115 answer = (answer << SHIFT) | random.randint(0, MASK)
116 if random.random() < 0.5:
117 answer = -answer
118 return answer
Guido van Rossum4365cab1998-08-13 14:20:17 +0000119
Walter Dörwalda0021592005-06-13 21:44:48 +0000120 def check_division(self, x, y):
121 eq = self.assertEqual
122 q, r = divmod(x, y)
123 q2, r2 = x//y, x%y
124 pab, pba = x*y, y*x
125 eq(pab, pba, Frm("multiplication does not commute for %r and %r", x, y))
126 eq(q, q2, Frm("divmod returns different quotient than / for %r and %r", x, y))
127 eq(r, r2, Frm("divmod returns different mod than %% for %r and %r", x, y))
128 eq(x, q*y + r, Frm("x != q*y + r after divmod on x=%r, y=%r", x, y))
129 if y > 0:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000130 self.assertTrue(0 <= r < y, Frm("bad mod from divmod on %r and %r", x, y))
Walter Dörwalda0021592005-06-13 21:44:48 +0000131 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000132 self.assertTrue(y < r <= 0, Frm("bad mod from divmod on %r and %r", x, y))
Guido van Rossum4365cab1998-08-13 14:20:17 +0000133
Walter Dörwalda0021592005-06-13 21:44:48 +0000134 def test_division(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000135 digits = list(range(1, MAXDIGITS+1)) + list(range(KARATSUBA_CUTOFF,
136 KARATSUBA_CUTOFF + 14))
Walter Dörwalda0021592005-06-13 21:44:48 +0000137 digits.append(KARATSUBA_CUTOFF * 3)
138 for lenx in digits:
139 x = self.getran(lenx)
140 for leny in digits:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000141 y = self.getran(leny) or 1
Walter Dörwalda0021592005-06-13 21:44:48 +0000142 self.check_division(x, y)
Guido van Rossum4365cab1998-08-13 14:20:17 +0000143
Mark Dickinsonbd792642009-03-18 20:06:12 +0000144 # specific numbers chosen to exercise corner cases of the
145 # current long division implementation
146
147 # 30-bit cases involving a quotient digit estimate of BASE+1
148 self.check_division(1231948412290879395966702881,
149 1147341367131428698)
150 self.check_division(815427756481275430342312021515587883,
151 707270836069027745)
152 self.check_division(627976073697012820849443363563599041,
153 643588798496057020)
154 self.check_division(1115141373653752303710932756325578065,
155 1038556335171453937726882627)
156 # 30-bit cases that require the post-subtraction correction step
157 self.check_division(922498905405436751940989320930368494,
158 949985870686786135626943396)
159 self.check_division(768235853328091167204009652174031844,
160 1091555541180371554426545266)
161
162 # 15-bit cases involving a quotient digit estimate of BASE+1
163 self.check_division(20172188947443, 615611397)
164 self.check_division(1020908530270155025, 950795710)
165 self.check_division(128589565723112408, 736393718)
166 self.check_division(609919780285761575, 18613274546784)
167 # 15-bit cases that require the post-subtraction correction step
168 self.check_division(710031681576388032, 26769404391308)
169 self.check_division(1933622614268221, 30212853348836)
170
171
172
Walter Dörwalda0021592005-06-13 21:44:48 +0000173 def test_karatsuba(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000174 digits = list(range(1, 5)) + list(range(KARATSUBA_CUTOFF,
175 KARATSUBA_CUTOFF + 10))
Walter Dörwalda0021592005-06-13 21:44:48 +0000176 digits.extend([KARATSUBA_CUTOFF * 10, KARATSUBA_CUTOFF * 100])
Guido van Rossum4365cab1998-08-13 14:20:17 +0000177
Walter Dörwalda0021592005-06-13 21:44:48 +0000178 bits = [digit * SHIFT for digit in digits]
Guido van Rossum4365cab1998-08-13 14:20:17 +0000179
Walter Dörwalda0021592005-06-13 21:44:48 +0000180 # Test products of long strings of 1 bits -- (2**x-1)*(2**y-1) ==
181 # 2**(x+y) - 2**x - 2**y + 1, so the proper result is easy to check.
182 for abits in bits:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000183 a = (1 << abits) - 1
Walter Dörwalda0021592005-06-13 21:44:48 +0000184 for bbits in bits:
185 if bbits < abits:
186 continue
Guido van Rossume2a383d2007-01-15 16:59:06 +0000187 b = (1 << bbits) - 1
Walter Dörwalda0021592005-06-13 21:44:48 +0000188 x = a * b
Guido van Rossume2a383d2007-01-15 16:59:06 +0000189 y = ((1 << (abits + bbits)) -
190 (1 << abits) -
191 (1 << bbits) +
Walter Dörwalda0021592005-06-13 21:44:48 +0000192 1)
193 self.assertEqual(x, y,
194 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 +0000195
Walter Dörwalda0021592005-06-13 21:44:48 +0000196 def check_bitop_identities_1(self, x):
197 eq = self.assertEqual
198 eq(x & 0, 0, Frm("x & 0 != 0 for x=%r", x))
199 eq(x | 0, x, Frm("x | 0 != x for x=%r", x))
200 eq(x ^ 0, x, Frm("x ^ 0 != x for x=%r", x))
201 eq(x & -1, x, Frm("x & -1 != x for x=%r", x))
202 eq(x | -1, -1, Frm("x | -1 != -1 for x=%r", x))
203 eq(x ^ -1, ~x, Frm("x ^ -1 != ~x for x=%r", x))
204 eq(x, ~~x, Frm("x != ~~x for x=%r", x))
205 eq(x & x, x, Frm("x & x != x for x=%r", x))
206 eq(x | x, x, Frm("x | x != x for x=%r", x))
207 eq(x ^ x, 0, Frm("x ^ x != 0 for x=%r", x))
208 eq(x & ~x, 0, Frm("x & ~x != 0 for x=%r", x))
209 eq(x | ~x, -1, Frm("x | ~x != -1 for x=%r", x))
210 eq(x ^ ~x, -1, Frm("x ^ ~x != -1 for x=%r", x))
211 eq(-x, 1 + ~x, Frm("not -x == 1 + ~x for x=%r", x))
212 eq(-x, ~(x-1), Frm("not -x == ~(x-1) forx =%r", x))
Guido van Rossum805365e2007-05-07 22:24:25 +0000213 for n in range(2*SHIFT):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000214 p2 = 2 ** n
Walter Dörwalda0021592005-06-13 21:44:48 +0000215 eq(x << n >> n, x,
216 Frm("x << n >> n != x for x=%r, n=%r", (x, n)))
217 eq(x // p2, x >> n,
218 Frm("x // p2 != x >> n for x=%r n=%r p2=%r", (x, n, p2)))
219 eq(x * p2, x << n,
220 Frm("x * p2 != x << n for x=%r n=%r p2=%r", (x, n, p2)))
221 eq(x & -p2, x >> n << n,
222 Frm("not x & -p2 == x >> n << n for x=%r n=%r p2=%r", (x, n, p2)))
223 eq(x & -p2, x & ~(p2 - 1),
224 Frm("not x & -p2 == x & ~(p2 - 1) for x=%r n=%r p2=%r", (x, n, p2)))
Tim Peters7f270ba2002-08-13 21:06:55 +0000225
Walter Dörwalda0021592005-06-13 21:44:48 +0000226 def check_bitop_identities_2(self, x, y):
227 eq = self.assertEqual
228 eq(x & y, y & x, Frm("x & y != y & x for x=%r, y=%r", (x, y)))
229 eq(x | y, y | x, Frm("x | y != y | x for x=%r, y=%r", (x, y)))
230 eq(x ^ y, y ^ x, Frm("x ^ y != y ^ x for x=%r, y=%r", (x, y)))
231 eq(x ^ y ^ x, y, Frm("x ^ y ^ x != y for x=%r, y=%r", (x, y)))
232 eq(x & y, ~(~x | ~y), Frm("x & y != ~(~x | ~y) for x=%r, y=%r", (x, y)))
233 eq(x | y, ~(~x & ~y), Frm("x | y != ~(~x & ~y) for x=%r, y=%r", (x, y)))
234 eq(x ^ y, (x | y) & ~(x & y),
235 Frm("x ^ y != (x | y) & ~(x & y) for x=%r, y=%r", (x, y)))
236 eq(x ^ y, (x & ~y) | (~x & y),
237 Frm("x ^ y == (x & ~y) | (~x & y) for x=%r, y=%r", (x, y)))
238 eq(x ^ y, (x | y) & (~x | ~y),
239 Frm("x ^ y == (x | y) & (~x | ~y) for x=%r, y=%r", (x, y)))
Tim Peters7f270ba2002-08-13 21:06:55 +0000240
Walter Dörwalda0021592005-06-13 21:44:48 +0000241 def check_bitop_identities_3(self, x, y, z):
242 eq = self.assertEqual
243 eq((x & y) & z, x & (y & z),
244 Frm("(x & y) & z != x & (y & z) for x=%r, y=%r, z=%r", (x, y, z)))
245 eq((x | y) | z, x | (y | z),
246 Frm("(x | y) | z != x | (y | z) for x=%r, y=%r, z=%r", (x, y, z)))
247 eq((x ^ y) ^ z, x ^ (y ^ z),
248 Frm("(x ^ y) ^ z != x ^ (y ^ z) for x=%r, y=%r, z=%r", (x, y, z)))
249 eq(x & (y | z), (x & y) | (x & z),
250 Frm("x & (y | z) != (x & y) | (x & z) for x=%r, y=%r, z=%r", (x, y, z)))
251 eq(x | (y & z), (x | y) & (x | z),
252 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 +0000253
Walter Dörwalda0021592005-06-13 21:44:48 +0000254 def test_bitop_identities(self):
255 for x in special:
256 self.check_bitop_identities_1(x)
Guido van Rossum805365e2007-05-07 22:24:25 +0000257 digits = range(1, MAXDIGITS+1)
Walter Dörwalda0021592005-06-13 21:44:48 +0000258 for lenx in digits:
259 x = self.getran(lenx)
260 self.check_bitop_identities_1(x)
261 for leny in digits:
262 y = self.getran(leny)
263 self.check_bitop_identities_2(x, y)
264 self.check_bitop_identities_3(x, y, self.getran((lenx + leny)//2))
Guido van Rossum4365cab1998-08-13 14:20:17 +0000265
Walter Dörwalda0021592005-06-13 21:44:48 +0000266 def slow_format(self, x, base):
Walter Dörwalda0021592005-06-13 21:44:48 +0000267 digits = []
268 sign = 0
269 if x < 0:
270 sign, x = 1, -x
271 while x:
272 x, r = divmod(x, base)
273 digits.append(int(r))
274 digits.reverse()
275 digits = digits or [0]
276 return '-'[:sign] + \
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000277 {2: '0b', 8: '0o', 10: '', 16: '0x'}[base] + \
Guido van Rossumd2dbecb2006-08-18 16:29:54 +0000278 "".join(map(lambda i: "0123456789abcdef"[i], digits))
Guido van Rossum4365cab1998-08-13 14:20:17 +0000279
Walter Dörwalda0021592005-06-13 21:44:48 +0000280 def check_format_1(self, x):
281 for base, mapper in (8, oct), (10, repr), (16, hex):
282 got = mapper(x)
283 expected = self.slow_format(x, base)
284 msg = Frm("%s returned %r but expected %r for %r",
285 mapper.__name__, got, expected, x)
286 self.assertEqual(got, expected, msg)
Mark Dickinson5c2db372009-12-05 20:28:34 +0000287 self.assertEqual(int(got, 0), x, Frm('int("%s", 0) != %r', got, x))
Walter Dörwalda0021592005-06-13 21:44:48 +0000288 # str() has to be checked a little differently since there's no
289 # trailing "L"
290 got = str(x)
Guido van Rossumd2dbecb2006-08-18 16:29:54 +0000291 expected = self.slow_format(x, 10)
Walter Dörwalda0021592005-06-13 21:44:48 +0000292 msg = Frm("%s returned %r but expected %r for %r",
293 mapper.__name__, got, expected, x)
294 self.assertEqual(got, expected, msg)
Guido van Rossum4365cab1998-08-13 14:20:17 +0000295
Walter Dörwalda0021592005-06-13 21:44:48 +0000296 def test_format(self):
297 for x in special:
298 self.check_format_1(x)
Guido van Rossum805365e2007-05-07 22:24:25 +0000299 for i in range(10):
300 for lenx in range(1, MAXDIGITS+1):
Walter Dörwalda0021592005-06-13 21:44:48 +0000301 x = self.getran(lenx)
302 self.check_format_1(x)
Guido van Rossum4365cab1998-08-13 14:20:17 +0000303
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000304 def test_long(self):
Mark Dickinson5c2db372009-12-05 20:28:34 +0000305 # Check conversions from string
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000306 LL = [
307 ('1' + '0'*20, 10**20),
308 ('1' + '0'*100, 10**100)
309 ]
Mark Dickinson5c2db372009-12-05 20:28:34 +0000310 for s, v in LL:
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000311 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:
Mark Dickinson5c2db372009-12-05 20:28:34 +0000318 self.assertEqual(int(ss), vv)
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000319 except ValueError:
320 pass
321
Mark Dickinson9ffc0202009-01-20 20:45:53 +0000322 # trailing L should no longer be accepted...
323 self.assertRaises(ValueError, int, '123L')
324 self.assertRaises(ValueError, int, '123l')
325 self.assertRaises(ValueError, int, '0L')
326 self.assertRaises(ValueError, int, '-37L')
327 self.assertRaises(ValueError, int, '0x32L', 16)
328 self.assertRaises(ValueError, int, '1L', 21)
329 # ... but it's just a normal digit if base >= 22
330 self.assertEqual(int('1L', 22), 43)
331
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000332 def test_conversion(self):
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000333
Mark Dickinson5c2db372009-12-05 20:28:34 +0000334 class JustLong:
335 # test that __long__ no longer used in 3.x
336 def __long__(self):
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000337 return 42
Mark Dickinson5c2db372009-12-05 20:28:34 +0000338 self.assertRaises(TypeError, int, JustLong())
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000339
Mark Dickinson5c2db372009-12-05 20:28:34 +0000340 class LongTrunc:
341 # __long__ should be ignored in 3.x
342 def __long__(self):
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000343 return 42
Mark Dickinson5c2db372009-12-05 20:28:34 +0000344 def __trunc__(self):
345 return 1729
346 self.assertEqual(int(LongTrunc()), 1729)
Tim Peters26c7fa32001-08-23 22:56:21 +0000347
Mark Dickinsonc6300392009-04-20 21:38:00 +0000348 @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
349 "test requires IEEE 754 doubles")
350 def test_float_conversion(self):
Mark Dickinsonc6300392009-04-20 21:38:00 +0000351
352 exact_values = [0, 1, 2,
353 2**53-3,
354 2**53-2,
355 2**53-1,
356 2**53,
357 2**53+2,
358 2**54-4,
359 2**54-2,
360 2**54,
361 2**54+4]
362 for x in exact_values:
363 self.assertEqual(float(x), x)
364 self.assertEqual(float(-x), -x)
365
366 # test round-half-even
367 for x, y in [(1, 0), (2, 2), (3, 4), (4, 4), (5, 4), (6, 6), (7, 8)]:
368 for p in range(15):
369 self.assertEqual(int(float(2**p*(2**53+x))), 2**p*(2**53+y))
370
371 for x, y in [(0, 0), (1, 0), (2, 0), (3, 4), (4, 4), (5, 4), (6, 8),
372 (7, 8), (8, 8), (9, 8), (10, 8), (11, 12), (12, 12),
373 (13, 12), (14, 16), (15, 16)]:
374 for p in range(15):
375 self.assertEqual(int(float(2**p*(2**54+x))), 2**p*(2**54+y))
376
377 # behaviour near extremes of floating-point range
378 int_dbl_max = int(DBL_MAX)
379 top_power = 2**DBL_MAX_EXP
380 halfway = (int_dbl_max + top_power)//2
381 self.assertEqual(float(int_dbl_max), DBL_MAX)
382 self.assertEqual(float(int_dbl_max+1), DBL_MAX)
383 self.assertEqual(float(halfway-1), DBL_MAX)
384 self.assertRaises(OverflowError, float, halfway)
385 self.assertEqual(float(1-halfway), -DBL_MAX)
386 self.assertRaises(OverflowError, float, -halfway)
387 self.assertRaises(OverflowError, float, top_power-1)
388 self.assertRaises(OverflowError, float, top_power)
389 self.assertRaises(OverflowError, float, top_power+1)
390 self.assertRaises(OverflowError, float, 2*top_power-1)
391 self.assertRaises(OverflowError, float, 2*top_power)
392 self.assertRaises(OverflowError, float, top_power*top_power)
393
394 for p in range(100):
395 x = 2**p * (2**53 + 1) + 1
396 y = 2**p * (2**53 + 2)
397 self.assertEqual(int(float(x)), y)
398
399 x = 2**p * (2**53 + 1)
400 y = 2**p * 2**53
401 self.assertEqual(int(float(x)), y)
402
Walter Dörwalda0021592005-06-13 21:44:48 +0000403 def test_float_overflow(self):
404 import math
Tim Peters9fffa3e2001-09-04 05:14:19 +0000405
Walter Dörwalda0021592005-06-13 21:44:48 +0000406 for x in -2.0, -1.0, 0.0, 1.0, 2.0:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000407 self.assertEqual(float(int(x)), x)
Tim Peters9fffa3e2001-09-04 05:14:19 +0000408
Walter Dörwalda0021592005-06-13 21:44:48 +0000409 shuge = '12345' * 120
Guido van Rossume2a383d2007-01-15 16:59:06 +0000410 huge = 1 << 30000
Walter Dörwalda0021592005-06-13 21:44:48 +0000411 mhuge = -huge
412 namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math}
413 for test in ["float(huge)", "float(mhuge)",
414 "complex(huge)", "complex(mhuge)",
415 "complex(huge, 1)", "complex(mhuge, 1)",
416 "complex(1, huge)", "complex(1, mhuge)",
417 "1. + huge", "huge + 1.", "1. + mhuge", "mhuge + 1.",
418 "1. - huge", "huge - 1.", "1. - mhuge", "mhuge - 1.",
419 "1. * huge", "huge * 1.", "1. * mhuge", "mhuge * 1.",
420 "1. // huge", "huge // 1.", "1. // mhuge", "mhuge // 1.",
421 "1. / huge", "huge / 1.", "1. / mhuge", "mhuge / 1.",
422 "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.",
423 "math.sin(huge)", "math.sin(mhuge)",
424 "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better
Guido van Rossum28bbe422007-08-24 03:46:30 +0000425 # math.floor() of an int returns an int now
426 ##"math.floor(huge)", "math.floor(mhuge)",
427 ]:
Tim Peters9fffa3e2001-09-04 05:14:19 +0000428
Walter Dörwalda0021592005-06-13 21:44:48 +0000429 self.assertRaises(OverflowError, eval, test, namespace)
Tim Peters9fffa3e2001-09-04 05:14:19 +0000430
Mark Dickinson5c2db372009-12-05 20:28:34 +0000431 # XXX Perhaps float(shuge) can raise OverflowError on some box?
432 # The comparison should not.
433 self.assertNotEqual(float(shuge), int(shuge),
434 "float(shuge) should not equal int(shuge)")
Tim Peters83e7ccc2001-09-04 06:37:28 +0000435
Walter Dörwalda0021592005-06-13 21:44:48 +0000436 def test_logs(self):
437 import math
Tim Peters78526162001-09-05 00:53:45 +0000438
Walter Dörwalda0021592005-06-13 21:44:48 +0000439 LOG10E = math.log10(math.e)
Tim Peters307fa782004-09-23 08:06:40 +0000440
Guido van Rossum805365e2007-05-07 22:24:25 +0000441 for exp in list(range(10)) + [100, 1000, 10000]:
Walter Dörwalda0021592005-06-13 21:44:48 +0000442 value = 10 ** exp
443 log10 = math.log10(value)
444 self.assertAlmostEqual(log10, exp)
Tim Peters78526162001-09-05 00:53:45 +0000445
Walter Dörwalda0021592005-06-13 21:44:48 +0000446 # log10(value) == exp, so log(value) == log10(value)/log10(e) ==
447 # exp/LOG10E
448 expected = exp / LOG10E
449 log = math.log(value)
450 self.assertAlmostEqual(log, expected)
Tim Peters78526162001-09-05 00:53:45 +0000451
Guido van Rossume2a383d2007-01-15 16:59:06 +0000452 for bad in -(1 << 10000), -2, 0:
Walter Dörwalda0021592005-06-13 21:44:48 +0000453 self.assertRaises(ValueError, math.log, bad)
454 self.assertRaises(ValueError, math.log10, bad)
Tim Peters78526162001-09-05 00:53:45 +0000455
Walter Dörwalda0021592005-06-13 21:44:48 +0000456 def test_mixed_compares(self):
457 eq = self.assertEqual
458 import math
Tim Peters78526162001-09-05 00:53:45 +0000459
Walter Dörwalda0021592005-06-13 21:44:48 +0000460 # We're mostly concerned with that mixing floats and longs does the
461 # right stuff, even when longs are too large to fit in a float.
462 # The safest way to check the results is to use an entirely different
463 # method, which we do here via a skeletal rational class (which
464 # represents all Python ints, longs and floats exactly).
465 class Rat:
466 def __init__(self, value):
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000467 if isinstance(value, int):
Walter Dörwalda0021592005-06-13 21:44:48 +0000468 self.n = value
469 self.d = 1
470 elif isinstance(value, float):
471 # Convert to exact rational equivalent.
472 f, e = math.frexp(abs(value))
473 assert f == 0 or 0.5 <= f < 1.0
474 # |value| = f * 2**e exactly
Tim Peters78526162001-09-05 00:53:45 +0000475
Walter Dörwalda0021592005-06-13 21:44:48 +0000476 # Suck up CHUNK bits at a time; 28 is enough so that we suck
477 # up all bits in 2 iterations for all known binary double-
478 # precision formats, and small enough to fit in an int.
479 CHUNK = 28
480 top = 0
481 # invariant: |value| = (top + f) * 2**e exactly
482 while f:
483 f = math.ldexp(f, CHUNK)
484 digit = int(f)
485 assert digit >> CHUNK == 0
486 top = (top << CHUNK) | digit
487 f -= digit
488 assert 0.0 <= f < 1.0
489 e -= CHUNK
Tim Peters78526162001-09-05 00:53:45 +0000490
Walter Dörwalda0021592005-06-13 21:44:48 +0000491 # Now |value| = top * 2**e exactly.
492 if e >= 0:
493 n = top << e
494 d = 1
495 else:
496 n = top
497 d = 1 << -e
498 if value < 0:
499 n = -n
500 self.n = n
501 self.d = d
502 assert float(n) / float(d) == value
Tim Peters307fa782004-09-23 08:06:40 +0000503 else:
Walter Dörwalda0021592005-06-13 21:44:48 +0000504 raise TypeError("can't deal with %r" % val)
Tim Peters307fa782004-09-23 08:06:40 +0000505
Benjamin Peterson60192082008-10-16 19:34:46 +0000506 def _cmp__(self, other):
Walter Dörwalda0021592005-06-13 21:44:48 +0000507 if not isinstance(other, Rat):
508 other = Rat(other)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000509 x, y = self.n * other.d, self.d * other.n
510 return (x > y) - (x < y)
Benjamin Peterson60192082008-10-16 19:34:46 +0000511 def __eq__(self, other):
512 return self._cmp__(other) == 0
513 def __ne__(self, other):
514 return self._cmp__(other) != 0
515 def __ge__(self, other):
516 return self._cmp__(other) >= 0
517 def __gt__(self, other):
518 return self._cmp__(other) > 0
519 def __le__(self, other):
520 return self._cmp__(other) <= 0
521 def __lt__(self, other):
522 return self._cmp__(other) < 0
Tim Peters307fa782004-09-23 08:06:40 +0000523
Walter Dörwalda0021592005-06-13 21:44:48 +0000524 cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200]
525 # 2**48 is an important boundary in the internals. 2**53 is an
526 # important boundary for IEEE double precision.
527 for t in 2.0**48, 2.0**50, 2.0**53:
528 cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0,
Guido van Rossume2a383d2007-01-15 16:59:06 +0000529 int(t-1), int(t), int(t+1)])
Christian Heimesa37d4c62007-12-04 23:02:19 +0000530 cases.extend([0, 1, 2, sys.maxsize, float(sys.maxsize)])
Mark Dickinson5c2db372009-12-05 20:28:34 +0000531 # 1 << 20000 should exceed all double formats. int(1e200) is to
Walter Dörwalda0021592005-06-13 21:44:48 +0000532 # check that we get equality with 1e200 above.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000533 t = int(1e200)
534 cases.extend([0, 1, 2, 1 << 20000, t-1, t, t+1])
Walter Dörwalda0021592005-06-13 21:44:48 +0000535 cases.extend([-x for x in cases])
536 for x in cases:
537 Rx = Rat(x)
538 for y in cases:
539 Ry = Rat(y)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000540 Rcmp = (Rx > Ry) - (Rx < Ry)
541 xycmp = (x > y) - (x < y)
Walter Dörwalda0021592005-06-13 21:44:48 +0000542 eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp))
543 eq(x == y, Rcmp == 0, Frm("%r == %r %d", x, y, Rcmp))
544 eq(x != y, Rcmp != 0, Frm("%r != %r %d", x, y, Rcmp))
545 eq(x < y, Rcmp < 0, Frm("%r < %r %d", x, y, Rcmp))
546 eq(x <= y, Rcmp <= 0, Frm("%r <= %r %d", x, y, Rcmp))
547 eq(x > y, Rcmp > 0, Frm("%r > %r %d", x, y, Rcmp))
548 eq(x >= y, Rcmp >= 0, Frm("%r >= %r %d", x, y, Rcmp))
Tim Peters307fa782004-09-23 08:06:40 +0000549
Eric Smith0dd1b632008-02-11 17:55:01 +0000550 def test__format__(self):
Eric Smith8c663262007-08-25 02:26:07 +0000551 self.assertEqual(format(123456789, 'd'), '123456789')
552 self.assertEqual(format(123456789, 'd'), '123456789')
553
Eric Smith185e30c2007-08-30 22:23:08 +0000554 # sign and aligning are interdependent
555 self.assertEqual(format(1, "-"), '1')
556 self.assertEqual(format(-1, "-"), '-1')
557 self.assertEqual(format(1, "-3"), ' 1')
558 self.assertEqual(format(-1, "-3"), ' -1')
559 self.assertEqual(format(1, "+3"), ' +1')
560 self.assertEqual(format(-1, "+3"), ' -1')
561 self.assertEqual(format(1, " 3"), ' 1')
562 self.assertEqual(format(-1, " 3"), ' -1')
563 self.assertEqual(format(1, " "), ' 1')
564 self.assertEqual(format(-1, " "), '-1')
565
Eric Smith8c663262007-08-25 02:26:07 +0000566 # hex
567 self.assertEqual(format(3, "x"), "3")
568 self.assertEqual(format(3, "X"), "3")
569 self.assertEqual(format(1234, "x"), "4d2")
570 self.assertEqual(format(-1234, "x"), "-4d2")
571 self.assertEqual(format(1234, "8x"), " 4d2")
Eric Smith185e30c2007-08-30 22:23:08 +0000572 self.assertEqual(format(-1234, "8x"), " -4d2")
Eric Smith8c663262007-08-25 02:26:07 +0000573 self.assertEqual(format(1234, "x"), "4d2")
574 self.assertEqual(format(-1234, "x"), "-4d2")
575 self.assertEqual(format(-3, "x"), "-3")
576 self.assertEqual(format(-3, "X"), "-3")
577 self.assertEqual(format(int('be', 16), "x"), "be")
578 self.assertEqual(format(int('be', 16), "X"), "BE")
579 self.assertEqual(format(-int('be', 16), "x"), "-be")
580 self.assertEqual(format(-int('be', 16), "X"), "-BE")
581
582 # octal
583 self.assertEqual(format(3, "b"), "11")
584 self.assertEqual(format(-3, "b"), "-11")
585 self.assertEqual(format(1234, "b"), "10011010010")
586 self.assertEqual(format(-1234, "b"), "-10011010010")
587 self.assertEqual(format(1234, "-b"), "10011010010")
588 self.assertEqual(format(-1234, "-b"), "-10011010010")
589 self.assertEqual(format(1234, " b"), " 10011010010")
590 self.assertEqual(format(-1234, " b"), "-10011010010")
591 self.assertEqual(format(1234, "+b"), "+10011010010")
592 self.assertEqual(format(-1234, "+b"), "-10011010010")
593
Eric Smith8c663262007-08-25 02:26:07 +0000594 # make sure these are errors
595 self.assertRaises(ValueError, format, 3, "1.3") # precision disallowed
Eric Smith8c663262007-08-25 02:26:07 +0000596 self.assertRaises(ValueError, format, 3, "+c") # sign not allowed
597 # with 'c'
Eric Smithfa767ef2008-01-28 10:59:27 +0000598
599 # ensure that only int and float type specifiers work
Eric Smith7b69c6c2008-01-27 21:07:59 +0000600 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
601 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
Eric Smithfa767ef2008-01-28 10:59:27 +0000602 if not format_spec in 'bcdoxXeEfFgGn%':
Eric Smith7b69c6c2008-01-27 21:07:59 +0000603 self.assertRaises(ValueError, format, 0, format_spec)
604 self.assertRaises(ValueError, format, 1, format_spec)
605 self.assertRaises(ValueError, format, -1, format_spec)
606 self.assertRaises(ValueError, format, 2**100, format_spec)
607 self.assertRaises(ValueError, format, -(2**100), format_spec)
608
Eric Smithfa767ef2008-01-28 10:59:27 +0000609 # ensure that float type specifiers work; format converts
610 # the int to a float
Eric Smith5807c412008-05-11 21:00:57 +0000611 for format_spec in 'eEfFgG%':
Eric Smithfa767ef2008-01-28 10:59:27 +0000612 for value in [0, 1, -1, 100, -100, 1234567890, -1234567890]:
613 self.assertEqual(format(value, format_spec),
614 format(float(value), format_spec))
Eric Smith8c663262007-08-25 02:26:07 +0000615
Christian Heimesa34706f2008-01-04 03:06:10 +0000616 def test_nan_inf(self):
Christian Heimes1aa7b302008-01-04 03:22:53 +0000617 self.assertRaises(OverflowError, int, float('inf'))
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000618 self.assertRaises(OverflowError, int, float('-inf'))
619 self.assertRaises(ValueError, int, float('nan'))
Christian Heimesa34706f2008-01-04 03:06:10 +0000620
Benjamin Peterson875d4c02008-07-13 17:44:16 +0000621 def test_true_division(self):
622 huge = 1 << 40000
623 mhuge = -huge
624 self.assertEqual(huge / huge, 1.0)
625 self.assertEqual(mhuge / mhuge, 1.0)
626 self.assertEqual(huge / mhuge, -1.0)
627 self.assertEqual(mhuge / huge, -1.0)
628 self.assertEqual(1 / huge, 0.0)
629 self.assertEqual(1 / huge, 0.0)
630 self.assertEqual(1 / mhuge, 0.0)
631 self.assertEqual(1 / mhuge, 0.0)
632 self.assertEqual((666 * huge + (huge >> 1)) / huge, 666.5)
633 self.assertEqual((666 * mhuge + (mhuge >> 1)) / mhuge, 666.5)
634 self.assertEqual((666 * huge + (huge >> 1)) / mhuge, -666.5)
635 self.assertEqual((666 * mhuge + (mhuge >> 1)) / huge, -666.5)
636 self.assertEqual(huge / (huge << 1), 0.5)
637 self.assertEqual((1000000 * huge) / huge, 1000000)
638
639 namespace = {'huge': huge, 'mhuge': mhuge}
640
641 for overflow in ["float(huge)", "float(mhuge)",
642 "huge / 1", "huge / 2", "huge / -1", "huge / -2",
643 "mhuge / 100", "mhuge / 200"]:
644 self.assertRaises(OverflowError, eval, overflow, namespace)
645
646 for underflow in ["1 / huge", "2 / huge", "-1 / huge", "-2 / huge",
647 "100 / mhuge", "200 / mhuge"]:
648 result = eval(underflow, namespace)
649 self.assertEqual(result, 0.0,
650 "expected underflow to 0 from %r" % underflow)
651
652 for zero in ["huge / 0", "mhuge / 0"]:
653 self.assertRaises(ZeroDivisionError, eval, zero, namespace)
654
Mark Dickinsoncbb62742009-12-27 15:09:50 +0000655 def check_truediv(self, a, b, skip_small=True):
656 """Verify that the result of a/b is correctly rounded, by
657 comparing it with a pure Python implementation of correctly
658 rounded division. b should be nonzero."""
659
660 # skip check for small a and b: in this case, the current
661 # implementation converts the arguments to float directly and
662 # then applies a float division. This can give doubly-rounded
663 # results on x87-using machines (particularly 32-bit Linux).
664 if skip_small and max(abs(a), abs(b)) < 2**DBL_MANT_DIG:
665 return
666
667 try:
668 # use repr so that we can distinguish between -0.0 and 0.0
669 expected = repr(truediv(a, b))
670 except OverflowError:
671 expected = 'overflow'
672 except ZeroDivisionError:
673 expected = 'zerodivision'
674
675 try:
676 got = repr(a / b)
677 except OverflowError:
678 got = 'overflow'
679 except ZeroDivisionError:
680 got = 'zerodivision'
681
Mark Dickinson2cfda802009-12-27 21:34:05 +0000682 self.assertEqual(expected, got, "Incorrectly rounded division {}/{}: "
683 "expected {}, got {}".format(a, b, expected, got))
Mark Dickinsoncbb62742009-12-27 15:09:50 +0000684
685 @requires_IEEE_754
686 def test_correctly_rounded_true_division(self):
687 # more stringent tests than those above, checking that the
688 # result of true division of ints is always correctly rounded.
689 # This test should probably be considered CPython-specific.
690
691 # Exercise all the code paths not involving Gb-sized ints.
692 # ... divisions involving zero
693 self.check_truediv(123, 0)
694 self.check_truediv(-456, 0)
695 self.check_truediv(0, 3)
696 self.check_truediv(0, -3)
697 self.check_truediv(0, 0)
698 # ... overflow or underflow by large margin
699 self.check_truediv(671 * 12345 * 2**DBL_MAX_EXP, 12345)
700 self.check_truediv(12345, 345678 * 2**(DBL_MANT_DIG - DBL_MIN_EXP))
701 # ... a much larger or smaller than b
702 self.check_truediv(12345*2**100, 98765)
703 self.check_truediv(12345*2**30, 98765*7**81)
704 # ... a / b near a boundary: one of 1, 2**DBL_MANT_DIG, 2**DBL_MIN_EXP,
705 # 2**DBL_MAX_EXP, 2**(DBL_MIN_EXP-DBL_MANT_DIG)
706 bases = (0, DBL_MANT_DIG, DBL_MIN_EXP,
707 DBL_MAX_EXP, DBL_MIN_EXP - DBL_MANT_DIG)
708 for base in bases:
709 for exp in range(base - 15, base + 15):
710 self.check_truediv(75312*2**max(exp, 0), 69187*2**max(-exp, 0))
711 self.check_truediv(69187*2**max(exp, 0), 75312*2**max(-exp, 0))
712
713 # overflow corner case
714 for m in [1, 2, 7, 17, 12345, 7**100,
715 -1, -2, -5, -23, -67891, -41**50]:
716 for n in range(-10, 10):
717 self.check_truediv(m*DBL_MIN_OVERFLOW + n, m)
718 self.check_truediv(m*DBL_MIN_OVERFLOW + n, -m)
719
720 # check detection of inexactness in shifting stage
721 for n in range(250):
722 # (2**DBL_MANT_DIG+1)/(2**DBL_MANT_DIG) lies halfway
723 # between two representable floats, and would usually be
724 # rounded down under round-half-to-even. The tiniest of
725 # additions to the numerator should cause it to be rounded
726 # up instead.
727 self.check_truediv((2**DBL_MANT_DIG + 1)*12345*2**200 + 2**n,
728 2**DBL_MANT_DIG*12345)
729
730 # 1/2731 is one of the smallest division cases that's subject
731 # to double rounding on IEEE 754 machines working internally with
732 # 64-bit precision. On such machines, the next check would fail,
733 # were it not explicitly skipped in check_truediv.
734 self.check_truediv(1, 2731)
735
736 # a particularly bad case for the old algorithm: gives an
737 # error of close to 3.5 ulps.
738 self.check_truediv(295147931372582273023, 295147932265116303360)
739 for i in range(1000):
740 self.check_truediv(10**(i+1), 10**i)
741 self.check_truediv(10**i, 10**(i+1))
742
743 # test round-half-to-even behaviour, normal result
744 for m in [1, 2, 4, 7, 8, 16, 17, 32, 12345, 7**100,
745 -1, -2, -5, -23, -67891, -41**50]:
746 for n in range(-10, 10):
747 self.check_truediv(2**DBL_MANT_DIG*m + n, m)
748
749 # test round-half-to-even, subnormal result
750 for n in range(-20, 20):
751 self.check_truediv(n, 2**1076)
752
753 # largeish random divisions: a/b where |a| <= |b| <=
754 # 2*|a|; |ans| is between 0.5 and 1.0, so error should
755 # always be bounded by 2**-54 with equality possible only
756 # if the least significant bit of q=ans*2**53 is zero.
757 for M in [10**10, 10**100, 10**1000]:
758 for i in range(1000):
759 a = random.randrange(1, M)
760 b = random.randrange(a, 2*a+1)
761 self.check_truediv(a, b)
762 self.check_truediv(-a, b)
763 self.check_truediv(a, -b)
764 self.check_truediv(-a, -b)
765
766 # and some (genuinely) random tests
767 for _ in range(10000):
768 a_bits = random.randrange(1000)
769 b_bits = random.randrange(1, 1000)
770 x = random.randrange(2**a_bits)
771 y = random.randrange(1, 2**b_bits)
772 self.check_truediv(x, y)
773 self.check_truediv(x, -y)
774 self.check_truediv(-x, y)
775 self.check_truediv(-x, -y)
Benjamin Peterson875d4c02008-07-13 17:44:16 +0000776
Facundo Batista6e6f59b2008-07-24 18:57:11 +0000777 def test_small_ints(self):
778 for i in range(-5, 257):
779 self.assertTrue(i is i + 0)
780 self.assertTrue(i is i * 1)
781 self.assertTrue(i is i - 0)
782 self.assertTrue(i is i // 1)
783 self.assertTrue(i is i & -1)
784 self.assertTrue(i is i | 0)
785 self.assertTrue(i is i ^ 0)
786 self.assertTrue(i is ~~i)
787 self.assertTrue(i is i**1)
788 self.assertTrue(i is int(str(i)))
789 self.assertTrue(i is i<<2>>2, str(i))
790 # corner cases
791 i = 1 << 70
792 self.assertTrue(i - i is 0)
793 self.assertTrue(0 * i is 0)
794
Mark Dickinson54bc1ec2008-12-17 16:19:07 +0000795 def test_bit_length(self):
796 tiny = 1e-10
797 for x in range(-65000, 65000):
798 k = x.bit_length()
799 # Check equivalence with Python version
800 self.assertEqual(k, len(bin(x).lstrip('-0b')))
801 # Behaviour as specified in the docs
802 if x != 0:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000803 self.assertTrue(2**(k-1) <= abs(x) < 2**k)
Mark Dickinson54bc1ec2008-12-17 16:19:07 +0000804 else:
805 self.assertEqual(k, 0)
806 # Alternative definition: x.bit_length() == 1 + floor(log_2(x))
807 if x != 0:
808 # When x is an exact power of 2, numeric errors can
809 # cause floor(log(x)/log(2)) to be one too small; for
810 # small x this can be fixed by adding a small quantity
811 # to the quotient before taking the floor.
812 self.assertEqual(k, 1 + math.floor(
813 math.log(abs(x))/math.log(2) + tiny))
814
815 self.assertEqual((0).bit_length(), 0)
816 self.assertEqual((1).bit_length(), 1)
817 self.assertEqual((-1).bit_length(), 1)
818 self.assertEqual((2).bit_length(), 2)
819 self.assertEqual((-2).bit_length(), 2)
820 for i in [2, 3, 15, 16, 17, 31, 32, 33, 63, 64, 234]:
821 a = 2**i
822 self.assertEqual((a-1).bit_length(), i)
823 self.assertEqual((1-a).bit_length(), i)
824 self.assertEqual((a).bit_length(), i+1)
825 self.assertEqual((-a).bit_length(), i+1)
826 self.assertEqual((a+1).bit_length(), i+1)
827 self.assertEqual((-a-1).bit_length(), i+1)
828
Mark Dickinson1124e712009-01-28 21:25:58 +0000829 def test_round(self):
830 # check round-half-even algorithm. For round to nearest ten;
831 # rounding map is invariant under adding multiples of 20
832 test_dict = {0:0, 1:0, 2:0, 3:0, 4:0, 5:0,
833 6:10, 7:10, 8:10, 9:10, 10:10, 11:10, 12:10, 13:10, 14:10,
834 15:20, 16:20, 17:20, 18:20, 19:20}
835 for offset in range(-520, 520, 20):
836 for k, v in test_dict.items():
837 got = round(k+offset, -1)
838 expected = v+offset
839 self.assertEqual(got, expected)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000840 self.assertTrue(type(got) is int)
Mark Dickinson1124e712009-01-28 21:25:58 +0000841
842 # larger second argument
843 self.assertEqual(round(-150, -2), -200)
844 self.assertEqual(round(-149, -2), -100)
845 self.assertEqual(round(-51, -2), -100)
846 self.assertEqual(round(-50, -2), 0)
847 self.assertEqual(round(-49, -2), 0)
848 self.assertEqual(round(-1, -2), 0)
849 self.assertEqual(round(0, -2), 0)
850 self.assertEqual(round(1, -2), 0)
851 self.assertEqual(round(49, -2), 0)
852 self.assertEqual(round(50, -2), 0)
853 self.assertEqual(round(51, -2), 100)
854 self.assertEqual(round(149, -2), 100)
855 self.assertEqual(round(150, -2), 200)
856 self.assertEqual(round(250, -2), 200)
857 self.assertEqual(round(251, -2), 300)
858 self.assertEqual(round(172500, -3), 172000)
859 self.assertEqual(round(173500, -3), 174000)
860 self.assertEqual(round(31415926535, -1), 31415926540)
861 self.assertEqual(round(31415926535, -2), 31415926500)
862 self.assertEqual(round(31415926535, -3), 31415927000)
863 self.assertEqual(round(31415926535, -4), 31415930000)
864 self.assertEqual(round(31415926535, -5), 31415900000)
865 self.assertEqual(round(31415926535, -6), 31416000000)
866 self.assertEqual(round(31415926535, -7), 31420000000)
867 self.assertEqual(round(31415926535, -8), 31400000000)
868 self.assertEqual(round(31415926535, -9), 31000000000)
869 self.assertEqual(round(31415926535, -10), 30000000000)
870 self.assertEqual(round(31415926535, -11), 0)
871 self.assertEqual(round(31415926535, -12), 0)
872 self.assertEqual(round(31415926535, -999), 0)
873
874 # should get correct results even for huge inputs
875 for k in range(10, 100):
876 got = round(10**k + 324678, -3)
877 expect = 10**k + 325000
878 self.assertEqual(got, expect)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000879 self.assertTrue(type(got) is int)
Mark Dickinson1124e712009-01-28 21:25:58 +0000880
881 # nonnegative second argument: round(x, n) should just return x
882 for n in range(5):
883 for i in range(100):
884 x = random.randrange(-10000, 10000)
885 got = round(x, n)
886 self.assertEqual(got, x)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000887 self.assertTrue(type(got) is int)
Mark Dickinson1124e712009-01-28 21:25:58 +0000888 for huge_n in 2**31-1, 2**31, 2**63-1, 2**63, 2**100, 10**100:
889 self.assertEqual(round(8979323, huge_n), 8979323)
890
891 # omitted second argument
892 for i in range(100):
893 x = random.randrange(-10000, 10000)
894 got = round(x)
895 self.assertEqual(got, x)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000896 self.assertTrue(type(got) is int)
Mark Dickinson1124e712009-01-28 21:25:58 +0000897
898 # bad second argument
899 bad_exponents = ('brian', 2.0, 0j, None)
900 for e in bad_exponents:
901 self.assertRaises(TypeError, round, 3, e)
902
903
Mark Dickinson54bc1ec2008-12-17 16:19:07 +0000904
Walter Dörwalda0021592005-06-13 21:44:48 +0000905def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000906 support.run_unittest(LongTest)
Tim Peters307fa782004-09-23 08:06:40 +0000907
Walter Dörwalda0021592005-06-13 21:44:48 +0000908if __name__ == "__main__":
909 test_main()