Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
SCAN Confused?
Message
From
08/06/2001 09:07:31
Dragan Nedeljkovich (Online)
Now officially retired
Zrenjanin, Serbia
 
 
To
07/06/2001 16:58:53
Dragan Nedeljkovich (Online)
Now officially retired
Zrenjanin, Serbia
General information
Forum:
Visual FoxPro
Category:
Databases,Tables, Views, Indexing and SQL syntax
Title:
Miscellaneous
Thread ID:
00515720
Message ID:
00516841
Views:
12
>
close data all
>set safe off
>create data test
>create table milli (pkey t primary key, ndiff Y)
>
>ldCount = {^2001-01-01 12:00:00 AM}
>for j=1 to 100000
>	ldCount=ctot(ttoc(ldCount+1.000)) && variants of this line follow
>	insert into milli (pkey) value (ldCount)
>	replace ndiff with pkey-ctot(ttoc(pkey))
>endfor
>
>
>It will not break, but it will give you a millisecond here and there.
>With ldCount=ldCount+1, you always get about up to 499 milliseconds, and the moment it errors out is when it reaches the 500 - at 501, it breaks the index.

After further thinking, it seems to be adding more than 1000 milliseconds each time, and there definitely seems to be a rounding issue (i.e. it's converting to decimal seconds and storing back as milliseconds integer), so each time you manipulate the seconds part, it sort of goes into the real numbers and gets back to the integers. It gradually adds the roundoff error, and the initial version of the above routine breaks when the cummulative error crosses the 500 millisecond boundary. The last value recorded has the 0.500 seconds difference.

Conclusion: it keeps datetime() as a pair of integers, first one for the Julian date number, second for the number of milliseconds after midnight. However, this number of milliseconds is converted to seconds and back when manipulated as an expression. This way a roundoff error is introduced. When used as an index tag, however, the datetime value ignores the millisecond part, and basically uses the visible part only to build a key value. This is why the different (by millisecond) values of datetimes seem to be the same in terms of key values.

If the marked line above is changed to ldCount={^2001-01-01 12:00:00 AM}+j the code doesn't break anymore. There's a roundoff error, but it's one ms in 49927 records and 0 in others. The error is not accumulating, because we're not adding to the previous value.

Now if the line is changed once more to ldCount={^2001-01-01 12:00:00 AM}+j/2, the uniqueness of the key is broken as early as the second record, because the first value was 01/01/2001 12:00:01 AM - actually, 12:00:00.500, but displayed with the rounded second, and the next value has the same time in seconds, which causes the primary key to break. This only confirms my opinion that milliseconds are rounded up when using datetime as a key. The probable reason for this is the ability to SEEK on such a value - there's no way to enter, or display these decimals except in an expression like above - so as far as the user is concerned, it is hiding its decimals. This behavior has bitten us in the past as well, so, take care out there.

back to same old

the first online autobiography, unfinished by design
What, me reckless? I'm full of recks!
Balkans, eh? Count them.
Previous
Reply
Map
View

Click here to load this message in the networking platform