diff --git a/extmod/moductypes.c b/extmod/moductypes.c index eb9ca57e3..cdbf49ad4 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -360,7 +360,7 @@ STATIC mp_obj_t get_aligned(uint val_type, void *p, mp_int_t index) { return mp_obj_new_int_from_ll(((int64_t *)p)[index]); #if MICROPY_PY_BUILTINS_FLOAT case FLOAT32: - return mp_obj_new_float(((float *)p)[index]); + return mp_obj_new_float_from_f(((float *)p)[index]); case FLOAT64: return mp_obj_new_float(((double *)p)[index]); #endif @@ -373,11 +373,10 @@ STATIC mp_obj_t get_aligned(uint val_type, void *p, mp_int_t index) { STATIC void set_aligned(uint val_type, void *p, mp_int_t index, mp_obj_t val) { #if MICROPY_PY_BUILTINS_FLOAT if (val_type == FLOAT32 || val_type == FLOAT64) { - mp_float_t v = mp_obj_get_float(val); if (val_type == FLOAT32) { - ((float *)p)[index] = v; + ((float *)p)[index] = mp_obj_get_float_to_f(val); } else { - ((double *)p)[index] = v; + ((double *)p)[index] = mp_obj_get_float_to_d(val); } return; } diff --git a/extmod/moduselect.c b/extmod/moduselect.c index 122365607..80beb8e09 100644 --- a/extmod/moduselect.c +++ b/extmod/moduselect.c @@ -125,7 +125,7 @@ STATIC mp_obj_t select_select(size_t n_args, const mp_obj_t *args) { if (n_args == 4) { if (args[3] != mp_const_none) { #if MICROPY_PY_BUILTINS_FLOAT - float timeout_f = mp_obj_get_float(args[3]); + float timeout_f = mp_obj_get_float_to_f(args[3]); if (timeout_f >= 0) { timeout = (mp_uint_t)(timeout_f * 1000); } diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c index 3a9a7eca6..e5bd092cc 100644 --- a/ports/unix/modffi.c +++ b/ports/unix/modffi.c @@ -167,7 +167,7 @@ STATIC mp_obj_t return_ffi_value(ffi_arg val, char type) { union { ffi_arg ffi; float flt; } val_union = { .ffi = val }; - return mp_obj_new_float(val_union.flt); + return mp_obj_new_float_from_f(val_union.flt); } case 'd': { double *p = (double *)&val; @@ -381,7 +381,7 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const *p = mp_obj_get_float(a); } else if (*argtype == 'd') { double *p = (double *)&values[i]; - *p = mp_obj_get_float(a); + *p = mp_obj_get_float_to_d(a); #endif } else if (a == mp_const_none) { values[i] = 0; diff --git a/ports/unix/modtime.c b/ports/unix/modtime.c index 126aec30c..16152152a 100644 --- a/ports/unix/modtime.c +++ b/ports/unix/modtime.c @@ -61,7 +61,7 @@ static inline int msec_sleep_tv(struct timeval *tv) { #endif #if defined(MP_CLOCKS_PER_SEC) -#define CLOCK_DIV (MP_CLOCKS_PER_SEC / 1000.0F) +#define CLOCK_DIV (MP_CLOCKS_PER_SEC / MICROPY_FLOAT_CONST(1000.0)) #else #error Unsupported clock() implementation #endif @@ -84,7 +84,7 @@ STATIC mp_obj_t mod_time_clock(void) { // 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); + return mp_obj_new_float((clock() / 1000) / CLOCK_DIV); #else return mp_obj_new_int((mp_int_t)clock()); #endif @@ -95,8 +95,8 @@ STATIC mp_obj_t mod_time_sleep(mp_obj_t arg) { #if MICROPY_PY_BUILTINS_FLOAT struct timeval tv; mp_float_t val = mp_obj_get_float(arg); - double ipart; - tv.tv_usec = round(modf(val, &ipart) * 1000000); + mp_float_t ipart; + tv.tv_usec = MICROPY_FLOAT_C_FUN(round)(MICROPY_FLOAT_C_FUN(modf)(val, &ipart) * MICROPY_FLOAT_CONST(1000000.)); tv.tv_sec = ipart; int res; while (1) { diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index 8bc453d42..f87a717c9 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -378,8 +378,8 @@ STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { if (timeout_in != mp_const_none) { #if MICROPY_PY_BUILTINS_FLOAT mp_float_t val = mp_obj_get_float(timeout_in); - double ipart; - tv.tv_usec = round(modf(val, &ipart) * 1000000); + mp_float_t ipart; + tv.tv_usec = MICROPY_FLOAT_C_FUN(round)(MICROPY_FLOAT_C_FUN(modf)(val, &ipart) * MICROPY_FLOAT_CONST(1000000.)); tv.tv_sec = ipart; #else tv.tv_sec = mp_obj_get_int(timeout_in); diff --git a/py/binary.c b/py/binary.c index b29438770..33515e880 100644 --- a/py/binary.c +++ b/py/binary.c @@ -176,7 +176,7 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, size_t index) { #endif #if MICROPY_PY_BUILTINS_FLOAT case 'f': - return mp_obj_new_float(((float *)p)[index]); + return mp_obj_new_float_from_f(((float *)p)[index]); case 'd': return mp_obj_new_float(((double *)p)[index]); #endif @@ -244,7 +244,7 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte *p_base, byte * union { uint32_t i; float f; } fpu = {val}; - return mp_obj_new_float(fpu.f); + return mp_obj_new_float_from_f(fpu.f); } else if (val_type == 'd') { union { uint64_t i; double f; @@ -320,7 +320,7 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte *p uint32_t i32[2]; double f; } fp_dp; - fp_dp.f = mp_obj_get_float(val_in); + fp_dp.f = mp_obj_get_float_to_d(val_in); if (BYTES_PER_WORD == 8) { val = fp_dp.i64; } else { @@ -362,7 +362,7 @@ void mp_binary_set_val_array(char typecode, void *p, size_t index, mp_obj_t val_ ((float *)p)[index] = mp_obj_get_float(val_in); break; case 'd': - ((double *)p)[index] = mp_obj_get_float(val_in); + ((double *)p)[index] = mp_obj_get_float_to_d(val_in); break; #endif // Extension to CPython: array of objects diff --git a/py/modcmath.c b/py/modcmath.c index ce1f4746f..f1ce8fb5d 100644 --- a/py/modcmath.c +++ b/py/modcmath.c @@ -72,7 +72,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_cmath_exp_obj, mp_cmath_exp); STATIC mp_obj_t mp_cmath_log(mp_obj_t z_obj) { mp_float_t real, imag; mp_obj_get_complex(z_obj, &real, &imag); - return mp_obj_new_complex(0.5 * MICROPY_FLOAT_C_FUN(log)(real * real + imag * imag), MICROPY_FLOAT_C_FUN(atan2)(imag, real)); + return mp_obj_new_complex(MICROPY_FLOAT_CONST(0.5) * MICROPY_FLOAT_C_FUN(log)(real * real + imag * imag), MICROPY_FLOAT_C_FUN(atan2)(imag, real)); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_cmath_log_obj, mp_cmath_log); @@ -81,7 +81,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_cmath_log_obj, mp_cmath_log); STATIC mp_obj_t mp_cmath_log10(mp_obj_t z_obj) { mp_float_t real, imag; mp_obj_get_complex(z_obj, &real, &imag); - return mp_obj_new_complex(0.5 * MICROPY_FLOAT_C_FUN(log10)(real * real + imag * imag), 0.4342944819032518 * MICROPY_FLOAT_C_FUN(atan2)(imag, real)); + return mp_obj_new_complex(MICROPY_FLOAT_CONST(0.5) * MICROPY_FLOAT_C_FUN(log10)(real * real + imag * imag), MICROPY_FLOAT_CONST(0.4342944819032518) * MICROPY_FLOAT_C_FUN(atan2)(imag, real)); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_cmath_log10_obj, mp_cmath_log10); #endif @@ -90,8 +90,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_cmath_log10_obj, mp_cmath_log10); STATIC mp_obj_t mp_cmath_sqrt(mp_obj_t z_obj) { mp_float_t real, imag; mp_obj_get_complex(z_obj, &real, &imag); - mp_float_t sqrt_abs = MICROPY_FLOAT_C_FUN(pow)(real * real + imag * imag, 0.25); - mp_float_t theta = 0.5 * MICROPY_FLOAT_C_FUN(atan2)(imag, real); + mp_float_t sqrt_abs = MICROPY_FLOAT_C_FUN(pow)(real * real + imag * imag, MICROPY_FLOAT_CONST(0.25)); + mp_float_t theta = MICROPY_FLOAT_CONST(0.5) * MICROPY_FLOAT_C_FUN(atan2)(imag, real); return mp_obj_new_complex(sqrt_abs * MICROPY_FLOAT_C_FUN(cos)(theta), sqrt_abs * MICROPY_FLOAT_C_FUN(sin)(theta)); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_cmath_sqrt_obj, mp_cmath_sqrt); diff --git a/py/nativeglue.c b/py/nativeglue.c index eebbe18bb..30e5b4006 100644 --- a/py/nativeglue.c +++ b/py/nativeglue.c @@ -227,25 +227,7 @@ STATIC bool mp_native_yield_from(mp_obj_t gen, mp_obj_t send_value, mp_obj_t *re return false; } -#if MICROPY_PY_BUILTINS_FLOAT - -STATIC mp_obj_t mp_obj_new_float_from_f(float f) { - return mp_obj_new_float((mp_float_t)f); -} - -STATIC mp_obj_t mp_obj_new_float_from_d(double d) { - return mp_obj_new_float((mp_float_t)d); -} - -STATIC float mp_obj_get_float_to_f(mp_obj_t o) { - return (float)mp_obj_get_float(o); -} - -STATIC double mp_obj_get_float_to_d(mp_obj_t o) { - return (double)mp_obj_get_float(o); -} - -#else +#if !MICROPY_PY_BUILTINS_FLOAT STATIC mp_obj_t mp_obj_new_float_from_f(float f) { (void)f; diff --git a/py/obj.h b/py/obj.h index b282c63db..d3abdab59 100644 --- a/py/obj.h +++ b/py/obj.h @@ -820,6 +820,39 @@ void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, size_t s #if MICROPY_PY_BUILTINS_FLOAT // float +#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT +static inline float mp_obj_get_float_to_f(mp_obj_t o) { + return mp_obj_get_float(o); +} + +static inline double mp_obj_get_float_to_d(mp_obj_t o) { + return (double)mp_obj_get_float(o); +} + +static inline mp_obj_t mp_obj_new_float_from_f(float o) { + return mp_obj_new_float(o); +} + +static inline mp_obj_t mp_obj_new_float_from_d(double o) { + return mp_obj_new_float((mp_float_t)o); +} +#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE +static inline float mp_obj_get_float_to_f(mp_obj_t o) { + return (float)mp_obj_get_float(o); +} + +static inline double mp_obj_get_float_to_d(mp_obj_t o) { + return mp_obj_get_float(o); +} + +static inline mp_obj_t mp_obj_new_float_from_f(float o) { + return mp_obj_new_float((mp_float_t)o); +} + +static inline mp_obj_t mp_obj_new_float_from_d(double o) { + return mp_obj_new_float(o); +} +#endif #if MICROPY_FLOAT_HIGH_QUALITY_HASH mp_int_t mp_float_hash(mp_float_t val); #else diff --git a/py/objfloat.c b/py/objfloat.c index c7cf049fb..09b73c8cd 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -52,11 +52,13 @@ typedef struct _mp_obj_float_t { mp_float_t value; } mp_obj_float_t; -const mp_obj_float_t mp_const_float_e_obj = {{&mp_type_float}, M_E}; -const mp_obj_float_t mp_const_float_pi_obj = {{&mp_type_float}, M_PI}; +const mp_obj_float_t mp_const_float_e_obj = {{&mp_type_float}, (mp_float_t)M_E}; +const mp_obj_float_t mp_const_float_pi_obj = {{&mp_type_float}, (mp_float_t)M_PI}; #endif +#define MICROPY_FLOAT_ZERO MICROPY_FLOAT_CONST(0.0) + #if MICROPY_FLOAT_HIGH_QUALITY_HASH // must return actual integer value if it fits in mp_int_t mp_int_t mp_float_hash(mp_float_t src) { @@ -208,24 +210,24 @@ STATIC void mp_obj_float_divmod(mp_float_t *x, mp_float_t *y) { mp_float_t div = (*x - mod) / *y; // Python specs require that mod has same sign as second operand - if (mod == 0.0) { - mod = MICROPY_FLOAT_C_FUN(copysign)(0.0, *y); + if (mod == MICROPY_FLOAT_ZERO) { + mod = MICROPY_FLOAT_C_FUN(copysign)(MICROPY_FLOAT_ZERO, *y); } else { - if ((mod < 0.0) != (*y < 0.0)) { + if ((mod < MICROPY_FLOAT_ZERO) != (*y < MICROPY_FLOAT_ZERO)) { mod += *y; - div -= 1.0; + div -= MICROPY_FLOAT_CONST(1.0); } } mp_float_t floordiv; - if (div == 0.0) { + if (div == MICROPY_FLOAT_ZERO) { // if division is zero, take the correct sign of zero - floordiv = MICROPY_FLOAT_C_FUN(copysign)(0.0, *x / *y); + floordiv = MICROPY_FLOAT_C_FUN(copysign)(MICROPY_FLOAT_ZERO, *x / *y); } else { // Python specs require that x == (x//y)*y + (x%y) floordiv = MICROPY_FLOAT_C_FUN(floor)(div); - if (div - floordiv > 0.5) { - floordiv += 1.0; + if (div - floordiv > MICROPY_FLOAT_CONST(0.5)) { + floordiv += MICROPY_FLOAT_CONST(1.0); } } @@ -273,15 +275,15 @@ mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t break; case MP_BINARY_OP_MODULO: case MP_BINARY_OP_INPLACE_MODULO: - if (rhs_val == 0) { + if (rhs_val == MICROPY_FLOAT_ZERO) { 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) { + if (lhs_val == MICROPY_FLOAT_ZERO) { lhs_val = MICROPY_FLOAT_C_FUN(copysign)(0.0, rhs_val); } else { - if ((lhs_val < 0.0) != (rhs_val < 0.0)) { + if ((lhs_val < MICROPY_FLOAT_ZERO) != (rhs_val < MICROPY_FLOAT_ZERO)) { lhs_val += rhs_val; } } diff --git a/py/parsenum.c b/py/parsenum.c index 234248c9d..e665da7d8 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -220,7 +220,7 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool if (str + 2 < top && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'f') { // inf str += 3; - dec_val = INFINITY; + dec_val = (mp_float_t)INFINITY; if (str + 4 < top && (str[0] | 0x20) == 'i' && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'i' && (str[3] | 0x20) == 't' && (str[4] | 0x20) == 'y') { // infinity str += 5;