Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7321ec4

Browse files
committed
SF bug #444510: int() should guarantee truncation.
It's guaranteed now, assuming the platform modf() works correctly.
1 parent 7cf92fa commit 7321ec4

3 files changed

Lines changed: 27 additions & 10 deletions

File tree

Doc/lib/libfuncs.tex

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,9 +338,7 @@ \section{Built-in Functions \label{built-in-funcs}}
338338
\exception{TypeError} is raised.
339339
Otherwise, the argument may be a plain or
340340
long integer or a floating point number. Conversion of floating
341-
point numbers to integers is defined by the C semantics; normally
342-
the conversion truncates towards zero.\footnote{This is ugly --- the
343-
language definition should require truncation towards zero.}
341+
point numbers to integers truncates (towards zero).
344342
\end{funcdesc}
345343

346344
\begin{funcdesc}{intern}{string}

Lib/test/test_b1.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,19 @@ def f(): pass
366366
pass
367367
else:
368368
raise TestFailed, "int(%s)" % `s[1:]` + " should raise ValueError"
369+
try:
370+
int(1e100)
371+
except OverflowError:
372+
pass
373+
else:
374+
raise TestFailed("int(1e100) expected OverflowError")
375+
try:
376+
int(-1e100)
377+
except OverflowError:
378+
pass
379+
else:
380+
raise TestFailed("int(-1e100) expected OverflowError")
381+
369382

370383
# SF bug 434186: 0x80000000/2 != 0x80000000>>1.
371384
# Worked by accident in Windows release build, but failed in debug build.

Objects/floatobject.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -606,13 +606,19 @@ static PyObject *
606606
float_int(PyObject *v)
607607
{
608608
double x = PyFloat_AsDouble(v);
609-
if (x < 0 ? (x = ceil(x)) < (double)LONG_MIN
610-
: (x = floor(x)) > (double)LONG_MAX) {
611-
PyErr_SetString(PyExc_OverflowError,
612-
"float too large to convert");
613-
return NULL;
614-
}
615-
return PyInt_FromLong((long)x);
609+
double wholepart; /* integral portion of x, rounded toward 0 */
610+
long aslong; /* (long)wholepart */
611+
612+
(void)modf(x, &wholepart);
613+
/* doubles may have more bits than longs, or vice versa; and casting
614+
to long may yield gibberish in either case. What really matters
615+
is whether converting back to double again reproduces what we
616+
started with. */
617+
aslong = (long)wholepart;
618+
if ((double)aslong == wholepart)
619+
return PyInt_FromLong(aslong);
620+
PyErr_SetString(PyExc_OverflowError, "float too large to convert");
621+
return NULL;
616622
}
617623

618624
static PyObject *

0 commit comments

Comments
 (0)