mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-24 06:12:27 +00:00
python-3.6.zip added from Github
README.cosmo contains the necessary links.
This commit is contained in:
parent
75fc601ff5
commit
0c4c56ff39
4219 changed files with 1968626 additions and 0 deletions
15
third_party/python/Modules/_decimal/tests/README.txt
vendored
Normal file
15
third_party/python/Modules/_decimal/tests/README.txt
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
|
||||
This directory contains extended tests and a benchmark against decimal.py:
|
||||
|
||||
bench.py -> Benchmark for small and large precisions.
|
||||
Usage: ../../../python bench.py
|
||||
|
||||
formathelper.py ->
|
||||
randdec.py -> Generate test cases for deccheck.py.
|
||||
randfloat.py ->
|
||||
|
||||
deccheck.py -> Run extended tests.
|
||||
Usage: ../../../python deccheck.py [--short|--medium|--long|--all]
|
||||
|
||||
|
133
third_party/python/Modules/_decimal/tests/bench.py
vendored
Normal file
133
third_party/python/Modules/_decimal/tests/bench.py
vendored
Normal file
|
@ -0,0 +1,133 @@
|
|||
#
|
||||
# Copyright (C) 2001-2012 Python Software Foundation. All Rights Reserved.
|
||||
# Modified and extended by Stefan Krah.
|
||||
#
|
||||
|
||||
# Usage: ../../../python bench.py
|
||||
|
||||
|
||||
import time
|
||||
from math import log, ceil
|
||||
try:
|
||||
from test.support import import_fresh_module
|
||||
except ImportError:
|
||||
from test.test_support import import_fresh_module
|
||||
|
||||
C = import_fresh_module('decimal', fresh=['_decimal'])
|
||||
P = import_fresh_module('decimal', blocked=['_decimal'])
|
||||
|
||||
#
|
||||
# NOTE: This is the pi function from the decimal documentation, modified
|
||||
# for benchmarking purposes. Since floats do not have a context, the higher
|
||||
# intermediate precision from the original is NOT used, so the modified
|
||||
# algorithm only gives an approximation to the correctly rounded result.
|
||||
# For serious use, refer to the documentation or the appropriate literature.
|
||||
#
|
||||
def pi_float():
|
||||
"""native float"""
|
||||
lasts, t, s, n, na, d, da = 0, 3.0, 3, 1, 0, 0, 24
|
||||
while s != lasts:
|
||||
lasts = s
|
||||
n, na = n+na, na+8
|
||||
d, da = d+da, da+32
|
||||
t = (t * n) / d
|
||||
s += t
|
||||
return s
|
||||
|
||||
def pi_cdecimal():
|
||||
"""cdecimal"""
|
||||
D = C.Decimal
|
||||
lasts, t, s, n, na, d, da = D(0), D(3), D(3), D(1), D(0), D(0), D(24)
|
||||
while s != lasts:
|
||||
lasts = s
|
||||
n, na = n+na, na+8
|
||||
d, da = d+da, da+32
|
||||
t = (t * n) / d
|
||||
s += t
|
||||
return s
|
||||
|
||||
def pi_decimal():
|
||||
"""decimal"""
|
||||
D = P.Decimal
|
||||
lasts, t, s, n, na, d, da = D(0), D(3), D(3), D(1), D(0), D(0), D(24)
|
||||
while s != lasts:
|
||||
lasts = s
|
||||
n, na = n+na, na+8
|
||||
d, da = d+da, da+32
|
||||
t = (t * n) / d
|
||||
s += t
|
||||
return s
|
||||
|
||||
def factorial(n, m):
|
||||
if (n > m):
|
||||
return factorial(m, n)
|
||||
elif m == 0:
|
||||
return 1
|
||||
elif n == m:
|
||||
return n
|
||||
else:
|
||||
return factorial(n, (n+m)//2) * factorial((n+m)//2 + 1, m)
|
||||
|
||||
|
||||
print("\n# ======================================================================")
|
||||
print("# Calculating pi, 10000 iterations")
|
||||
print("# ======================================================================\n")
|
||||
|
||||
to_benchmark = [pi_float, pi_decimal]
|
||||
if C is not None:
|
||||
to_benchmark.insert(1, pi_cdecimal)
|
||||
|
||||
for prec in [9, 19]:
|
||||
print("\nPrecision: %d decimal digits\n" % prec)
|
||||
for func in to_benchmark:
|
||||
start = time.time()
|
||||
if C is not None:
|
||||
C.getcontext().prec = prec
|
||||
P.getcontext().prec = prec
|
||||
for i in range(10000):
|
||||
x = func()
|
||||
print("%s:" % func.__name__.replace("pi_", ""))
|
||||
print("result: %s" % str(x))
|
||||
print("time: %fs\n" % (time.time()-start))
|
||||
|
||||
|
||||
print("\n# ======================================================================")
|
||||
print("# Factorial")
|
||||
print("# ======================================================================\n")
|
||||
|
||||
if C is not None:
|
||||
c = C.getcontext()
|
||||
c.prec = C.MAX_PREC
|
||||
c.Emax = C.MAX_EMAX
|
||||
c.Emin = C.MIN_EMIN
|
||||
|
||||
for n in [100000, 1000000]:
|
||||
|
||||
print("n = %d\n" % n)
|
||||
|
||||
if C is not None:
|
||||
# C version of decimal
|
||||
start_calc = time.time()
|
||||
x = factorial(C.Decimal(n), 0)
|
||||
end_calc = time.time()
|
||||
start_conv = time.time()
|
||||
sx = str(x)
|
||||
end_conv = time.time()
|
||||
print("cdecimal:")
|
||||
print("calculation time: %fs" % (end_calc-start_calc))
|
||||
print("conversion time: %fs\n" % (end_conv-start_conv))
|
||||
|
||||
# Python integers
|
||||
start_calc = time.time()
|
||||
y = factorial(n, 0)
|
||||
end_calc = time.time()
|
||||
start_conv = time.time()
|
||||
sy = str(y)
|
||||
end_conv = time.time()
|
||||
|
||||
print("int:")
|
||||
print("calculation time: %fs" % (end_calc-start_calc))
|
||||
print("conversion time: %fs\n\n" % (end_conv-start_conv))
|
||||
|
||||
if C is not None:
|
||||
assert(sx == sy)
|
42
third_party/python/Modules/_decimal/tests/bignum.py
vendored
Normal file
42
third_party/python/Modules/_decimal/tests/bignum.py
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
#
|
||||
# These tests require gmpy and test the limits of the 32-bit build. The
|
||||
# limits of the 64-bit build are so large that they cannot be tested
|
||||
# on accessible hardware.
|
||||
#
|
||||
|
||||
import sys
|
||||
from decimal import *
|
||||
from gmpy import mpz
|
||||
|
||||
|
||||
_PyHASH_MODULUS = sys.hash_info.modulus
|
||||
# hash values to use for positive and negative infinities, and nans
|
||||
_PyHASH_INF = sys.hash_info.inf
|
||||
_PyHASH_NAN = sys.hash_info.nan
|
||||
|
||||
# _PyHASH_10INV is the inverse of 10 modulo the prime _PyHASH_MODULUS
|
||||
_PyHASH_10INV = pow(10, _PyHASH_MODULUS - 2, _PyHASH_MODULUS)
|
||||
|
||||
def xhash(coeff, exp):
|
||||
sign = 1
|
||||
if coeff < 0:
|
||||
sign = -1
|
||||
coeff = -coeff
|
||||
if exp >= 0:
|
||||
exp_hash = pow(10, exp, _PyHASH_MODULUS)
|
||||
else:
|
||||
exp_hash = pow(_PyHASH_10INV, -exp, _PyHASH_MODULUS)
|
||||
hash_ = coeff * exp_hash % _PyHASH_MODULUS
|
||||
ans = hash_ if sign == 1 else -hash_
|
||||
return -2 if ans == -1 else ans
|
||||
|
||||
|
||||
x = mpz(10) ** 425000000 - 1
|
||||
coeff = int(x)
|
||||
|
||||
d = Decimal('9' * 425000000 + 'e-849999999')
|
||||
|
||||
h1 = xhash(coeff, -849999999)
|
||||
h2 = hash(d)
|
||||
|
||||
assert h2 == h1
|
1100
third_party/python/Modules/_decimal/tests/deccheck.py
vendored
Normal file
1100
third_party/python/Modules/_decimal/tests/deccheck.py
vendored
Normal file
File diff suppressed because it is too large
Load diff
342
third_party/python/Modules/_decimal/tests/formathelper.py
vendored
Normal file
342
third_party/python/Modules/_decimal/tests/formathelper.py
vendored
Normal file
|
@ -0,0 +1,342 @@
|
|||
#
|
||||
# Copyright (c) 2008-2012 Stefan Krah. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
|
||||
|
||||
# Generate PEP-3101 format strings.
|
||||
|
||||
|
||||
import os, sys, locale, random
|
||||
import platform, subprocess
|
||||
from test.support import import_fresh_module
|
||||
from distutils.spawn import find_executable
|
||||
|
||||
C = import_fresh_module('decimal', fresh=['_decimal'])
|
||||
P = import_fresh_module('decimal', blocked=['_decimal'])
|
||||
|
||||
|
||||
windows_lang_strings = [
|
||||
"chinese", "chinese-simplified", "chinese-traditional", "czech", "danish",
|
||||
"dutch", "belgian", "english", "australian", "canadian", "english-nz",
|
||||
"english-uk", "english-us", "finnish", "french", "french-belgian",
|
||||
"french-canadian", "french-swiss", "german", "german-austrian",
|
||||
"german-swiss", "greek", "hungarian", "icelandic", "italian", "italian-swiss",
|
||||
"japanese", "korean", "norwegian", "norwegian-bokmal", "norwegian-nynorsk",
|
||||
"polish", "portuguese", "portuguese-brazil", "russian", "slovak", "spanish",
|
||||
"spanish-mexican", "spanish-modern", "swedish", "turkish",
|
||||
]
|
||||
|
||||
preferred_encoding = {
|
||||
'cs_CZ': 'ISO8859-2',
|
||||
'cs_CZ.iso88592': 'ISO8859-2',
|
||||
'czech': 'ISO8859-2',
|
||||
'eesti': 'ISO8859-1',
|
||||
'estonian': 'ISO8859-1',
|
||||
'et_EE': 'ISO8859-15',
|
||||
'et_EE.ISO-8859-15': 'ISO8859-15',
|
||||
'et_EE.iso885915': 'ISO8859-15',
|
||||
'et_EE.iso88591': 'ISO8859-1',
|
||||
'fi_FI.iso88591': 'ISO8859-1',
|
||||
'fi_FI': 'ISO8859-15',
|
||||
'fi_FI@euro': 'ISO8859-15',
|
||||
'fi_FI.iso885915@euro': 'ISO8859-15',
|
||||
'finnish': 'ISO8859-1',
|
||||
'lv_LV': 'ISO8859-13',
|
||||
'lv_LV.iso885913': 'ISO8859-13',
|
||||
'nb_NO': 'ISO8859-1',
|
||||
'nb_NO.iso88591': 'ISO8859-1',
|
||||
'bokmal': 'ISO8859-1',
|
||||
'nn_NO': 'ISO8859-1',
|
||||
'nn_NO.iso88591': 'ISO8859-1',
|
||||
'no_NO': 'ISO8859-1',
|
||||
'norwegian': 'ISO8859-1',
|
||||
'nynorsk': 'ISO8859-1',
|
||||
'ru_RU': 'ISO8859-5',
|
||||
'ru_RU.iso88595': 'ISO8859-5',
|
||||
'russian': 'ISO8859-5',
|
||||
'ru_RU.KOI8-R': 'KOI8-R',
|
||||
'ru_RU.koi8r': 'KOI8-R',
|
||||
'ru_RU.CP1251': 'CP1251',
|
||||
'ru_RU.cp1251': 'CP1251',
|
||||
'sk_SK': 'ISO8859-2',
|
||||
'sk_SK.iso88592': 'ISO8859-2',
|
||||
'slovak': 'ISO8859-2',
|
||||
'sv_FI': 'ISO8859-1',
|
||||
'sv_FI.iso88591': 'ISO8859-1',
|
||||
'sv_FI@euro': 'ISO8859-15',
|
||||
'sv_FI.iso885915@euro': 'ISO8859-15',
|
||||
'uk_UA': 'KOI8-U',
|
||||
'uk_UA.koi8u': 'KOI8-U'
|
||||
}
|
||||
|
||||
integers = [
|
||||
"",
|
||||
"1",
|
||||
"12",
|
||||
"123",
|
||||
"1234",
|
||||
"12345",
|
||||
"123456",
|
||||
"1234567",
|
||||
"12345678",
|
||||
"123456789",
|
||||
"1234567890",
|
||||
"12345678901",
|
||||
"123456789012",
|
||||
"1234567890123",
|
||||
"12345678901234",
|
||||
"123456789012345",
|
||||
"1234567890123456",
|
||||
"12345678901234567",
|
||||
"123456789012345678",
|
||||
"1234567890123456789",
|
||||
"12345678901234567890",
|
||||
"123456789012345678901",
|
||||
"1234567890123456789012",
|
||||
]
|
||||
|
||||
numbers = [
|
||||
"0", "-0", "+0",
|
||||
"0.0", "-0.0", "+0.0",
|
||||
"0e0", "-0e0", "+0e0",
|
||||
".0", "-.0",
|
||||
".1", "-.1",
|
||||
"1.1", "-1.1",
|
||||
"1e1", "-1e1"
|
||||
]
|
||||
|
||||
# Get the list of available locales.
|
||||
if platform.system() == 'Windows':
|
||||
locale_list = windows_lang_strings
|
||||
else:
|
||||
locale_list = ['C']
|
||||
if os.path.isfile("/var/lib/locales/supported.d/local"):
|
||||
# On Ubuntu, `locale -a` gives the wrong case for some locales,
|
||||
# so we get the correct names directly:
|
||||
with open("/var/lib/locales/supported.d/local") as f:
|
||||
locale_list = [loc.split()[0] for loc in f.readlines() \
|
||||
if not loc.startswith('#')]
|
||||
elif find_executable('locale'):
|
||||
locale_list = subprocess.Popen(["locale", "-a"],
|
||||
stdout=subprocess.PIPE).communicate()[0]
|
||||
try:
|
||||
locale_list = locale_list.decode()
|
||||
except UnicodeDecodeError:
|
||||
# Some distributions insist on using latin-1 characters
|
||||
# in their locale names.
|
||||
locale_list = locale_list.decode('latin-1')
|
||||
locale_list = locale_list.split('\n')
|
||||
try:
|
||||
locale_list.remove('')
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# Debian
|
||||
if os.path.isfile("/etc/locale.alias"):
|
||||
with open("/etc/locale.alias") as f:
|
||||
while 1:
|
||||
try:
|
||||
line = f.readline()
|
||||
except UnicodeDecodeError:
|
||||
continue
|
||||
if line == "":
|
||||
break
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
x = line.split()
|
||||
if len(x) == 2:
|
||||
if x[0] in locale_list:
|
||||
locale_list.remove(x[0])
|
||||
|
||||
# FreeBSD
|
||||
if platform.system() == 'FreeBSD':
|
||||
# http://www.freebsd.org/cgi/query-pr.cgi?pr=142173
|
||||
# en_GB.US-ASCII has 163 as the currency symbol.
|
||||
for loc in ['it_CH.ISO8859-1', 'it_CH.ISO8859-15', 'it_CH.UTF-8',
|
||||
'it_IT.ISO8859-1', 'it_IT.ISO8859-15', 'it_IT.UTF-8',
|
||||
'sl_SI.ISO8859-2', 'sl_SI.UTF-8',
|
||||
'en_GB.US-ASCII']:
|
||||
try:
|
||||
locale_list.remove(loc)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# Print a testcase in the format of the IBM tests (for runtest.c):
|
||||
def get_preferred_encoding():
|
||||
loc = locale.setlocale(locale.LC_CTYPE)
|
||||
if loc in preferred_encoding:
|
||||
return preferred_encoding[loc]
|
||||
else:
|
||||
return locale.getpreferredencoding()
|
||||
|
||||
def printit(testno, s, fmt, encoding=None):
|
||||
if not encoding:
|
||||
encoding = get_preferred_encoding()
|
||||
try:
|
||||
result = format(P.Decimal(s), fmt)
|
||||
fmt = str(fmt.encode(encoding))[2:-1]
|
||||
result = str(result.encode(encoding))[2:-1]
|
||||
if "'" in result:
|
||||
sys.stdout.write("xfmt%d format %s '%s' -> \"%s\"\n"
|
||||
% (testno, s, fmt, result))
|
||||
else:
|
||||
sys.stdout.write("xfmt%d format %s '%s' -> '%s'\n"
|
||||
% (testno, s, fmt, result))
|
||||
except Exception as err:
|
||||
sys.stderr.write("%s %s %s\n" % (err, s, fmt))
|
||||
|
||||
|
||||
# Check if an integer can be converted to a valid fill character.
|
||||
def check_fillchar(i):
|
||||
try:
|
||||
c = chr(i)
|
||||
c.encode('utf-8').decode()
|
||||
format(P.Decimal(0), c + '<19g')
|
||||
return c
|
||||
except:
|
||||
return None
|
||||
|
||||
# Generate all unicode characters that are accepted as
|
||||
# fill characters by decimal.py.
|
||||
def all_fillchars():
|
||||
for i in range(0, 0x110002):
|
||||
c = check_fillchar(i)
|
||||
if c: yield c
|
||||
|
||||
# Return random fill character.
|
||||
def rand_fillchar():
|
||||
while 1:
|
||||
i = random.randrange(0, 0x110002)
|
||||
c = check_fillchar(i)
|
||||
if c: return c
|
||||
|
||||
# Generate random format strings
|
||||
# [[fill]align][sign][#][0][width][.precision][type]
|
||||
def rand_format(fill, typespec='EeGgFfn%'):
|
||||
active = sorted(random.sample(range(7), random.randrange(8)))
|
||||
have_align = 0
|
||||
s = ''
|
||||
for elem in active:
|
||||
if elem == 0: # fill+align
|
||||
s += fill
|
||||
s += random.choice('<>=^')
|
||||
have_align = 1
|
||||
elif elem == 1: # sign
|
||||
s += random.choice('+- ')
|
||||
elif elem == 2 and not have_align: # zeropad
|
||||
s += '0'
|
||||
elif elem == 3: # width
|
||||
s += str(random.randrange(1, 100))
|
||||
elif elem == 4: # thousands separator
|
||||
s += ','
|
||||
elif elem == 5: # prec
|
||||
s += '.'
|
||||
s += str(random.randrange(100))
|
||||
elif elem == 6:
|
||||
if 4 in active: c = typespec.replace('n', '')
|
||||
else: c = typespec
|
||||
s += random.choice(c)
|
||||
return s
|
||||
|
||||
# Partially brute force all possible format strings containing a thousands
|
||||
# separator. Fall back to random where the runtime would become excessive.
|
||||
# [[fill]align][sign][#][0][width][,][.precision][type]
|
||||
def all_format_sep():
|
||||
for align in ('', '<', '>', '=', '^'):
|
||||
for fill in ('', 'x'):
|
||||
if align == '': fill = ''
|
||||
for sign in ('', '+', '-', ' '):
|
||||
for zeropad in ('', '0'):
|
||||
if align != '': zeropad = ''
|
||||
for width in ['']+[str(y) for y in range(1, 15)]+['101']:
|
||||
for prec in ['']+['.'+str(y) for y in range(15)]:
|
||||
# for type in ('', 'E', 'e', 'G', 'g', 'F', 'f', '%'):
|
||||
type = random.choice(('', 'E', 'e', 'G', 'g', 'F', 'f', '%'))
|
||||
yield ''.join((fill, align, sign, zeropad, width, ',', prec, type))
|
||||
|
||||
# Partially brute force all possible format strings with an 'n' specifier.
|
||||
# [[fill]align][sign][#][0][width][,][.precision][type]
|
||||
def all_format_loc():
|
||||
for align in ('', '<', '>', '=', '^'):
|
||||
for fill in ('', 'x'):
|
||||
if align == '': fill = ''
|
||||
for sign in ('', '+', '-', ' '):
|
||||
for zeropad in ('', '0'):
|
||||
if align != '': zeropad = ''
|
||||
for width in ['']+[str(y) for y in range(1, 20)]+['101']:
|
||||
for prec in ['']+['.'+str(y) for y in range(1, 20)]:
|
||||
yield ''.join((fill, align, sign, zeropad, width, prec, 'n'))
|
||||
|
||||
# Generate random format strings with a unicode fill character
|
||||
# [[fill]align][sign][#][0][width][,][.precision][type]
|
||||
def randfill(fill):
|
||||
active = sorted(random.sample(range(5), random.randrange(6)))
|
||||
s = ''
|
||||
s += str(fill)
|
||||
s += random.choice('<>=^')
|
||||
for elem in active:
|
||||
if elem == 0: # sign
|
||||
s += random.choice('+- ')
|
||||
elif elem == 1: # width
|
||||
s += str(random.randrange(1, 100))
|
||||
elif elem == 2: # thousands separator
|
||||
s += ','
|
||||
elif elem == 3: # prec
|
||||
s += '.'
|
||||
s += str(random.randrange(100))
|
||||
elif elem == 4:
|
||||
if 2 in active: c = 'EeGgFf%'
|
||||
else: c = 'EeGgFfn%'
|
||||
s += random.choice(c)
|
||||
return s
|
||||
|
||||
# Generate random format strings with random locale setting
|
||||
# [[fill]align][sign][#][0][width][,][.precision][type]
|
||||
def rand_locale():
|
||||
try:
|
||||
loc = random.choice(locale_list)
|
||||
locale.setlocale(locale.LC_ALL, loc)
|
||||
except locale.Error as err:
|
||||
pass
|
||||
active = sorted(random.sample(range(5), random.randrange(6)))
|
||||
s = ''
|
||||
have_align = 0
|
||||
for elem in active:
|
||||
if elem == 0: # fill+align
|
||||
s += chr(random.randrange(32, 128))
|
||||
s += random.choice('<>=^')
|
||||
have_align = 1
|
||||
elif elem == 1: # sign
|
||||
s += random.choice('+- ')
|
||||
elif elem == 2 and not have_align: # zeropad
|
||||
s += '0'
|
||||
elif elem == 3: # width
|
||||
s += str(random.randrange(1, 100))
|
||||
elif elem == 4: # prec
|
||||
s += '.'
|
||||
s += str(random.randrange(100))
|
||||
s += 'n'
|
||||
return s
|
575
third_party/python/Modules/_decimal/tests/randdec.py
vendored
Normal file
575
third_party/python/Modules/_decimal/tests/randdec.py
vendored
Normal file
|
@ -0,0 +1,575 @@
|
|||
#
|
||||
# Copyright (c) 2008-2012 Stefan Krah. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
|
||||
|
||||
# Generate test cases for deccheck.py.
|
||||
|
||||
|
||||
#
|
||||
# Grammar from http://speleotrove.com/decimal/daconvs.html
|
||||
#
|
||||
# sign ::= '+' | '-'
|
||||
# digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' |
|
||||
# '8' | '9'
|
||||
# indicator ::= 'e' | 'E'
|
||||
# digits ::= digit [digit]...
|
||||
# decimal-part ::= digits '.' [digits] | ['.'] digits
|
||||
# exponent-part ::= indicator [sign] digits
|
||||
# infinity ::= 'Infinity' | 'Inf'
|
||||
# nan ::= 'NaN' [digits] | 'sNaN' [digits]
|
||||
# numeric-value ::= decimal-part [exponent-part] | infinity
|
||||
# numeric-string ::= [sign] numeric-value | [sign] nan
|
||||
#
|
||||
|
||||
|
||||
from random import randrange, sample
|
||||
from fractions import Fraction
|
||||
from randfloat import un_randfloat, bin_randfloat, tern_randfloat
|
||||
|
||||
|
||||
def sign():
|
||||
if randrange(2):
|
||||
if randrange(2): return '+'
|
||||
return ''
|
||||
return '-'
|
||||
|
||||
def indicator():
|
||||
return "eE"[randrange(2)]
|
||||
|
||||
def digits(maxprec):
|
||||
if maxprec == 0: return ''
|
||||
return str(randrange(10**maxprec))
|
||||
|
||||
def dot():
|
||||
if randrange(2): return '.'
|
||||
return ''
|
||||
|
||||
def decimal_part(maxprec):
|
||||
if randrange(100) > 60: # integers
|
||||
return digits(maxprec)
|
||||
if randrange(2):
|
||||
intlen = randrange(1, maxprec+1)
|
||||
fraclen = maxprec-intlen
|
||||
intpart = digits(intlen)
|
||||
fracpart = digits(fraclen)
|
||||
return ''.join((intpart, '.', fracpart))
|
||||
else:
|
||||
return ''.join((dot(), digits(maxprec)))
|
||||
|
||||
def expdigits(maxexp):
|
||||
return str(randrange(maxexp))
|
||||
|
||||
def exponent_part(maxexp):
|
||||
return ''.join((indicator(), sign(), expdigits(maxexp)))
|
||||
|
||||
def infinity():
|
||||
if randrange(2): return 'Infinity'
|
||||
return 'Inf'
|
||||
|
||||
def nan():
|
||||
d = ''
|
||||
if randrange(2):
|
||||
d = digits(randrange(99))
|
||||
if randrange(2):
|
||||
return ''.join(('NaN', d))
|
||||
else:
|
||||
return ''.join(('sNaN', d))
|
||||
|
||||
def numeric_value(maxprec, maxexp):
|
||||
if randrange(100) > 90:
|
||||
return infinity()
|
||||
exp_part = ''
|
||||
if randrange(100) > 60:
|
||||
exp_part = exponent_part(maxexp)
|
||||
return ''.join((decimal_part(maxprec), exp_part))
|
||||
|
||||
def numeric_string(maxprec, maxexp):
|
||||
if randrange(100) > 95:
|
||||
return ''.join((sign(), nan()))
|
||||
else:
|
||||
return ''.join((sign(), numeric_value(maxprec, maxexp)))
|
||||
|
||||
def randdec(maxprec, maxexp):
|
||||
return numeric_string(maxprec, maxexp)
|
||||
|
||||
def rand_adjexp(maxprec, maxadjexp):
|
||||
d = digits(maxprec)
|
||||
maxexp = maxadjexp-len(d)+1
|
||||
if maxexp == 0: maxexp = 1
|
||||
exp = str(randrange(maxexp-2*(abs(maxexp)), maxexp))
|
||||
return ''.join((sign(), d, 'E', exp))
|
||||
|
||||
|
||||
def ndigits(n):
|
||||
if n < 1: return 0
|
||||
return randrange(10**(n-1), 10**n)
|
||||
|
||||
def randtuple(maxprec, maxexp):
|
||||
n = randrange(100)
|
||||
sign = randrange(2)
|
||||
coeff = ndigits(maxprec)
|
||||
if n >= 95:
|
||||
coeff = ()
|
||||
exp = 'F'
|
||||
elif n >= 85:
|
||||
coeff = tuple(map(int, str(ndigits(maxprec))))
|
||||
exp = "nN"[randrange(2)]
|
||||
else:
|
||||
coeff = tuple(map(int, str(ndigits(maxprec))))
|
||||
exp = randrange(-maxexp, maxexp)
|
||||
return (sign, coeff, exp)
|
||||
|
||||
def from_triple(sign, coeff, exp):
|
||||
return ''.join((str(sign*coeff), indicator(), str(exp)))
|
||||
|
||||
|
||||
# Close to 10**n
|
||||
def un_close_to_pow10(prec, maxexp, itr=None):
|
||||
if itr is None:
|
||||
lst = range(prec+30)
|
||||
else:
|
||||
lst = sample(range(prec+30), itr)
|
||||
nines = [10**n - 1 for n in lst]
|
||||
pow10 = [10**n for n in lst]
|
||||
for coeff in nines:
|
||||
yield coeff
|
||||
yield -coeff
|
||||
yield from_triple(1, coeff, randrange(2*maxexp))
|
||||
yield from_triple(-1, coeff, randrange(2*maxexp))
|
||||
for coeff in pow10:
|
||||
yield coeff
|
||||
yield -coeff
|
||||
|
||||
# Close to 10**n
|
||||
def bin_close_to_pow10(prec, maxexp, itr=None):
|
||||
if itr is None:
|
||||
lst = range(prec+30)
|
||||
else:
|
||||
lst = sample(range(prec+30), itr)
|
||||
nines = [10**n - 1 for n in lst]
|
||||
pow10 = [10**n for n in lst]
|
||||
for coeff in nines:
|
||||
yield coeff, 1
|
||||
yield -coeff, -1
|
||||
yield 1, coeff
|
||||
yield -1, -coeff
|
||||
yield from_triple(1, coeff, randrange(2*maxexp)), 1
|
||||
yield from_triple(-1, coeff, randrange(2*maxexp)), -1
|
||||
yield 1, from_triple(1, coeff, -randrange(2*maxexp))
|
||||
yield -1, from_triple(-1, coeff, -randrange(2*maxexp))
|
||||
for coeff in pow10:
|
||||
yield coeff, -1
|
||||
yield -coeff, 1
|
||||
yield 1, -coeff
|
||||
yield -coeff, 1
|
||||
|
||||
# Close to 1:
|
||||
def close_to_one_greater(prec, emax, emin):
|
||||
rprec = 10**prec
|
||||
return ''.join(("1.", '0'*randrange(prec),
|
||||
str(randrange(rprec))))
|
||||
|
||||
def close_to_one_less(prec, emax, emin):
|
||||
rprec = 10**prec
|
||||
return ''.join(("0.9", '9'*randrange(prec),
|
||||
str(randrange(rprec))))
|
||||
|
||||
# Close to 0:
|
||||
def close_to_zero_greater(prec, emax, emin):
|
||||
rprec = 10**prec
|
||||
return ''.join(("0.", '0'*randrange(prec),
|
||||
str(randrange(rprec))))
|
||||
|
||||
def close_to_zero_less(prec, emax, emin):
|
||||
rprec = 10**prec
|
||||
return ''.join(("-0.", '0'*randrange(prec),
|
||||
str(randrange(rprec))))
|
||||
|
||||
# Close to emax:
|
||||
def close_to_emax_less(prec, emax, emin):
|
||||
rprec = 10**prec
|
||||
return ''.join(("9.", '9'*randrange(prec),
|
||||
str(randrange(rprec)), "E", str(emax)))
|
||||
|
||||
def close_to_emax_greater(prec, emax, emin):
|
||||
rprec = 10**prec
|
||||
return ''.join(("1.", '0'*randrange(prec),
|
||||
str(randrange(rprec)), "E", str(emax+1)))
|
||||
|
||||
# Close to emin:
|
||||
def close_to_emin_greater(prec, emax, emin):
|
||||
rprec = 10**prec
|
||||
return ''.join(("1.", '0'*randrange(prec),
|
||||
str(randrange(rprec)), "E", str(emin)))
|
||||
|
||||
def close_to_emin_less(prec, emax, emin):
|
||||
rprec = 10**prec
|
||||
return ''.join(("9.", '9'*randrange(prec),
|
||||
str(randrange(rprec)), "E", str(emin-1)))
|
||||
|
||||
# Close to etiny:
|
||||
def close_to_etiny_greater(prec, emax, emin):
|
||||
rprec = 10**prec
|
||||
etiny = emin - (prec - 1)
|
||||
return ''.join(("1.", '0'*randrange(prec),
|
||||
str(randrange(rprec)), "E", str(etiny)))
|
||||
|
||||
def close_to_etiny_less(prec, emax, emin):
|
||||
rprec = 10**prec
|
||||
etiny = emin - (prec - 1)
|
||||
return ''.join(("9.", '9'*randrange(prec),
|
||||
str(randrange(rprec)), "E", str(etiny-1)))
|
||||
|
||||
|
||||
def close_to_min_etiny_greater(prec, max_prec, min_emin):
|
||||
rprec = 10**prec
|
||||
etiny = min_emin - (max_prec - 1)
|
||||
return ''.join(("1.", '0'*randrange(prec),
|
||||
str(randrange(rprec)), "E", str(etiny)))
|
||||
|
||||
def close_to_min_etiny_less(prec, max_prec, min_emin):
|
||||
rprec = 10**prec
|
||||
etiny = min_emin - (max_prec - 1)
|
||||
return ''.join(("9.", '9'*randrange(prec),
|
||||
str(randrange(rprec)), "E", str(etiny-1)))
|
||||
|
||||
|
||||
close_funcs = [
|
||||
close_to_one_greater, close_to_one_less, close_to_zero_greater,
|
||||
close_to_zero_less, close_to_emax_less, close_to_emax_greater,
|
||||
close_to_emin_greater, close_to_emin_less, close_to_etiny_greater,
|
||||
close_to_etiny_less, close_to_min_etiny_greater, close_to_min_etiny_less
|
||||
]
|
||||
|
||||
|
||||
def un_close_numbers(prec, emax, emin, itr=None):
|
||||
if itr is None:
|
||||
itr = 1000
|
||||
for _ in range(itr):
|
||||
for func in close_funcs:
|
||||
yield func(prec, emax, emin)
|
||||
|
||||
def bin_close_numbers(prec, emax, emin, itr=None):
|
||||
if itr is None:
|
||||
itr = 1000
|
||||
for _ in range(itr):
|
||||
for func1 in close_funcs:
|
||||
for func2 in close_funcs:
|
||||
yield func1(prec, emax, emin), func2(prec, emax, emin)
|
||||
for func in close_funcs:
|
||||
yield randdec(prec, emax), func(prec, emax, emin)
|
||||
yield func(prec, emax, emin), randdec(prec, emax)
|
||||
|
||||
def tern_close_numbers(prec, emax, emin, itr):
|
||||
if itr is None:
|
||||
itr = 1000
|
||||
for _ in range(itr):
|
||||
for func1 in close_funcs:
|
||||
for func2 in close_funcs:
|
||||
for func3 in close_funcs:
|
||||
yield (func1(prec, emax, emin), func2(prec, emax, emin),
|
||||
func3(prec, emax, emin))
|
||||
for func in close_funcs:
|
||||
yield (randdec(prec, emax), func(prec, emax, emin),
|
||||
func(prec, emax, emin))
|
||||
yield (func(prec, emax, emin), randdec(prec, emax),
|
||||
func(prec, emax, emin))
|
||||
yield (func(prec, emax, emin), func(prec, emax, emin),
|
||||
randdec(prec, emax))
|
||||
for func in close_funcs:
|
||||
yield (randdec(prec, emax), randdec(prec, emax),
|
||||
func(prec, emax, emin))
|
||||
yield (randdec(prec, emax), func(prec, emax, emin),
|
||||
randdec(prec, emax))
|
||||
yield (func(prec, emax, emin), randdec(prec, emax),
|
||||
randdec(prec, emax))
|
||||
|
||||
|
||||
# If itr == None, test all digit lengths up to prec + 30
|
||||
def un_incr_digits(prec, maxexp, itr):
|
||||
if itr is None:
|
||||
lst = range(prec+30)
|
||||
else:
|
||||
lst = sample(range(prec+30), itr)
|
||||
for m in lst:
|
||||
yield from_triple(1, ndigits(m), 0)
|
||||
yield from_triple(-1, ndigits(m), 0)
|
||||
yield from_triple(1, ndigits(m), randrange(maxexp))
|
||||
yield from_triple(-1, ndigits(m), randrange(maxexp))
|
||||
|
||||
# If itr == None, test all digit lengths up to prec + 30
|
||||
# Also output decimals im tuple form.
|
||||
def un_incr_digits_tuple(prec, maxexp, itr):
|
||||
if itr is None:
|
||||
lst = range(prec+30)
|
||||
else:
|
||||
lst = sample(range(prec+30), itr)
|
||||
for m in lst:
|
||||
yield from_triple(1, ndigits(m), 0)
|
||||
yield from_triple(-1, ndigits(m), 0)
|
||||
yield from_triple(1, ndigits(m), randrange(maxexp))
|
||||
yield from_triple(-1, ndigits(m), randrange(maxexp))
|
||||
# test from tuple
|
||||
yield (0, tuple(map(int, str(ndigits(m)))), 0)
|
||||
yield (1, tuple(map(int, str(ndigits(m)))), 0)
|
||||
yield (0, tuple(map(int, str(ndigits(m)))), randrange(maxexp))
|
||||
yield (1, tuple(map(int, str(ndigits(m)))), randrange(maxexp))
|
||||
|
||||
# If itr == None, test all combinations of digit lengths up to prec + 30
|
||||
def bin_incr_digits(prec, maxexp, itr):
|
||||
if itr is None:
|
||||
lst1 = range(prec+30)
|
||||
lst2 = range(prec+30)
|
||||
else:
|
||||
lst1 = sample(range(prec+30), itr)
|
||||
lst2 = sample(range(prec+30), itr)
|
||||
for m in lst1:
|
||||
x = from_triple(1, ndigits(m), 0)
|
||||
yield x, x
|
||||
x = from_triple(-1, ndigits(m), 0)
|
||||
yield x, x
|
||||
x = from_triple(1, ndigits(m), randrange(maxexp))
|
||||
yield x, x
|
||||
x = from_triple(-1, ndigits(m), randrange(maxexp))
|
||||
yield x, x
|
||||
for m in lst1:
|
||||
for n in lst2:
|
||||
x = from_triple(1, ndigits(m), 0)
|
||||
y = from_triple(1, ndigits(n), 0)
|
||||
yield x, y
|
||||
x = from_triple(-1, ndigits(m), 0)
|
||||
y = from_triple(1, ndigits(n), 0)
|
||||
yield x, y
|
||||
x = from_triple(1, ndigits(m), 0)
|
||||
y = from_triple(-1, ndigits(n), 0)
|
||||
yield x, y
|
||||
x = from_triple(-1, ndigits(m), 0)
|
||||
y = from_triple(-1, ndigits(n), 0)
|
||||
yield x, y
|
||||
x = from_triple(1, ndigits(m), randrange(maxexp))
|
||||
y = from_triple(1, ndigits(n), randrange(maxexp))
|
||||
yield x, y
|
||||
x = from_triple(-1, ndigits(m), randrange(maxexp))
|
||||
y = from_triple(1, ndigits(n), randrange(maxexp))
|
||||
yield x, y
|
||||
x = from_triple(1, ndigits(m), randrange(maxexp))
|
||||
y = from_triple(-1, ndigits(n), randrange(maxexp))
|
||||
yield x, y
|
||||
x = from_triple(-1, ndigits(m), randrange(maxexp))
|
||||
y = from_triple(-1, ndigits(n), randrange(maxexp))
|
||||
yield x, y
|
||||
|
||||
|
||||
def randsign():
|
||||
return (1, -1)[randrange(2)]
|
||||
|
||||
# If itr == None, test all combinations of digit lengths up to prec + 30
|
||||
def tern_incr_digits(prec, maxexp, itr):
|
||||
if itr is None:
|
||||
lst1 = range(prec+30)
|
||||
lst2 = range(prec+30)
|
||||
lst3 = range(prec+30)
|
||||
else:
|
||||
lst1 = sample(range(prec+30), itr)
|
||||
lst2 = sample(range(prec+30), itr)
|
||||
lst3 = sample(range(prec+30), itr)
|
||||
for m in lst1:
|
||||
for n in lst2:
|
||||
for p in lst3:
|
||||
x = from_triple(randsign(), ndigits(m), 0)
|
||||
y = from_triple(randsign(), ndigits(n), 0)
|
||||
z = from_triple(randsign(), ndigits(p), 0)
|
||||
yield x, y, z
|
||||
|
||||
|
||||
# Tests for the 'logical' functions
|
||||
def bindigits(prec):
|
||||
z = 0
|
||||
for i in range(prec):
|
||||
z += randrange(2) * 10**i
|
||||
return z
|
||||
|
||||
def logical_un_incr_digits(prec, itr):
|
||||
if itr is None:
|
||||
lst = range(prec+30)
|
||||
else:
|
||||
lst = sample(range(prec+30), itr)
|
||||
for m in lst:
|
||||
yield from_triple(1, bindigits(m), 0)
|
||||
|
||||
def logical_bin_incr_digits(prec, itr):
|
||||
if itr is None:
|
||||
lst1 = range(prec+30)
|
||||
lst2 = range(prec+30)
|
||||
else:
|
||||
lst1 = sample(range(prec+30), itr)
|
||||
lst2 = sample(range(prec+30), itr)
|
||||
for m in lst1:
|
||||
x = from_triple(1, bindigits(m), 0)
|
||||
yield x, x
|
||||
for m in lst1:
|
||||
for n in lst2:
|
||||
x = from_triple(1, bindigits(m), 0)
|
||||
y = from_triple(1, bindigits(n), 0)
|
||||
yield x, y
|
||||
|
||||
|
||||
def randint():
|
||||
p = randrange(1, 100)
|
||||
return ndigits(p) * (1,-1)[randrange(2)]
|
||||
|
||||
def randfloat():
|
||||
p = randrange(1, 100)
|
||||
s = numeric_value(p, 383)
|
||||
try:
|
||||
f = float(numeric_value(p, 383))
|
||||
except ValueError:
|
||||
f = 0.0
|
||||
return f
|
||||
|
||||
def randcomplex():
|
||||
real = randfloat()
|
||||
if randrange(100) > 30:
|
||||
imag = 0.0
|
||||
else:
|
||||
imag = randfloat()
|
||||
return complex(real, imag)
|
||||
|
||||
def randfraction():
|
||||
num = randint()
|
||||
denom = randint()
|
||||
if denom == 0:
|
||||
denom = 1
|
||||
return Fraction(num, denom)
|
||||
|
||||
number_funcs = [randint, randfloat, randcomplex, randfraction]
|
||||
|
||||
def un_random_mixed_op(itr=None):
|
||||
if itr is None:
|
||||
itr = 1000
|
||||
for _ in range(itr):
|
||||
for func in number_funcs:
|
||||
yield func()
|
||||
# Test garbage input
|
||||
for x in (['x'], ('y',), {'z'}, {1:'z'}):
|
||||
yield x
|
||||
|
||||
def bin_random_mixed_op(prec, emax, emin, itr=None):
|
||||
if itr is None:
|
||||
itr = 1000
|
||||
for _ in range(itr):
|
||||
for func in number_funcs:
|
||||
yield randdec(prec, emax), func()
|
||||
yield func(), randdec(prec, emax)
|
||||
for number in number_funcs:
|
||||
for dec in close_funcs:
|
||||
yield dec(prec, emax, emin), number()
|
||||
# Test garbage input
|
||||
for x in (['x'], ('y',), {'z'}, {1:'z'}):
|
||||
for y in (['x'], ('y',), {'z'}, {1:'z'}):
|
||||
yield x, y
|
||||
|
||||
def tern_random_mixed_op(prec, emax, emin, itr):
|
||||
if itr is None:
|
||||
itr = 1000
|
||||
for _ in range(itr):
|
||||
for func in number_funcs:
|
||||
yield randdec(prec, emax), randdec(prec, emax), func()
|
||||
yield randdec(prec, emax), func(), func()
|
||||
yield func(), func(), func()
|
||||
# Test garbage input
|
||||
for x in (['x'], ('y',), {'z'}, {1:'z'}):
|
||||
for y in (['x'], ('y',), {'z'}, {1:'z'}):
|
||||
for z in (['x'], ('y',), {'z'}, {1:'z'}):
|
||||
yield x, y, z
|
||||
|
||||
def all_unary(prec, exp_range, itr):
|
||||
for a in un_close_to_pow10(prec, exp_range, itr):
|
||||
yield (a,)
|
||||
for a in un_close_numbers(prec, exp_range, -exp_range, itr):
|
||||
yield (a,)
|
||||
for a in un_incr_digits_tuple(prec, exp_range, itr):
|
||||
yield (a,)
|
||||
for a in un_randfloat():
|
||||
yield (a,)
|
||||
for a in un_random_mixed_op(itr):
|
||||
yield (a,)
|
||||
for a in logical_un_incr_digits(prec, itr):
|
||||
yield (a,)
|
||||
for _ in range(100):
|
||||
yield (randdec(prec, exp_range),)
|
||||
for _ in range(100):
|
||||
yield (randtuple(prec, exp_range),)
|
||||
|
||||
def unary_optarg(prec, exp_range, itr):
|
||||
for _ in range(100):
|
||||
yield randdec(prec, exp_range), None
|
||||
yield randdec(prec, exp_range), None, None
|
||||
|
||||
def all_binary(prec, exp_range, itr):
|
||||
for a, b in bin_close_to_pow10(prec, exp_range, itr):
|
||||
yield a, b
|
||||
for a, b in bin_close_numbers(prec, exp_range, -exp_range, itr):
|
||||
yield a, b
|
||||
for a, b in bin_incr_digits(prec, exp_range, itr):
|
||||
yield a, b
|
||||
for a, b in bin_randfloat():
|
||||
yield a, b
|
||||
for a, b in bin_random_mixed_op(prec, exp_range, -exp_range, itr):
|
||||
yield a, b
|
||||
for a, b in logical_bin_incr_digits(prec, itr):
|
||||
yield a, b
|
||||
for _ in range(100):
|
||||
yield randdec(prec, exp_range), randdec(prec, exp_range)
|
||||
|
||||
def binary_optarg(prec, exp_range, itr):
|
||||
for _ in range(100):
|
||||
yield randdec(prec, exp_range), randdec(prec, exp_range), None
|
||||
yield randdec(prec, exp_range), randdec(prec, exp_range), None, None
|
||||
|
||||
def all_ternary(prec, exp_range, itr):
|
||||
for a, b, c in tern_close_numbers(prec, exp_range, -exp_range, itr):
|
||||
yield a, b, c
|
||||
for a, b, c in tern_incr_digits(prec, exp_range, itr):
|
||||
yield a, b, c
|
||||
for a, b, c in tern_randfloat():
|
||||
yield a, b, c
|
||||
for a, b, c in tern_random_mixed_op(prec, exp_range, -exp_range, itr):
|
||||
yield a, b, c
|
||||
for _ in range(100):
|
||||
a = randdec(prec, 2*exp_range)
|
||||
b = randdec(prec, 2*exp_range)
|
||||
c = randdec(prec, 2*exp_range)
|
||||
yield a, b, c
|
||||
|
||||
def ternary_optarg(prec, exp_range, itr):
|
||||
for _ in range(100):
|
||||
a = randdec(prec, 2*exp_range)
|
||||
b = randdec(prec, 2*exp_range)
|
||||
c = randdec(prec, 2*exp_range)
|
||||
yield a, b, c, None
|
||||
yield a, b, c, None, None
|
250
third_party/python/Modules/_decimal/tests/randfloat.py
vendored
Normal file
250
third_party/python/Modules/_decimal/tests/randfloat.py
vendored
Normal file
|
@ -0,0 +1,250 @@
|
|||
# Copyright (c) 2010 Python Software Foundation. All Rights Reserved.
|
||||
# Adapted from Python's Lib/test/test_strtod.py (by Mark Dickinson)
|
||||
|
||||
# More test cases for deccheck.py.
|
||||
|
||||
import random
|
||||
|
||||
TEST_SIZE = 2
|
||||
|
||||
|
||||
def test_short_halfway_cases():
|
||||
# exact halfway cases with a small number of significant digits
|
||||
for k in 0, 5, 10, 15, 20:
|
||||
# upper = smallest integer >= 2**54/5**k
|
||||
upper = -(-2**54//5**k)
|
||||
# lower = smallest odd number >= 2**53/5**k
|
||||
lower = -(-2**53//5**k)
|
||||
if lower % 2 == 0:
|
||||
lower += 1
|
||||
for i in range(10 * TEST_SIZE):
|
||||
# Select a random odd n in [2**53/5**k,
|
||||
# 2**54/5**k). Then n * 10**k gives a halfway case
|
||||
# with small number of significant digits.
|
||||
n, e = random.randrange(lower, upper, 2), k
|
||||
|
||||
# Remove any additional powers of 5.
|
||||
while n % 5 == 0:
|
||||
n, e = n // 5, e + 1
|
||||
assert n % 10 in (1, 3, 7, 9)
|
||||
|
||||
# Try numbers of the form n * 2**p2 * 10**e, p2 >= 0,
|
||||
# until n * 2**p2 has more than 20 significant digits.
|
||||
digits, exponent = n, e
|
||||
while digits < 10**20:
|
||||
s = '{}e{}'.format(digits, exponent)
|
||||
yield s
|
||||
# Same again, but with extra trailing zeros.
|
||||
s = '{}e{}'.format(digits * 10**40, exponent - 40)
|
||||
yield s
|
||||
digits *= 2
|
||||
|
||||
# Try numbers of the form n * 5**p2 * 10**(e - p5), p5
|
||||
# >= 0, with n * 5**p5 < 10**20.
|
||||
digits, exponent = n, e
|
||||
while digits < 10**20:
|
||||
s = '{}e{}'.format(digits, exponent)
|
||||
yield s
|
||||
# Same again, but with extra trailing zeros.
|
||||
s = '{}e{}'.format(digits * 10**40, exponent - 40)
|
||||
yield s
|
||||
digits *= 5
|
||||
exponent -= 1
|
||||
|
||||
def test_halfway_cases():
|
||||
# test halfway cases for the round-half-to-even rule
|
||||
for i in range(1000):
|
||||
for j in range(TEST_SIZE):
|
||||
# bit pattern for a random finite positive (or +0.0) float
|
||||
bits = random.randrange(2047*2**52)
|
||||
|
||||
# convert bit pattern to a number of the form m * 2**e
|
||||
e, m = divmod(bits, 2**52)
|
||||
if e:
|
||||
m, e = m + 2**52, e - 1
|
||||
e -= 1074
|
||||
|
||||
# add 0.5 ulps
|
||||
m, e = 2*m + 1, e - 1
|
||||
|
||||
# convert to a decimal string
|
||||
if e >= 0:
|
||||
digits = m << e
|
||||
exponent = 0
|
||||
else:
|
||||
# m * 2**e = (m * 5**-e) * 10**e
|
||||
digits = m * 5**-e
|
||||
exponent = e
|
||||
s = '{}e{}'.format(digits, exponent)
|
||||
yield s
|
||||
|
||||
def test_boundaries():
|
||||
# boundaries expressed as triples (n, e, u), where
|
||||
# n*10**e is an approximation to the boundary value and
|
||||
# u*10**e is 1ulp
|
||||
boundaries = [
|
||||
(10000000000000000000, -19, 1110), # a power of 2 boundary (1.0)
|
||||
(17976931348623159077, 289, 1995), # overflow boundary (2.**1024)
|
||||
(22250738585072013831, -327, 4941), # normal/subnormal (2.**-1022)
|
||||
(0, -327, 4941), # zero
|
||||
]
|
||||
for n, e, u in boundaries:
|
||||
for j in range(1000):
|
||||
for i in range(TEST_SIZE):
|
||||
digits = n + random.randrange(-3*u, 3*u)
|
||||
exponent = e
|
||||
s = '{}e{}'.format(digits, exponent)
|
||||
yield s
|
||||
n *= 10
|
||||
u *= 10
|
||||
e -= 1
|
||||
|
||||
def test_underflow_boundary():
|
||||
# test values close to 2**-1075, the underflow boundary; similar
|
||||
# to boundary_tests, except that the random error doesn't scale
|
||||
# with n
|
||||
for exponent in range(-400, -320):
|
||||
base = 10**-exponent // 2**1075
|
||||
for j in range(TEST_SIZE):
|
||||
digits = base + random.randrange(-1000, 1000)
|
||||
s = '{}e{}'.format(digits, exponent)
|
||||
yield s
|
||||
|
||||
def test_bigcomp():
|
||||
for ndigs in 5, 10, 14, 15, 16, 17, 18, 19, 20, 40, 41, 50:
|
||||
dig10 = 10**ndigs
|
||||
for i in range(100 * TEST_SIZE):
|
||||
digits = random.randrange(dig10)
|
||||
exponent = random.randrange(-400, 400)
|
||||
s = '{}e{}'.format(digits, exponent)
|
||||
yield s
|
||||
|
||||
def test_parsing():
|
||||
# make '0' more likely to be chosen than other digits
|
||||
digits = '000000123456789'
|
||||
signs = ('+', '-', '')
|
||||
|
||||
# put together random short valid strings
|
||||
# \d*[.\d*]?e
|
||||
for i in range(1000):
|
||||
for j in range(TEST_SIZE):
|
||||
s = random.choice(signs)
|
||||
intpart_len = random.randrange(5)
|
||||
s += ''.join(random.choice(digits) for _ in range(intpart_len))
|
||||
if random.choice([True, False]):
|
||||
s += '.'
|
||||
fracpart_len = random.randrange(5)
|
||||
s += ''.join(random.choice(digits)
|
||||
for _ in range(fracpart_len))
|
||||
else:
|
||||
fracpart_len = 0
|
||||
if random.choice([True, False]):
|
||||
s += random.choice(['e', 'E'])
|
||||
s += random.choice(signs)
|
||||
exponent_len = random.randrange(1, 4)
|
||||
s += ''.join(random.choice(digits)
|
||||
for _ in range(exponent_len))
|
||||
|
||||
if intpart_len + fracpart_len:
|
||||
yield s
|
||||
|
||||
test_particular = [
|
||||
# squares
|
||||
'1.00000000100000000025',
|
||||
'1.0000000000000000000000000100000000000000000000000' #...
|
||||
'00025',
|
||||
'1.0000000000000000000000000000000000000000000010000' #...
|
||||
'0000000000000000000000000000000000000000025',
|
||||
'1.0000000000000000000000000000000000000000000000000' #...
|
||||
'000001000000000000000000000000000000000000000000000' #...
|
||||
'000000000025',
|
||||
'0.99999999900000000025',
|
||||
'0.9999999999999999999999999999999999999999999999999' #...
|
||||
'999000000000000000000000000000000000000000000000000' #...
|
||||
'000025',
|
||||
'0.9999999999999999999999999999999999999999999999999' #...
|
||||
'999999999999999999999999999999999999999999999999999' #...
|
||||
'999999999999999999999999999999999999999990000000000' #...
|
||||
'000000000000000000000000000000000000000000000000000' #...
|
||||
'000000000000000000000000000000000000000000000000000' #...
|
||||
'0000000000000000000000000000025',
|
||||
|
||||
'1.0000000000000000000000000000000000000000000000000' #...
|
||||
'000000000000000000000000000000000000000000000000000' #...
|
||||
'100000000000000000000000000000000000000000000000000' #...
|
||||
'000000000000000000000000000000000000000000000000001',
|
||||
'1.0000000000000000000000000000000000000000000000000' #...
|
||||
'000000000000000000000000000000000000000000000000000' #...
|
||||
'500000000000000000000000000000000000000000000000000' #...
|
||||
'000000000000000000000000000000000000000000000000005',
|
||||
'1.0000000000000000000000000000000000000000000000000' #...
|
||||
'000000000100000000000000000000000000000000000000000' #...
|
||||
'000000000000000000250000000000000002000000000000000' #...
|
||||
'000000000000000000000000000000000000000000010000000' #...
|
||||
'000000000000000000000000000000000000000000000000000' #...
|
||||
'0000000000000000001',
|
||||
'1.0000000000000000000000000000000000000000000000000' #...
|
||||
'000000000100000000000000000000000000000000000000000' #...
|
||||
'000000000000000000249999999999999999999999999999999' #...
|
||||
'999999999999979999999999999999999999999999999999999' #...
|
||||
'999999999999999999999900000000000000000000000000000' #...
|
||||
'000000000000000000000000000000000000000000000000000' #...
|
||||
'00000000000000000000000001',
|
||||
|
||||
'0.9999999999999999999999999999999999999999999999999' #...
|
||||
'999999999900000000000000000000000000000000000000000' #...
|
||||
'000000000000000000249999999999999998000000000000000' #...
|
||||
'000000000000000000000000000000000000000000010000000' #...
|
||||
'000000000000000000000000000000000000000000000000000' #...
|
||||
'0000000000000000001',
|
||||
'0.9999999999999999999999999999999999999999999999999' #...
|
||||
'999999999900000000000000000000000000000000000000000' #...
|
||||
'000000000000000000250000001999999999999999999999999' #...
|
||||
'999999999999999999999999999999999990000000000000000' #...
|
||||
'000000000000000000000000000000000000000000000000000' #...
|
||||
'1',
|
||||
|
||||
# tough cases for ln etc.
|
||||
'1.000000000000000000000000000000000000000000000000' #...
|
||||
'00000000000000000000000000000000000000000000000000' #...
|
||||
'00100000000000000000000000000000000000000000000000' #...
|
||||
'00000000000000000000000000000000000000000000000000' #...
|
||||
'0001',
|
||||
'0.999999999999999999999999999999999999999999999999' #...
|
||||
'99999999999999999999999999999999999999999999999999' #...
|
||||
'99899999999999999999999999999999999999999999999999' #...
|
||||
'99999999999999999999999999999999999999999999999999' #...
|
||||
'99999999999999999999999999999999999999999999999999' #...
|
||||
'9999'
|
||||
]
|
||||
|
||||
|
||||
TESTCASES = [
|
||||
[x for x in test_short_halfway_cases()],
|
||||
[x for x in test_halfway_cases()],
|
||||
[x for x in test_boundaries()],
|
||||
[x for x in test_underflow_boundary()],
|
||||
[x for x in test_bigcomp()],
|
||||
[x for x in test_parsing()],
|
||||
test_particular
|
||||
]
|
||||
|
||||
def un_randfloat():
|
||||
for i in range(1000):
|
||||
l = random.choice(TESTCASES[:6])
|
||||
yield random.choice(l)
|
||||
for v in test_particular:
|
||||
yield v
|
||||
|
||||
def bin_randfloat():
|
||||
for i in range(1000):
|
||||
l1 = random.choice(TESTCASES)
|
||||
l2 = random.choice(TESTCASES)
|
||||
yield random.choice(l1), random.choice(l2)
|
||||
|
||||
def tern_randfloat():
|
||||
for i in range(1000):
|
||||
l1 = random.choice(TESTCASES)
|
||||
l2 = random.choice(TESTCASES)
|
||||
l3 = random.choice(TESTCASES)
|
||||
yield random.choice(l1), random.choice(l2), random.choice(l3)
|
176
third_party/python/Modules/_decimal/tests/runall-memorydebugger.sh
vendored
Executable file
176
third_party/python/Modules/_decimal/tests/runall-memorydebugger.sh
vendored
Executable file
|
@ -0,0 +1,176 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Purpose: test with and without threads, all machine configurations, pydebug,
|
||||
# refleaks, release build and release build with valgrind.
|
||||
#
|
||||
# Synopsis: ./runall-memorydebugger.sh [--all-configs64 | --all-configs32]
|
||||
#
|
||||
# Requirements: valgrind
|
||||
#
|
||||
|
||||
# Set additional CFLAGS and LDFLAGS for ./configure
|
||||
ADD_CFLAGS=
|
||||
ADD_LDFLAGS=
|
||||
|
||||
|
||||
CONFIGS_64="x64 uint128 ansi64 universal"
|
||||
CONFIGS_32="ppro ansi32 ansi-legacy universal"
|
||||
|
||||
VALGRIND="valgrind --tool=memcheck --leak-resolution=high \
|
||||
--db-attach=yes --suppressions=Misc/valgrind-python.supp"
|
||||
|
||||
# Get args
|
||||
case $@ in
|
||||
*--all-configs64*)
|
||||
CONFIGS=$CONFIGS_64
|
||||
;;
|
||||
*--all-configs32*)
|
||||
CONFIGS=$CONFIGS_32
|
||||
;;
|
||||
*)
|
||||
CONFIGS="auto"
|
||||
;;
|
||||
esac
|
||||
|
||||
# gmake required
|
||||
GMAKE=`which gmake`
|
||||
if [ X"$GMAKE" = X"" ]; then
|
||||
GMAKE=make
|
||||
fi
|
||||
|
||||
# Pretty print configurations
|
||||
print_config ()
|
||||
{
|
||||
len=`echo $@ | wc -c`
|
||||
margin="#%"`expr \( 74 - $len \) / 2`"s"
|
||||
|
||||
echo ""
|
||||
echo "# ========================================================================"
|
||||
printf $margin ""
|
||||
echo $@
|
||||
echo "# ========================================================================"
|
||||
echo ""
|
||||
}
|
||||
|
||||
|
||||
cd ..
|
||||
|
||||
# test_decimal: refleak, regular and Valgrind tests
|
||||
for args in "--without-threads" ""; do
|
||||
for config in $CONFIGS; do
|
||||
|
||||
unset PYTHON_DECIMAL_WITH_MACHINE
|
||||
libmpdec_config=$config
|
||||
if [ X"$config" != X"auto" ]; then
|
||||
PYTHON_DECIMAL_WITH_MACHINE=$config
|
||||
export PYTHON_DECIMAL_WITH_MACHINE
|
||||
else
|
||||
libmpdec_config=""
|
||||
fi
|
||||
|
||||
############ refleak tests ###########
|
||||
print_config "refleak tests: config=$config" $args
|
||||
printf "\nbuilding python ...\n\n"
|
||||
|
||||
cd ../../
|
||||
$GMAKE distclean > /dev/null 2>&1
|
||||
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug $args > /dev/null 2>&1
|
||||
$GMAKE | grep _decimal
|
||||
|
||||
printf "\n\n# ======================== refleak tests ===========================\n\n"
|
||||
./python -m test -uall -R 2:2 test_decimal
|
||||
|
||||
|
||||
############ regular tests ###########
|
||||
print_config "regular tests: config=$config" $args
|
||||
printf "\nbuilding python ...\n\n"
|
||||
|
||||
$GMAKE distclean > /dev/null 2>&1
|
||||
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" $args > /dev/null 2>&1
|
||||
$GMAKE | grep _decimal
|
||||
|
||||
printf "\n\n# ======================== regular tests ===========================\n\n"
|
||||
./python -m test -uall test_decimal
|
||||
|
||||
|
||||
########### valgrind tests ###########
|
||||
valgrind=$VALGRIND
|
||||
case "$config" in
|
||||
# Valgrind has no support for 80 bit long double arithmetic.
|
||||
ppro) valgrind= ;;
|
||||
auto) case `uname -m` in
|
||||
i386|i486|i586|i686) valgrind= ;;
|
||||
esac
|
||||
esac
|
||||
|
||||
print_config "valgrind tests: config=$config" $args
|
||||
printf "\nbuilding python ...\n\n"
|
||||
$GMAKE distclean > /dev/null 2>&1
|
||||
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc $args > /dev/null 2>&1
|
||||
$GMAKE | grep _decimal
|
||||
|
||||
printf "\n\n# ======================== valgrind tests ===========================\n\n"
|
||||
$valgrind ./python -m test -uall test_decimal
|
||||
|
||||
cd Modules/_decimal
|
||||
done
|
||||
done
|
||||
|
||||
# deccheck
|
||||
cd ../../
|
||||
for config in $CONFIGS; do
|
||||
for args in "--without-threads" ""; do
|
||||
|
||||
unset PYTHON_DECIMAL_WITH_MACHINE
|
||||
if [ X"$config" != X"auto" ]; then
|
||||
PYTHON_DECIMAL_WITH_MACHINE=$config
|
||||
export PYTHON_DECIMAL_WITH_MACHINE
|
||||
fi
|
||||
|
||||
############ debug ############
|
||||
print_config "deccheck: config=$config --with-pydebug" $args
|
||||
printf "\nbuilding python ...\n\n"
|
||||
|
||||
$GMAKE distclean > /dev/null 2>&1
|
||||
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug $args > /dev/null 2>&1
|
||||
$GMAKE | grep _decimal
|
||||
|
||||
printf "\n\n# ========================== debug ===========================\n\n"
|
||||
./python Modules/_decimal/tests/deccheck.py
|
||||
|
||||
########### regular ###########
|
||||
print_config "deccheck: config=$config " $args
|
||||
printf "\nbuilding python ...\n\n"
|
||||
|
||||
$GMAKE distclean > /dev/null 2>&1
|
||||
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" $args > /dev/null 2>&1
|
||||
$GMAKE | grep _decimal
|
||||
|
||||
printf "\n\n# ======================== regular ===========================\n\n"
|
||||
./python Modules/_decimal/tests/deccheck.py
|
||||
|
||||
########### valgrind ###########
|
||||
valgrind=$VALGRIND
|
||||
case "$config" in
|
||||
# Valgrind has no support for 80 bit long double arithmetic.
|
||||
ppro) valgrind= ;;
|
||||
auto) case `uname -m` in
|
||||
i386|i486|i586|i686) valgrind= ;;
|
||||
esac
|
||||
esac
|
||||
|
||||
print_config "valgrind deccheck: config=$config " $args
|
||||
printf "\nbuilding python ...\n\n"
|
||||
|
||||
$GMAKE distclean > /dev/null 2>&1
|
||||
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc $args > /dev/null 2>&1
|
||||
$GMAKE | grep _decimal
|
||||
|
||||
printf "\n\n# ======================== valgrind ==========================\n\n"
|
||||
$valgrind ./python Modules/_decimal/tests/deccheck.py
|
||||
done
|
||||
done
|
||||
|
||||
|
||||
|
111
third_party/python/Modules/_decimal/tests/runall.bat
vendored
Executable file
111
third_party/python/Modules/_decimal/tests/runall.bat
vendored
Executable file
|
@ -0,0 +1,111 @@
|
|||
@ECHO OFF
|
||||
|
||||
rem Test all machine configurations, pydebug, refleaks, release build.
|
||||
|
||||
cd ..\..\..\
|
||||
|
||||
|
||||
echo.
|
||||
echo # ======================================================================
|
||||
echo # Building Python
|
||||
echo # ======================================================================
|
||||
echo.
|
||||
|
||||
call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x64
|
||||
msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Release /p:PlatformTarget=x64
|
||||
msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Debug /p:PlatformTarget=x64
|
||||
msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=x64
|
||||
msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=x64
|
||||
|
||||
call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86
|
||||
msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=Win32
|
||||
msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=Win32
|
||||
echo.
|
||||
echo.
|
||||
|
||||
echo.
|
||||
echo # ======================================================================
|
||||
echo # test_decimal: platform=x64
|
||||
echo # ======================================================================
|
||||
echo.
|
||||
|
||||
cd PCbuild\amd64
|
||||
|
||||
echo # ==================== refleak tests =======================
|
||||
echo.
|
||||
python_d.exe -m test -uall -R 2:2 test_decimal
|
||||
echo.
|
||||
echo.
|
||||
|
||||
echo # ==================== regular tests =======================
|
||||
echo.
|
||||
python.exe -m test -uall test_decimal
|
||||
echo.
|
||||
echo.
|
||||
|
||||
cd ..
|
||||
|
||||
echo.
|
||||
echo # ======================================================================
|
||||
echo # test_decimal: platform=x86
|
||||
echo # ======================================================================
|
||||
echo.
|
||||
|
||||
echo # ==================== refleak tests =======================
|
||||
echo.
|
||||
python_d.exe -m test -uall -R 2:2 test_decimal
|
||||
echo.
|
||||
echo.
|
||||
|
||||
echo # ==================== regular tests =======================
|
||||
echo.
|
||||
python.exe -m test -uall test_decimal
|
||||
echo.
|
||||
echo.
|
||||
|
||||
cd amd64
|
||||
|
||||
echo.
|
||||
echo # ======================================================================
|
||||
echo # deccheck: platform=x64
|
||||
echo # ======================================================================
|
||||
echo.
|
||||
|
||||
echo # ==================== debug build =======================
|
||||
echo.
|
||||
python_d.exe ..\..\Modules\_decimal\tests\deccheck.py
|
||||
echo.
|
||||
echo.
|
||||
|
||||
echo # =================== release build ======================
|
||||
echo.
|
||||
python.exe ..\..\Modules\_decimal\tests\deccheck.py
|
||||
echo.
|
||||
echo.
|
||||
|
||||
cd ..
|
||||
|
||||
echo.
|
||||
echo # ======================================================================
|
||||
echo # deccheck: platform=x86
|
||||
echo # ======================================================================
|
||||
echo.
|
||||
echo.
|
||||
|
||||
echo # ==================== debug build =======================
|
||||
echo.
|
||||
python_d.exe ..\Modules\_decimal\tests\deccheck.py
|
||||
echo.
|
||||
echo.
|
||||
|
||||
echo # =================== release build ======================
|
||||
echo.
|
||||
python.exe ..\Modules\_decimal\tests\deccheck.py
|
||||
echo.
|
||||
echo.
|
||||
|
||||
|
||||
cd ..\Modules\_decimal\tests
|
||||
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue