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; } }
STATIC mp_obj_t return_ffi_value(ffi_arg val, char type) { switch (type) { case 's': { const char *s = (const char *)(intptr_t)val; if (!s) { return mp_const_none; } return mp_obj_new_str(s, strlen(s), false); } case 'v': return mp_const_none; #if MICROPY_PY_BUILTINS_FLOAT case 'f': { union { ffi_arg ffi; float flt; } val_union = { .ffi = val }; return mp_obj_new_float(val_union.flt); } case 'd': { double *p = (double*)&val; return mp_obj_new_float(*p); } #endif case 'O': return (mp_obj_t)(intptr_t)val; default: return mp_obj_new_int(val); } }
mp_obj_t mp_math_modf(mp_obj_t x_obj) { mp_float_t int_part = 0.0; mp_float_t fractional_part = MICROPY_FLOAT_C_FUN(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); }
// log(x[, base]) STATIC mp_obj_t mp_math_log(mp_uint_t n_args, const mp_obj_t *args) { mp_float_t l = MICROPY_FLOAT_C_FUN(log)(mp_obj_get_float(args[0])); if (n_args == 1) { return mp_obj_new_float(l); } else { return mp_obj_new_float(l / MICROPY_FLOAT_C_FUN(log)(mp_obj_get_float(args[1]))); } }
mp_obj_t mp_cmath_polar(mp_obj_t z_obj) { mp_float_t real, imag; mp_obj_get_complex(z_obj, &real, &imag); mp_obj_t tuple[2] = { mp_obj_new_float(MICROPY_FLOAT_C_FUN(sqrt)(real*real + imag*imag)), mp_obj_new_float(MICROPY_FLOAT_C_FUN(atan2)(imag, real)), }; return mp_obj_new_tuple(2, tuple); }
STATIC void complex_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { if (dest[0] != MP_OBJ_NULL) { // not load attribute return; } mp_obj_complex_t *self = MP_OBJ_TO_PTR(self_in); if (attr == MP_QSTR_real) { dest[0] = mp_obj_new_float(self->real); } else if (attr == MP_QSTR_imag) { dest[0] = mp_obj_new_float(self->imag); } }
/* store default values so that no crash due to undefined variable */ if (v->flags & PY_FLAG_ARRAY) { v->index = MP_OBJ_NEW_SMALL_INT(0); v->list = mp_obj_new_list((mp_uint_t)v->dim, v->items); obj = v->list; } else { obj = v->items[0]; } mp_store_name(v->name, obj); if (v->flags & PY_FLAG_FLOAT) { size = dim * sizeof(mp_float_t); data = (void**)&v->data.f; } else { size = dim * sizeof(mp_int_t); data = (void**)&v->data.i; } *data = malloc(size); if (*data == NULL) goto on_error_2; return v; on_error_2: free(v->items); on_error_1: free(v); on_error_0: return NULL; } static py_var_t* py_create_scalar (py_handle_t* py, const char* name, uint32_t flags) { return py_create_var(py, name, 1, flags); } static py_var_t* py_create_array (py_handle_t* py, const char* name, size_t dim, uint32_t flags) { return py_create_var(py, name, dim, flags | PY_FLAG_ARRAY); } static void py_destroy_var(py_var_t* v) { void* data; if (v->flags & PY_FLAG_FLOAT) data = (void*)v->data.f; else data = (void*)v->data.i; free(data); free(v->items); free(v); } static void py_print_var(py_var_t* v) { size_t i; for (i = 0; i != v->dim; ++i) { if (v->flags & PY_FLAG_INT) printf(" %d", v->data.i[i]); else printf(" %lf", v->data.f[i]); } printf("\n"); } static void py_print_out_vars(py_handle_t* py) { size_t i; for (i = 0; i != py->nvar; ++i) { py_var_t* const v = py->vars[i]; if ((v->flags & PY_FLAG_OUT) == 0) continue ; py_print_var(v); } } static int py_compile(py_handle_t* py, const char* s) { static const mp_parse_input_kind_t input_kind = MP_PARSE_FILE_INPUT; static const uint emit_opt = MP_EMIT_OPT_NATIVE_PYTHON; nlr_buf_t nlr; int err = -1; if (nlr_push(&nlr)) return -1; py->lex = mp_lexer_new_from_str_len (MP_QSTR__lt_stdin_gt_, s, strlen(s), false); if (py->lex == NULL) goto on_error_0; py->parse_tree = mp_parse(py->lex, input_kind); py->module_fun = mp_compile (&py->parse_tree, py->lex->source_name, emit_opt, false); err = 0; on_error_0: nlr_pop(); return err; } static int py_open(py_handle_t* py) { py->lex = NULL; py->nvar = 0; return 0; } static int py_close(py_handle_t* py) { size_t i; for (i = 0; i != py->nvar; ++i) py_destroy_var(py->vars[i]); return 0; } #if 0 /* does not work, should recompile entirely */ static int py_collect(py_handle_t* py) { mp_obj_t obj; size_t i; size_t j; gc_collect(); for (i = 0; i != py->nvar; ++i) { py_var_t* const v = py->vars[i]; v->name = qstr_from_str(v->_name); if (v->flags & PY_FLAG_INT) { for (j = 0; j != v->dim; ++j) { if (v->flags & PY_FLAG_IN) obj = MP_OBJ_NEW_SMALL_INT(v->in.i[j]); else obj = MP_OBJ_NEW_SMALL_INT(v->data.i[j]); v->items[j] = obj; } } else { for (j = 0; j != v->dim; ++j) { if (v->flags & PY_FLAG_IN) obj = mp_obj_new_float(v->in.f[j]); else obj = mp_obj_new_float(v->data.f[j]); v->items[j] = obj; } } /* store default values so that no crash due to undefined variable */ if (v->flags & PY_FLAG_ARRAY) { v->index = MP_OBJ_NEW_SMALL_INT(0); v->list = mp_obj_new_list((mp_uint_t)v->dim, v->items); obj = v->list; } else { obj = v->items[0]; } mp_store_name(v->name, obj); } return 0; }
// log(x[, base]) STATIC mp_obj_t mp_math_log(size_t n_args, const mp_obj_t *args) { mp_float_t x = mp_obj_get_float(args[0]); if (x <= (mp_float_t)0.0) { math_error(); } mp_float_t l = MICROPY_FLOAT_C_FUN(log)(x); if (n_args == 1) { return mp_obj_new_float(l); } else { mp_float_t base = mp_obj_get_float(args[1]); if (base <= (mp_float_t)0.0) { math_error(); } return mp_obj_new_float(l / MICROPY_FLOAT_C_FUN(log)(base)); } }
static mp_obj_t float_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) { switch (n_args) { case 0: return mp_obj_new_float(0); case 1: // TODO allow string as arg and parse it if (MP_OBJ_IS_TYPE(args[0], &float_type)) { return args[0]; } else { return mp_obj_new_float(mp_obj_get_float(args[0])); } default: nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "float takes at most 1 argument, %d given", (void*)(machine_int_t)n_args)); } }
// Functions that return a tuple mp_obj_t mp_math_frexp(mp_obj_t x_obj) { int int_exponent = 0; mp_float_t significand = MICROPY_FLOAT_C_FUN(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); }
// Note: this is deprecated since CPy3.3, but pystone still uses it. STATIC mp_obj_t mod_time_clock() { // return mp_obj_new_int((machine_int_t)clock()); // POSIX requires CLOCKS_PER_SEC equals 1000000, so that's what we assume // float cannot represent full range of int32 precisely, so we pre-divide // int to reduce resolution, and then actually do float division hoping // to preserve integer part resolution. return mp_obj_new_float((float)(clock() / 1000) / 1000.0); }
mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) { mp_int_t val = 0; switch (typecode) { case 'b': val = ((signed char*)p)[index]; break; case BYTEARRAY_TYPECODE: case 'B': val = ((unsigned char*)p)[index]; break; case 'h': val = ((short*)p)[index]; break; case 'H': val = ((unsigned short*)p)[index]; break; case 'i': return mp_obj_new_int(((int*)p)[index]); case 'I': return mp_obj_new_int_from_uint(((unsigned int*)p)[index]); case 'l': return mp_obj_new_int(((long*)p)[index]); case 'L': return mp_obj_new_int_from_uint(((unsigned long*)p)[index]); #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE case 'q': return mp_obj_new_int_from_ll(((long long*)p)[index]); case 'Q': return mp_obj_new_int_from_ull(((unsigned long long*)p)[index]); #endif #if MICROPY_PY_BUILTINS_FLOAT case 'f': return mp_obj_new_float(((float*)p)[index]); case 'd': return mp_obj_new_float(((double*)p)[index]); #endif // Extension to CPython: array of objects case 'O': return ((mp_obj_t*)p)[index]; // Extension to CPython: array of pointers case 'P': return mp_obj_new_int((mp_int_t)((void**)p)[index]); } return MP_OBJ_NEW_SMALL_INT(val); }
mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) { byte *p = *ptr; mp_uint_t align; size_t size = mp_binary_get_size(struct_type, val_type, &align); if (struct_type == '@') { // Make pointer aligned p = (byte*)(((mp_uint_t)p + align - 1) & ~((mp_uint_t)align - 1)); #if MP_ENDIANNESS_LITTLE struct_type = '<'; #else struct_type = '>'; #endif } *ptr = p + size; long long val = mp_binary_get_int(size, is_signed(val_type), (struct_type == '>'), p); if (val_type == 'O') { return (mp_obj_t)(mp_uint_t)val; } else if (val_type == 'S') { const char *s_val = (const char*)(mp_uint_t)val; return mp_obj_new_str(s_val, strlen(s_val), false); #if MICROPY_PY_BUILTINS_FLOAT } else if (val_type == 'f') { union { uint32_t i; float f; } fpu = {val}; return mp_obj_new_float(fpu.f); } else if (val_type == 'd') { union { uint64_t i; double f; } fpu = {val}; return mp_obj_new_float(fpu.f); #endif } else if (is_signed(val_type)) { if ((long long)MP_SMALL_INT_MIN <= val && val <= (long long)MP_SMALL_INT_MAX) { return mp_obj_new_int((mp_int_t)val); } else { return mp_obj_new_int_from_ll(val); } } else { if ((unsigned long long)val <= (unsigned long long)MP_SMALL_INT_MAX) { return mp_obj_new_int_from_uint((mp_uint_t)val); } else { return mp_obj_new_int_from_ull(val); } } }
STATIC mp_obj_t float_unary_op(mp_uint_t op, mp_obj_t o_in) { mp_float_t val = mp_obj_float_get(o_in); switch (op) { case MP_UNARY_OP_BOOL: return mp_obj_new_bool(val != 0); case MP_UNARY_OP_POSITIVE: return o_in; case MP_UNARY_OP_NEGATIVE: return mp_obj_new_float(-val); default: return MP_OBJ_NULL; // op not supported } }
STATIC mp_obj_t microbit_temperature(void) { int temp; NRF_TEMP->TASKS_START = 1; while (NRF_TEMP->EVENTS_DATARDY == 0); NRF_TEMP->EVENTS_DATARDY = 0; temp = NRF_TEMP->TEMP; NRF_TEMP->TASKS_STOP = 1; return mp_obj_new_float(temp/4.0); }
STATIC mp_obj_t float_unary_op(int op, mp_obj_t o_in) { mp_obj_float_t *o = o_in; switch (op) { case MP_UNARY_OP_BOOL: return MP_BOOL(o->value != 0); case MP_UNARY_OP_POSITIVE: return o_in; case MP_UNARY_OP_NEGATIVE: return mp_obj_new_float(-o->value); default: return MP_OBJ_NOT_SUPPORTED; } }
static mp_obj_t float_unary_op(int op, mp_obj_t o_in) { mp_obj_float_t *o = o_in; switch (op) { case RT_UNARY_OP_NOT: if (o->value != 0) { return mp_const_true;} else { return mp_const_false; } case RT_UNARY_OP_POSITIVE: return o_in; case RT_UNARY_OP_NEGATIVE: return mp_obj_new_float(-o->value); default: return NULL; // op not supported } }
STATIC mp_obj_t float_unary_op(mp_uint_t op, mp_obj_t o_in) { mp_obj_float_t *o = o_in; switch (op) { case MP_UNARY_OP_BOOL: return MP_BOOL(o->value != 0); case MP_UNARY_OP_POSITIVE: return o_in; case MP_UNARY_OP_NEGATIVE: return mp_obj_new_float(-o->value); default: return MP_OBJ_NULL; // op not supported } }
// Note: this is deprecated since CPy3.3, but pystone still uses it. STATIC mp_obj_t mod_time_clock() { #if MICROPY_PY_BUILTINS_FLOAT // float cannot represent full range of int32 precisely, so we pre-divide // int to reduce resolution, and then actually do float division hoping // to preserve integer part resolution. return mp_obj_new_float((float)(clock() / 1000) / CLOCK_DIV); #else return mp_obj_new_int((machine_int_t)clock()); #endif }
static mp_obj_t adc_all_read_core_vref(mp_obj_t self_in) { pyb_obj_adc_all_t *self = self_in; if (self->is_enabled) { float data = adc_read_core_vref(); return mp_obj_new_float(data); } else { return mp_const_none; } }
STATIC mp_obj_t mod_time_time() { #if MICROPY_PY_BUILTINS_FLOAT struct timeval tv; gettimeofday(&tv, NULL); mp_float_t val = tv.tv_sec + (mp_float_t)tv.tv_usec / 1000000; return mp_obj_new_float(val); #else return mp_obj_new_int((machine_int_t)time(NULL)); #endif }
mp_obj_t mp_obj_float_binary_op(mp_uint_t op, mp_float_t lhs_val, mp_obj_t rhs_in) { mp_float_t rhs_val = mp_obj_get_float(rhs_in); // can be any type, this function will convert to float (if possible) switch (op) { case MP_BINARY_OP_ADD: case MP_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break; case MP_BINARY_OP_SUBTRACT: case MP_BINARY_OP_INPLACE_SUBTRACT: lhs_val -= rhs_val; break; case MP_BINARY_OP_MULTIPLY: case MP_BINARY_OP_INPLACE_MULTIPLY: lhs_val *= rhs_val; break; case MP_BINARY_OP_FLOOR_DIVIDE: case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: if (rhs_val == 0) { zero_division_error: nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "division by zero")); } // Python specs require that x == (x//y)*y + (x%y) so we must // call divmod to compute the correct floor division, which // returns the floor divide in lhs_val. mp_obj_float_divmod(&lhs_val, &rhs_val); break; case MP_BINARY_OP_TRUE_DIVIDE: case MP_BINARY_OP_INPLACE_TRUE_DIVIDE: if (rhs_val == 0) { goto zero_division_error; } lhs_val /= rhs_val; break; case MP_BINARY_OP_MODULO: case MP_BINARY_OP_INPLACE_MODULO: if (rhs_val == 0) { goto zero_division_error; } lhs_val = MICROPY_FLOAT_C_FUN(fmod)(lhs_val, rhs_val); // Python specs require that mod has same sign as second operand if (lhs_val == 0.0) { lhs_val = MICROPY_FLOAT_C_FUN(copysign)(0.0, rhs_val); } else { if ((lhs_val < 0.0) != (rhs_val < 0.0)) { lhs_val += rhs_val; } } break; case MP_BINARY_OP_POWER: case MP_BINARY_OP_INPLACE_POWER: lhs_val = MICROPY_FLOAT_C_FUN(pow)(lhs_val, rhs_val); break; case MP_BINARY_OP_LESS: return MP_BOOL(lhs_val < rhs_val); case MP_BINARY_OP_MORE: return MP_BOOL(lhs_val > rhs_val); case MP_BINARY_OP_EQUAL: return MP_BOOL(lhs_val == rhs_val); case MP_BINARY_OP_LESS_EQUAL: return MP_BOOL(lhs_val <= rhs_val); case MP_BINARY_OP_MORE_EQUAL: return MP_BOOL(lhs_val >= rhs_val); default: return MP_OBJ_NULL; // op not supported } return mp_obj_new_float(lhs_val); }
STATIC mp_obj_t return_ffi_value(ffi_arg val, char type) { switch (type) { case 's': { const char *s = (const char *)val; return mp_obj_new_str(s, strlen(s), false); } case 'v': return mp_const_none; case 'f': { union { ffi_arg ffi; float flt; } val_union = { .ffi = val }; return mp_obj_new_float(val_union.flt); } case 'd': { double *p = (double*)&val; return mp_obj_new_float(*p); } default: return mp_obj_new_int(val); } }
mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) { mp_int_t val = 0; switch (typecode) { case 'b': val = ((signed char*)p)[index]; break; case BYTEARRAY_TYPECODE: case 'B': val = ((unsigned char*)p)[index]; break; case 'h': val = ((short*)p)[index]; break; case 'H': val = ((unsigned short*)p)[index]; break; case 'i': return mp_obj_new_int(((int*)p)[index]); case 'I': return mp_obj_new_int_from_uint(((unsigned int*)p)[index]); case 'l': return mp_obj_new_int(((long*)p)[index]); case 'L': return mp_obj_new_int_from_uint(((unsigned long*)p)[index]); #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE case 'q': case 'Q': // TODO: Explode API more to cover signedness return mp_obj_new_int_from_ll(((long long*)p)[index]); #endif #if MICROPY_PY_BUILTINS_FLOAT case 'f': return mp_obj_new_float(((float*)p)[index]); case 'd': return mp_obj_new_float(((double*)p)[index]); #endif } return MP_OBJ_NEW_SMALL_INT(val); }
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); }
mp_obj_t ffifunc_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { mp_obj_ffifunc_t *self = self_in; assert(n_kw == 0); assert(n_args == self->cif.nargs); ffi_arg values[n_args]; void *valueptrs[n_args]; int i; for (i = 0; i < n_args; i++) { mp_obj_t a = args[i]; if (a == mp_const_none) { values[i] = 0; } else if (MP_OBJ_IS_INT(a)) { values[i] = mp_obj_int_get(a); } else if (MP_OBJ_IS_STR(a)) { const char *s = mp_obj_str_get_str(a); values[i] = (ffi_arg)s; } else if (((mp_obj_base_t*)a)->type->buffer_p.get_buffer != NULL) { mp_obj_base_t *o = (mp_obj_base_t*)a; mp_buffer_info_t bufinfo; int ret = o->type->buffer_p.get_buffer(o, &bufinfo, MP_BUFFER_READ); // TODO: MP_BUFFER_READ? if (ret != 0 || bufinfo.buf == NULL) { goto error; } values[i] = (ffi_arg)bufinfo.buf; } else if (MP_OBJ_IS_TYPE(a, &fficallback_type)) { mp_obj_fficallback_t *p = a; values[i] = (ffi_arg)p->func; } else { goto error; } valueptrs[i] = &values[i]; } // If ffi_arg is not big enough to hold a double, then we must pass along a // pointer to a memory location of the correct size. // TODO check if this needs to be done for other types which don't fit into // ffi_arg. if (sizeof(ffi_arg) == 4 && self->rettype == 'd') { double retval; ffi_call(&self->cif, self->func, &retval, valueptrs); return mp_obj_new_float(retval); } else { ffi_arg retval; ffi_call(&self->cif, self->func, &retval, valueptrs); return return_ffi_value(retval, self->rettype); } error: nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "Don't know how to pass object to native function")); }
STATIC mp_obj_t float_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); switch (n_args) { case 0: return mp_obj_new_float(0); case 1: default: 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, false, false); } else if (MP_OBJ_IS_TYPE(args[0], &mp_type_float)) { // a float, just return it return args[0]; } else { // something else, try to cast it to a float return mp_obj_new_float(mp_obj_get_float(args[0])); } } }
mp_obj_t mp_binary_get_val(char typecode, void *p, int index) { machine_int_t val = 0; switch (typecode) { case 'b': val = ((int8_t*)p)[index]; break; case BYTEARRAY_TYPECODE: case 'B': val = ((uint8_t*)p)[index]; break; case 'h': val = ((int16_t*)p)[index]; break; case 'H': val = ((uint16_t*)p)[index]; break; case 'i': case 'l': return mp_obj_new_int(((int32_t*)p)[index]); case 'I': case 'L': return mp_obj_new_int_from_uint(((uint32_t*)p)[index]); #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE case 'q': case 'Q': // TODO: Explode API more to cover signedness return mp_obj_new_int_from_ll(((long long*)p)[index]); #endif #if MICROPY_ENABLE_FLOAT case 'f': return mp_obj_new_float(((float*)p)[index]); case 'd': return mp_obj_new_float(((double*)p)[index]); #endif } return MP_OBJ_NEW_SMALL_INT(val); }
mp_obj_t mp_obj_float_binary_op(int op, mp_float_t lhs_val, mp_obj_t rhs_in) { mp_float_t rhs_val = mp_obj_get_float(rhs_in); // can be any type, this function will convert to float (if possible) switch (op) { case RT_BINARY_OP_ADD: case RT_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break; case RT_BINARY_OP_SUBTRACT: case RT_BINARY_OP_INPLACE_SUBTRACT: lhs_val -= rhs_val; break; case RT_BINARY_OP_MULTIPLY: case RT_BINARY_OP_INPLACE_MULTIPLY: lhs_val *= rhs_val; break; /* TODO floor(?) the value case RT_BINARY_OP_FLOOR_DIVIDE: case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: val = lhs_val / rhs_val; break; */ case RT_BINARY_OP_TRUE_DIVIDE: case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: lhs_val /= rhs_val; break; return NULL; // op not supported } return mp_obj_new_float(lhs_val); }
// Helper function to compute percentage from timer perion and PWM value. STATIC mp_obj_t compute_percent_from_pwm_value(uint32_t period, uint32_t cmp) { #if MICROPY_PY_BUILTINS_FLOAT float percent = (float)cmp * 100.0 / (float)period; if (cmp >= period) { percent = 100.0; } else { percent = (float)cmp * 100.0 / (float)period; } return mp_obj_new_float(percent); #else mp_int_t percent; if (cmp >= period) { percent = 100; } else { percent = cmp * 100 / period; } return mp_obj_new_int(percent); #endif }