Message361139
>>> a / 10**9 <= b
False
Try to use a/1e9 <= b.
--
The C code to get the system clock is the same for time.time() and time.time_ns(). It's only the conversion of the result which is different:
static PyObject *
time_time(PyObject *self, PyObject *unused)
{
_PyTime_t t = _PyTime_GetSystemClock();
return _PyFloat_FromPyTime(t);
}
static PyObject *
time_time_ns(PyObject *self, PyObject *unused)
{
_PyTime_t t = _PyTime_GetSystemClock();
return _PyTime_AsNanosecondsObject(t);
}
where _PyTime_t is int64_t: 64-bit signed integer.
Conversions:
static PyObject*
_PyFloat_FromPyTime(_PyTime_t t)
{
double d = _PyTime_AsSecondsDouble(t);
return PyFloat_FromDouble(d);
}
double
_PyTime_AsSecondsDouble(_PyTime_t t)
{
/* volatile avoids optimization changing how numbers are rounded */
volatile double d;
if (t % SEC_TO_NS == 0) {
_PyTime_t secs;
/* Divide using integers to avoid rounding issues on the integer part.
1e-9 cannot be stored exactly in IEEE 64-bit. */
secs = t / SEC_TO_NS;
d = (double)secs;
}
else {
d = (double)t;
d /= 1e9;
}
return d;
}
PyObject *
_PyTime_AsNanosecondsObject(_PyTime_t t)
{
Py_BUILD_ASSERT(sizeof(long long) >= sizeof(_PyTime_t));
return PyLong_FromLongLong((long long)t);
}
In short, time.time() = float(time.time_ns()) / 1e9.
--
The problem can be reproduced in Python:
>>> a=1580301619906185300
>>> b=a/1e9
>>> a / 10**9 <= b
False
I added time.time_ns() because we loose precision if you care about nanosecond resolution, with such "large number". float has a precision around 238 nanoseconds:
>>> import math; ulp=math.ulp(b)
>>> ulp
2.384185791015625e-07
>>> "%.0f +- %.0f" % (b*1e9, ulp*1e9)
'1580301619906185216 +- 238'
int/int and int/float don't give the same result:
>>> a/10**9
1580301619.9061854
>>> a/1e9
1580301619.9061852
I'm not sure which one is "correct". To understand the issue, you can use the next math.nextafter() function to get the next floating point towards -inf:
>>> a/10**9
1580301619.9061854
>>> a/1e9
1580301619.9061852
>>> math.nextafter(a/10**9, -math.inf)
1580301619.9061852
>>> math.nextafter(a/1e9, -math.inf)
1580301619.906185
Handling floating point numbers are hard.
Why don't use only use integers? :-) |
|
Date |
User |
Action |
Args |
2020-02-01 00:59:08 | vstinner | set | recipients:
+ vstinner, larry, serhiy.storchaka, vxgmichel |
2020-02-01 00:59:08 | vstinner | set | messageid: <1580518748.47.0.557874428735.issue39484@roundup.psfhosted.org> |
2020-02-01 00:59:08 | vstinner | link | issue39484 messages |
2020-02-01 00:59:08 | vstinner | create | |
|