@@ -171,6 +171,42 @@ MATH_FUN_1(lgamma, lgamma)
171171#endif
172172//TODO: fsum
173173
174+ #if MICROPY_PY_MATH_ISCLOSE
175+ STATIC mp_obj_t mp_math_isclose (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
176+ enum { ARG_a , ARG_b , ARG_rel_tol , ARG_abs_tol };
177+ static const mp_arg_t allowed_args [] = {
178+ {MP_QSTR_ , MP_ARG_REQUIRED | MP_ARG_OBJ },
179+ {MP_QSTR_ , MP_ARG_REQUIRED | MP_ARG_OBJ },
180+ {MP_QSTR_rel_tol , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL }},
181+ {MP_QSTR_abs_tol , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = MP_OBJ_NEW_SMALL_INT (0 )}},
182+ };
183+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
184+ mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
185+ const mp_float_t a = mp_obj_get_float (args [ARG_a ].u_obj );
186+ const mp_float_t b = mp_obj_get_float (args [ARG_b ].u_obj );
187+ const mp_float_t rel_tol = args [ARG_rel_tol ].u_obj == MP_OBJ_NULL
188+ ? (mp_float_t )1e-9 : mp_obj_get_float (args [ARG_rel_tol ].u_obj );
189+ const mp_float_t abs_tol = mp_obj_get_float (args [ARG_abs_tol ].u_obj );
190+ if (rel_tol < (mp_float_t )0.0 || abs_tol < (mp_float_t )0.0 ) {
191+ math_error ();
192+ }
193+ if (a == b ) {
194+ return mp_const_true ;
195+ }
196+ const mp_float_t difference = MICROPY_FLOAT_C_FUN (fabs )(a - b );
197+ if (isinf (difference )) { // Either a or b is inf
198+ return mp_const_false ;
199+ }
200+ if ((difference <= abs_tol ) ||
201+ (difference <= MICROPY_FLOAT_C_FUN (fabs )(rel_tol * a )) ||
202+ (difference <= MICROPY_FLOAT_C_FUN (fabs )(rel_tol * b ))) {
203+ return mp_const_true ;
204+ }
205+ return mp_const_false ;
206+ }
207+ MP_DEFINE_CONST_FUN_OBJ_KW (mp_math_isclose_obj , 2 , mp_math_isclose );
208+ #endif
209+
174210// Function that takes a variable number of arguments
175211
176212// log(x[, base])
@@ -335,6 +371,9 @@ STATIC const mp_rom_map_elem_t mp_module_math_globals_table[] = {
335371 { MP_ROM_QSTR (MP_QSTR_isfinite ), MP_ROM_PTR (& mp_math_isfinite_obj ) },
336372 { MP_ROM_QSTR (MP_QSTR_isinf ), MP_ROM_PTR (& mp_math_isinf_obj ) },
337373 { MP_ROM_QSTR (MP_QSTR_isnan ), MP_ROM_PTR (& mp_math_isnan_obj ) },
374+ #if MICROPY_PY_MATH_ISCLOSE
375+ { MP_ROM_QSTR (MP_QSTR_isclose ), MP_ROM_PTR (& mp_math_isclose_obj ) },
376+ #endif
338377 { MP_ROM_QSTR (MP_QSTR_trunc ), MP_ROM_PTR (& mp_math_trunc_obj ) },
339378 { MP_ROM_QSTR (MP_QSTR_radians ), MP_ROM_PTR (& mp_math_radians_obj ) },
340379 { MP_ROM_QSTR (MP_QSTR_degrees ), MP_ROM_PTR (& mp_math_degrees_obj ) },
0 commit comments