From: Patrice on 18 Mar 2010 06:38 > The only thing where floating points are not 'accurate' is when converting > numbers from integer, long, and so on into reals or doubles. IMO the underlying API used doesn't return a single value but a long value which is then converted to a single value. This is during this conversion to a floating point value that I believe we could have this approximation... It makes me think it could be interested to test Timer in parallel with GetTickCount (http://msdn.microsoft.com/en-us/library/ms724408(VS.85).aspx). It would allow to see if the same behavior seen with Timer occurs or not with GetTickCount. -- Patrice
From: Nobody on 18 Mar 2010 10:46 Single was a poor choice for Timer function. Single has accuracy of about 7 digits, so in the middle of the day it would look like 45123.15, so it's pushing the Single limit. You could use ABS() function to eliminate negative values, but it's better to use GetTickCount(). GetTickCount() is unaffected by the user changing the time by mistake, nor when the system synchronize with an external clock, so it's more reliable than Timer or DateDiff, both of which are affected by the time of day. The only issue with GetTickCount() is that it appears negative after 25 days from last boot, and rolls over to 0 after 49.7 days. To account for that, you can check if the return value suddenly went negative, or suddenly went 0. The code below account for all that. The only limitation is that intervals of more than 49.7 days are not supported, but in most situations nobody wants that. Option Explicit Private Declare Function GetTickCount Lib "kernel32" () As Long Private Sub Form_Load() Dim t As Double Dim i As Long t = GetTime() Debug.Print t For i = 1 To 10000 DoEvents Next Debug.Print GetTimeDiff(t) End Sub ' Returns the time in seconds since Windows has started, or ' since the last rollover to 0 every 49.7 days Public Function GetTime() As Double Dim t As Long Dim d As Double t = GetTickCount() If t < 0 Then ' Convert the negative number to 32 bit unsigned d = 2 ^ 32 - CDbl(t) * -1 Else d = CDbl(t) End If GetTime = Round(d / 1000, 3) End Function ' Returns the difference in seconds. Maximum period is ' 4294967.295 Seconds or 49.7 days. Compensates for negative ' values or rollover to 0 if it occurred after GetTime() call Public Function GetTimeDiff(ByRef dStart As Double) As Double Dim t As Long Dim d As Double t = GetTickCount() If t < 0 Then ' Convert the negative number to 32 bit unsigned d = 2 ^ 32 - CDbl(t) * -1 Else d = CDbl(t) End If d = d - dStart * 1000 If d < -1 Then ' Avoid very small negative numbers due to precision ' A rollover to 0 has happened, adjust for it d = d + 2 ^ 32 End If GetTimeDiff = Round(d / 1000, 3) End Function
First
|
Prev
|
Pages: 1 2 Prev: Run time error 4003→what can I do ? Next: Copy File to Linux Server |