3

I want to capture timestamps with sub-second precision in python. It looks like the standard answer is int(time.time() * 1000)

However, if time.time() returns a float, won't you have precision problems? There will be some values that won't represent accurately as a float.

I'm worried about some fractional times that don't represent correctly as a float, and the timestamp jumping forward or backward in those cases.

Is that a valid concern?

If so, what's the work-around?

mgilson
  • 300,191
  • 65
  • 633
  • 696
sea-rob
  • 2,275
  • 1
  • 22
  • 22
  • if it is for performance measurements then you could use [timeit.default_timer()](http://stackoverflow.com/a/12444065/4279) – jfs Nov 08 '12 at 00:53
  • Is there a particular reason why you don't want to just keep the result of time.time directly? Multiplying by a non-power-of-two certainly has the power to muddle your "precision"; it may be best to keep what you get and then only round or truncate at the end. E.g. `starttime = time.time(); DoStuff(); now = time.time(); elapsed = now - starttime; elapsedms = int(1000 * elapsed)` – dash-tom-bang Nov 08 '12 at 00:58
  • I'm actually trying to throw measurements into time "buckets". So I need to take some sort of absolute time, divide by a period length, and then throw the measurement into that bucket. But I'm worried that in that calculation, some measurements will fall into the wrong bucket. However, it sounds like I'm OK; that the error that shows up is so small that the natural roundoff takes care of it. – sea-rob Nov 08 '12 at 01:05
  • well, see below. I was going to try to find an example, and the very first one I typed in was >>> int(1.001*1000) \ 1000 So I'll have to force a little bit of rounding with >>> int(1.001*1000+.1) \ 1001 – sea-rob Nov 08 '12 at 01:11

1 Answers1

3

How much precision do you want? While it's true that there are finite decimal fractions that can't be represented as finite binary fractions, the nearest approximate value is going to round to the correct number of integer milliseconds as long as you aren't timing a program running for 143 millenia (2**52 milliseconds).

In short: I don't think you need to worry about floating-point precision for this. You might need to worry about system timer accuracy, precision, or monotonicity, though.

Jamey Sharp
  • 8,363
  • 2
  • 29
  • 42
  • *"the nearest approximate value is going to round to the correct number"* ... so I think this is the right answer, with the caveat that I have to make sure some rounding happens. So I'm going to use int(time.time() * 1000 + 0.1) (see the example in the comment above). If you can find fault with that, please let me know! – sea-rob Nov 08 '12 at 02:42
  • Because I don't want half going up and half going down. I really do want to truncate -- to consider the first millisecond the start of a new bucket. Really, since I'm already being fussy, I should do something like int(time.time() * 1000 + 0.0001) so that pretty much the only round-up I get is for floating point precision errors. – sea-rob Nov 08 '12 at 08:12