Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Anomalous llGetTimestamp result

Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
11-16-2007 10:53
Hi,
For a testing project I had to develop a combination of the values from hours minutes and seconds from the results of a llGetTimestamp.
I was very surprised to get the results from the following code
CODE

list timestamp;
float timeonly;
default
{
state_entry()
{
llSay(0, "Hello, Avatar!");
}
touch_start(integer total_number)
{
llSay(0, "Touched: "+(string)total_number);
timestamp = llParseString2List( llGetTimestamp(), ["-","T",":","Z"] , [] );
llSay(0,llList2String(timestamp,0));
llSay(0,llList2String(timestamp,1));
llSay(0,llList2String(timestamp,2));
llSay(0,llList2String(timestamp,3));
llSay(0,llList2String(timestamp,4));
llSay(0,llList2String(timestamp,5));
timeonly = (((llList2Float(timestamp,3) * 60) + llList2Float(timestamp,4)) * 60 + llList2Float(timestamp,5));
llSay(0,(string)timeonly);
}
}
[\code]

results
[begin]
timebox: Hello, Avatar!
timebox: Touched: 1
timebox: 2007
timebox: 11
timebox: 16
timebox: 16
timebox: 44
timebox: 51.049803
timebox: 60291.050781
[end]

Can anyone explain the difference in the valuesin the hundredths of seconds?
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
11-16-2007 11:59
Well, not sure about "explain" but... I think you're just encountering the limited precision of floating point numbers. When those hours and minutes get multiplied and added together with the seconds, it's a much bigger number, so the significand gets truncated so the digits after the decimal point lose precision. At least that's what I think is going on.
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
11-16-2007 14:34
From: Qie Niangao
Well, not sure about "explain" but... I think you're just encountering the limited precision of floating point numbers. When those hours and minutes get multiplied and added together with the seconds, it's a much bigger number, so the significand gets truncated so the digits after the decimal point lose precision. At least that's what I think is going on.
If you multiply one number by another, especially if one is one without any decimal positions the result has fewer decimal positions.
2 * 2 = 4 so what does 2.0 * 2.0 equal? or 16 * 60 or 1004 * 60? adding the final value shouldn't change the precision of the result. Or am i wrong?
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
11-16-2007 15:19
But the numbers are stored as floating-point (not separately as integers and fractional parts), so what matters is the total number of significant digits (or, actually, significant bits) in each number being represented (notably, the sum).

I'm not sure, though, about the original representation of the number(s) being reported with llGetTimestamp, in order to get those results. (maybe unsigned? double?)
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
11-16-2007 15:39
It does seem indeed, that the typecast from float to string produces pretty arbitrary results.

Try the following:

float numb = 51.049803

llSay(0, (string)numb);

Result: 51.049805

When numb = 51.04

the result of llSay is: 51.040001

interesting, I'd say... and most likely a bug - either in the floating point unit or in the typecast function for float to string...
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
11-16-2007 16:13
I don't know the best resource to point you to in regards to this. It has to do with IEEE 754 single precision floating point. But it isn't a bug. The simulator is still having to process the float even if it is just having to typecast it from a float to a string.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
11-16-2007 16:19
http://www.lslwiki.net/lslwiki/wakka.php?wakka=float[/float]

More specifically,

[url=]http://steve.hollasch.net/cgindex/coding/ieeefloat.html[/url]

and

[url=]http://cch.loria.fr/documentation/IEEE754/ACM/goldberg.pdf[/url]
Ace Cassidy
Resident Bohemian
Join date: 5 Apr 2004
Posts: 1,228
11-16-2007 16:37
I have a Mathematics degree, and when I was going to school, I took a course in "Numerical Analysis" which was a year-long course that considered computational problems that are the result of the fact that a computer has to represent floating point numbers with a finite number of bits.

To offer some insight, consider the fact that with 32 bits, there are approximately 4 billion unique numbers that can be represented. That sounds like a lot of numbers, but if the number you are trying to represent with those bits isn't exactly one of those 4 billion, then there is inevitably some "roundoff error".

Given the way that floating point numbers are represented, exactly half of those 4 billion are numbers between -1 and +1. Basically, the further from 0 that the number you are trying to represent, the larger the roundoff error.

There are "numerical methods" that can minimize computational roundoff error to any arbitrary precision that you want, but these methods are computationally expensive, and typically only used when precision is required for the task at hand. In general, most computing simply accepts this roundoff error, and hopes that whatever calculations are being performed don't accumulate the roundoff error too much.

Its a fact of computational life, and there ain't nuttin' we can do about it.

- Ace
_____________________
"Free your mind, and your ass will follow" - George Clinton
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
11-16-2007 16:46
Aye. I have done some of those "computationally expensive" methods before, doing things like managing fractions (keeping the numerator and denominator separate until the final calculation is needed, for example), but it is only good for simple math.

When you have a need for extreme precision, the code to implement arbitrary precision math can get very hairy indeed.
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
11-16-2007 17:01
It usually isn't a problem with one notable exception in SL; prim drift. A problem that has been around forever and finally just accepted by everyone. You could build a long wall and would have to go back and straighten up the prims every now and then. Gearsawe Stonecutter and I spent two months in Aditi and shared well over a hundred hours working on the problem. Finally came up with one model of a prim that would rotate back and forth constantly, non-stop. Adjusting path cut and other attributes gave us a prim that would move several meters per day.

Finally came to the conclussion that because of Havok priority prim data was stored by it's bounding box first. Everytime it had to rotate or there was a sim restart then the simulator would get that value and start multiplying the other floats for different attributes. So you had floating point errors multiplied by floating point errors on top of other errors. Milo Linden had some involvement and Kelly was updated a few times on it. We haven't heard anything else about and haven't gotten around to asking but................ it is fixed now in Havok 4. No more prim drift after all of this time.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
11-16-2007 17:27
I recommended for a while that folks use binary fractions for positioning prims, both in the world, and in linksets. It sometimes helped, but not always. Chances are, the problem was the bounding box centers weren't calculated to exact binary fractions every time, depending on the object itself.

Anyway, glad it is solved in H4. Now, if we can just get it rolled to live. :)
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
11-16-2007 23:12
after having played with making a calculator in lsl (negation, exponents, */+-, and brace supported) I found that rounding errors in sl tend to creep up to about the 5-6th decimal place... my solution was to round all decimal returns to the 4th place, not a perfect solution, but an effective one
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
11-17-2007 00:54
These are interesting insights into the world of math, pholks...

I guess, the suggestion of one of you to just use the digits after the decimal point up to the 4th or 5th number doesn't really work.

Say, I have the number 51.049800 which results in 51.049801 when I convert it to a string (which actually is kinda ridiculous, since the 1 at the end is just 1 millionth of 1). I can't get rid of this «1» at the end.

I tried the following:

CODE


float res;
string s_res;
integer int;

res = llFloor(100000 * 51.049803);

int = (integer)res; // results in 5104980

s_res = (string)int + "0"; // results in 51049800

res = (float)s_res / 1000000; // results in 51.049801



I guess, there's no chance to make this number actually read 51.049800?

Again - I think this isn't that bad since the 1 at the end is such a small number and wouldn't really have an impact on anything. Unless I do some computation that goes on for a long time which - the sooner or later - would mess up the whole math...

damn... I thought that computers were smarter :) (or maybe it's me who's the dumbass?)
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
11-17-2007 01:58
All I can say is thanks Guys for updating me.

I feel like a bear that has taken a stick and poked it in a hole to get the honey and got the bees instead!

I think for the purpose I had in mind I will neglect the hours and minutes and just report the seconds and the differences between successive calls to the timer.
I am trying to speed up a script and thus need to know where the most time is being spent. Hopefully I will then be able to change that (whatever it is) to improve its performance.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
11-17-2007 16:39
From: Haruki Watanabe
These are interesting insights into the world of math, pholks...

I guess, the suggestion of one of you to just use the digits after the decimal point up to the 4th or 5th number doesn't really work.

the trick here is to round before the end, not at the begining, because lsl floats seems to only be accurate to 6 places which is odd since I think the standard for single precision floats is 7 places? ...

@Gregory:
do you even need anything past seonds?, if not you could just typecast to integer... or even fake it by getting just the fractional part, multiplying it upwards, save as integer, and use a string coded version that concatates and inserts a decimal point... and if you are just timing nternal events, you can just use llGetTime (which will give the scripts runtime in seconds, but is affected by time dilation)
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -