From 249b9c761d1fa0893740092df1d713ce0d91e856 Mon Sep 17 00:00:00 2001 From: Rachel Dowdall Date: Sat, 22 Mar 2014 14:39:33 +0000 Subject: [PATCH] Fixed broken math functions that return bool and added some more. --- py/builtinmath.c | 68 +++++++++++++++++++++++++++++------ py/qstrdefs.h | 12 +++++-- tests/basics/math-fun-bool.py | 12 +++++++ tests/basics/math-fun.py | 9 ++--- 4 files changed, 83 insertions(+), 18 deletions(-) create mode 100644 tests/basics/math-fun-bool.py diff --git a/py/builtinmath.c b/py/builtinmath.c index 59af5a021..818ac1d9d 100644 --- a/py/builtinmath.c +++ b/py/builtinmath.c @@ -9,6 +9,7 @@ #if MICROPY_ENABLE_FLOAT +//TODO: Change macros to check for overflow and raise OverflowError or RangeError #define MATH_FUN_1(py_name, c_name) \ mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj))); } \ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name); @@ -17,6 +18,10 @@ mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj, mp_obj_t y_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj), mp_obj_get_float(y_obj))); } \ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_math_## py_name ## _obj, mp_math_ ## py_name); +#define MATH_FUN_BOOL1(py_name, c_name) \ + mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return MP_BOOL(c_name(mp_obj_get_float(x_obj))); } \ + STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name); + STATIC const mp_obj_float_t mp_math_e_obj = {{&mp_type_float}, M_E}; STATIC const mp_obj_float_t mp_math_pi_obj = {{&mp_type_float}, M_PI}; @@ -45,13 +50,49 @@ MATH_FUN_2(copysign, copysign) MATH_FUN_1(fabs, fabs) MATH_FUN_1(floor, floor) //TODO: delegate to x.__floor__() if x is not a float MATH_FUN_2(fmod, fmod) -//MATH_FUN_1(frexp, frexp) -//MATH_FUN_1(isfinite, isfinite) -//MATH_FUN_1(isinf, isinf) -//MATH_FUN_1(isnan, isnan) +MATH_FUN_BOOL1(isfinite, isfinite) +MATH_FUN_BOOL1(isinf, isinf) +MATH_FUN_BOOL1(isnan, isnan) MATH_FUN_1(trunc, trunc) +MATH_FUN_2(ldexp, ldexp) +MATH_FUN_1(erf, erf) +MATH_FUN_1(erfc, erfc) +MATH_FUN_1(gamma, gamma) +MATH_FUN_1(lgamma, lgamma) +//TODO: factorial, fsum + +// Functions that return a tuple +mp_obj_t mp_math_frexp(mp_obj_t x_obj){ + machine_int_t int_exponent = 0; + mp_float_t significand = frexp(mp_obj_get_float(x_obj), &int_exponent); + mp_obj_t tuple[2]; + tuple[0] = mp_obj_new_float(significand); + tuple[1] = mp_obj_new_int(int_exponent); + return mp_obj_new_tuple(2, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_frexp_obj, mp_math_frexp); + +mp_obj_t mp_math_modf(mp_obj_t x_obj){ + mp_float_t int_part = 0.0; + mp_float_t fractional_part = modf(mp_obj_get_float(x_obj), &int_part); + mp_obj_t tuple[2]; + tuple[0] = mp_obj_new_float(fractional_part); + tuple[1] = mp_obj_new_float(int_part); + return mp_obj_new_tuple(2, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_modf_obj, mp_math_modf); + +// Angular conversions +mp_obj_t mp_math_radians(mp_obj_t x_obj){ + return mp_obj_new_float(mp_obj_get_float(x_obj) * M_PI / 180.0); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_radians_obj, mp_math_radians); + +mp_obj_t mp_math_degrees(mp_obj_t x_obj){ + return mp_obj_new_float(mp_obj_get_float(x_obj) * 180.0 / M_PI); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_degrees_obj, mp_math_degrees); -//TODO: factorial, fsum, frexp, ldexp, modf STATIC const mp_map_elem_t mp_module_math_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_math) }, @@ -81,12 +122,19 @@ STATIC const mp_map_elem_t mp_module_math_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_copysign), (mp_obj_t)&mp_math_copysign_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_fabs), (mp_obj_t)&mp_math_fabs_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_floor), (mp_obj_t)&mp_math_floor_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_fmod), (mp_obj_t)&mp_math_fmod_obj }, - //{ MP_OBJ_NEW_QSTR(MP_QSTR_frexp), (mp_obj_t)&mp_math_frexp_obj }, - //{ MP_OBJ_NEW_QSTR(MP_QSTR_isfinite), (mp_obj_t)&mp_math_isfinite_obj }, - //{ MP_OBJ_NEW_QSTR(MP_QSTR_isinf), (mp_obj_t)&mp_math_isinf_obj }, - //{ MP_OBJ_NEW_QSTR(MP_QSTR_isnan), (mp_obj_t)&mp_math_isnan_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_frexp), (mp_obj_t)&mp_math_frexp_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ldexp), (mp_obj_t)&mp_math_ldexp_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_modf), (mp_obj_t)&mp_math_modf_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_isfinite), (mp_obj_t)&mp_math_isfinite_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_isinf), (mp_obj_t)&mp_math_isinf_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_isnan), (mp_obj_t)&mp_math_isnan_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_trunc), (mp_obj_t)&mp_math_trunc_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_radians), (mp_obj_t)&mp_math_radians_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_degrees), (mp_obj_t)&mp_math_degrees_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_erf), (mp_obj_t)&mp_math_erf_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_erfc), (mp_obj_t)&mp_math_erfc_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_gamma), (mp_obj_t)&mp_math_gamma_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_lgamma), (mp_obj_t)&mp_math_lgamma_obj }, }; STATIC const mp_map_t mp_module_math_globals = { diff --git a/py/qstrdefs.h b/py/qstrdefs.h index 929fcaf06..0e0479e9b 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -145,13 +145,21 @@ Q(atan2) Q(ceil) Q(copysign) Q(fabs) -Q(floor) Q(fmod) -Q(frexp) +Q(floor) Q(isfinite) Q(isinf) Q(isnan) Q(trunc) +Q(modf) +Q(frexp) +Q(ldexp) +Q(degrees) +Q(radians) +Q(erf) +Q(erfc) +Q(gamma) +Q(lgamma) Q(mem_total) Q(mem_current) diff --git a/tests/basics/math-fun-bool.py b/tests/basics/math-fun-bool.py new file mode 100644 index 000000000..cf718d4b8 --- /dev/null +++ b/tests/basics/math-fun-bool.py @@ -0,0 +1,12 @@ +# Test the bool functions from math + +from math import isfinite, isnan, isinf + +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)) diff --git a/tests/basics/math-fun.py b/tests/basics/math-fun.py index f5ffbf40d..1301dc2a5 100644 --- a/tests/basics/math-fun.py +++ b/tests/basics/math-fun.py @@ -5,8 +5,6 @@ from math import * test_values = [-100., -1.23456, -1, -0.5, 0.0, 0.5, 1.23456, 100.] p_test_values = [0.1, 0.5, 1.23456] unit_range_test_values = [-1., -0.75, -0.5, -0.25, 0., 0.25, 0.5, 0.75, 1.] -#IEEE_test_values = [1, 0, float('NaN'), float('Inf'), -float('NaN'), -float('Inf')] -#TODO: float('NaN') functions = [(sqrt, p_test_values), (exp, test_values), @@ -30,7 +28,6 @@ functions = [(sqrt, p_test_values), (fabs, test_values), (floor, test_values), #(frexp, test_values), - #(isfinite, [1, 0, float('NaN'), float('Inf')]) (trunc, test_values) ] @@ -42,8 +39,8 @@ binary_functions = [(copysign, [(23., 42.), (-23., 42.), (23., -42.), (-23., -42.), (1., 0.0), (1., -0.0)]) ] -#for function, test_vals in binary_functions: -# for value1, value2 in test_vals: -# print("{:8.7f}".format(function(value1, value2))) +for function, test_vals in binary_functions: + for value1, value2 in test_vals: + print("{:8.7f}".format(function(value1, value2)))