@@ -140,19 +140,6 @@ divmod(int x, int y, int *r)
140140 return quo ;
141141}
142142
143- /* Round a double to the nearest long. |x| must be small enough to fit
144- * in a C long; this is not checked.
145- */
146- static long
147- round_to_long (double x )
148- {
149- if (x >= 0.0 )
150- x = floor (x + 0.5 );
151- else
152- x = ceil (x - 0.5 );
153- return (long )x ;
154- }
155-
156143/* Nearest integer to m / n for integers m and n. Half-integer results
157144 * are rounded to even.
158145 */
@@ -1397,7 +1384,7 @@ cmperror(PyObject *a, PyObject *b)
13971384 */
13981385
13991386/* Conversion factors. */
1400- static PyObject * us_per_us = NULL ; /* 1 */
1387+ static PyObject * one = NULL ; /* 1 */
14011388static PyObject * us_per_ms = NULL ; /* 1000 */
14021389static PyObject * us_per_second = NULL ; /* 1000000 */
14031390static PyObject * us_per_minute = NULL ; /* 1e6 * 60 as Python int */
@@ -2119,7 +2106,7 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
21192106 goto Done
21202107
21212108 if (us ) {
2122- y = accum ("microseconds" , x , us , us_per_us , & leftover_us );
2109+ y = accum ("microseconds" , x , us , one , & leftover_us );
21232110 CLEANUP ;
21242111 }
21252112 if (ms ) {
@@ -2148,7 +2135,33 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
21482135 }
21492136 if (leftover_us ) {
21502137 /* Round to nearest whole # of us, and add into x. */
2151- PyObject * temp = PyLong_FromLong (round_to_long (leftover_us ));
2138+ double whole_us = round (leftover_us );
2139+ int x_is_odd ;
2140+ PyObject * temp ;
2141+
2142+ whole_us = round (leftover_us );
2143+ if (fabs (whole_us - leftover_us ) == 0.5 ) {
2144+ /* We're exactly halfway between two integers. In order
2145+ * to do round-half-to-even, we must determine whether x
2146+ * is odd. Note that x is odd when it's last bit is 1. The
2147+ * code below uses bitwise and operation to check the last
2148+ * bit. */
2149+ temp = PyNumber_And (x , one ); /* temp <- x & 1 */
2150+ if (temp == NULL ) {
2151+ Py_DECREF (x );
2152+ goto Done ;
2153+ }
2154+ x_is_odd = PyObject_IsTrue (temp );
2155+ Py_DECREF (temp );
2156+ if (x_is_odd == -1 ) {
2157+ Py_DECREF (x );
2158+ goto Done ;
2159+ }
2160+ whole_us = 2.0 * round ((leftover_us + x_is_odd ) * 0.5 ) - x_is_odd ;
2161+ }
2162+
2163+ temp = PyLong_FromLong (whole_us );
2164+
21522165 if (temp == NULL ) {
21532166 Py_DECREF (x );
21542167 goto Done ;
@@ -5351,12 +5364,12 @@ PyInit__datetime(void)
53515364 assert (DI100Y == 25 * DI4Y - 1 );
53525365 assert (DI100Y == days_before_year (100 + 1 ));
53535366
5354- us_per_us = PyLong_FromLong (1 );
5367+ one = PyLong_FromLong (1 );
53555368 us_per_ms = PyLong_FromLong (1000 );
53565369 us_per_second = PyLong_FromLong (1000000 );
53575370 us_per_minute = PyLong_FromLong (60000000 );
53585371 seconds_per_day = PyLong_FromLong (24 * 3600 );
5359- if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5372+ if (one == NULL || us_per_ms == NULL || us_per_second == NULL ||
53605373 us_per_minute == NULL || seconds_per_day == NULL )
53615374 return NULL ;
53625375
0 commit comments