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

Reply via email to