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

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

Issue 7652: Merge C version of decimal into py3k.
Patch Set: Created 7 years, 8 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/formathelper.py ('k') | Modules/_decimal/tests/randfloat.py » ('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 #!/usr/bin/env python
2
3 #
4 # Copyright (c) 2008-2010 Stefan Krah. All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # 1. Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 #
13 # 2. Redistributions in binary form must reproduce the above copyright
14 # notice, this list of conditions and the following disclaimer in the
15 # documentation and/or other materials provided with the distribution.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
18 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 # SUCH DAMAGE.
28 #
29
30
31 # Generate test cases for deccheck.py.
32
33
34 #
35 # Grammar from http://speleotrove.com/decimal/daconvs.html
36 #
37 # sign ::= '+' | '-'
38 # digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' |
39 # '8' | '9'
40 # indicator ::= 'e' | 'E'
41 # digits ::= digit [digit]...
42 # decimal-part ::= digits '.' [digits] | ['.'] digits
43 # exponent-part ::= indicator [sign] digits
44 # infinity ::= 'Infinity' | 'Inf'
45 # nan ::= 'NaN' [digits] | 'sNaN' [digits]
46 # numeric-value ::= decimal-part [exponent-part] | infinity
47 # numeric-string ::= [sign] numeric-value | [sign] nan
48 #
49
50
51 from random import randrange, sample
52 from fractions import Fraction
53 from randfloat import un_randfloat, bin_randfloat, tern_randfloat
54
55
56 def sign():
57 if randrange(2):
58 if randrange(2): return '+'
59 return ''
60 return '-'
61
62 def indicator():
63 return "eE"[randrange(2)]
64
65 def digits(maxprec):
66 if maxprec == 0: return ''
67 return str(randrange(10**maxprec))
68
69 def dot():
70 if randrange(2): return '.'
71 return ''
72
73 def decimal_part(maxprec):
74 if randrange(100) > 60: # integers
75 return digits(maxprec)
76 if randrange(2):
77 intlen = randrange(1, maxprec+1)
78 fraclen = maxprec-intlen
79 intpart = digits(intlen)
80 fracpart = digits(fraclen)
81 return ''.join((intpart, '.', fracpart))
82 else:
83 return ''.join((dot(), digits(maxprec)))
84
85 def expdigits(maxexp):
86 return str(randrange(maxexp))
87
88 def exponent_part(maxexp):
89 return ''.join((indicator(), sign(), expdigits(maxexp)))
90
91 def infinity():
92 if randrange(2): return 'Infinity'
93 return 'Inf'
94
95 def nan():
96 d = ''
97 if randrange(2):
98 d = digits(randrange(99))
99 if randrange(2):
100 return ''.join(('NaN', d))
101 else:
102 return ''.join(('sNaN', d))
103
104 def numeric_value(maxprec, maxexp):
105 if randrange(100) > 90:
106 return infinity()
107 exp_part = ''
108 if randrange(100) > 60:
109 exp_part = exponent_part(maxexp)
110 return ''.join((decimal_part(maxprec), exp_part))
111
112 def numeric_string(maxprec, maxexp):
113 if randrange(100) > 95:
114 return ''.join((sign(), nan()))
115 else:
116 return ''.join((sign(), numeric_value(maxprec, maxexp)))
117
118 def randdec(maxprec, maxexp):
119 return numeric_string(maxprec, maxexp)
120
121 def rand_adjexp(maxprec, maxadjexp):
122 d = digits(maxprec)
123 maxexp = maxadjexp-len(d)+1
124 if maxexp == 0: maxexp = 1
125 exp = str(randrange(maxexp-2*(abs(maxexp)), maxexp))
126 return ''.join((sign(), d, 'E', exp))
127
128
129 def ndigits(n):
130 if n < 1: return 0
131 return randrange(10**(n-1), 10**n)
132
133 def randtuple(maxprec, maxexp):
134 n = randrange(100)
135 sign = randrange(2)
136 coeff = ndigits(maxprec)
137 if n >= 95:
138 coeff = ()
139 exp = 'F'
140 elif n >= 85:
141 coeff = tuple(map(int, str(ndigits(maxprec))))
142 exp = "nN"[randrange(2)]
143 else:
144 coeff = tuple(map(int, str(ndigits(maxprec))))
145 exp = randrange(-maxexp, maxexp)
146 return (sign, coeff, exp)
147
148 def from_triple(sign, coeff, exp):
149 return ''.join((str(sign*coeff), indicator(), str(exp)))
150
151
152 # Close to 10**n
153 def un_close_to_pow10(prec, maxexp, itr=None):
154 if itr is None:
155 lst = range(prec+30)
156 else:
157 lst = sample(range(prec+30), itr)
158 nines = [10**n - 1 for n in lst]
159 pow10 = [10**n for n in lst]
160 for coeff in nines:
161 yield coeff
162 yield -coeff
163 yield from_triple(1, coeff, randrange(2*maxexp))
164 yield from_triple(-1, coeff, randrange(2*maxexp))
165 for coeff in pow10:
166 yield coeff
167 yield -coeff
168
169 # Close to 10**n
170 def bin_close_to_pow10(prec, maxexp, itr=None):
171 if itr is None:
172 lst = range(prec+30)
173 else:
174 lst = sample(range(prec+30), itr)
175 nines = [10**n - 1 for n in lst]
176 pow10 = [10**n for n in lst]
177 for coeff in nines:
178 yield coeff, 1
179 yield -coeff, -1
180 yield 1, coeff
181 yield -1, -coeff
182 yield from_triple(1, coeff, randrange(2*maxexp)), 1
183 yield from_triple(-1, coeff, randrange(2*maxexp)), -1
184 yield 1, from_triple(1, coeff, -randrange(2*maxexp))
185 yield -1, from_triple(-1, coeff, -randrange(2*maxexp))
186 for coeff in pow10:
187 yield coeff, -1
188 yield -coeff, 1
189 yield 1, -coeff
190 yield -coeff, 1
191
192 # Close to 1:
193 def close_to_one_greater(prec, emax, emin):
194 rprec = 10**prec
195 return ''.join(("1.", '0'*randrange(prec),
196 str(randrange(rprec))))
197
198 def close_to_one_less(prec, emax, emin):
199 rprec = 10**prec
200 return ''.join(("0.9", '9'*randrange(prec),
201 str(randrange(rprec))))
202
203 # Close to 0:
204 def close_to_zero_greater(prec, emax, emin):
205 rprec = 10**prec
206 return ''.join(("0.", '0'*randrange(prec),
207 str(randrange(rprec))))
208
209 def close_to_zero_less(prec, emax, emin):
210 rprec = 10**prec
211 return ''.join(("-0.", '0'*randrange(prec),
212 str(randrange(rprec))))
213
214 # Close to emax:
215 def close_to_emax_less(prec, emax, emin):
216 rprec = 10**prec
217 return ''.join(("9.", '9'*randrange(prec),
218 str(randrange(rprec)), "E", str(emax)))
219
220 def close_to_emax_greater(prec, emax, emin):
221 rprec = 10**prec
222 return ''.join(("1.", '0'*randrange(prec),
223 str(randrange(rprec)), "E", str(emax+1)))
224
225 # Close to emin:
226 def close_to_emin_greater(prec, emax, emin):
227 rprec = 10**prec
228 return ''.join(("1.", '0'*randrange(prec),
229 str(randrange(rprec)), "E", str(emin)))
230
231 def close_to_emin_less(prec, emax, emin):
232 rprec = 10**prec
233 return ''.join(("9.", '9'*randrange(prec),
234 str(randrange(rprec)), "E", str(emin-1)))
235
236 # Close to etiny:
237 def close_to_etiny_greater(prec, emax, emin):
238 rprec = 10**prec
239 etiny = emin - (prec - 1)
240 return ''.join(("1.", '0'*randrange(prec),
241 str(randrange(rprec)), "E", str(etiny)))
242
243 def close_to_etiny_less(prec, emax, emin):
244 rprec = 10**prec
245 etiny = emin - (prec - 1)
246 return ''.join(("9.", '9'*randrange(prec),
247 str(randrange(rprec)), "E", str(etiny-1)))
248
249
250 def close_to_min_etiny_greater(prec, max_prec, min_emin):
251 rprec = 10**prec
252 etiny = min_emin - (max_prec - 1)
253 return ''.join(("1.", '0'*randrange(prec),
254 str(randrange(rprec)), "E", str(etiny)))
255
256 def close_to_min_etiny_less(prec, max_prec, min_emin):
257 rprec = 10**prec
258 etiny = min_emin - (max_prec - 1)
259 return ''.join(("9.", '9'*randrange(prec),
260 str(randrange(rprec)), "E", str(etiny-1)))
261
262
263 close_funcs = [
264 close_to_one_greater, close_to_one_less, close_to_zero_greater,
265 close_to_zero_less, close_to_emax_less, close_to_emax_greater,
266 close_to_emin_greater, close_to_emin_less, close_to_etiny_greater,
267 close_to_etiny_less, close_to_min_etiny_greater, close_to_min_etiny_less
268 ]
269
270
271 def un_close_numbers(prec, emax, emin, itr=None):
272 if itr is None:
273 itr = 1000
274 for _ in range(itr):
275 for func in close_funcs:
276 yield func(prec, emax, emin)
277
278 def bin_close_numbers(prec, emax, emin, itr=None):
279 if itr is None:
280 itr = 1000
281 for _ in range(itr):
282 for func1 in close_funcs:
283 for func2 in close_funcs:
284 yield func1(prec, emax, emin), func2(prec, emax, emin)
285 for func in close_funcs:
286 yield randdec(prec, emax), func(prec, emax, emin)
287 yield func(prec, emax, emin), randdec(prec, emax)
288
289 def tern_close_numbers(prec, emax, emin, itr):
290 if itr is None:
291 itr = 1000
292 for _ in range(itr):
293 for func1 in close_funcs:
294 for func2 in close_funcs:
295 for func3 in close_funcs:
296 yield (func1(prec, emax, emin), func2(prec, emax, emin),
297 func3(prec, emax, emin))
298 for func in close_funcs:
299 yield (randdec(prec, emax), func(prec, emax, emin),
300 func(prec, emax, emin))
301 yield (func(prec, emax, emin), randdec(prec, emax),
302 func(prec, emax, emin))
303 yield (func(prec, emax, emin), func(prec, emax, emin),
304 randdec(prec, emax))
305 for func in close_funcs:
306 yield (randdec(prec, emax), randdec(prec, emax),
307 func(prec, emax, emin))
308 yield (randdec(prec, emax), func(prec, emax, emin),
309 randdec(prec, emax))
310 yield (func(prec, emax, emin), randdec(prec, emax),
311 randdec(prec, emax))
312
313
314 # If itr == None, test all digit lengths up to prec + 30
315 def un_incr_digits(prec, maxexp, itr):
316 if itr is None:
317 lst = range(prec+30)
318 else:
319 lst = sample(range(prec+30), itr)
320 for m in lst:
321 yield from_triple(1, ndigits(m), 0)
322 yield from_triple(-1, ndigits(m), 0)
323 yield from_triple(1, ndigits(m), randrange(maxexp))
324 yield from_triple(-1, ndigits(m), randrange(maxexp))
325
326 # If itr == None, test all digit lengths up to prec + 30
327 # Also output decimals im tuple form.
328 def un_incr_digits_tuple(prec, maxexp, itr):
329 if itr is None:
330 lst = range(prec+30)
331 else:
332 lst = sample(range(prec+30), itr)
333 for m in lst:
334 yield from_triple(1, ndigits(m), 0)
335 yield from_triple(-1, ndigits(m), 0)
336 yield from_triple(1, ndigits(m), randrange(maxexp))
337 yield from_triple(-1, ndigits(m), randrange(maxexp))
338 # test from tuple
339 yield (0, tuple(map(int, str(ndigits(m)))), 0)
340 yield (1, tuple(map(int, str(ndigits(m)))), 0)
341 yield (0, tuple(map(int, str(ndigits(m)))), randrange(maxexp))
342 yield (1, tuple(map(int, str(ndigits(m)))), randrange(maxexp))
343
344 # If itr == None, test all combinations of digit lengths up to prec + 30
345 def bin_incr_digits(prec, maxexp, itr):
346 if itr is None:
347 lst1 = range(prec+30)
348 lst2 = range(prec+30)
349 else:
350 lst1 = sample(range(prec+30), itr)
351 lst2 = sample(range(prec+30), itr)
352 for m in lst1:
353 x = from_triple(1, ndigits(m), 0)
354 yield x, x
355 x = from_triple(-1, ndigits(m), 0)
356 yield x, x
357 x = from_triple(1, ndigits(m), randrange(maxexp))
358 yield x, x
359 x = from_triple(-1, ndigits(m), randrange(maxexp))
360 yield x, x
361 for m in lst1:
362 for n in lst2:
363 x = from_triple(1, ndigits(m), 0)
364 y = from_triple(1, ndigits(n), 0)
365 yield x, y
366 x = from_triple(-1, ndigits(m), 0)
367 y = from_triple(1, ndigits(n), 0)
368 yield x, y
369 x = from_triple(1, ndigits(m), 0)
370 y = from_triple(-1, ndigits(n), 0)
371 yield x, y
372 x = from_triple(-1, ndigits(m), 0)
373 y = from_triple(-1, ndigits(n), 0)
374 yield x, y
375 x = from_triple(1, ndigits(m), randrange(maxexp))
376 y = from_triple(1, ndigits(n), randrange(maxexp))
377 yield x, y
378 x = from_triple(-1, ndigits(m), randrange(maxexp))
379 y = from_triple(1, ndigits(n), randrange(maxexp))
380 yield x, y
381 x = from_triple(1, ndigits(m), randrange(maxexp))
382 y = from_triple(-1, ndigits(n), randrange(maxexp))
383 yield x, y
384 x = from_triple(-1, ndigits(m), randrange(maxexp))
385 y = from_triple(-1, ndigits(n), randrange(maxexp))
386 yield x, y
387
388
389 def randsign():
390 return (1, -1)[randrange(2)]
391
392 # If itr == None, test all combinations of digit lengths up to prec + 30
393 def tern_incr_digits(prec, maxexp, itr):
394 if itr is None:
395 lst1 = range(prec+30)
396 lst2 = range(prec+30)
397 lst3 = range(prec+30)
398 else:
399 lst1 = sample(range(prec+30), itr)
400 lst2 = sample(range(prec+30), itr)
401 lst3 = sample(range(prec+30), itr)
402 for m in lst1:
403 for n in lst2:
404 for p in lst3:
405 x = from_triple(randsign(), ndigits(m), 0)
406 y = from_triple(randsign(), ndigits(n), 0)
407 z = from_triple(randsign(), ndigits(p), 0)
408 yield x, y, z
409
410
411 # Tests for the 'logical' functions
412 def bindigits(prec):
413 z = 0
414 for i in range(prec):
415 z += randrange(2) * 10**i
416 return z
417
418 def logical_un_incr_digits(prec, itr):
419 if itr is None:
420 lst = range(prec+30)
421 else:
422 lst = sample(range(prec+30), itr)
423 for m in lst:
424 yield from_triple(1, bindigits(m), 0)
425
426 def logical_bin_incr_digits(prec, itr):
427 if itr is None:
428 lst1 = range(prec+30)
429 lst2 = range(prec+30)
430 else:
431 lst1 = sample(range(prec+30), itr)
432 lst2 = sample(range(prec+30), itr)
433 for m in lst1:
434 x = from_triple(1, bindigits(m), 0)
435 yield x, x
436 for m in lst1:
437 for n in lst2:
438 x = from_triple(1, bindigits(m), 0)
439 y = from_triple(1, bindigits(n), 0)
440 yield x, y
441
442
443 def randint():
444 p = randrange(1, 100)
445 return ndigits(p) * (1,-1)[randrange(2)]
446
447 def randfloat():
448 p = randrange(1, 100)
449 s = numeric_value(p, 383)
450 try:
451 f = float(numeric_value(p, 383))
452 except ValueError:
453 f = 0.0
454 return f
455
456 def randcomplex():
457 real = randfloat()
458 if randrange(100) > 30:
459 imag = 0.0
460 else:
461 imag = randfloat()
462 return complex(real, imag)
463
464 def randfraction():
465 num = randint()
466 denom = randint()
467 if denom == 0:
468 denom = 1
469 return Fraction(num, denom)
470
471 number_funcs = [randint, randfloat, randcomplex, randfraction]
472
473 def un_random_mixed_op(itr=None):
474 if itr is None:
475 itr = 1000
476 for _ in range(itr):
477 for func in number_funcs:
478 yield func()
479 # Test garbage input
480 for x in (['x'], ('y',), {'z'}, {1:'z'}):
481 yield x
482
483 def bin_random_mixed_op(prec, emax, emin, itr=None):
484 if itr is None:
485 itr = 1000
486 for _ in range(itr):
487 for func in number_funcs:
488 yield randdec(prec, emax), func()
489 yield func(), randdec(prec, emax)
490 for number in number_funcs:
491 for dec in close_funcs:
492 yield dec(prec, emax, emin), number()
493 # Test garbage input
494 for x in (['x'], ('y',), {'z'}, {1:'z'}):
495 for y in (['x'], ('y',), {'z'}, {1:'z'}):
496 yield x, y
497
498 def tern_random_mixed_op(prec, emax, emin, itr):
499 if itr is None:
500 itr = 1000
501 for _ in range(itr):
502 for func in number_funcs:
503 yield randdec(prec, emax), randdec(prec, emax), func()
504 yield randdec(prec, emax), func(), func()
505 yield func(), func(), func()
506 # Test garbage input
507 for x in (['x'], ('y',), {'z'}, {1:'z'}):
508 for y in (['x'], ('y',), {'z'}, {1:'z'}):
509 for z in (['x'], ('y',), {'z'}, {1:'z'}):
510 yield x, y, z
511
512 def all_unary(prec, exp_range, itr):
513 for a in un_close_to_pow10(prec, exp_range, itr):
514 yield (a,)
515 for a in un_close_numbers(prec, exp_range, -exp_range, itr):
516 yield (a,)
517 for a in un_incr_digits_tuple(prec, exp_range, itr):
518 yield (a,)
519 for a in un_randfloat():
520 yield (a,)
521 for a in un_random_mixed_op(itr):
522 yield (a,)
523 for a in logical_un_incr_digits(prec, itr):
524 yield (a,)
525 for _ in range(100):
526 yield (randdec(prec, exp_range),)
527 for _ in range(100):
528 yield (randtuple(prec, exp_range),)
529
530 def all_binary(prec, exp_range, itr):
531 for a, b in bin_close_to_pow10(prec, exp_range, itr):
532 yield a, b
533 for a, b in bin_close_numbers(prec, exp_range, -exp_range, itr):
534 yield a, b
535 for a, b in bin_incr_digits(prec, exp_range, itr):
536 yield a, b
537 for a, b in bin_randfloat():
538 yield a, b
539 for a, b in bin_random_mixed_op(prec, exp_range, -exp_range, itr):
540 yield a, b
541 for a, b in logical_bin_incr_digits(prec, itr):
542 yield a, b
543 for _ in range(100):
544 yield randdec(prec, exp_range), randdec(prec, exp_range)
545
546 def all_ternary(prec, exp_range, itr):
547 for a, b, c in tern_close_numbers(prec, exp_range, -exp_range, itr):
548 yield a, b, c
549 for a, b, c in tern_incr_digits(prec, exp_range, itr):
550 yield a, b, c
551 for a, b, c in tern_randfloat():
552 yield a, b, c
553 for a, b, c in tern_random_mixed_op(prec, exp_range, -exp_range, itr):
554 yield a, b, c
555 for _ in range(100):
556 a = randdec(prec, 2*exp_range)
557 b = randdec(prec, 2*exp_range)
558 c = randdec(prec, 2*exp_range)
559 yield a, b, c
OLDNEW
« no previous file with comments | « Modules/_decimal/tests/formathelper.py ('k') | Modules/_decimal/tests/randfloat.py » ('j') | no next file with comments »

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