1

I need the current time with nanosec. As string "%.9f" % float_time it is 1502872986.653693676. You can see 76 at the end. If I try to write the same time as int int(float_time*10**9), it will be 1502872986653693696 and 96 at the end. Why? And which is the right way to get nano format?

from time import time

float_time = time()
print("float_time:", float_time)
int_nano_time = int(float_time*10**9)
print("int_nano_time:", int_nano_time)
str_nano_time = "%.9f" % float_time
print("str_nano_time:", str_nano_time)

float_time: 1502872986.6536937

int_nano_time: 1502872986653693696

str_nano_time: 1502872986.653693676

Solution:

time.monotonic()

float_time: 536596.296

int_nano_time: 536596296000000

str_nano_time: 536596.296000000

Elena
  • 119
  • 2
  • 8
  • 1
    [python uses IEEE-754 double precision](https://docs.python.org/3.3/tutorial/floatingpoint.html), hence have only 53 bits in significand part which is about 15-17 decimal digits (1502872986.6536936 has 17 significant digits, the rest is just noise) – phuclv Aug 16 '17 at 09:40
  • 1
    @Elena it is highly probable that the `time()` returned isn't correct to nanosecond precision. – Antti Haapala -- Слава Україні Aug 16 '17 at 09:48
  • @AnttiHaapala is it possible to get nanosec in int in python? In C++ world they don't have the problem, because they get it in 64bits int. They don't meet the IEEE754. – Elena Aug 16 '17 at 10:03
  • 1
    @Elena as I've tried to explain, if you use the time returned by `time()` its precision doesn't matter, because *both* instants 1502872986653693696 and 15028729866536937 occurred *while* the `time()` function was fetching the timestamp and converting the timestamp to a floating point object etc. – Antti Haapala -- Слава Україні Aug 16 '17 at 12:13

1 Answers1

1

Both are correct within the IEEE754 double precision of ~15.7 decimal digits. The reason is that the multiples of ten cannot be produced exactly, so while multiplying by 2 ** 10 is exact, multiplying by 5 ** 10 will have rounding errors again, and that's why the last numbers differ.

'1502872986.653693675994873046875000000000'
>>> "%.30f" % (1502872986.653693676 * 10 ** 9)
'1502872986653693696.000000000000000000000000000000'

The hex representations of these 2 floating point numbers are wildly different:

>>> (1502872986.653693676 * 10 ** 9).hex()
'0x1.4db4704d00617p+60'
>>> (1502872986.653693676).hex()
'0x1.6650166a9d61ep+30'

As for the time returned from the time() call - well it is highly probable that should the computer have a timer that gives a timestamp with high enough precision any time value will be between the exact time time() was called and when it returned:

>>> (time() - time()) * 10 ** 9
-715.2557373046875
>>> (time() - time()) * 10 ** 9
-953.67431640625
>>> (time() - time()) * 10 ** 9
-953.67431640625

your error was 20 nanoseconds, but the time difference between 2 consecutive timestamps returned from time() call is 700-100 nanoseconds on my computer.