summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-07-26 20:02:17 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-07-26 20:02:17 (GMT)
commit7321ec437b0aef968b83137d9c638551cabab706 (patch)
tree83890a0d039e47d282d2abda1f8eb173710de3f8
parent7cf92fa1c891b53e6143e090009911c0231bb24a (diff)
downloadcpython-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.tex4
-rw-r--r--Lib/test/test_b1.py13
-rw-r--r--Objects/floatobject.c20
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 *