Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(33168)

Side by Side Diff: Modules/_decimal/tests/randfloat.py

Issue 7652: Merge C version of decimal into py3k.
Patch Set: Created 7 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Modules/_decimal/tests/randdec.py ('k') | Modules/_decimal/tests/README.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright (c) 2010 Python Software Foundation. All Rights Reserved.
2 # Adapted from Python's Lib/test/test_strtod.py (by Mark Dickinson)
3
4 # More test cases for deccheck.py.
5
6 import random
7
8 TEST_SIZE = 2
9
10
11 def test_short_halfway_cases():
12 # exact halfway cases with a small number of significant digits
13 for k in 0, 5, 10, 15, 20:
14 # upper = smallest integer >= 2**54/5**k
15 upper = -(-2**54//5**k)
16 # lower = smallest odd number >= 2**53/5**k
17 lower = -(-2**53//5**k)
18 if lower % 2 == 0:
19 lower += 1
20 for i in range(10 * TEST_SIZE):
21 # Select a random odd n in [2**53/5**k,
22 # 2**54/5**k). Then n * 10**k gives a halfway case
23 # with small number of significant digits.
24 n, e = random.randrange(lower, upper, 2), k
25
26 # Remove any additional powers of 5.
27 while n % 5 == 0:
28 n, e = n // 5, e + 1
29 assert n % 10 in (1, 3, 7, 9)
30
31 # Try numbers of the form n * 2**p2 * 10**e, p2 >= 0,
32 # until n * 2**p2 has more than 20 significant digits.
33 digits, exponent = n, e
34 while digits < 10**20:
35 s = '{}e{}'.format(digits, exponent)
36 yield s
37 # Same again, but with extra trailing zeros.
38 s = '{}e{}'.format(digits * 10**40, exponent - 40)
39 yield s
40 digits *= 2
41
42 # Try numbers of the form n * 5**p2 * 10**(e - p5), p5
43 # >= 0, with n * 5**p5 < 10**20.
44 digits, exponent = n, e
45 while digits < 10**20:
46 s = '{}e{}'.format(digits, exponent)
47 yield s
48 # Same again, but with extra trailing zeros.
49 s = '{}e{}'.format(digits * 10**40, exponent - 40)
50 yield s
51 digits *= 5
52 exponent -= 1
53
54 def test_halfway_cases():
55 # test halfway cases for the round-half-to-even rule
56 for i in range(1000):
57 for j in range(TEST_SIZE):
58 # bit pattern for a random finite positive (or +0.0) float
59 bits = random.randrange(2047*2**52)
60
61 # convert bit pattern to a number of the form m * 2**e
62 e, m = divmod(bits, 2**52)
63 if e:
64 m, e = m + 2**52, e - 1
65 e -= 1074
66
67 # add 0.5 ulps
68 m, e = 2*m + 1, e - 1
69
70 # convert to a decimal string
71 if e >= 0:
72 digits = m << e
73 exponent = 0
74 else:
75 # m * 2**e = (m * 5**-e) * 10**e
76 digits = m * 5**-e
77 exponent = e
78 s = '{}e{}'.format(digits, exponent)
79 yield s
80
81 def test_boundaries():
82 # boundaries expressed as triples (n, e, u), where
83 # n*10**e is an approximation to the boundary value and
84 # u*10**e is 1ulp
85 boundaries = [
86 (10000000000000000000, -19, 1110), # a power of 2 boundary (1.0)
87 (17976931348623159077, 289, 1995), # overflow boundary (2.**1024)
88 (22250738585072013831, -327, 4941), # normal/subnormal (2.**-1022)
89 (0, -327, 4941), # zero
90 ]
91 for n, e, u in boundaries:
92 for j in range(1000):
93 for i in range(TEST_SIZE):
94 digits = n + random.randrange(-3*u, 3*u)
95 exponent = e
96 s = '{}e{}'.format(digits, exponent)
97 yield s
98 n *= 10
99 u *= 10
100 e -= 1
101
102 def test_underflow_boundary():
103 # test values close to 2**-1075, the underflow boundary; similar
104 # to boundary_tests, except that the random error doesn't scale
105 # with n
106 for exponent in range(-400, -320):
107 base = 10**-exponent // 2**1075
108 for j in range(TEST_SIZE):
109 digits = base + random.randrange(-1000, 1000)
110 s = '{}e{}'.format(digits, exponent)
111 yield s
112
113 def test_bigcomp():
114 for ndigs in 5, 10, 14, 15, 16, 17, 18, 19, 20, 40, 41, 50:
115 dig10 = 10**ndigs
116 for i in range(100 * TEST_SIZE):
117 digits = random.randrange(dig10)
118 exponent = random.randrange(-400, 400)
119 s = '{}e{}'.format(digits, exponent)
120 yield s
121
122 def test_parsing():
123 # make '0' more likely to be chosen than other digits
124 digits = '000000123456789'
125 signs = ('+', '-', '')
126
127 # put together random short valid strings
128 # \d*[.\d*]?e
129 for i in range(1000):
130 for j in range(TEST_SIZE):
131 s = random.choice(signs)
132 intpart_len = random.randrange(5)
133 s += ''.join(random.choice(digits) for _ in range(intpart_len))
134 if random.choice([True, False]):
135 s += '.'
136 fracpart_len = random.randrange(5)
137 s += ''.join(random.choice(digits)
138 for _ in range(fracpart_len))
139 else:
140 fracpart_len = 0
141 if random.choice([True, False]):
142 s += random.choice(['e', 'E'])
143 s += random.choice(signs)
144 exponent_len = random.randrange(1, 4)
145 s += ''.join(random.choice(digits)
146 for _ in range(exponent_len))
147
148 if intpart_len + fracpart_len:
149 yield s
150
151 test_particular = [
152 # squares
153 '1.00000000100000000025',
154 '1.0000000000000000000000000100000000000000000000000' #...
155 '00025',
156 '1.0000000000000000000000000000000000000000000010000' #...
157 '0000000000000000000000000000000000000000025',
158 '1.0000000000000000000000000000000000000000000000000' #...
159 '000001000000000000000000000000000000000000000000000' #...
160 '000000000025',
161 '0.99999999900000000025',
162 '0.9999999999999999999999999999999999999999999999999' #...
163 '999000000000000000000000000000000000000000000000000' #...
164 '000025',
165 '0.9999999999999999999999999999999999999999999999999' #...
166 '999999999999999999999999999999999999999999999999999' #...
167 '999999999999999999999999999999999999999990000000000' #...
168 '000000000000000000000000000000000000000000000000000' #...
169 '000000000000000000000000000000000000000000000000000' #...
170 '0000000000000000000000000000025',
171
172 '1.0000000000000000000000000000000000000000000000000' #...
173 '000000000000000000000000000000000000000000000000000' #...
174 '100000000000000000000000000000000000000000000000000' #...
175 '000000000000000000000000000000000000000000000000001',
176 '1.0000000000000000000000000000000000000000000000000' #...
177 '000000000000000000000000000000000000000000000000000' #...
178 '500000000000000000000000000000000000000000000000000' #...
179 '000000000000000000000000000000000000000000000000005',
180 '1.0000000000000000000000000000000000000000000000000' #...
181 '000000000100000000000000000000000000000000000000000' #...
182 '000000000000000000250000000000000002000000000000000' #...
183 '000000000000000000000000000000000000000000010000000' #...
184 '000000000000000000000000000000000000000000000000000' #...
185 '0000000000000000001',
186 '1.0000000000000000000000000000000000000000000000000' #...
187 '000000000100000000000000000000000000000000000000000' #...
188 '000000000000000000249999999999999999999999999999999' #...
189 '999999999999979999999999999999999999999999999999999' #...
190 '999999999999999999999900000000000000000000000000000' #...
191 '000000000000000000000000000000000000000000000000000' #...
192 '00000000000000000000000001',
193
194 '0.9999999999999999999999999999999999999999999999999' #...
195 '999999999900000000000000000000000000000000000000000' #...
196 '000000000000000000249999999999999998000000000000000' #...
197 '000000000000000000000000000000000000000000010000000' #...
198 '000000000000000000000000000000000000000000000000000' #...
199 '0000000000000000001',
200 '0.9999999999999999999999999999999999999999999999999' #...
201 '999999999900000000000000000000000000000000000000000' #...
202 '000000000000000000250000001999999999999999999999999' #...
203 '999999999999999999999999999999999990000000000000000' #...
204 '000000000000000000000000000000000000000000000000000' #...
205 '1',
206
207 # tough cases for ln etc.
208 '1.000000000000000000000000000000000000000000000000' #...
209 '00000000000000000000000000000000000000000000000000' #...
210 '00100000000000000000000000000000000000000000000000' #...
211 '00000000000000000000000000000000000000000000000000' #...
212 '0001',
213 '0.999999999999999999999999999999999999999999999999' #...
214 '99999999999999999999999999999999999999999999999999' #...
215 '99899999999999999999999999999999999999999999999999' #...
216 '99999999999999999999999999999999999999999999999999' #...
217 '99999999999999999999999999999999999999999999999999' #...
218 '9999'
219 ]
220
221
222 TESTCASES = [
223 [x for x in test_short_halfway_cases()],
224 [x for x in test_halfway_cases()],
225 [x for x in test_boundaries()],
226 [x for x in test_underflow_boundary()],
227 [x for x in test_bigcomp()],
228 [x for x in test_parsing()],
229 test_particular
230 ]
231
232 def un_randfloat():
233 for i in range(1000):
234 l = random.choice(TESTCASES[:6])
235 yield random.choice(l)
236 for v in test_particular:
237 yield v
238
239 def bin_randfloat():
240 for i in range(1000):
241 l1 = random.choice(TESTCASES)
242 l2 = random.choice(TESTCASES)
243 yield random.choice(l1), random.choice(l2)
244
245 def tern_randfloat():
246 for i in range(1000):
247 l1 = random.choice(TESTCASES)
248 l2 = random.choice(TESTCASES)
249 l3 = random.choice(TESTCASES)
250 yield random.choice(l1), random.choice(l2), random.choice(l3)
OLDNEW
« no previous file with comments | « Modules/_decimal/tests/randdec.py ('k') | Modules/_decimal/tests/README.txt » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+