STINNER Victor <[email protected]> added the comment:
>>> 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? :-)
----------
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue39484>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com