micropython: add micropython component
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
# test construction of array from array with float type
|
||||
|
||||
try:
|
||||
from uarray import array
|
||||
except ImportError:
|
||||
try:
|
||||
from array import array
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
print(array("f", array("h", [1, 2])))
|
||||
print(array("d", array("f", [1, 2])))
|
@@ -0,0 +1,13 @@
|
||||
# test builtin abs function with float args
|
||||
|
||||
for val in (
|
||||
"1.0",
|
||||
"-1.0",
|
||||
"0.0",
|
||||
"-0.0",
|
||||
"nan",
|
||||
"-nan",
|
||||
"inf",
|
||||
"-inf",
|
||||
):
|
||||
print(val, abs(float(val)))
|
@@ -0,0 +1,25 @@
|
||||
# test builtin hash function with float args
|
||||
|
||||
# these should hash to an integer with a specific value
|
||||
for val in (
|
||||
"0.0",
|
||||
"-0.0",
|
||||
"1.0",
|
||||
"2.0",
|
||||
"-12.0",
|
||||
"12345.0",
|
||||
):
|
||||
print(val, hash(float(val)))
|
||||
|
||||
# just check that these values are hashable
|
||||
for val in (
|
||||
"0.1",
|
||||
"-0.1",
|
||||
"10.3",
|
||||
"0.4e3",
|
||||
"1e16",
|
||||
"inf",
|
||||
"-inf",
|
||||
"nan",
|
||||
):
|
||||
print(val, type(hash(float(val))))
|
@@ -0,0 +1,31 @@
|
||||
# test builtin min and max functions with float args
|
||||
try:
|
||||
min
|
||||
max
|
||||
except:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
print(min(0, 1.0))
|
||||
print(min(1.0, 0))
|
||||
print(min(0, -1.0))
|
||||
print(min(-1.0, 0))
|
||||
|
||||
print(max(0, 1.0))
|
||||
print(max(1.0, 0))
|
||||
print(max(0, -1.0))
|
||||
print(max(-1.0, 0))
|
||||
|
||||
print(min(1.5, -1.5))
|
||||
print(min(-1.5, 1.5))
|
||||
|
||||
print(max(1.5, -1.5))
|
||||
print(max(-1.5, 1.5))
|
||||
|
||||
print(min([1, 2.9, 4, 0, -1, 2]))
|
||||
print(max([1, 2.9, 4, 0, -1, 2]))
|
||||
|
||||
print(min([1, 2.9, 4, 6.5, -1, 2]))
|
||||
print(max([1, 2.9, 4, 6.5, -1, 2]))
|
||||
print(min([1, 2.9, 4, -6.5, -1, 2]))
|
||||
print(max([1, 2.9, 4, -6.5, -1, 2]))
|
@@ -0,0 +1,11 @@
|
||||
# test builtin pow function with float args
|
||||
|
||||
print(pow(0.0, 0.0))
|
||||
print(pow(0, 1.0))
|
||||
print(pow(1.0, 1))
|
||||
print(pow(2.0, 3.0))
|
||||
print(pow(2.0, -4.0))
|
||||
|
||||
print(pow(0.0, float("inf")))
|
||||
print(pow(0.0, float("-inf")))
|
||||
print(pow(0.0, float("nan")))
|
@@ -0,0 +1,34 @@
|
||||
# test round() with floats
|
||||
|
||||
# check basic cases
|
||||
tests = [
|
||||
[0.0],
|
||||
[1.0],
|
||||
[0.1],
|
||||
[-0.1],
|
||||
[123.4],
|
||||
[123.6],
|
||||
[-123.4],
|
||||
[-123.6],
|
||||
[1.234567, 5],
|
||||
[1.23456, 1],
|
||||
[1.23456, 0],
|
||||
[1234.56, -2],
|
||||
]
|
||||
for t in tests:
|
||||
print(round(*t))
|
||||
|
||||
# check .5 cases
|
||||
for i in range(11):
|
||||
print(round((i - 5) / 2))
|
||||
|
||||
# test second arg
|
||||
for i in range(-1, 3):
|
||||
print(round(1.47, i))
|
||||
|
||||
# test inf and nan
|
||||
for val in (float("inf"), float("nan")):
|
||||
try:
|
||||
round(val)
|
||||
except (ValueError, OverflowError) as e:
|
||||
print(type(e))
|
@@ -0,0 +1,4 @@
|
||||
# test round() with floats that return large integers
|
||||
|
||||
for x in (-1e25, 1e25):
|
||||
print("%.3g" % round(x))
|
@@ -0,0 +1,12 @@
|
||||
# test construction of bytearray from array with float type
|
||||
|
||||
try:
|
||||
from uarray import array
|
||||
except ImportError:
|
||||
try:
|
||||
from array import array
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
print(bytearray(array("f", [1, 2.5])))
|
@@ -0,0 +1,12 @@
|
||||
# test construction of bytes from array with float type
|
||||
|
||||
try:
|
||||
from uarray import array
|
||||
except ImportError:
|
||||
try:
|
||||
from array import array
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
print(bytes(array("f", [1, 2.5])))
|
65
components/language/micropython/tests/float/cmath_fun.py
Normal file
65
components/language/micropython/tests/float/cmath_fun.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# test the functions imported from cmath
|
||||
|
||||
try:
|
||||
from cmath import *
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
# make sure these constants exist in cmath
|
||||
print("%.5g" % e)
|
||||
print("%.5g" % pi)
|
||||
|
||||
test_values_non_zero = []
|
||||
base_values = (0.0, 0.5, 1.2345, 10.0)
|
||||
for r in base_values:
|
||||
for i in base_values:
|
||||
if r != 0.0 or i != 0.0:
|
||||
test_values_non_zero.append(complex(r, i))
|
||||
if r != 0.0:
|
||||
test_values_non_zero.append(complex(-r, i))
|
||||
if i != 0.0:
|
||||
test_values_non_zero.append(complex(r, -i))
|
||||
if r != 0.0 and i != 0.0:
|
||||
test_values_non_zero.append(complex(-r, -i))
|
||||
test_values = [complex(0.0, 0.0)] + test_values_non_zero
|
||||
print(test_values)
|
||||
|
||||
functions = [
|
||||
("phase", phase, test_values),
|
||||
("polar", polar, test_values),
|
||||
(
|
||||
"rect",
|
||||
rect,
|
||||
((0, 0), (0, 1), (0, -1), (1, 0), (-1, 0), (1, 1), (-1, 1), (1, -1), (123.0, -456.0)),
|
||||
),
|
||||
("exp", exp, test_values),
|
||||
("log", log, test_values_non_zero),
|
||||
("sqrt", sqrt, test_values),
|
||||
("cos", cos, test_values),
|
||||
("sin", sin, test_values),
|
||||
]
|
||||
|
||||
for f_name, f, test_vals in functions:
|
||||
print(f_name)
|
||||
for val in test_vals:
|
||||
if type(val) == tuple:
|
||||
ret = f(*val)
|
||||
else:
|
||||
ret = f(val)
|
||||
if type(ret) == float:
|
||||
print("%.5g" % ret)
|
||||
elif type(ret) == tuple:
|
||||
print("%.5g %.5g" % ret)
|
||||
else:
|
||||
# some test (eg cmath.sqrt(-0.5)) disagree with CPython with tiny real part
|
||||
real = ret.real
|
||||
if abs(real) < 1e-6:
|
||||
real = 0.0
|
||||
print("complex(%.5g, %.5g)" % (real, ret.imag))
|
||||
|
||||
# test invalid type passed to cmath function
|
||||
try:
|
||||
log([])
|
||||
except TypeError:
|
||||
print("TypeError")
|
@@ -0,0 +1,32 @@
|
||||
# test the special functions imported from cmath
|
||||
|
||||
try:
|
||||
from cmath import *
|
||||
|
||||
log10
|
||||
except (ImportError, NameError):
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
test_values_non_zero = []
|
||||
base_values = (0.0, 0.5, 1.2345, 10.0)
|
||||
for r in base_values:
|
||||
for i in base_values:
|
||||
if r != 0.0 or i != 0.0:
|
||||
test_values_non_zero.append(complex(r, i))
|
||||
if r != 0.0:
|
||||
test_values_non_zero.append(complex(-r, i))
|
||||
if i != 0.0:
|
||||
test_values_non_zero.append(complex(r, -i))
|
||||
if r != 0.0 and i != 0.0:
|
||||
test_values_non_zero.append(complex(-r, -i))
|
||||
|
||||
functions = [
|
||||
("log10", log10, test_values_non_zero),
|
||||
]
|
||||
|
||||
for f_name, f, test_vals in functions:
|
||||
print(f_name)
|
||||
for val in test_vals:
|
||||
ret = f(val)
|
||||
print("complex(%.4g, %.4g)" % (ret.real, ret.imag))
|
125
components/language/micropython/tests/float/complex1.py
Normal file
125
components/language/micropython/tests/float/complex1.py
Normal file
@@ -0,0 +1,125 @@
|
||||
# test basic complex number functionality
|
||||
|
||||
# constructor
|
||||
print(complex(1))
|
||||
print(complex(1.2))
|
||||
print(complex(1.2j))
|
||||
print(complex("1"))
|
||||
print(complex("1.2"))
|
||||
print(complex("1.2j"))
|
||||
print(complex(1, 2))
|
||||
print(complex(1j, 2j))
|
||||
|
||||
# unary ops
|
||||
print(bool(1j))
|
||||
print(+(1j))
|
||||
print(-(1 + 2j))
|
||||
|
||||
# binary ops
|
||||
print(1j + False)
|
||||
print(1j + True)
|
||||
print(1j + 2)
|
||||
print(1j + 2j)
|
||||
print(1j - 2)
|
||||
print(1j - 2j)
|
||||
print(1j * 2)
|
||||
print(1j * 2j)
|
||||
print(1j / 2)
|
||||
print((1j / 2j).real)
|
||||
print(1j / (1 + 2j))
|
||||
ans = 0j**0
|
||||
print("%.5g %.5g" % (ans.real, ans.imag))
|
||||
ans = 0j**1
|
||||
print("%.5g %.5g" % (ans.real, ans.imag))
|
||||
ans = 0j**0j
|
||||
print("%.5g %.5g" % (ans.real, ans.imag))
|
||||
ans = 1j**2.5
|
||||
print("%.5g %.5g" % (ans.real, ans.imag))
|
||||
ans = 1j**2.5j
|
||||
print("%.5g %.5g" % (ans.real, ans.imag))
|
||||
|
||||
# comparison
|
||||
print(1j == 1)
|
||||
print(1j == 1j)
|
||||
print(0 + 0j == False, 1 + 0j == True)
|
||||
print(False == 0 + 0j, True == 1 + 0j)
|
||||
|
||||
# comparison of nan is special
|
||||
nan = float("nan") * 1j
|
||||
print(nan == 1j)
|
||||
print(nan == nan)
|
||||
|
||||
# builtin abs
|
||||
print(abs(1j))
|
||||
print("%.5g" % abs(1j + 2))
|
||||
|
||||
# builtin hash
|
||||
print(hash(1 + 0j))
|
||||
print(type(hash(1j)))
|
||||
|
||||
# float on lhs should delegate to complex
|
||||
print(1.2 + 3j)
|
||||
|
||||
# negative base and fractional power should create a complex
|
||||
ans = (-1) ** 2.3
|
||||
print("%.5g %.5g" % (ans.real, ans.imag))
|
||||
ans = (-1.2) ** -3.4
|
||||
print("%.5g %.5g" % (ans.real, ans.imag))
|
||||
|
||||
# check printing of inf/nan
|
||||
print(float("nan") * 1j)
|
||||
print(float("-nan") * 1j)
|
||||
print(float("inf") * (1 + 1j))
|
||||
print(float("-inf") * (1 + 1j))
|
||||
|
||||
# can't assign to attributes
|
||||
try:
|
||||
(1j).imag = 0
|
||||
except AttributeError:
|
||||
print("AttributeError")
|
||||
|
||||
# can't convert rhs to complex
|
||||
try:
|
||||
1j + []
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
# unsupported unary op
|
||||
try:
|
||||
~(1j)
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
# unsupported binary op
|
||||
try:
|
||||
1j // 2
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
# unsupported binary op
|
||||
try:
|
||||
1j < 2j
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
# small int on LHS, complex on RHS, unsupported op
|
||||
try:
|
||||
print(1 | 1j)
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
# zero division
|
||||
try:
|
||||
1j / 0
|
||||
except ZeroDivisionError:
|
||||
print("ZeroDivisionError")
|
||||
|
||||
# zero division via power
|
||||
try:
|
||||
0j**-1
|
||||
except ZeroDivisionError:
|
||||
print("ZeroDivisionError")
|
||||
try:
|
||||
0j**1j
|
||||
except ZeroDivisionError:
|
||||
print("ZeroDivisionError")
|
@@ -0,0 +1,5 @@
|
||||
# test basic complex number functionality
|
||||
|
||||
# convert bignum to complex on rhs
|
||||
ans = 1j + (1 << 70)
|
||||
print("%.5g %.5g" % (ans.real, ans.imag))
|
@@ -0,0 +1,10 @@
|
||||
# test complex interacting with special reverse methods
|
||||
|
||||
|
||||
class A:
|
||||
def __radd__(self, x):
|
||||
print("__radd__")
|
||||
return 2
|
||||
|
||||
|
||||
print(1j + A())
|
@@ -0,0 +1,10 @@
|
||||
# test complex interacting with special methods
|
||||
|
||||
|
||||
class A:
|
||||
def __add__(self, x):
|
||||
print("__add__")
|
||||
return 1
|
||||
|
||||
|
||||
print(A() + 1j)
|
121
components/language/micropython/tests/float/float1.py
Normal file
121
components/language/micropython/tests/float/float1.py
Normal file
@@ -0,0 +1,121 @@
|
||||
# test basic float capabilities
|
||||
|
||||
# literals
|
||||
print(0.12)
|
||||
print(1.0)
|
||||
print(1.2)
|
||||
print(0e0)
|
||||
print(0e0)
|
||||
print(0e-0)
|
||||
|
||||
# float construction
|
||||
print(float(1.2))
|
||||
print(float("1.2"))
|
||||
print(float("+1"))
|
||||
print(float("1e1"))
|
||||
print(float("1e+1"))
|
||||
print(float("1e-1"))
|
||||
print(float("inf"))
|
||||
print(float("-inf"))
|
||||
print(float("INF"))
|
||||
print(float("infinity"))
|
||||
print(float("INFINITY"))
|
||||
print(float("nan"))
|
||||
print(float("-nan"))
|
||||
print(float("NaN"))
|
||||
try:
|
||||
float("")
|
||||
except ValueError:
|
||||
print("ValueError")
|
||||
try:
|
||||
float("1e+")
|
||||
except ValueError:
|
||||
print("ValueError")
|
||||
try:
|
||||
float("1z")
|
||||
except ValueError:
|
||||
print("ValueError")
|
||||
|
||||
# construct from something with the buffer protocol
|
||||
print(float(b"1.2"))
|
||||
print(float(bytearray(b"3.4")))
|
||||
|
||||
# unary operators
|
||||
print(bool(0.0))
|
||||
print(bool(1.2))
|
||||
print(+(1.2))
|
||||
print(-(1.2))
|
||||
|
||||
# division of integers
|
||||
x = 1 / 2
|
||||
print(x)
|
||||
|
||||
# /= operator
|
||||
a = 1
|
||||
a /= 2
|
||||
print(a)
|
||||
|
||||
# floor division
|
||||
print(1.0 // 2)
|
||||
print(2.0 // 2)
|
||||
|
||||
# comparison
|
||||
print(1.2 <= 3.4)
|
||||
print(1.2 <= -3.4)
|
||||
print(1.2 >= 3.4)
|
||||
print(1.2 >= -3.4)
|
||||
print(0.0 == False, 1.0 == True)
|
||||
print(False == 0.0, True == 1.0)
|
||||
|
||||
# comparison of nan is special
|
||||
nan = float("nan")
|
||||
print(nan == 1.2)
|
||||
print(nan == nan)
|
||||
|
||||
try:
|
||||
1.0 / 0
|
||||
except ZeroDivisionError:
|
||||
print("ZeroDivisionError")
|
||||
|
||||
try:
|
||||
1.0 // 0
|
||||
except ZeroDivisionError:
|
||||
print("ZeroDivisionError")
|
||||
|
||||
try:
|
||||
1.2 % 0
|
||||
except ZeroDivisionError:
|
||||
print("ZeroDivisionError")
|
||||
|
||||
try:
|
||||
0.0**-1
|
||||
except ZeroDivisionError:
|
||||
print("ZeroDivisionError")
|
||||
|
||||
# unsupported unary ops
|
||||
|
||||
try:
|
||||
~1.2
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
try:
|
||||
1.2 in 3.4
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
# small int on LHS, float on RHS, unsupported op
|
||||
try:
|
||||
print(1 | 1.0)
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
# can't convert list to float
|
||||
try:
|
||||
float([])
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
# test constant float with more than 255 chars
|
||||
x = 1.84728699436059052516398251149631771898472869943605905251639825114963177189847286994360590525163982511496317718984728699436059052516398251149631771898472869943605905251639825114963177189847286994360590525163982511496317718984728699436059052516398251149631771898472869943605905251639825114963177189
|
||||
print("%.5f" % x)
|
@@ -0,0 +1,104 @@
|
||||
# check cases converting float to int, requiring double precision float
|
||||
|
||||
try:
|
||||
import ustruct as struct
|
||||
import usys as sys
|
||||
except:
|
||||
import struct
|
||||
import sys
|
||||
|
||||
maxsize_bits = 0
|
||||
maxsize = sys.maxsize
|
||||
while maxsize:
|
||||
maxsize >>= 1
|
||||
maxsize_bits += 1
|
||||
|
||||
# work out configuration values
|
||||
is_64bit = maxsize_bits > 32
|
||||
# 0 = none, 1 = long long, 2 = mpz
|
||||
ll_type = None
|
||||
if is_64bit:
|
||||
if maxsize_bits < 63:
|
||||
ll_type = 0
|
||||
else:
|
||||
if maxsize_bits < 31:
|
||||
ll_type = 0
|
||||
if ll_type is None:
|
||||
one = 1
|
||||
if one << 65 < one << 62:
|
||||
ll_type = 1
|
||||
else:
|
||||
ll_type = 2
|
||||
|
||||
# This case occurs with time.time() values
|
||||
if ll_type != 0:
|
||||
print(int(1418774543.0))
|
||||
print("%d" % 1418774543.0)
|
||||
if ll_type == 3:
|
||||
print(int(2.0**100))
|
||||
print("%d" % 2.0**100)
|
||||
else:
|
||||
print(int(1073741823.0))
|
||||
print("%d" % 1073741823.0)
|
||||
|
||||
testpass = True
|
||||
p2_rng = ((30, 63, 1024), (62, 63, 1024))[is_64bit][ll_type]
|
||||
for i in range(0, p2_rng):
|
||||
bitcnt = len(bin(int(2.0**i))) - 3
|
||||
if i != bitcnt:
|
||||
print("fail: 2**%u was %u bits long" % (i, bitcnt))
|
||||
testpass = False
|
||||
print("power of 2 test: %s" % (testpass and "passed" or "failed"))
|
||||
|
||||
testpass = True
|
||||
p10_rng = ((9, 18, 23), (18, 18, 23))[is_64bit][ll_type]
|
||||
for i in range(0, p10_rng):
|
||||
digcnt = len(str(int(10.0**i))) - 1
|
||||
if i != digcnt:
|
||||
print("fail: 10**%u was %u digits long" % (i, digcnt))
|
||||
testpass = False
|
||||
print("power of 10 test: %s" % (testpass and "passed" or "failed"))
|
||||
|
||||
|
||||
def fp2int_test(num, name, should_fail):
|
||||
try:
|
||||
x = int(num)
|
||||
passed = ~should_fail
|
||||
except:
|
||||
passed = should_fail
|
||||
print("%s: %s" % (name, passed and "passed" or "failed"))
|
||||
|
||||
|
||||
if ll_type != 2:
|
||||
if ll_type == 0:
|
||||
if is_64bit:
|
||||
neg_bad_fp = -1.00000005 * 2.0**62.0
|
||||
pos_bad_fp = 2.0**62.0
|
||||
neg_good_fp = -(2.0**62.0)
|
||||
pos_good_fp = 0.99999993 * 2.0**62.0
|
||||
else:
|
||||
neg_bad_fp = -1.00000005 * 2.0**30.0
|
||||
pos_bad_fp = 2.0**30.0
|
||||
neg_good_fp = -(2.0**30.0)
|
||||
pos_good_fp = 0.9999999499 * 2.0**30.0
|
||||
else:
|
||||
neg_bad_fp = -0.51 * 2.0**64.0
|
||||
pos_bad_fp = 2.0**63.0
|
||||
neg_good_fp = -(2.0**63.0)
|
||||
pos_good_fp = 1.9999998 * 2.0**62.0
|
||||
|
||||
fp2int_test(neg_bad_fp, "neg bad", True)
|
||||
fp2int_test(pos_bad_fp, "pos bad", True)
|
||||
fp2int_test(neg_good_fp, "neg good", False)
|
||||
fp2int_test(pos_good_fp, "pos good", False)
|
||||
else:
|
||||
fp2int_test(-1.9999999999999981 * 2.0**1023.0, "large neg", False)
|
||||
fp2int_test(1.9999999999999981 * 2.0**1023.0, "large pos", False)
|
||||
|
||||
fp2int_test(float("inf"), "inf test", True)
|
||||
fp2int_test(float("-inf"), "inf test", True)
|
||||
fp2int_test(float("nan"), "NaN test", True)
|
||||
|
||||
# test numbers < 1 (this used to fail; see issue #1044)
|
||||
fp2int_test(0.0001, "small num", False)
|
||||
struct.pack("I", int(1 / 2))
|
@@ -0,0 +1,101 @@
|
||||
# check cases converting float to int, relying only on single precision float
|
||||
|
||||
try:
|
||||
import ustruct as struct
|
||||
import usys as sys
|
||||
except:
|
||||
import struct
|
||||
import sys
|
||||
|
||||
maxsize_bits = 0
|
||||
maxsize = sys.maxsize
|
||||
while maxsize:
|
||||
maxsize >>= 1
|
||||
maxsize_bits += 1
|
||||
|
||||
# work out configuration values
|
||||
is_64bit = maxsize_bits > 32
|
||||
# 0 = none, 1 = long long, 2 = mpz
|
||||
ll_type = None
|
||||
if is_64bit:
|
||||
if maxsize_bits < 63:
|
||||
ll_type = 0
|
||||
else:
|
||||
if maxsize_bits < 31:
|
||||
ll_type = 0
|
||||
if ll_type is None:
|
||||
one = 1
|
||||
if one << 65 < one << 62:
|
||||
ll_type = 1
|
||||
else:
|
||||
ll_type = 2
|
||||
|
||||
# basic conversion
|
||||
print(int(14187744.0))
|
||||
print("%d" % 14187744.0)
|
||||
if ll_type == 2:
|
||||
print(int(2.0**100))
|
||||
print("%d" % 2.0**100)
|
||||
|
||||
testpass = True
|
||||
p2_rng = ((30, 63, 127), (62, 63, 127))[is_64bit][ll_type]
|
||||
for i in range(0, p2_rng):
|
||||
bitcnt = len(bin(int(2.0**i))) - 3
|
||||
if i != bitcnt:
|
||||
print("fail: 2.**%u was %u bits long" % (i, bitcnt))
|
||||
testpass = False
|
||||
print("power of 2 test: %s" % (testpass and "passed" or "failed"))
|
||||
|
||||
# TODO why does 10**12 fail this test for single precision float?
|
||||
testpass = True
|
||||
p10_rng = 9
|
||||
for i in range(0, p10_rng):
|
||||
digcnt = len(str(int(10.0**i))) - 1
|
||||
if i != digcnt:
|
||||
print("fail: 10.**%u was %u digits long" % (i, digcnt))
|
||||
testpass = False
|
||||
print("power of 10 test: %s" % (testpass and "passed" or "failed"))
|
||||
|
||||
|
||||
def fp2int_test(num, name, should_fail):
|
||||
try:
|
||||
x = int(num)
|
||||
passed = ~should_fail
|
||||
except:
|
||||
passed = should_fail
|
||||
print("%s: %s" % (name, passed and "passed" or "failed"))
|
||||
|
||||
|
||||
if ll_type != 2:
|
||||
if ll_type == 0:
|
||||
if is_64bit:
|
||||
neg_bad_fp = -1.00000005 * 2.0**62.0
|
||||
pos_bad_fp = 2.0**62.0
|
||||
neg_good_fp = -(2.0**62.0)
|
||||
pos_good_fp = 0.99999993 * 2.0**62.0
|
||||
else:
|
||||
neg_bad_fp = -1.00000005 * 2.0**30.0
|
||||
pos_bad_fp = 2.0**30.0
|
||||
neg_good_fp = -(2.0**30.0)
|
||||
pos_good_fp = 0.9999999499 * 2.0**30.0
|
||||
else:
|
||||
neg_bad_fp = -0.51 * 2.0**64.0
|
||||
pos_bad_fp = 2.0**63.0
|
||||
neg_good_fp = -(2.0**63.0)
|
||||
pos_good_fp = 1.9999998 * 2.0**62.0
|
||||
|
||||
fp2int_test(neg_bad_fp, "neg bad", True)
|
||||
fp2int_test(pos_bad_fp, "pos bad", True)
|
||||
fp2int_test(neg_good_fp, "neg good", False)
|
||||
fp2int_test(pos_good_fp, "pos good", False)
|
||||
else:
|
||||
fp2int_test(-1.999999879 * 2.0**126.0, "large neg", False)
|
||||
fp2int_test(1.999999879 * 2.0**126.0, "large pos", False)
|
||||
|
||||
fp2int_test(float("inf"), "inf test", True)
|
||||
fp2int_test(float("-inf"), "inf test", True)
|
||||
fp2int_test(float("nan"), "NaN test", True)
|
||||
|
||||
# test numbers < 1 (this used to fail; see issue #1044)
|
||||
fp2int_test(0.0001, "small num", False)
|
||||
struct.pack("I", int(1 / 2))
|
103
components/language/micropython/tests/float/float2int_intbig.py
Normal file
103
components/language/micropython/tests/float/float2int_intbig.py
Normal file
@@ -0,0 +1,103 @@
|
||||
# check cases converting float to int, relying only on single precision float
|
||||
|
||||
try:
|
||||
import ustruct as struct
|
||||
import usys as sys
|
||||
except:
|
||||
import struct
|
||||
import sys
|
||||
|
||||
maxsize_bits = 0
|
||||
maxsize = sys.maxsize
|
||||
while maxsize:
|
||||
maxsize >>= 1
|
||||
maxsize_bits += 1
|
||||
|
||||
# work out configuration values
|
||||
is_64bit = maxsize_bits > 32
|
||||
# 0 = none, 1 = long long, 2 = mpz
|
||||
ll_type = None
|
||||
if is_64bit:
|
||||
if maxsize_bits < 63:
|
||||
ll_type = 0
|
||||
else:
|
||||
if maxsize_bits < 31:
|
||||
ll_type = 0
|
||||
if ll_type is None:
|
||||
one = 1
|
||||
if one << 65 < one << 62:
|
||||
ll_type = 1
|
||||
else:
|
||||
ll_type = 2
|
||||
|
||||
|
||||
# basic conversion
|
||||
# fmt: off
|
||||
print(int(14187745.))
|
||||
print("%d" % 14187745.)
|
||||
# fmt: on
|
||||
if ll_type == 2:
|
||||
print(int(2.0**100))
|
||||
print("%d" % 2.0**100)
|
||||
|
||||
testpass = True
|
||||
p2_rng = ((30, 63, 127), (62, 63, 127))[is_64bit][ll_type]
|
||||
for i in range(0, p2_rng):
|
||||
bitcnt = len(bin(int(2.0**i))) - 3
|
||||
if i != bitcnt:
|
||||
print("fail: 2.**%u was %u bits long" % (i, bitcnt))
|
||||
testpass = False
|
||||
print("power of 2 test: %s" % (testpass and "passed" or "failed"))
|
||||
|
||||
# TODO why does 10**12 fail this test for single precision float?
|
||||
testpass = True
|
||||
p10_rng = 9 if (ll_type == 0 and ~is_64bit) else 11
|
||||
for i in range(0, p10_rng):
|
||||
digcnt = len(str(int(10.0**i))) - 1
|
||||
if i != digcnt:
|
||||
print("fail: 10.**%u was %u digits long" % (i, digcnt))
|
||||
testpass = False
|
||||
print("power of 10 test: %s" % (testpass and "passed" or "failed"))
|
||||
|
||||
|
||||
def fp2int_test(num, name, should_fail):
|
||||
try:
|
||||
x = int(num)
|
||||
passed = ~should_fail
|
||||
except:
|
||||
passed = should_fail
|
||||
print("%s: %s" % (name, passed and "passed" or "failed"))
|
||||
|
||||
|
||||
if ll_type != 2:
|
||||
if ll_type == 0:
|
||||
if is_64bit:
|
||||
neg_bad_fp = -1.00000005 * 2.0**62.0
|
||||
pos_bad_fp = 2.0**62.0
|
||||
neg_good_fp = -(2.0**62.0)
|
||||
pos_good_fp = 0.99999993 * 2.0**62.0
|
||||
else:
|
||||
neg_bad_fp = -1.00000005 * 2.0**30.0
|
||||
pos_bad_fp = 2.0**30.0
|
||||
neg_good_fp = -(2.0**30.0)
|
||||
pos_good_fp = 0.9999999499 * 2.0**30.0
|
||||
else:
|
||||
neg_bad_fp = -0.51 * 2.0**64.0
|
||||
pos_bad_fp = 2.0**63.0
|
||||
neg_good_fp = -(2.0**63.0)
|
||||
pos_good_fp = 1.9999998 * 2.0**62.0
|
||||
|
||||
fp2int_test(neg_bad_fp, "neg bad", True)
|
||||
fp2int_test(pos_bad_fp, "pos bad", True)
|
||||
fp2int_test(neg_good_fp, "neg good", False)
|
||||
fp2int_test(pos_good_fp, "pos good", False)
|
||||
else:
|
||||
fp2int_test(-1.999999879 * 2.0**127.0, "large neg", False)
|
||||
fp2int_test(1.999999879 * 2.0**127.0, "large pos", False)
|
||||
|
||||
fp2int_test(float("inf"), "inf test", True)
|
||||
fp2int_test(float("nan"), "NaN test", True)
|
||||
|
||||
# test numbers < 1 (this used to fail; see issue #1044)
|
||||
fp2int_test(0.0001, "small num", False)
|
||||
struct.pack("I", int(1 / 2))
|
25
components/language/micropython/tests/float/float_array.py
Normal file
25
components/language/micropython/tests/float/float_array.py
Normal file
@@ -0,0 +1,25 @@
|
||||
try:
|
||||
from uarray import array
|
||||
except ImportError:
|
||||
try:
|
||||
from array import array
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
def test(a):
|
||||
print(a)
|
||||
a.append(1.2)
|
||||
print(len(a), "%.3f" % a[0])
|
||||
a.append(1)
|
||||
a.append(False)
|
||||
print(len(a), "%.3f %.3f" % (a[1], a[2]))
|
||||
a[-1] = 3.45
|
||||
print("%.3f" % a[-1])
|
||||
|
||||
|
||||
test(array("f"))
|
||||
test(array("d"))
|
||||
|
||||
print("{:.4f}".format(array("f", bytes(array("I", [0x3DCCCCCC])))[0]))
|
24
components/language/micropython/tests/float/float_compare.py
Normal file
24
components/language/micropython/tests/float/float_compare.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# Extended float comparisons
|
||||
|
||||
|
||||
class Foo:
|
||||
pass
|
||||
|
||||
|
||||
foo = Foo()
|
||||
|
||||
print(foo == 1.0)
|
||||
print(1.0 == foo)
|
||||
print(1.0 == Foo)
|
||||
print(1.0 == [])
|
||||
print(1.0 == {})
|
||||
|
||||
try:
|
||||
print(foo < 1.0)
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
try:
|
||||
print(1.0 < foo)
|
||||
except TypeError:
|
||||
print("TypeError")
|
27
components/language/micropython/tests/float/float_divmod.py
Normal file
27
components/language/micropython/tests/float/float_divmod.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# test floating point floor divide and modulus
|
||||
# it has some tricky corner cases
|
||||
|
||||
|
||||
def test(x, y):
|
||||
div, mod = divmod(x, y)
|
||||
print("%.8f %.8f %.8f %.8f" % (x // y, x % y, div, mod))
|
||||
print(div == x // y, mod == x % y, abs(div * y + mod - x) < 1e-15)
|
||||
|
||||
|
||||
test(1.23456, 0.7)
|
||||
test(-1.23456, 0.7)
|
||||
test(1.23456, -0.7)
|
||||
test(-1.23456, -0.7)
|
||||
|
||||
a = 1.23456
|
||||
b = 0.7
|
||||
test(a, b)
|
||||
test(a, -b)
|
||||
test(-a, b)
|
||||
test(-a, -b)
|
||||
|
||||
for i in range(25):
|
||||
x = (i - 12.5) / 6
|
||||
for j in range(25):
|
||||
y = (j - 12.5) / 6
|
||||
test(x, y)
|
@@ -0,0 +1,35 @@
|
||||
# test floating point floor divide and modulus
|
||||
# it has some tricky corner cases
|
||||
|
||||
# pyboard has 32-bit floating point and gives different (but still
|
||||
# correct) answers for certain combinations of divmod arguments.
|
||||
|
||||
|
||||
def test(x, y):
|
||||
div, mod = divmod(x, y)
|
||||
print(div == x // y, mod == x % y, abs(div * y + mod - x) < 1e-6)
|
||||
|
||||
|
||||
test(1.23456, 0.7)
|
||||
test(-1.23456, 0.7)
|
||||
test(1.23456, -0.7)
|
||||
test(-1.23456, -0.7)
|
||||
|
||||
a = 1.23456
|
||||
b = 0.7
|
||||
test(a, b)
|
||||
test(a, -b)
|
||||
test(-a, b)
|
||||
test(-a, -b)
|
||||
|
||||
for i in range(25):
|
||||
x = (i - 12.5) / 6
|
||||
for j in range(25):
|
||||
y = (j - 12.5) / 6
|
||||
test(x, y)
|
||||
|
||||
# test division by zero error
|
||||
try:
|
||||
divmod(1.0, 0)
|
||||
except ZeroDivisionError:
|
||||
print("ZeroDivisionError")
|
19
components/language/micropython/tests/float/float_format.py
Normal file
19
components/language/micropython/tests/float/float_format.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# test float formatting
|
||||
|
||||
# general rounding
|
||||
for val in (116, 1111, 1234, 5010, 11111):
|
||||
print("%.0f" % val)
|
||||
print("%.1f" % val)
|
||||
print("%.3f" % val)
|
||||
|
||||
# make sure rounding is done at the correct precision
|
||||
for prec in range(8):
|
||||
print(("%%.%df" % prec) % 6e-5)
|
||||
|
||||
# check certain cases that had a digit value of 10 render as a ":" character
|
||||
print("%.2e" % float("9" * 51 + "e-39"))
|
||||
print("%.2e" % float("9" * 40 + "e-21"))
|
||||
|
||||
# check a case that would render negative digit values, eg ")" characters
|
||||
# the string is converted back to a float to check for no illegal characters
|
||||
float("%.23e" % 1e-80)
|
36
components/language/micropython/tests/float/float_parse.py
Normal file
36
components/language/micropython/tests/float/float_parse.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# test parsing of floats
|
||||
|
||||
inf = float("inf")
|
||||
|
||||
# it shouldn't matter where the decimal point is if the exponent balances the value
|
||||
print(float("1234") - float("0.1234e4"))
|
||||
print(float("1.015625") - float("1015625e-6"))
|
||||
|
||||
# very large integer part with a very negative exponent should cancel out
|
||||
print("%.4e" % float("9" * 60 + "e-60"))
|
||||
print("%.4e" % float("9" * 60 + "e-40"))
|
||||
|
||||
# many fractional digits
|
||||
print(float("." + "9" * 70))
|
||||
print(float("." + "9" * 70 + "e20"))
|
||||
print(float("." + "9" * 70 + "e-50") == float("1e-50"))
|
||||
|
||||
# tiny fraction with large exponent
|
||||
print(float("." + "0" * 60 + "1e10") == float("1e-51"))
|
||||
print(float("." + "0" * 60 + "9e25") == float("9e-36"))
|
||||
print(float("." + "0" * 60 + "9e40") == float("9e-21"))
|
||||
|
||||
# ensure that accuracy is retained when value is close to a subnormal
|
||||
print(float("1.00000000000000000000e-37"))
|
||||
print(float("10.0000000000000000000e-38"))
|
||||
print(float("100.000000000000000000e-39"))
|
||||
|
||||
# very large exponent literal
|
||||
print(float("1e4294967301"))
|
||||
print(float("1e-4294967301"))
|
||||
print(float("1e18446744073709551621"))
|
||||
print(float("1e-18446744073709551621"))
|
||||
|
||||
# check small decimals are as close to their true value as possible
|
||||
for n in range(1, 10):
|
||||
print(float("0.%u" % n) == n / 10)
|
@@ -0,0 +1,21 @@
|
||||
# test parsing of floats, requiring double-precision
|
||||
|
||||
# very large integer part with a very negative exponent should cancel out
|
||||
print(float("9" * 400 + "e-100"))
|
||||
print(float("9" * 400 + "e-200"))
|
||||
print(float("9" * 400 + "e-400"))
|
||||
|
||||
# many fractional digits
|
||||
print(float("." + "9" * 400))
|
||||
print(float("." + "9" * 400 + "e100"))
|
||||
print(float("." + "9" * 400 + "e-100"))
|
||||
|
||||
# tiny fraction with large exponent
|
||||
print("%.14e" % float("." + "0" * 400 + "9e100"))
|
||||
print("%.14e" % float("." + "0" * 400 + "9e200"))
|
||||
print("%.14e" % float("." + "0" * 400 + "9e400"))
|
||||
|
||||
# ensure that accuracy is retained when value is close to a subnormal
|
||||
print(float("1.00000000000000000000e-307"))
|
||||
print(float("10.0000000000000000000e-308"))
|
||||
print(float("100.000000000000000000e-309"))
|
17
components/language/micropython/tests/float/float_struct.py
Normal file
17
components/language/micropython/tests/float/float_struct.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# test struct package with floats
|
||||
try:
|
||||
try:
|
||||
import ustruct as struct
|
||||
except:
|
||||
import struct
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
i = 1.0 + 1 / 2
|
||||
# TODO: it looks like '=' format modifier is not yet supported
|
||||
# for fmt in ('f', 'd', '>f', '>d', '<f', '<d', '=f', '=d'):
|
||||
for fmt in ("f", "d", ">f", ">d", "<f", "<d"):
|
||||
x = struct.pack(fmt, i)
|
||||
v = struct.unpack(fmt, x)[0]
|
||||
print("%2s: %.17f - %s" % (fmt, v, (i == v) and "passed" or "failed"))
|
20
components/language/micropython/tests/float/inf_nan_arith.py
Normal file
20
components/language/micropython/tests/float/inf_nan_arith.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Test behaviour of inf and nan in basic float operations
|
||||
|
||||
inf = float("inf")
|
||||
nan = float("nan")
|
||||
|
||||
values = (-2, -1, 0, 1, 2, inf, nan)
|
||||
|
||||
for x in values:
|
||||
for y in values:
|
||||
print(x, y)
|
||||
print(" + - *", x + y, x - y, x * y)
|
||||
try:
|
||||
print(" /", x / y)
|
||||
except ZeroDivisionError:
|
||||
print(" / ZeroDivisionError")
|
||||
try:
|
||||
print(" ** pow", x**y, pow(x, y))
|
||||
except ZeroDivisionError:
|
||||
print(" ** pow ZeroDivisionError")
|
||||
print(" == != < <= > >=", x == y, x != y, x < y, x <= y, x > y, x >= y)
|
28
components/language/micropython/tests/float/int_big_float.py
Normal file
28
components/language/micropython/tests/float/int_big_float.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# test bignum operation with float/complex
|
||||
|
||||
i = 1 << 65
|
||||
|
||||
# convert bignum to float on rhs
|
||||
print("%.5g" % (2.0 * i))
|
||||
|
||||
# negative bignum as float
|
||||
print("%.5g" % float(-i))
|
||||
|
||||
# this should convert to float
|
||||
print("%.5g" % (i / 5))
|
||||
|
||||
# these should delegate to float
|
||||
print("%.5g" % (i * 1.2))
|
||||
print("%.5g" % (i / 1.2))
|
||||
|
||||
# this should delegate to complex
|
||||
print("%.5g" % (i * 1.2j).imag)
|
||||
|
||||
# negative power should produce float
|
||||
print("%.5g" % (i**-1))
|
||||
print("%.5g" % ((2 + i - i) ** -3))
|
||||
|
||||
try:
|
||||
i / 0
|
||||
except ZeroDivisionError:
|
||||
print("ZeroDivisionError")
|
@@ -0,0 +1,9 @@
|
||||
try:
|
||||
1 / 0
|
||||
except ZeroDivisionError:
|
||||
print("ZeroDivisionError")
|
||||
|
||||
try:
|
||||
0**-1
|
||||
except ZeroDivisionError:
|
||||
print("ZeroDivisionError")
|
8
components/language/micropython/tests/float/int_power.py
Normal file
8
components/language/micropython/tests/float/int_power.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# negative power should produce float
|
||||
|
||||
x = 2
|
||||
print(x**-2)
|
||||
|
||||
x = 3
|
||||
x **= -2
|
||||
print("%.5f" % x)
|
6
components/language/micropython/tests/float/lexer.py
Normal file
6
components/language/micropython/tests/float/lexer.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# since black code formatter does not allow leading decimal point with nothing
|
||||
# before it, we need to test it explicitly
|
||||
|
||||
# fmt: off
|
||||
print(.1)
|
||||
# fmt: on
|
@@ -0,0 +1,8 @@
|
||||
x = [1, 2]
|
||||
|
||||
print(x[1])
|
||||
|
||||
try:
|
||||
print(x[1.0])
|
||||
except TypeError:
|
||||
print("TypeError")
|
@@ -0,0 +1,11 @@
|
||||
# Tests various constants of the math module.
|
||||
try:
|
||||
import math
|
||||
from math import exp, cos
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
print(math.e == exp(1.0))
|
||||
|
||||
print(cos(math.pi))
|
@@ -0,0 +1,17 @@
|
||||
# Tests constants of the math module available only with MICROPY_PY_MATH_CONSTANTS.
|
||||
try:
|
||||
import math
|
||||
from math import isnan
|
||||
|
||||
math.tau
|
||||
except (ImportError, AttributeError):
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
print(math.tau == 2.0 * math.pi)
|
||||
|
||||
print(math.inf == float("inf"))
|
||||
print(-math.inf == -float("inf"))
|
||||
|
||||
print(isnan(math.nan))
|
||||
print(isnan(-math.nan))
|
51
components/language/micropython/tests/float/math_domain.py
Normal file
51
components/language/micropython/tests/float/math_domain.py
Normal file
@@ -0,0 +1,51 @@
|
||||
# Tests domain errors in math functions
|
||||
|
||||
try:
|
||||
import math
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
inf = float("inf")
|
||||
nan = float("nan")
|
||||
|
||||
# single argument functions
|
||||
for name, f, args in (
|
||||
("fabs", math.fabs, ()),
|
||||
("ceil", math.ceil, ()),
|
||||
("floor", math.floor, ()),
|
||||
("trunc", math.trunc, ()),
|
||||
("sqrt", math.sqrt, (-1, 0)),
|
||||
("exp", math.exp, ()),
|
||||
("sin", math.sin, ()),
|
||||
("cos", math.cos, ()),
|
||||
("tan", math.tan, ()),
|
||||
("asin", math.asin, (-1.1, 1, 1.1)),
|
||||
("acos", math.acos, (-1.1, 1, 1.1)),
|
||||
("atan", math.atan, ()),
|
||||
("ldexp", lambda x: math.ldexp(x, 0), ()),
|
||||
("radians", math.radians, ()),
|
||||
("degrees", math.degrees, ()),
|
||||
):
|
||||
for x in args + (inf, nan):
|
||||
try:
|
||||
ans = f(x)
|
||||
print("%.4f" % ans)
|
||||
except ValueError:
|
||||
print(name, "ValueError")
|
||||
except OverflowError:
|
||||
print(name, "OverflowError")
|
||||
|
||||
# double argument functions
|
||||
for name, f, args in (
|
||||
("pow", math.pow, ((0, 2), (-1, 2), (0, -1), (-1, 2.3), (nan, 0), (1, nan))),
|
||||
("fmod", math.fmod, ((1.2, inf), (1.2, -inf), (1.2, 0), (inf, 1.2))),
|
||||
("atan2", math.atan2, ((0, 0), (-inf, inf), (-inf, -inf), (inf, -inf))),
|
||||
("copysign", math.copysign, ()),
|
||||
):
|
||||
for x in args + ((0, inf), (inf, 0), (inf, inf), (inf, nan), (nan, inf), (nan, nan)):
|
||||
try:
|
||||
ans = f(*x)
|
||||
print("%.4f" % ans)
|
||||
except ValueError:
|
||||
print(name, "ValueError")
|
@@ -0,0 +1,37 @@
|
||||
# Tests domain errors in special math functions
|
||||
|
||||
try:
|
||||
import math
|
||||
|
||||
math.erf
|
||||
except (ImportError, AttributeError):
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
inf = float("inf")
|
||||
nan = float("nan")
|
||||
|
||||
# single argument functions
|
||||
for name, f, args in (
|
||||
("expm1", math.exp, ()),
|
||||
("log2", math.log2, (-1, 0)),
|
||||
("log10", math.log10, (-1, 0)),
|
||||
("sinh", math.sinh, ()),
|
||||
("cosh", math.cosh, ()),
|
||||
("tanh", math.tanh, ()),
|
||||
("asinh", math.asinh, ()),
|
||||
("acosh", math.acosh, (-1, 0.9, 1)),
|
||||
("atanh", math.atanh, (-1, 1)),
|
||||
("erf", math.erf, ()),
|
||||
("erfc", math.erfc, ()),
|
||||
("gamma", math.gamma, (-2, -1, 0, 1)),
|
||||
("lgamma", math.lgamma, (-2, -1, 0, 1)),
|
||||
):
|
||||
for x in args + (inf, -inf, nan):
|
||||
try:
|
||||
ans = f(x)
|
||||
print("%.4f" % ans)
|
||||
except ValueError:
|
||||
print(name, "ValueError")
|
||||
except OverflowError:
|
||||
print(name, "OverflowError")
|
@@ -0,0 +1,15 @@
|
||||
try:
|
||||
import math
|
||||
|
||||
math.factorial
|
||||
except (ImportError, AttributeError):
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
for fun in (math.factorial,):
|
||||
for x in range(-1, 30):
|
||||
try:
|
||||
print("%d" % fun(x))
|
||||
except ValueError as e:
|
||||
print("ValueError")
|
91
components/language/micropython/tests/float/math_fun.py
Normal file
91
components/language/micropython/tests/float/math_fun.py
Normal file
@@ -0,0 +1,91 @@
|
||||
# Tests the functions imported from math
|
||||
|
||||
try:
|
||||
from math import *
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
test_values = [-100.0, -1.23456, -1, -0.5, 0.0, 0.5, 1.23456, 100.0]
|
||||
test_values_small = [
|
||||
-10.0,
|
||||
-1.23456,
|
||||
-1,
|
||||
-0.5,
|
||||
0.0,
|
||||
0.5,
|
||||
1.23456,
|
||||
10.0,
|
||||
] # so we don't overflow 32-bit precision
|
||||
unit_range_test_values = [-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0]
|
||||
|
||||
functions = [
|
||||
("sqrt", sqrt, test_values),
|
||||
("exp", exp, test_values_small),
|
||||
("log", log, test_values),
|
||||
("cos", cos, test_values),
|
||||
("sin", sin, test_values),
|
||||
("tan", tan, test_values),
|
||||
("acos", acos, unit_range_test_values),
|
||||
("asin", asin, unit_range_test_values),
|
||||
("atan", atan, test_values),
|
||||
("ceil", ceil, test_values),
|
||||
("fabs", fabs, test_values),
|
||||
("floor", floor, test_values),
|
||||
("trunc", trunc, test_values),
|
||||
("radians", radians, test_values),
|
||||
("degrees", degrees, test_values),
|
||||
]
|
||||
|
||||
for function_name, function, test_vals in functions:
|
||||
print(function_name)
|
||||
for value in test_vals:
|
||||
try:
|
||||
print("{:.5g}".format(function(value)))
|
||||
except ValueError as e:
|
||||
print(str(e))
|
||||
|
||||
tuple_functions = [
|
||||
("frexp", frexp, test_values),
|
||||
("modf", modf, test_values),
|
||||
]
|
||||
|
||||
for function_name, function, test_vals in tuple_functions:
|
||||
print(function_name)
|
||||
for value in test_vals:
|
||||
x, y = function(value)
|
||||
print("{:.5g} {:.5g}".format(x, y))
|
||||
|
||||
binary_functions = [
|
||||
(
|
||||
"copysign",
|
||||
copysign,
|
||||
[(23.0, 42.0), (-23.0, 42.0), (23.0, -42.0), (-23.0, -42.0), (1.0, 0.0), (1.0, -0.0)],
|
||||
),
|
||||
("pow", pow, ((1.0, 0.0), (0.0, 1.0), (2.0, 0.5), (-3.0, 5.0), (-3.0, -4.0))),
|
||||
("atan2", atan2, ((1.0, 0.0), (0.0, 1.0), (2.0, 0.5), (-3.0, 5.0), (-3.0, -4.0))),
|
||||
("fmod", fmod, ((1.0, 1.0), (0.0, 1.0), (2.0, 0.5), (-3.0, 5.0), (-3.0, -4.0))),
|
||||
("ldexp", ldexp, ((1.0, 0), (0.0, 1), (2.0, 2), (3.0, -2), (-3.0, -4))),
|
||||
(
|
||||
"log",
|
||||
log,
|
||||
(
|
||||
(2.0, 2.0),
|
||||
(3.0, 2.0),
|
||||
(4.0, 5.0),
|
||||
(0.0, 1.0),
|
||||
(1.0, 0.0),
|
||||
(-1.0, 1.0),
|
||||
(1.0, -1.0),
|
||||
(2.0, 1.0),
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
for function_name, function, test_vals in binary_functions:
|
||||
print(function_name)
|
||||
for value1, value2 in test_vals:
|
||||
try:
|
||||
print("{:.5g}".format(function(value1, value2)))
|
||||
except (ValueError, ZeroDivisionError) as e:
|
||||
print(type(e))
|
15
components/language/micropython/tests/float/math_fun_bool.py
Normal file
15
components/language/micropython/tests/float/math_fun_bool.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# Test the bool functions from math
|
||||
|
||||
try:
|
||||
from math import isfinite, isnan, isinf
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
test_values = [1, 0, -1, 1.0, 0.0, -1.0, float("NaN"), float("Inf"), -float("NaN"), -float("Inf")]
|
||||
|
||||
functions = [isfinite, isnan, isinf]
|
||||
|
||||
for val in test_values:
|
||||
for f in functions:
|
||||
print(f(val))
|
14
components/language/micropython/tests/float/math_fun_int.py
Normal file
14
components/language/micropython/tests/float/math_fun_int.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# test the math functions that return ints
|
||||
|
||||
try:
|
||||
import math
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
for fun in (math.ceil, math.floor, math.trunc):
|
||||
for x in (-1.6, -0.2, 0, 0.6, 1.4, float("inf"), float("nan")):
|
||||
try:
|
||||
print(fun(x))
|
||||
except (ValueError, OverflowError) as e:
|
||||
print(type(e))
|
@@ -0,0 +1,11 @@
|
||||
# test the math functions that return ints, with very large results
|
||||
|
||||
try:
|
||||
import math
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
for fun in (math.ceil, math.floor, math.trunc):
|
||||
for x in (-1e25, 1e25):
|
||||
print("%.3g" % fun(x))
|
@@ -0,0 +1,52 @@
|
||||
# test the special functions imported from math
|
||||
|
||||
try:
|
||||
from math import *
|
||||
|
||||
erf
|
||||
except (ImportError, NameError):
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
test_values = [
|
||||
-8.0,
|
||||
-2.5,
|
||||
-1,
|
||||
-0.5,
|
||||
0.0,
|
||||
0.5,
|
||||
2.5,
|
||||
8.0,
|
||||
]
|
||||
pos_test_values = [
|
||||
0.001,
|
||||
0.1,
|
||||
0.5,
|
||||
1.0,
|
||||
1.5,
|
||||
10.0,
|
||||
]
|
||||
|
||||
functions = [
|
||||
("expm1", expm1, test_values),
|
||||
("log2", log2, test_values),
|
||||
("log10", log10, test_values),
|
||||
("cosh", cosh, test_values),
|
||||
("sinh", sinh, test_values),
|
||||
("tanh", tanh, [-1e6, -100] + test_values + [100, 1e6]),
|
||||
("acosh", acosh, [1.0, 5.0, 1.0]),
|
||||
("asinh", asinh, test_values),
|
||||
("atanh", atanh, [-0.99, -0.5, 0.0, 0.5, 0.99]),
|
||||
("erf", erf, test_values),
|
||||
("erfc", erfc, test_values),
|
||||
("gamma", gamma, pos_test_values),
|
||||
("lgamma", lgamma, pos_test_values + [50.0, 100.0]),
|
||||
]
|
||||
|
||||
for function_name, function, test_vals in functions:
|
||||
print(function_name)
|
||||
for value in test_vals:
|
||||
try:
|
||||
print("{:.4g}".format(function(value)))
|
||||
except ValueError as e:
|
||||
print(str(e))
|
50
components/language/micropython/tests/float/math_isclose.py
Normal file
50
components/language/micropython/tests/float/math_isclose.py
Normal file
@@ -0,0 +1,50 @@
|
||||
# test math.isclose (appeared in Python 3.5)
|
||||
|
||||
try:
|
||||
from math import isclose
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
def test(a, b, **kwargs):
|
||||
print(isclose(a, b, **kwargs))
|
||||
|
||||
|
||||
def test_combinations(a, b, **kwargs):
|
||||
test(a, a, **kwargs)
|
||||
test(a, b, **kwargs)
|
||||
test(b, a, **kwargs)
|
||||
test(b, b, **kwargs)
|
||||
|
||||
|
||||
# Special numbers
|
||||
test_combinations(float("nan"), 1)
|
||||
test_combinations(float("inf"), 1)
|
||||
test_combinations(float("-inf"), 1)
|
||||
|
||||
# Equality
|
||||
test(1.0, 1.0, rel_tol=0.0, abs_tol=0.0)
|
||||
test(2.35e-100, 2.35e-100, rel_tol=0.0, abs_tol=0.0)
|
||||
test(2.1234e100, 2.1234e100, rel_tol=0.0, abs_tol=0.0)
|
||||
|
||||
# Relative tolerance
|
||||
test(1000.0, 1001.0, rel_tol=1e-3)
|
||||
test(1000.0, 1001.0, rel_tol=1e-4)
|
||||
test(1000, 1001, rel_tol=1e-3)
|
||||
test(1000, 1001, rel_tol=1e-4)
|
||||
test_combinations(0, 1, rel_tol=1.0)
|
||||
|
||||
# Absolute tolerance
|
||||
test(0.0, 1e-10, abs_tol=1e-10, rel_tol=0.1)
|
||||
test(0.0, 1e-10, abs_tol=0.0, rel_tol=0.1)
|
||||
|
||||
# Bad parameters
|
||||
try:
|
||||
isclose(0, 0, abs_tol=-1)
|
||||
except ValueError:
|
||||
print("ValueError")
|
||||
try:
|
||||
isclose(0, 0, rel_tol=-1)
|
||||
except ValueError:
|
||||
print("ValueError")
|
@@ -0,0 +1,27 @@
|
||||
False
|
||||
False
|
||||
False
|
||||
True
|
||||
True
|
||||
False
|
||||
False
|
||||
True
|
||||
True
|
||||
False
|
||||
False
|
||||
True
|
||||
True
|
||||
True
|
||||
True
|
||||
True
|
||||
False
|
||||
True
|
||||
False
|
||||
True
|
||||
True
|
||||
True
|
||||
True
|
||||
True
|
||||
False
|
||||
ValueError
|
||||
ValueError
|
10
components/language/micropython/tests/float/python36.py
Normal file
10
components/language/micropython/tests/float/python36.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# tests for things that only Python 3.6 supports, needing floats
|
||||
|
||||
# underscores in numeric literals
|
||||
print(1_000.1_8)
|
||||
print("%.2g" % 1e1_2)
|
||||
|
||||
# underscore supported by int/float constructors
|
||||
print(float("1_2_3"))
|
||||
print(float("1_2_3.4"))
|
||||
print("%.2g" % float("1e1_3"))
|
@@ -0,0 +1,5 @@
|
||||
1000.18
|
||||
1e+12
|
||||
123.0
|
||||
123.4
|
||||
1e+13
|
45
components/language/micropython/tests/float/string_format.py
Normal file
45
components/language/micropython/tests/float/string_format.py
Normal file
@@ -0,0 +1,45 @@
|
||||
def test(fmt, *args):
|
||||
print("{:8s}".format(fmt) + ">" + fmt.format(*args) + "<")
|
||||
|
||||
|
||||
test("{:10.4}", 123.456)
|
||||
test("{:10.4e}", 123.456)
|
||||
test("{:10.4e}", -123.456)
|
||||
test("{:10.4f}", 123.456)
|
||||
test("{:10.4f}", -123.456)
|
||||
test("{:10.4g}", 123.456)
|
||||
test("{:10.4g}", -123.456)
|
||||
test("{:10.4n}", 123.456)
|
||||
test("{:e}", 100)
|
||||
test("{:f}", 200)
|
||||
test("{:g}", 300)
|
||||
|
||||
test("{:10.4E}", 123.456)
|
||||
test("{:10.4E}", -123.456)
|
||||
test("{:10.4F}", 123.456)
|
||||
test("{:10.4F}", -123.456)
|
||||
test("{:10.4G}", 123.456)
|
||||
test("{:10.4G}", -123.456)
|
||||
|
||||
test("{:06e}", float("inf"))
|
||||
test("{:06e}", float("-inf"))
|
||||
test("{:06e}", float("nan"))
|
||||
|
||||
test("{:f}", False)
|
||||
test("{:f}", True)
|
||||
|
||||
# The following fails right now
|
||||
# test("{:10.1}", 0.0)
|
||||
|
||||
print("%.0f" % (1.750000 % 0.08333333333))
|
||||
# Below isn't compatible with single-precision float
|
||||
# print("%.1f" % (1.750000 % 0.08333333333))
|
||||
# print("%.2f" % (1.750000 % 0.08333333333))
|
||||
# print("%.12f" % (1.750000 % 0.08333333333))
|
||||
|
||||
# tests for errors in format string
|
||||
|
||||
try:
|
||||
"{:10.1b}".format(0.0)
|
||||
except ValueError:
|
||||
print("ValueError")
|
182
components/language/micropython/tests/float/string_format2.py
Normal file
182
components/language/micropython/tests/float/string_format2.py
Normal file
@@ -0,0 +1,182 @@
|
||||
# Change the following to True to get a much more comprehensive set of tests
|
||||
# to run, albeit, which take considerably longer.
|
||||
|
||||
full_tests = False
|
||||
|
||||
|
||||
def test(fmt, *args):
|
||||
print("{:8s}".format(fmt) + ">" + fmt.format(*args) + "<")
|
||||
|
||||
|
||||
def test_fmt(conv, fill, alignment, sign, prefix, width, precision, type, arg):
|
||||
fmt = "{"
|
||||
if conv:
|
||||
fmt += "!"
|
||||
fmt += conv
|
||||
fmt += ":"
|
||||
if alignment:
|
||||
fmt += fill
|
||||
fmt += alignment
|
||||
fmt += sign
|
||||
fmt += prefix
|
||||
fmt += width
|
||||
if precision:
|
||||
fmt += "."
|
||||
fmt += precision
|
||||
fmt += type
|
||||
fmt += "}"
|
||||
test(fmt, arg)
|
||||
if fill == "0" and alignment == "=":
|
||||
fmt = "{:"
|
||||
fmt += sign
|
||||
fmt += prefix
|
||||
fmt += width
|
||||
if precision:
|
||||
fmt += "."
|
||||
fmt += precision
|
||||
fmt += type
|
||||
fmt += "}"
|
||||
test(fmt, arg)
|
||||
|
||||
|
||||
eg_nums = (
|
||||
0.0,
|
||||
-0.0,
|
||||
0.1,
|
||||
1.234,
|
||||
12.3459,
|
||||
1.23456789,
|
||||
123456789.0,
|
||||
-0.0,
|
||||
-0.1,
|
||||
-1.234,
|
||||
-12.3459,
|
||||
1e4,
|
||||
1e-4,
|
||||
1e5,
|
||||
1e-5,
|
||||
1e6,
|
||||
1e-6,
|
||||
1e10,
|
||||
1e37,
|
||||
-1e37,
|
||||
1e-37,
|
||||
-1e-37,
|
||||
1.23456e8,
|
||||
1.23456e7,
|
||||
1.23456e6,
|
||||
1.23456e5,
|
||||
1.23456e4,
|
||||
1.23456e3,
|
||||
1.23456e2,
|
||||
1.23456e1,
|
||||
1.23456e0,
|
||||
1.23456e-1,
|
||||
1.23456e-2,
|
||||
1.23456e-3,
|
||||
1.23456e-4,
|
||||
1.23456e-5,
|
||||
1.23456e-6,
|
||||
1.23456e-7,
|
||||
1.23456e-8,
|
||||
-1.23456e8,
|
||||
-1.23456e7,
|
||||
-1.23456e6,
|
||||
-1.23456e5,
|
||||
-1.23456e4,
|
||||
-1.23456e3,
|
||||
-1.23456e2,
|
||||
-1.23456e1,
|
||||
-1.23456e0,
|
||||
-1.23456e-1,
|
||||
-1.23456e-2,
|
||||
-1.23456e-3,
|
||||
-1.23456e-4,
|
||||
-1.23456e-5,
|
||||
-1.23456e-6,
|
||||
-1.23456e-7,
|
||||
-1.23456e-8,
|
||||
)
|
||||
|
||||
if full_tests:
|
||||
for type in ("e", "E", "g", "G", "n"):
|
||||
for width in ("", "4", "6", "8", "10"):
|
||||
for alignment in ("", "<", ">", "=", "^"):
|
||||
for fill in ("", "@", "0", " "):
|
||||
for sign in ("", "+", "-", " "):
|
||||
for prec in ("", "1", "3", "6"):
|
||||
for num in eg_nums:
|
||||
test_fmt("", fill, alignment, sign, "", width, prec, type, num)
|
||||
|
||||
# Note: We use 1.23459 rather than 1.2345 because '{:3f}'.format(1.2345)
|
||||
# rounds differently than print("%.3f", 1.2345);
|
||||
|
||||
f_nums = (
|
||||
0.0,
|
||||
-0.0,
|
||||
0.0001,
|
||||
0.001,
|
||||
0.01,
|
||||
0.1,
|
||||
1.0,
|
||||
10.0,
|
||||
0.0012,
|
||||
0.0123,
|
||||
0.1234,
|
||||
1.23459,
|
||||
12.3456,
|
||||
-0.0001,
|
||||
-0.001,
|
||||
-0.01,
|
||||
-0.1,
|
||||
-1.0,
|
||||
-10.0,
|
||||
-0.0012,
|
||||
-0.0123,
|
||||
-0.1234,
|
||||
-1.23459,
|
||||
-12.3456,
|
||||
)
|
||||
|
||||
if full_tests:
|
||||
for type in ("f", "F"):
|
||||
for width in ("", "4", "6", "8", "10"):
|
||||
for alignment in ("", "<", ">", "=", "^"):
|
||||
for fill in ("", " ", "0", "@"):
|
||||
for sign in ("", "+", "-", " "):
|
||||
# An empty precision defaults to 6, but when uPy is
|
||||
# configured to use a float, we can only use a
|
||||
# precision of 6 with numbers less than 10 and still
|
||||
# get results that compare to CPython (which uses
|
||||
# long doubles).
|
||||
for prec in ("1", "2", "3"):
|
||||
for num in f_nums:
|
||||
test_fmt("", fill, alignment, sign, "", width, prec, type, num)
|
||||
for num in int_nums2:
|
||||
test_fmt("", fill, alignment, sign, "", width, "", type, num)
|
||||
|
||||
pct_nums1 = (0.1, 0.58, 0.99, -0.1, -0.58, -0.99)
|
||||
pct_nums2 = (True, False, 1, 0, -1)
|
||||
|
||||
if full_tests:
|
||||
type = "%"
|
||||
for width in ("", "4", "6", "8", "10"):
|
||||
for alignment in ("", "<", ">", "=", "^"):
|
||||
for fill in ("", " ", "0", "@"):
|
||||
for sign in ("", "+", "-", " "):
|
||||
# An empty precision defaults to 6, but when uPy is
|
||||
# configured to use a float, we can only use a
|
||||
# precision of 6 with numbers less than 10 and still
|
||||
# get results that compare to CPython (which uses
|
||||
# long doubles).
|
||||
for prec in ("1", "2", "3"):
|
||||
for num in pct_nums1:
|
||||
test_fmt("", fill, alignment, sign, "", width, prec, type, num)
|
||||
for num in pct_nums2:
|
||||
test_fmt("", fill, alignment, sign, "", width, "", type, num)
|
||||
else:
|
||||
for num in pct_nums1:
|
||||
test_fmt("", "", "", "", "", "", "1", "%", num)
|
||||
|
||||
# We don't currently test a type of '' with floats (see the detailed comment
|
||||
# in objstr.c)
|
@@ -0,0 +1,42 @@
|
||||
def test(fmt, *args):
|
||||
print("{:8s}".format(fmt) + ">" + fmt.format(*args) + "<")
|
||||
|
||||
|
||||
test("{:10.4}", 123.456)
|
||||
test("{:10.4e}", 123.456)
|
||||
test("{:10.4e}", -123.456)
|
||||
# test("{:10.4f}", 123.456)
|
||||
# test("{:10.4f}", -123.456)
|
||||
test("{:10.4g}", 123.456)
|
||||
test("{:10.4g}", -123.456)
|
||||
test("{:10.4n}", 123.456)
|
||||
test("{:e}", 100)
|
||||
test("{:f}", 200)
|
||||
test("{:g}", 300)
|
||||
|
||||
test("{:10.4E}", 123.456)
|
||||
test("{:10.4E}", -123.456)
|
||||
# test("{:10.4F}", 123.456)
|
||||
# test("{:10.4F}", -123.456)
|
||||
test("{:10.4G}", 123.456)
|
||||
test("{:10.4G}", -123.456)
|
||||
|
||||
test("{:06e}", float("inf"))
|
||||
test("{:06e}", float("-inf"))
|
||||
test("{:06e}", float("nan"))
|
||||
|
||||
# The following fails right now
|
||||
# test("{:10.1}", 0.0)
|
||||
|
||||
print("%.0f" % (1.750000 % 0.08333333333))
|
||||
# Below isn't compatible with single-precision float
|
||||
# print("%.1f" % (1.750000 % 0.08333333333))
|
||||
# print("%.2f" % (1.750000 % 0.08333333333))
|
||||
# print("%.12f" % (1.750000 % 0.08333333333))
|
||||
|
||||
# tests for errors in format string
|
||||
|
||||
try:
|
||||
"{:10.1b}".format(0.0)
|
||||
except ValueError:
|
||||
print("ValueError")
|
@@ -0,0 +1,49 @@
|
||||
print("%s" % 1.0)
|
||||
print("%r" % 1.0)
|
||||
|
||||
print("%d" % 1.0)
|
||||
print("%i" % 1.0)
|
||||
print("%u" % 1.0)
|
||||
|
||||
# these 3 have different behaviour in Python 3.x versions
|
||||
# uPy raises a TypeError, following Python 3.5 (earlier versions don't)
|
||||
# print("%x" % 18.0)
|
||||
# print("%o" % 18.0)
|
||||
# print("%X" % 18.0)
|
||||
|
||||
print("%e" % 1.23456)
|
||||
print("%E" % 1.23456)
|
||||
print("%f" % 1.23456)
|
||||
print("%F" % 1.23456)
|
||||
print("%g" % 1.23456)
|
||||
print("%G" % 1.23456)
|
||||
|
||||
print("%06e" % float("inf"))
|
||||
print("%06e" % float("-inf"))
|
||||
print("%06e" % float("nan"))
|
||||
|
||||
print("%02.3d" % 123) # prec > width
|
||||
print("%+f %+f" % (1.23, -1.23)) # float sign
|
||||
print("% f % f" % (1.23, -1.23)) # float space sign
|
||||
print("%0f" % -1.23) # negative number with 0 padding
|
||||
|
||||
# numbers with large negative exponents
|
||||
print("%f" % 1e-10)
|
||||
print("%f" % 1e-20)
|
||||
print("%f" % 1e-50)
|
||||
print("%f" % 1e-100)
|
||||
print("%f" % 1e-300)
|
||||
|
||||
# large decimal precision should be truncated and not overflow buffer
|
||||
# the output depends on the FP calculation so only first 2 digits are printed
|
||||
# (the 'g' with small e are printed using 'f' style, so need to be checked)
|
||||
print(("%.40f" % 1e-300)[:2])
|
||||
print(("%.40g" % 1e-1)[:2])
|
||||
print(("%.40g" % 1e-2)[:2])
|
||||
print(("%.40g" % 1e-3)[:2])
|
||||
print(("%.40g" % 1e-4)[:2])
|
||||
|
||||
print("%.0g" % 1) # 0 precision 'g'
|
||||
|
||||
print("%.1e" % 9.99) # round up with positive exponent
|
||||
print("%.1e" % 0.999) # round up with negative exponent
|
@@ -0,0 +1,26 @@
|
||||
# test formatting floats with large precision, that it doesn't overflow the buffer
|
||||
|
||||
|
||||
def test(num, num_str):
|
||||
if num == float("inf") or num == 0.0 and num_str != "0.0":
|
||||
# skip numbers that overflow or underflow the FP precision
|
||||
return
|
||||
for kind in ("e", "f", "g"):
|
||||
# check precision either side of the size of the buffer (32 bytes)
|
||||
for prec in range(23, 36, 2):
|
||||
fmt = "%." + "%d" % prec + kind
|
||||
s = fmt % num
|
||||
check = abs(float(s) - num)
|
||||
if num > 1:
|
||||
check /= num
|
||||
if check > 1e-6:
|
||||
print("FAIL", num_str, fmt, s, len(s), check)
|
||||
|
||||
|
||||
# check pure zero
|
||||
test(0.0, "0.0")
|
||||
|
||||
# check some powers of 10, making sure to include exponents with 3 digits
|
||||
for e in range(-8, 8):
|
||||
num = pow(10, e)
|
||||
test(num, "1e%d" % e)
|
@@ -0,0 +1,23 @@
|
||||
# test formatting floats with large precision, that it doesn't overflow the buffer
|
||||
|
||||
|
||||
def test(num, num_str):
|
||||
if num == float("inf") or num == 0.0 and num_str != "0.0":
|
||||
# skip numbers that overflow or underflow the FP precision
|
||||
return
|
||||
for kind in ("e", "f", "g"):
|
||||
# check precision either side of the size of the buffer (32 bytes)
|
||||
for prec in range(23, 36, 2):
|
||||
fmt = "%." + "%d" % prec + kind
|
||||
s = fmt % num
|
||||
check = abs(float(s) - num)
|
||||
if num > 1:
|
||||
check /= num
|
||||
if check > 1e-6:
|
||||
print("FAIL", num_str, fmt, s, len(s), check)
|
||||
|
||||
|
||||
# check most powers of 10, making sure to include exponents with 3 digits
|
||||
for e in range(-101, 102):
|
||||
num = pow(10, e)
|
||||
test(num, "1e%d" % e)
|
@@ -0,0 +1,3 @@
|
||||
# uPy and CPython outputs differ for the following
|
||||
print("%.1g" % -9.9) # round up 'g' with '-' sign
|
||||
print("%.2g" % 99.9) # round up
|
@@ -0,0 +1,2 @@
|
||||
-10
|
||||
100
|
@@ -0,0 +1,7 @@
|
||||
# Test true-ish value handling
|
||||
|
||||
if not 0.0:
|
||||
print("float 0")
|
||||
|
||||
if not 0 + 0j:
|
||||
print("complex 0")
|
17
components/language/micropython/tests/float/types.py
Normal file
17
components/language/micropython/tests/float/types.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# float types
|
||||
|
||||
print(float)
|
||||
print(complex)
|
||||
|
||||
print(type(float()) == float)
|
||||
print(type(complex()) == complex)
|
||||
|
||||
print(type(0.0) == float)
|
||||
print(type(1j) == complex)
|
||||
|
||||
# hashing float types
|
||||
|
||||
d = dict()
|
||||
d[float] = complex
|
||||
d[complex] = float
|
||||
print(len(d))
|
Reference in New Issue
Block a user