I'm not sure that I understand what you mean about overflowing at 32 bits. I believe that you either lose range, resolution or both. With the scaling factors that you mentioned the maximum value of ((m << + t) is 0x4FFFFFFB as compared to 0xFFFFFFFF in the other cases. While it is true that the maximum return value will be 0xFFFFFFFF you still need to know the range in order to compute elapsed time when the second data point has a lower value than the first, i.e., when the value has wrapped.

Don, I guess all I was trying to argue was that scaling (for the 20MHz case) using y = (x / 5) * 16 is superior to y = (x * 16) / 5

IF you are interested (as David is) in making sure the values of y are evenly distributed throughout the entire range of 32-bit values. Yes, you lose some resolution, but you gain the ability to compute time deltas by simply subtracting them.

The expression (((m <<

+ t) / 5) * 16) overflows at

0xFFFFFFF0 with resolution 16. Meanwhile, the expression (((m <<

+ t) * 16) / 5), which is roughly equivalent otherwise, overflows at 0x19999996 (albeit with better resolution). They both, more or less, represent microseconds elapsed.

Here's a brief summary of the the tradeoffs between overflow and resolution:

A = 16MHz algorithm

B = 8MHz algorithm

C = 20MHz algorithm with y = x * 16 / 5

D = 20MHz algorithm with y = x / 5 * 16

Scheme | Overflow | Resolution (us)

-----------------------------------

A | FFFFFFFC | 4

B | FFFFFFF8 | 8

C | 19999996 | ~16/5

D | FFFFFFF0 | 16I vote for A, B, and D.

D could easily be applied to elapsedMicroseconds. Just do the division first and then the multiplication.

I like hpticks() a lot too, by the way. I think I would use it a bunch. Thanks!

Thoughts, anyone?

Mikal

PS: Nice work on "round".