Skip to content

Commit 6fd4b36

Browse files
committed
py: Raise exception if trying to convert inf/nan to int.
1 parent 6e0b6d0 commit 6fd4b36

3 files changed

Lines changed: 24 additions & 12 deletions

File tree

py/mpz.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -711,16 +711,9 @@ typedef uint32_t mp_float_int_t;
711711
// value == 0 || value < 1
712712
mpz_init_zero(z);
713713
} else if (u.p.exp == ((1 << EXP_SZ) - 1)) {
714-
// inf or NaN
715-
#if 0
716-
// TODO: this probably isn't the right place to throw an exception
717-
if(u.p.frc == 0)
718-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OverflowError, "cannot convert float infinity to integer"));
719-
else
720-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "cannot convert float NaN to integer"));
721-
#else
714+
// u.p.frc == 0 indicates inf, else NaN
715+
// should be handled by caller
722716
mpz_init_zero(z);
723-
#endif
724717
} else {
725718
const int adj_exp = (int)u.p.exp - ((1 << (EXP_SZ - 1)) - 1);
726719
if (adj_exp < 0) {

py/objint_mpz.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,16 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) {
298298

299299
#if MICROPY_PY_BUILTINS_FLOAT
300300
mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
301-
mp_obj_int_t *o = mp_obj_int_new_mpz();
302-
mpz_set_from_float(&o->mpz, val);
303-
return o;
301+
int cl = fpclassify(val);
302+
if (cl == FP_INFINITE) {
303+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OverflowError, "can't convert inf to int"));
304+
} else if (cl == FP_NAN) {
305+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "can't convert NaN to int"));
306+
} else {
307+
mp_obj_int_t *o = mp_obj_int_new_mpz();
308+
mpz_set_from_float(&o->mpz, val);
309+
return o;
310+
}
304311
}
305312
#endif
306313

tests/float/float2int.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,15 @@
2222
print('fail: 10**%u was %u digits long' % (i, digcnt));
2323
testpass = False
2424
print("power of 10 test: %s" % (testpass and 'passed' or 'failed'))
25+
26+
# test inf conversion
27+
try:
28+
int(float('inf'))
29+
except OverflowError:
30+
print("OverflowError")
31+
32+
# test nan conversion
33+
try:
34+
int(float('nan'))
35+
except ValueError:
36+
print("ValueError")

0 commit comments

Comments
 (0)