]> granicus.if.org Git - python/commitdiff
Issue #22117: Fix rounding and implement _PyTime_ROUND_FLOOR in:
authorVictor Stinner <victor.stinner@gmail.com>
Sun, 29 Mar 2015 22:44:06 +0000 (00:44 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Sun, 29 Mar 2015 22:44:06 +0000 (00:44 +0200)
- _PyTime_ObjectToTime_t()
- _PyTime_ObjectToTimespec()
- _PyTime_ObjectToTimeval()

Lib/test/test_time.py
Python/pytime.c

index b0c97d5919f04280023f34a7c34b397bcf36919d..bcbf41d0db85bee774479fcdeccf6e16c6af1e1f 100644 (file)
@@ -647,13 +647,13 @@ class TestPytime(unittest.TestCase):
             (1e-9, (0, 1), _PyTime.ROUND_DOWN),
             (1e-10, (0, 0), _PyTime.ROUND_DOWN),
             (-1e-9, (-1, 999999999), _PyTime.ROUND_DOWN),
-            (-1e-10, (-1, 999999999), _PyTime.ROUND_DOWN),
+            (-1e-10, (0, 0), _PyTime.ROUND_DOWN),
             (-1.2, (-2, 800000000), _PyTime.ROUND_DOWN),
             (0.9999999999, (0, 999999999), _PyTime.ROUND_DOWN),
             (1.1234567890, (1, 123456789), _PyTime.ROUND_DOWN),
             (1.1234567899, (1, 123456789), _PyTime.ROUND_DOWN),
             (-1.1234567890, (-2, 876543211), _PyTime.ROUND_DOWN),
-            (-1.1234567891, (-2, 876543210), _PyTime.ROUND_DOWN),
+            (-1.1234567891, (-2, 876543211), _PyTime.ROUND_DOWN),
             # Round away from zero
             (0, (0, 0), _PyTime.ROUND_UP),
             (-1, (-1, 0), _PyTime.ROUND_UP),
index d9ff3c63105ca6e9f6e3be52bdd8002c60665372..2bf6ba5cf28587b4d9b3fd438db9cdaa87e2ade3 100644 (file)
@@ -26,6 +26,14 @@ error_time_t_overflow(void)
                     "timestamp out of range for platform time_t");
 }
 
+static int
+_PyTime_RoundTowardsPosInf(int is_neg, _PyTime_round_t round)
+{
+    if (round == _PyTime_ROUND_FLOOR)
+        return 0;
+    return ((round == _PyTime_ROUND_UP) ^ is_neg);
+}
+
 time_t
 _PyLong_AsTime_t(PyObject *obj)
 {
@@ -74,18 +82,16 @@ _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
         }
 
         floatpart *= denominator;
-        if (round == _PyTime_ROUND_UP) {
-            if (intpart >= 0) {
-                floatpart = ceil(floatpart);
-                if (floatpart >= denominator) {
-                    floatpart = 0.0;
-                    intpart += 1.0;
-                }
-            }
-            else {
-                floatpart = floor(floatpart);
+        if (_PyTime_RoundTowardsPosInf(intpart < 0, round)) {
+            floatpart = ceil(floatpart);
+            if (floatpart >= denominator) {
+                floatpart = 0.0;
+                intpart += 1.0;
             }
         }
+        else {
+            floatpart = floor(floatpart);
+        }
 
         *sec = (time_t)intpart;
         err = intpart - (double)*sec;
@@ -113,12 +119,10 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
         double d, intpart, err;
 
         d = PyFloat_AsDouble(obj);
-        if (round == _PyTime_ROUND_UP) {
-            if (d >= 0)
-                d = ceil(d);
-            else
-                d = floor(d);
-        }
+        if (_PyTime_RoundTowardsPosInf(d < 0, round))
+            d = ceil(d);
+        else
+            d = floor(d);
         (void)modf(d, &intpart);
 
         *sec = (time_t)intpart;
@@ -158,14 +162,6 @@ _PyTime_overflow(void)
                     "timestamp too large to convert to C _PyTime_t");
 }
 
-int
-_PyTime_RoundTowardsPosInf(int is_neg, _PyTime_round_t round)
-{
-    if (round == _PyTime_ROUND_FLOOR)
-        return 0;
-    return ((round == _PyTime_ROUND_UP) ^ is_neg);
-}
-
 _PyTime_t
 _PyTime_FromNanoseconds(PY_LONG_LONG ns)
 {