mirror of
https://github.com/AdaCore/cpython.git
synced 2026-02-12 12:57:15 -08:00
Merged revisions 68889 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k
........
r68889 | mark.dickinson | 2009-01-24 15:02:35 +0000 (Sat, 24 Jan 2009) | 9 lines
Some minor cleanups in PyLong_FromLong:
- fast path wasn't being properly taken for negative ints;
thanks Victor Stinner for pointing this out.
- use Py_SAFE_DOWNCAST instead of direct casting to digit
(it's safer, especially if we ever consider moving to 30-bit
digits)
- cleaner way to write negation
........
This commit is contained in:
@@ -175,7 +175,7 @@ PyObject *
|
||||
PyLong_FromLong(long ival)
|
||||
{
|
||||
PyLongObject *v;
|
||||
unsigned long abs_ival;
|
||||
unsigned long abs_ival;
|
||||
unsigned long t; /* unsigned so >> doesn't propagate sign bit */
|
||||
int ndigits = 0;
|
||||
int sign = 1;
|
||||
@@ -183,33 +183,35 @@ PyLong_FromLong(long ival)
|
||||
CHECK_SMALL_INT(ival);
|
||||
|
||||
if (ival < 0) {
|
||||
/* if LONG_MIN == -LONG_MAX-1 (true on most platforms) then
|
||||
ANSI C says that the result of -ival is undefined when ival
|
||||
== LONG_MIN. Hence the following workaround. */
|
||||
abs_ival = (unsigned long)(-1-ival) + 1;
|
||||
/* negate: can't write this as abs_ival = -ival since that
|
||||
invokes undefined behaviour when ival is LONG_MIN */
|
||||
abs_ival = 0U-(unsigned long)ival;
|
||||
sign = -1;
|
||||
}
|
||||
else {
|
||||
abs_ival = (unsigned long)ival;
|
||||
}
|
||||
|
||||
/* Fast path for single-digits ints */
|
||||
if (!(ival>>PyLong_SHIFT)) {
|
||||
/* Fast path for single-digit ints */
|
||||
if (!(abs_ival >> PyLong_SHIFT)) {
|
||||
v = _PyLong_New(1);
|
||||
if (v) {
|
||||
Py_SIZE(v) = sign;
|
||||
v->ob_digit[0] = (digit)ival;
|
||||
v->ob_digit[0] = Py_SAFE_DOWNCAST(
|
||||
abs_ival, unsigned long, digit);
|
||||
}
|
||||
return (PyObject*)v;
|
||||
}
|
||||
|
||||
/* 2 digits */
|
||||
if (!(ival >> 2*PyLong_SHIFT)) {
|
||||
if (!(abs_ival >> 2*PyLong_SHIFT)) {
|
||||
v = _PyLong_New(2);
|
||||
if (v) {
|
||||
Py_SIZE(v) = 2*sign;
|
||||
v->ob_digit[0] = (digit)ival & PyLong_MASK;
|
||||
v->ob_digit[1] = (digit)(ival >> PyLong_SHIFT);
|
||||
v->ob_digit[0] = Py_SAFE_DOWNCAST(
|
||||
abs_ival & PyLong_MASK, unsigned long, digit);
|
||||
v->ob_digit[1] = Py_SAFE_DOWNCAST(
|
||||
abs_ival >> PyLong_SHIFT, unsigned long, digit);
|
||||
}
|
||||
return (PyObject*)v;
|
||||
}
|
||||
@@ -226,7 +228,8 @@ PyLong_FromLong(long ival)
|
||||
Py_SIZE(v) = ndigits*sign;
|
||||
t = abs_ival;
|
||||
while (t) {
|
||||
*p++ = (digit)(t & PyLong_MASK);
|
||||
*p++ = Py_SAFE_DOWNCAST(
|
||||
t & PyLong_MASK, unsigned long, digit);
|
||||
t >>= PyLong_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user