Skip to content

Commit 125eae1

Browse files
committed
py/modbuiltins: For round() builtin use nearbyint instead of round.
The C nearbyint function has exactly the semantics that Python's round() requires, whereas C's round() requires extra steps to handle rounding of numbers half way between integers. So using nearbyint reduces code size and potentially eliminates any source of errors in the handling of half-way numbers. Also, bare-metal implementations of nearbyint can be more efficient than round, so further code size is saved (and efficiency improved). nearbyint is provided in the C99 standard so it should be available on all supported platforms.
1 parent fb161aa commit 125eae1

4 files changed

Lines changed: 5 additions & 12 deletions

File tree

esp8266/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ LIB_SRC_C = $(addprefix lib/,\
108108
libc/string0.c \
109109
libm/math.c \
110110
libm/fmodf.c \
111-
libm/roundf.c \
111+
libm/nearbyintf.c \
112112
libm/ef_sqrt.c \
113113
libm/kf_rem_pio2.c \
114114
libm/kf_sin.c \

py/modbuiltins.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -473,18 +473,11 @@ STATIC mp_obj_t mp_builtin_round(size_t n_args, const mp_obj_t *args) {
473473
mp_float_t val = mp_obj_get_float(o_in);
474474
mp_float_t mult = MICROPY_FLOAT_C_FUN(pow)(10, num_dig);
475475
// TODO may lead to overflow
476-
mp_float_t rounded = MICROPY_FLOAT_C_FUN(round)(val * mult) / mult;
476+
mp_float_t rounded = MICROPY_FLOAT_C_FUN(nearbyint)(val * mult) / mult;
477477
return mp_obj_new_float(rounded);
478478
}
479479
mp_float_t val = mp_obj_get_float(o_in);
480-
mp_float_t rounded = MICROPY_FLOAT_C_FUN(round)(val);
481-
mp_int_t r = rounded;
482-
// make rounded value even if it was halfway between ints
483-
if (val - rounded == 0.5) {
484-
r = (r + 1) & (~1);
485-
} else if (val - rounded == -0.5) {
486-
r &= ~1;
487-
}
480+
mp_float_t rounded = MICROPY_FLOAT_C_FUN(nearbyint)(val);
488481
#else
489482
mp_int_t r = mp_obj_get_int(o_in);
490483
#endif

qemu-arm/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ SRC_TEST_C = \
4747
LIB_SRC_C = $(addprefix lib/,\
4848
libm/math.c \
4949
libm/fmodf.c \
50-
libm/roundf.c \
50+
libm/nearbyintf.c \
5151
libm/ef_sqrt.c \
5252
libm/kf_rem_pio2.c \
5353
libm/kf_sin.c \

stmhal/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ SRC_LIB = $(addprefix lib/,\
8686
libm/atanf.c \
8787
libm/atan2f.c \
8888
libm/fmodf.c \
89-
libm/roundf.c \
89+
libm/nearbyintf.c \
9090
libm/log1pf.c \
9191
libm/acoshf.c \
9292
libm/asinhf.c \

0 commit comments

Comments
 (0)