py/objint: Do not use fpclassify.
For combinations of certain versions of glibc and gcc the definition of fpclassify always takes float as argument instead of adapting itself to float/double/long double as required by the C99 standard. At the time of writing this happens for instance for glibc 2.27 with gcc 7.5.0 when compiled with -Os and glibc 3.0.7 with gcc 9.3.0. When calling fpclassify with double as argument, as in objint.c, this results in an implicit narrowing conversion which is not really correct plus results in a warning when compiled with -Wfloat-conversion. So fix this by spelling out the logic manually.
This commit is contained in:
parent
70affd9ba2
commit
f31f9a8b70
10
py/objint.c
10
py/objint.c
|
@ -135,11 +135,15 @@ STATIC mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val) {
|
||||||
#undef MP_FLOAT_EXP_SHIFT_I32
|
#undef MP_FLOAT_EXP_SHIFT_I32
|
||||||
|
|
||||||
mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
|
mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
|
||||||
int cl = fpclassify(val);
|
mp_float_union_t u = {val};
|
||||||
if (cl == FP_INFINITE) {
|
// IEEE-754: if biased exponent is all 1 bits...
|
||||||
|
if (u.p.exp == ((1 << MP_FLOAT_EXP_BITS) - 1)) {
|
||||||
|
// ...then number is Inf (positive or negative) if fraction is 0, else NaN.
|
||||||
|
if (u.p.frc == 0) {
|
||||||
mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("can't convert inf to int"));
|
mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("can't convert inf to int"));
|
||||||
} else if (cl == FP_NAN) {
|
} else {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("can't convert NaN to int"));
|
mp_raise_ValueError(MP_ERROR_TEXT("can't convert NaN to int"));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mp_fp_as_int_class_t icl = mp_classify_fp_as_int(val);
|
mp_fp_as_int_class_t icl = mp_classify_fp_as_int(val);
|
||||||
if (icl == MP_FP_CLASS_FIT_SMALLINT) {
|
if (icl == MP_FP_CLASS_FIT_SMALLINT) {
|
||||||
|
|
|
@ -96,6 +96,7 @@ else:
|
||||||
fp2int_test(1.9999999999999981 * 2.0 ** 1023.0, "large pos", False)
|
fp2int_test(1.9999999999999981 * 2.0 ** 1023.0, "large pos", False)
|
||||||
|
|
||||||
fp2int_test(float("inf"), "inf test", True)
|
fp2int_test(float("inf"), "inf test", True)
|
||||||
|
fp2int_test(float("-inf"), "inf test", True)
|
||||||
fp2int_test(float("nan"), "NaN test", True)
|
fp2int_test(float("nan"), "NaN test", True)
|
||||||
|
|
||||||
# test numbers < 1 (this used to fail; see issue #1044)
|
# test numbers < 1 (this used to fail; see issue #1044)
|
||||||
|
|
|
@ -93,6 +93,7 @@ else:
|
||||||
fp2int_test(1.999999879 * 2.0 ** 126.0, "large pos", False)
|
fp2int_test(1.999999879 * 2.0 ** 126.0, "large pos", False)
|
||||||
|
|
||||||
fp2int_test(float("inf"), "inf test", True)
|
fp2int_test(float("inf"), "inf test", True)
|
||||||
|
fp2int_test(float("-inf"), "inf test", True)
|
||||||
fp2int_test(float("nan"), "NaN test", True)
|
fp2int_test(float("nan"), "NaN test", True)
|
||||||
|
|
||||||
# test numbers < 1 (this used to fail; see issue #1044)
|
# test numbers < 1 (this used to fail; see issue #1044)
|
||||||
|
|
Loading…
Reference in New Issue