ItHadToComeToThis Posted December 28, 2019 Share Posted December 28, 2019 I really should know this but its 3.33am and im 7 hours into a 12 hour shift and im tired and my brain just is having a "blank moment" on this piece of code So, integer i=0; float alpha=1.0; while(++i<=10){ alpha-=0.1; llSetLinkPrimitiveParamsFast(tLink,[ PRIM_TEXT,llList2String(pStr,1),<1.0,1.0,1.0>,alpha ]); llSleep(1.0); llOwnerSay((string)alpha); } Why is this returning a bounds error when alpha reaches 0.1. What glaringly obvious thing am I missing here that I am going to kick myself over once I realise what it is. Link to comment Share on other sites More sharing options...
KT Kingsley Posted December 28, 2019 Share Posted December 28, 2019 (edited) Object: llSetPrimitiveParams error running rule #1 (PRIM_TEXT): bounds error; -7.45058e-08 is not in (0, 1). That's a very tiny negative number, so I'd say it's a rounding error. This does seem to work, though: integer i=0; integer alpha = 10; while(++i<=10) { alpha-=1; llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_TEXT,"test",<1.0,1.0,1.0>,(float) alpha / 10.0]); llSleep(1.0); } Edited December 28, 2019 by KT Kingsley 1 Link to comment Share on other sites More sharing options...
animats Posted December 28, 2019 Share Posted December 28, 2019 57 minutes ago, ItHadToComeToThis said: I really should know this but its 3.33am and im 7 hours into a 12 hour shift and im tired and my brain just is having a "blank moment" on this piece of code So, integer i=0; float alpha=1.0; while(++i<=10){ alpha-=0.1; llSetLinkPrimitiveParamsFast(tLink,[ PRIM_TEXT,llList2String(pStr,1),<1.0,1.0,1.0>,alpha ]); llSleep(1.0); llOwnerSay((string)alpha); } Why is this returning a bounds error when alpha reaches 0.1. What glaringly obvious thing am I missing here that I am going to kick myself over once I realise what it is. Because, at the end of that loop, alpha is very slightly less than zero. If you convert alpha to a string, you will get 0.000000. But that's a rounded value. Displaying 1000*alpha gets i: 1 alpha:0.900000 ltzero: 0 1000 x alpha: 900.000000 i: 2 alpha:0.800000 ltzero: 0 1000 x alpha: 799.999900 i: 3 alpha:0.700000 ltzero: 0 1000 x alpha: 699.999900 i: 4 alpha:0.600000 ltzero: 0 1000 x alpha: 599.999900 i: 5 alpha:0.500000 ltzero: 0 1000 x alpha: 499.999900 i: 6 alpha:0.400000 ltzero: 0 1000 x alpha: 399.999900 i: 7 alpha:0.300000 ltzero: 0 1000 x alpha: 299.999900 i: 8 alpha:0.200000 ltzero: 0 1000 x alpha: 199.999900 i: 9 alpha:0.100000 ltzero: 0 1000 x alpha: 99.999920 i: 10 alpha:0.000000 ltzero: 1 1000 x alpha: -0.000075 Link to comment Share on other sites More sharing options...
ItHadToComeToThis Posted December 28, 2019 Author Share Posted December 28, 2019 Thank you. I forgot all about rounding. I need to stop coding for the night. Thank you so much, really appreciated Link to comment Share on other sites More sharing options...
Madelaine McMasters Posted December 28, 2019 Share Posted December 28, 2019 When I'm coding a loop that is intended to produce a series of floating point numbers, I usually compute them from the loop index rather than by accumulation. This forces me to think through the math and avoids accumulating errors along the way. That's how KT did it. 1 Link to comment Share on other sites More sharing options...
Nova Convair Posted December 28, 2019 Share Posted December 28, 2019 There are decimal numbers (like 0.1) that you can not convert into a binary format (like the SL floating point). If you convert it anyways it will not be 0.1 but a tiny bit different. If you really dare to do that in a loop then your error will sum up and become more prominent. So, that's a great example you gave. There are many ways to compensate. I never directly compare 2 floats/vectors/rotations for equality btw. - for the same reasons. Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted December 28, 2019 Share Posted December 28, 2019 1 hour ago, Nova Convair said: I never directly compare 2 floats/vectors/rotations for equality Quite right, industry best-practice is to subtract item A from item B, take the absolute value of the result, see if it less than a constant giving the tolerance for the particular type of item. It just gets tedious sometimes, all that extra coding @) Link to comment Share on other sites More sharing options...
Nova Convair Posted December 28, 2019 Share Posted December 28, 2019 10 hours ago, Profaitchikenz Haiku said: It just gets tedious sometimes, all that extra coding No, not really. Example for float, vector and rotation: if (llFabs(float1-float2)<0.01) ... if (llVecDist(vector1,vector2)<0.01) ... if (llAngleBetween(rotation1,rotation2)<0.01) ... The 0.01 needs to be replaced with the precision you need. 2 Link to comment Share on other sites More sharing options...
Mollymews Posted December 31, 2019 Share Posted December 31, 2019 adding to what KT and Maddy mention we can get a tiny performance gain by using a multiplication rather than a division. Example: integer i = 0; while (++i <= 10) { float alpha = (10.0 - (float)i) * 0.1; } alternatively for another tiny performance gain, by eliminating the subtraction integer i = 10; while (--i) { float alpha = (float)i * 0.1; } Link to comment Share on other sites More sharing options...
Recommended Posts
Please take a moment to consider if this thread is worth bumping.
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now