Commit 21aeab70 authored by Stefan Behnel's avatar Stefan Behnel

Optimise float(int).

parent c137916c
......@@ -474,20 +474,43 @@ static CYTHON_INLINE PyObject* __Pyx__PyNumber_Float(PyObject* obj); /* proto */
//@requires: Optimize.c::pyunicode_as_double
static CYTHON_INLINE PyObject* __Pyx__PyNumber_Float(PyObject* obj) {
// obj is PyFloat is handled in the calling macro
// 'obj is PyFloat' is handled in the calling macro
double val;
if (PyUnicode_CheckExact(obj)) {
if (PyLong_CheckExact(obj)) {
#if CYTHON_USE_PYLONG_INTERNALS
const digit* digits = ((PyLongObject*)obj)->ob_digit;
switch (Py_SIZE(obj)) {
case 0:
val = 0.0;
goto no_error;
// single digit PyLong values always cast safely to double
case 1:
val = (double) digits[0];
goto no_error;
case -1:
val = (double) - (sdigit) digits[0];
goto no_error;
default:
val = PyLong_AsDouble(obj);
}
#else
val = PyLong_AsDouble(obj);
#endif
} else if (PyUnicode_CheckExact(obj)) {
val = __Pyx_PyUnicode_AsDouble(obj);
return unlikely(val == -1 && PyErr_Occurred()) ? NULL : PyFloat_FromDouble(val);
} else if (PyBytes_CheckExact(obj)) {
val = __Pyx_PyBytes_AsDouble(obj);
return unlikely(val == -1 && PyErr_Occurred()) ? NULL : PyFloat_FromDouble(val);
} else if (PyByteArray_CheckExact(obj)) {
val = __Pyx_PyByteArray_AsDouble(obj);
return unlikely(val == -1 && PyErr_Occurred()) ? NULL : PyFloat_FromDouble(val);
} else {
return PyNumber_Float(obj);
}
if (unlikely(val == -1 && PyErr_Occurred())) {
return NULL;
}
no_error:
return PyFloat_FromDouble(val);
}
/////////////// GCCDiagnostics.proto ///////////////
......
......@@ -44,6 +44,29 @@ def float_call_conjugate():
return x
def from_int(i):
"""
>>> from_int(0)
0.0
>>> from_int(1)
1.0
>>> from_int(-1)
-1.0
>>> from_int(99)
99.0
>>> from_int(-99)
-99.0
>>> for exp in (14, 15, 16, 30, 31, 32, 52, 53, 54, 60, 61, 62, 63, 64):
... for sign in (1, 0, -1):
... value = (sign or 1) * 2**exp + sign
... float_value = from_int(value)
... assert float_value == float(value), "expected %s2**%s+%s == %r, got %r, difference %r" % (
... '-' if sign < 0 else '', exp, sign, float(value), float_value, float_value - float(value))
"""
return float(i)
@cython.test_assert_path_exists(
"//CoerceToPyTypeNode",
"//CoerceToPyTypeNode//PythonCapiCallNode",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment