diff options
author | Tim Peters <tim.peters@gmail.com> | 2001-07-26 20:02:17 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2001-07-26 20:02:17 (GMT) |
commit | 7321ec437b0aef968b83137d9c638551cabab706 (patch) | |
tree | 83890a0d039e47d282d2abda1f8eb173710de3f8 | |
parent | 7cf92fa1c891b53e6143e090009911c0231bb24a (diff) | |
download | cpython-7321ec437b0aef968b83137d9c638551cabab706.zip cpython-7321ec437b0aef968b83137d9c638551cabab706.tar.gz cpython-7321ec437b0aef968b83137d9c638551cabab706.tar.bz2 |
SF bug #444510: int() should guarantee truncation.
It's guaranteed now, assuming the platform modf() works correctly.
-rw-r--r-- | Doc/lib/libfuncs.tex | 4 | ||||
-rw-r--r-- | Lib/test/test_b1.py | 13 | ||||
-rw-r--r-- | Objects/floatobject.c | 20 |
3 files changed, 27 insertions, 10 deletions
diff --git a/Doc/lib/libfuncs.tex b/Doc/lib/libfuncs.tex index e493375..12b7cf7 100644 --- a/Doc/lib/libfuncs.tex +++ b/Doc/lib/libfuncs.tex @@ -338,9 +338,7 @@ module from which it is called). \exception{TypeError} is raised. Otherwise, the argument may be a plain or long integer or a floating point number. Conversion of floating - point numbers to integers is defined by the C semantics; normally - the conversion truncates towards zero.\footnote{This is ugly --- the - language definition should require truncation towards zero.} + point numbers to integers truncates (towards zero). \end{funcdesc} \begin{funcdesc}{intern}{string} diff --git a/Lib/test/test_b1.py b/Lib/test/test_b1.py index e2cc49b..bddd157 100644 --- a/Lib/test/test_b1.py +++ b/Lib/test/test_b1.py @@ -366,6 +366,19 @@ except ValueError: pass else: raise TestFailed, "int(%s)" % `s[1:]` + " should raise ValueError" +try: + int(1e100) +except OverflowError: + pass +else: + raise TestFailed("int(1e100) expected OverflowError") +try: + int(-1e100) +except OverflowError: + pass +else: + raise TestFailed("int(-1e100) expected OverflowError") + # SF bug 434186: 0x80000000/2 != 0x80000000>>1. # Worked by accident in Windows release build, but failed in debug build. diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 2f17d02..d1ce092 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -606,13 +606,19 @@ static PyObject * float_int(PyObject *v) { double x = PyFloat_AsDouble(v); - if (x < 0 ? (x = ceil(x)) < (double)LONG_MIN - : (x = floor(x)) > (double)LONG_MAX) { - PyErr_SetString(PyExc_OverflowError, - "float too large to convert"); - return NULL; - } - return PyInt_FromLong((long)x); + double wholepart; /* integral portion of x, rounded toward 0 */ + long aslong; /* (long)wholepart */ + + (void)modf(x, &wholepart); + /* doubles may have more bits than longs, or vice versa; and casting + to long may yield gibberish in either case. What really matters + is whether converting back to double again reproduces what we + started with. */ + aslong = (long)wholepart; + if ((double)aslong == wholepart) + return PyInt_FromLong(aslong); + PyErr_SetString(PyExc_OverflowError, "float too large to convert"); + return NULL; } static PyObject * |