Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f81f0f9

Browse files
committed
Issue #22117: Fix rounding and implement _PyTime_ROUND_FLOOR in:
- _PyTime_ObjectToTime_t() - _PyTime_ObjectToTimespec() - _PyTime_ObjectToTimeval()
1 parent 1bd18ba commit f81f0f9

2 files changed

Lines changed: 22 additions & 26 deletions

File tree

Lib/test/test_time.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -647,13 +647,13 @@ def test_timespec(self):
647647
(1e-9, (0, 1), _PyTime.ROUND_DOWN),
648648
(1e-10, (0, 0), _PyTime.ROUND_DOWN),
649649
(-1e-9, (-1, 999999999), _PyTime.ROUND_DOWN),
650-
(-1e-10, (-1, 999999999), _PyTime.ROUND_DOWN),
650+
(-1e-10, (0, 0), _PyTime.ROUND_DOWN),
651651
(-1.2, (-2, 800000000), _PyTime.ROUND_DOWN),
652652
(0.9999999999, (0, 999999999), _PyTime.ROUND_DOWN),
653653
(1.1234567890, (1, 123456789), _PyTime.ROUND_DOWN),
654654
(1.1234567899, (1, 123456789), _PyTime.ROUND_DOWN),
655655
(-1.1234567890, (-2, 876543211), _PyTime.ROUND_DOWN),
656-
(-1.1234567891, (-2, 876543210), _PyTime.ROUND_DOWN),
656+
(-1.1234567891, (-2, 876543211), _PyTime.ROUND_DOWN),
657657
# Round away from zero
658658
(0, (0, 0), _PyTime.ROUND_UP),
659659
(-1, (-1, 0), _PyTime.ROUND_UP),

Python/pytime.c

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ error_time_t_overflow(void)
2626
"timestamp out of range for platform time_t");
2727
}
2828

29+
static int
30+
_PyTime_RoundTowardsPosInf(int is_neg, _PyTime_round_t round)
31+
{
32+
if (round == _PyTime_ROUND_FLOOR)
33+
return 0;
34+
return ((round == _PyTime_ROUND_UP) ^ is_neg);
35+
}
36+
2937
time_t
3038
_PyLong_AsTime_t(PyObject *obj)
3139
{
@@ -74,18 +82,16 @@ _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
7482
}
7583

7684
floatpart *= denominator;
77-
if (round == _PyTime_ROUND_UP) {
78-
if (intpart >= 0) {
79-
floatpart = ceil(floatpart);
80-
if (floatpart >= denominator) {
81-
floatpart = 0.0;
82-
intpart += 1.0;
83-
}
84-
}
85-
else {
86-
floatpart = floor(floatpart);
85+
if (_PyTime_RoundTowardsPosInf(intpart < 0, round)) {
86+
floatpart = ceil(floatpart);
87+
if (floatpart >= denominator) {
88+
floatpart = 0.0;
89+
intpart += 1.0;
8790
}
8891
}
92+
else {
93+
floatpart = floor(floatpart);
94+
}
8995

9096
*sec = (time_t)intpart;
9197
err = intpart - (double)*sec;
@@ -113,12 +119,10 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
113119
double d, intpart, err;
114120

115121
d = PyFloat_AsDouble(obj);
116-
if (round == _PyTime_ROUND_UP) {
117-
if (d >= 0)
118-
d = ceil(d);
119-
else
120-
d = floor(d);
121-
}
122+
if (_PyTime_RoundTowardsPosInf(d < 0, round))
123+
d = ceil(d);
124+
else
125+
d = floor(d);
122126
(void)modf(d, &intpart);
123127

124128
*sec = (time_t)intpart;
@@ -158,14 +162,6 @@ _PyTime_overflow(void)
158162
"timestamp too large to convert to C _PyTime_t");
159163
}
160164

161-
int
162-
_PyTime_RoundTowardsPosInf(int is_neg, _PyTime_round_t round)
163-
{
164-
if (round == _PyTime_ROUND_FLOOR)
165-
return 0;
166-
return ((round == _PyTime_ROUND_UP) ^ is_neg);
167-
}
168-
169165
_PyTime_t
170166
_PyTime_FromNanoseconds(PY_LONG_LONG ns)
171167
{

0 commit comments

Comments
 (0)