Skip Montanaro added the comment:
Attached is a diff to the datetime module that
implements floating point division. Comments?
Is it worthwhile to pursue? If so, I'll
implement the other floating point arithmetic
operations.
----------
versions: +Python 2.6
_____________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1289118>
_____________________________________
Index: Modules/datetimemodule.c
===================================================================
--- Modules/datetimemodule.c (revision 57877)
+++ Modules/datetimemodule.c (working copy)
@@ -1628,6 +1628,47 @@
}
static PyObject *
+divide_timedelta_float(PyDateTime_Delta *delta, PyObject *denom)
+{
+ int days;
+ double seconds;
+ double us;
+ double f;
+
+ if (PyFloat_Check(denom)) {
+ f = PyFloat_AS_DOUBLE(denom);
+ } else if (PyInt_Check(denom)) {
+ f = (double)PyInt_AsLong(denom);
+ } else if (PyLong_Check(denom)) {
+ f = (double)PyLong_AsLong(denom);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "Invalid denominator for timedelta division.");
+ return NULL;
+ }
+
+ /* convert to seconds */
+ seconds = GET_TD_DAYS(delta) * (24 * 3600) +
+ (double)GET_TD_SECONDS(delta) +
+ (double)GET_TD_MICROSECONDS(delta) / 1e6;
+
+ /* arithmetic is now trivial */
+ seconds /= f;
+
+ /* convert back to days, seconds and us, checking for range error */
+ days = (int)(seconds / (24 * 3600));
+ if (check_delta_day_range(days) < 0)
+ return NULL;
+
+ seconds = seconds - days * (24 * 3600);
+ us = (seconds - (int)seconds) * 1e6;
+ /* round us to nearest whole number */
+ us = (int)(us + 0.5);
+
+ return new_delta(days, (int)seconds, (int)us, 1);
+}
+
+static PyObject *
delta_add(PyObject *left, PyObject *right)
{
PyObject *result = Py_NotImplemented;
@@ -1776,10 +1817,14 @@
if (PyDelta_Check(left)) {
/* delta * ??? */
- if (PyInt_Check(right) || PyLong_Check(right))
+ if (PyFloat_Check(right))
+ result = divide_timedelta_float(
+ (PyDateTime_Delta *)left,
+ right);
+ else if (PyInt_Check(right) || PyLong_Check(right))
result = divide_timedelta_int(
- (PyDateTime_Delta *)left,
- right);
+ (PyDateTime_Delta *)left,
+ right);
}
if (result == Py_NotImplemented)
@@ -2119,7 +2164,7 @@
0, /*nb_inplace_xor*/
0, /*nb_inplace_or*/
delta_divide, /* nb_floor_divide */
- 0, /* nb_true_divide */
+ delta_divide, /* nb_true_divide */
0, /* nb_inplace_floor_divide */
0, /* nb_inplace_true_divide */
};
Index: Lib/test/test_datetime.py
===================================================================
--- Lib/test/test_datetime.py (revision 57877)
+++ Lib/test/test_datetime.py (working copy)
@@ -234,6 +234,18 @@
eq(c//1000, td(0, 0, 1))
eq(a//10, td(0, 7*24*360))
eq(a//3600000, td(0, 0, 7*24*1000))
+ eq(a//7.0, td(1))
+ eq(b//10.0, td(0, 6))
+ eq(c//1000.0, td(0, 0, 1))
+ eq(a//10.0, td(0, 7*24*360))
+ eq(a//3600000.0, td(0, 0, 7*24*1000))
+ eq(a/0.5, td(14))
+ eq(b/0.5, td(0, 120))
+ eq(a/7, td(1))
+ eq(b/10, td(0, 6))
+ eq(c/1000, td(0, 0, 1))
+ eq(a/10, td(0, 7*24*360))
+ eq(a/3600000, td(0, 0, 7*24*1000))
def test_disallowed_computations(self):
a = timedelta(42)
@@ -245,14 +257,10 @@
self.assertRaises(TypeError, lambda: i+a)
self.assertRaises(TypeError, lambda: i-a)
- # Mul/div by float isn't supported.
+ # Mul by float isn't supported.
x = 2.3
self.assertRaises(TypeError, lambda: a*x)
self.assertRaises(TypeError, lambda: x*a)
- self.assertRaises(TypeError, lambda: a/x)
- self.assertRaises(TypeError, lambda: x/a)
- self.assertRaises(TypeError, lambda: a // x)
- self.assertRaises(TypeError, lambda: x // a)
# Divison of int by timedelta doesn't make sense.
# Division by zero doesn't make sense.
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com