mirror of https://github.com/python/cpython
Issue #22117: Fix rounding and implement _PyTime_ROUND_FLOOR in:
- _PyTime_ObjectToTime_t() - _PyTime_ObjectToTimespec() - _PyTime_ObjectToTimeval()
This commit is contained in:
parent
1bd18ba9a7
commit
f81f0f9c63
|
@ -647,13 +647,13 @@ class TestPytime(unittest.TestCase):
|
||||||
(1e-9, (0, 1), _PyTime.ROUND_DOWN),
|
(1e-9, (0, 1), _PyTime.ROUND_DOWN),
|
||||||
(1e-10, (0, 0), _PyTime.ROUND_DOWN),
|
(1e-10, (0, 0), _PyTime.ROUND_DOWN),
|
||||||
(-1e-9, (-1, 999999999), _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),
|
(-1.2, (-2, 800000000), _PyTime.ROUND_DOWN),
|
||||||
(0.9999999999, (0, 999999999), _PyTime.ROUND_DOWN),
|
(0.9999999999, (0, 999999999), _PyTime.ROUND_DOWN),
|
||||||
(1.1234567890, (1, 123456789), _PyTime.ROUND_DOWN),
|
(1.1234567890, (1, 123456789), _PyTime.ROUND_DOWN),
|
||||||
(1.1234567899, (1, 123456789), _PyTime.ROUND_DOWN),
|
(1.1234567899, (1, 123456789), _PyTime.ROUND_DOWN),
|
||||||
(-1.1234567890, (-2, 876543211), _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
|
# Round away from zero
|
||||||
(0, (0, 0), _PyTime.ROUND_UP),
|
(0, (0, 0), _PyTime.ROUND_UP),
|
||||||
(-1, (-1, 0), _PyTime.ROUND_UP),
|
(-1, (-1, 0), _PyTime.ROUND_UP),
|
||||||
|
|
|
@ -26,6 +26,14 @@ error_time_t_overflow(void)
|
||||||
"timestamp out of range for platform time_t");
|
"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
|
time_t
|
||||||
_PyLong_AsTime_t(PyObject *obj)
|
_PyLong_AsTime_t(PyObject *obj)
|
||||||
{
|
{
|
||||||
|
@ -74,18 +82,16 @@ _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
|
||||||
}
|
}
|
||||||
|
|
||||||
floatpart *= denominator;
|
floatpart *= denominator;
|
||||||
if (round == _PyTime_ROUND_UP) {
|
if (_PyTime_RoundTowardsPosInf(intpart < 0, round)) {
|
||||||
if (intpart >= 0) {
|
floatpart = ceil(floatpart);
|
||||||
floatpart = ceil(floatpart);
|
if (floatpart >= denominator) {
|
||||||
if (floatpart >= denominator) {
|
floatpart = 0.0;
|
||||||
floatpart = 0.0;
|
intpart += 1.0;
|
||||||
intpart += 1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
floatpart = floor(floatpart);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
floatpart = floor(floatpart);
|
||||||
|
}
|
||||||
|
|
||||||
*sec = (time_t)intpart;
|
*sec = (time_t)intpart;
|
||||||
err = intpart - (double)*sec;
|
err = intpart - (double)*sec;
|
||||||
|
@ -113,12 +119,10 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
|
||||||
double d, intpart, err;
|
double d, intpart, err;
|
||||||
|
|
||||||
d = PyFloat_AsDouble(obj);
|
d = PyFloat_AsDouble(obj);
|
||||||
if (round == _PyTime_ROUND_UP) {
|
if (_PyTime_RoundTowardsPosInf(d < 0, round))
|
||||||
if (d >= 0)
|
d = ceil(d);
|
||||||
d = ceil(d);
|
else
|
||||||
else
|
d = floor(d);
|
||||||
d = floor(d);
|
|
||||||
}
|
|
||||||
(void)modf(d, &intpart);
|
(void)modf(d, &intpart);
|
||||||
|
|
||||||
*sec = (time_t)intpart;
|
*sec = (time_t)intpart;
|
||||||
|
@ -158,14 +162,6 @@ _PyTime_overflow(void)
|
||||||
"timestamp too large to convert to C _PyTime_t");
|
"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_t
|
||||||
_PyTime_FromNanoseconds(PY_LONG_LONG ns)
|
_PyTime_FromNanoseconds(PY_LONG_LONG ns)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue