mp_obj_t mp_builtin_abs(mp_obj_t o_in) { if (MP_OBJ_IS_SMALL_INT(o_in)) { mp_small_int_t val = MP_OBJ_SMALL_INT_VALUE(o_in); if (val < 0) { val = -val; } return MP_OBJ_NEW_SMALL_INT(val); #if MICROPY_ENABLE_FLOAT } else if (MP_OBJ_IS_TYPE(o_in, &mp_type_float)) { mp_float_t value = mp_obj_float_get(o_in); // TODO check for NaN etc if (value < 0) { return mp_obj_new_float(-value); } else { return o_in; } } else if (MP_OBJ_IS_TYPE(o_in, &mp_type_complex)) { mp_float_t real, imag; mp_obj_complex_get(o_in, &real, &imag); return mp_obj_new_float(MICROPY_FLOAT_C_FUN(sqrt)(real*real + imag*imag)); #endif } else { assert(0); return mp_const_none; } }
void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { if (arg == mp_const_false) { *real = 0; *imag = 0; } else if (arg == mp_const_true) { *real = 1; *imag = 0; } else if (MP_OBJ_IS_SMALL_INT(arg)) { *real = MP_OBJ_SMALL_INT_VALUE(arg); *imag = 0; } else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) { *real = mp_obj_int_as_float(arg); *imag = 0; } else if (mp_obj_is_float(arg)) { *real = mp_obj_float_get(arg); *imag = 0; } else if (MP_OBJ_IS_TYPE(arg, &mp_type_complex)) { mp_obj_complex_get(arg, real, imag); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "can't convert to complex")); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to complex", mp_obj_get_type_str(arg))); } } }
STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // TODO check n_kw == 0 switch (n_args) { case 0: return mp_obj_new_complex(0, 0); case 1: if (MP_OBJ_IS_STR(args[0])) { // a string, parse it uint l; const char *s = mp_obj_str_get_data(args[0], &l); return mp_parse_num_decimal(s, l, true, true); } else if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) { // a complex, just return it return args[0]; } else { // something else, try to cast it to a complex return mp_obj_new_complex(mp_obj_get_float(args[0]), 0); } case 2: { mp_float_t real, imag; if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) { mp_obj_complex_get(args[0], &real, &imag); } else { real = mp_obj_get_float(args[0]); imag = 0; } if (MP_OBJ_IS_TYPE(args[1], &mp_type_complex)) { mp_float_t real2, imag2; mp_obj_complex_get(args[1], &real2, &imag2); real -= imag2; imag += real2; } else { imag += mp_obj_get_float(args[1]); } return mp_obj_new_complex(real, imag); } default: nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "complex takes at most 2 arguments, %d given", n_args)); } }
STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { (void)type_in; mp_arg_check_num(n_args, n_kw, 0, 2, false); switch (n_args) { case 0: return mp_obj_new_complex(0, 0); case 1: if (MP_OBJ_IS_STR(args[0])) { // a string, parse it size_t l; const char *s = mp_obj_str_get_data(args[0], &l); return mp_parse_num_decimal(s, l, true, true, NULL); } else if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) { // a complex, just return it return args[0]; } else { // something else, try to cast it to a complex return mp_obj_new_complex(mp_obj_get_float(args[0]), 0); } case 2: default: { mp_float_t real, imag; if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) { mp_obj_complex_get(args[0], &real, &imag); } else { real = mp_obj_get_float(args[0]); imag = 0; } if (MP_OBJ_IS_TYPE(args[1], &mp_type_complex)) { mp_float_t real2, imag2; mp_obj_complex_get(args[1], &real2, &imag2); real -= imag2; imag += real2; } else { imag += mp_obj_get_float(args[1]); } return mp_obj_new_complex(real, imag); } } }
static mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // TODO check n_kw == 0 switch (n_args) { case 0: return mp_obj_new_complex(0, 0); case 1: // TODO allow string as first arg and parse it if (MP_OBJ_IS_TYPE(args[0], &complex_type)) { return args[0]; } else { return mp_obj_new_complex(mp_obj_get_float(args[0]), 0); } case 2: { mp_float_t real, imag; if (MP_OBJ_IS_TYPE(args[0], &complex_type)) { mp_obj_complex_get(args[0], &real, &imag); } else { real = mp_obj_get_float(args[0]); imag = 0; } if (MP_OBJ_IS_TYPE(args[1], &complex_type)) { mp_float_t real2, imag2; mp_obj_complex_get(args[1], &real2, &imag2); real -= imag2; imag += real2; } else { imag += mp_obj_get_float(args[1]); } return mp_obj_new_complex(real, imag); } default: nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "complex takes at most 2 arguments, %d given", (void*)(machine_int_t)n_args)); } }
STATIC mp_obj_t mp_builtin_abs(mp_obj_t o_in) { #if MICROPY_PY_BUILTINS_FLOAT if (mp_obj_is_float(o_in)) { mp_float_t value = mp_obj_float_get(o_in); // TODO check for NaN etc if (value < 0) { return mp_obj_new_float(-value); } else { return o_in; } #if MICROPY_PY_BUILTINS_COMPLEX } else if (MP_OBJ_IS_TYPE(o_in, &mp_type_complex)) { mp_float_t real, imag; mp_obj_complex_get(o_in, &real, &imag); return mp_obj_new_float(MICROPY_FLOAT_C_FUN(sqrt)(real*real + imag*imag)); #endif } #endif // this will raise a TypeError if the argument is not integral return mp_obj_int_abs(o_in); }