GameHour decimal places

Post » Sat Feb 19, 2011 4:33 am

I need a "time stamp" sort of variable to keep track of when certain events occur. What I'd like to do is set a variable equal to ( GameDaysPassed + GameHour / 100 ), however I've read that floats are limited to 7 decimal places, so this raises my question:

How many decimal places does the GameHour variable require without losing precision?

(I think it's only 4, thus 6 for my timestamp, but I figured I'd check if anyone knew different.)

EDIT:
Ok, I used a MessageBox instead of the Show console command, and it's certainly more than 4 places, and now I'm also skeptical of the 7 place precision reported in the CS wiki.

This returned a number with 15 place precision:
MessageBox "%.20f" GameHour


This returned a number with 16 place precision:
float TimeStamplet TimeStamp := GameDaysPass + GameHour / 100MessageBox "%.20f" TimeStamp

User avatar
Kaley X
 
Posts: 3372
Joined: Wed Jul 05, 2006 5:46 pm

Post » Fri Feb 18, 2011 8:09 pm

In general floats have a total precision, rather than a limited number of decimal places. I don't recall the standard precision of float, but let's take 10 digits as a round number. With three positions of days left of the decimal point, you'd have 7 digits remaining available for the right. My guess would be that the quote of 7 decimal places was for a specific instance with a fair number of digits on the left. There may also be limits on scale, so if you're working with numbers where the decimal point is further away than the precision, you could have problems, but your instance isn't one of those.

The next issue is the accuracy of the variable, i.e. how often does it get evaluated? You may see a higher apparent precision than you really get. If you get the value multiple times in quick succession, you may not get any change, even though the interval between the calls is longer than the value itself implies. What I mean is that you if you call a hundredth of a second later, you may get the same result, even though you get a value with 1/1000 sec "accuracy". Some of that will be due to base conversion (you're looking at decimal digits, but the hardware's doing binary) and some will be due to the value actually being that accurate when taken, but not being replaced every time you call. If you're just using it to label events to distinguish them or put them in order, that's OK, but if you're trying to calculate intervals it could be an issue. I doubt you'd be using GameHour for that, though, as it's a derived value rather than real time.
User avatar
jeremey wisor
 
Posts: 3458
Joined: Mon Oct 22, 2007 5:30 pm

Post » Sat Feb 19, 2011 3:52 am

That's helpful info, thank you. I feel like I should have recognized both of those issues, but fact is I hadn't.
The actual vs apparent precision issue relieves my concern about using my decimal shifted time stamp.

I can't help but wonder, though: If GameHour is a derived value, what's the real-time value that it's derived from, and do we have access to it?
User avatar
willow
 
Posts: 3414
Joined: Wed Jul 26, 2006 9:43 pm

Post » Fri Feb 18, 2011 5:50 pm

Game time advances as a function of real time set by a value in the .ini file, but anything that enters menumode will suspend or override it. So time is stopped entirely when you shop, but advances rapidly when you wait or sleep.
User avatar
TWITTER.COM
 
Posts: 3355
Joined: Tue Nov 27, 2007 3:15 pm

Post » Sat Feb 19, 2011 7:13 am

The way I understand oblivion floats is that they can hold the 7 most significant digits, no matter the decimal point.

So, a float can hold 1,234,567,000,000, but will not hold 1,234,567,800,000 (the 8 would be lost)
The same way, 0.0000001234567 is OK while 0.00000012345678 would lose the 8.

This way, Gamehour will have up to 5 decimal places: hh.ddddd, which is a precision of about 1/20 of a second.
But if you use GameDaysPassed plus hours (as fractions of a day), you would have max = DDD.dddd, which is a precision of about 10 seconds. When you get to GameDaysPassed = 1000, your precision drops to three decimals (DDDD.ddd), or about one minute.

If this may be of any help, I timestamp all my console lines with the following code:

float v short iHourstring_var sTime;-------------------------------;	Set timestamp string;-------------------------------set v to GameHour			;= hh.ddddset iHour to GameHour		; integer if iHour < 10	let sTime   := "0" + sv_construct "%0.0f:" iHourelse	let sTime := sv_construct "%0.0f:" iHourendifset v to (v - iHour) * 60		;= mm.ddddset iMin to v 				;= mmif iMin < 10	let sTime := sTime + "0" + sv_construct "%0.0f:" iMinelse	let sTime := sTime + sv_construct "%0.0f:" iMinendifset v to (v - iMin) * 60		;= ss.ddddif v < 10	let sTime := sTime + "0" + sv_construct "%2.1f " velse	let sTime := sTime + sv_construct "%2.1f " vendif

User avatar
JERMAINE VIDAURRI
 
Posts: 3382
Joined: Tue Dec 04, 2007 9:06 am

Post » Sat Feb 19, 2011 10:08 am

Hmm, I don't like the sound 10sec, and especially not 1min, precision (or lack thereof..).
I kind of like the idea of using the strings, I'll play around with that and see what I come up with.

Thank you for the input.
User avatar
Beat freak
 
Posts: 3403
Joined: Thu Dec 14, 2006 6:04 am

Post » Sat Feb 19, 2011 10:26 am

Barring any unforeseen complications, I believe I'm settled on a format.
In an effort to both retain as much precision as possible, and to keep it within a single variable (using it as an obse array key), I've done this:
string_var dswTimeStamplet dswTimeStamp := sv_Construct "%.0f:%.15f" GameDaysPassed GameHour

Tearing it apart with sv_Split and sv_ToNumeric for comparisons is a little more intensive than I'd like, but I'd rather have to deal with that than worry about losing precision down the road.
Possibly overkill, but thus far I'm pleased with it.
User avatar
Bellismydesi
 
Posts: 3360
Joined: Sun Jun 18, 2006 7:25 am


Return to IV - Oblivion