llFloor() has floating point precision in LSL/Luau
in progress
Log In
Signal Linden
in progress
Maestro Linden
Merged in a post:
Integer formatted as float compiling LSL in Luau/LSL mode.
animats Resident
LSL Mono mode:
[20:13] Lua/:LSL test 1: Step calculation: 92 Escalator steps
LSL/Luau mode:
[20:13] Lua/:LSL test 1: Step calculation: 92.000000 Escalator steps
Code:
default
{
state_entry()
{
llSay(0, "Hello, Avatar!");
}
touch_start(integer total_number)
{
llSay(0, "Step calculation");
vector hibound = <0, 0, 20.0>;
vector lobound = <0, 0, 1.0>;
float NONSTEPHEIGHT = 1.0;
float STEPHEIGHT = 0.20;
integer EXTRASTEPS = 2;
float stepareaheight = hibound.z - lobound.z - NONSTEPHEIGHT;
integer stepcount = llCeil(stepareaheight / STEPHEIGHT) + EXTRASTEPS;
////integer stepcount = 32;
string name = "Escalator steps";
string namepart = " " + (string) stepcount + " " + name;
llSay(0, "Step calculation: " + namepart);
}
}
See related bug: https://feedback.secondlife.com/luau-alpha/p/llfloor-has-floating-point-precision-in-lsl-luau
Note that even though "stepcount" is explicitly declared integer, it is treated as a floating point number by the cast to string.
Now, if I just use the line "integer stepcount = 32;", I get an integer result.
This breaks my escalators, which compute how many steps are needed from the size and select the appropriate set of steps from inventory by a constructed name.
Maestro Linden
Here's a slightly simpler repro script:
default
{
state_entry()
{
integer one = llCeil(1);
llSay(0, (string)(one + 2));
}
}
The output is "3.000000". So not only is llCeil() returning a float; it's also being stored in an integer. Merging this into the bug Peter mentioned.
animats Resident
Maestro Linden - right. It makes sense. Internally, "number" in Lua is a 64-bit float, and typing is dynamic. Mapping that to LSL's static typing requires checks where something has to be integer.
Maestro Linden
tracked
Maestro Linden
Confirmed; it appears that llFloor() and llCeil() both return a float rather than the expected integer in LSL/Luau mode. llRound() returns an integer:
default
{
state_entry()
{
llOwnerSay("llFloor(12.34) = " + (string)llFloor(12.34));
llOwnerSay("llCeil(12.34) = " + (string)llCeil(12.34));
llOwnerSay("llRound(12.34) = " + (string)llRound(12.34));
}
}
> llFloor(12.34) = 12.000000
> llCeil(12.34) = 13.000000
> llRound(12.34) = 12
animats Resident
More trouble involving llCeil:
Tried compiling my NPC code in LSL/Lual mode.
Run time error:
(Testi v22.1 (Lual Mesa)) Testi v22.1 (Lual Mesa) in trouble at Luau Mesa <236.36690, 241.64190, 28.21679>: Testi v22.1 (Lual Mesa) [script:Path prep task] Script run-time error
[20:47] Debug relay: [20:47:03] (Testi v22.1 (Lual Mesa)) Testi v22.1 (Lual Mesa) in trouble at Luau Mesa <236.36690, 241.64190, 28.21679>: lsl_script:0: attempt to compare userdata <= number
lsl_script function _fdopathturn
lsl_script function _e0/link_messa...
[20:47] Debug relay: === STORED LOG DUMP END ===
(I have a listener on the error channel to catch and log errors. The usual error popup appeared, too.)
Code:
dopathturn(float heading, integer pathid)
{
vector facedir = <llSin(heading), llCos(heading), 0.0>;
float TURNRATE = 90*DEG_TO_RAD;
float PATH_ROTATION_EASE = 0.5;
rotation endrot = llAxes2Rot(llVecNorm(facedir),<0,0,1>%llVecNorm(facedir),<0,0,1>);
rotation startrot = llGetRot();
float turntime = llFabs(llAngleBetween(startrot, endrot)) / TURNRATE;
integer steps = llCeil(turntime/0.200 + 0.001);
integer i;
for (i=0; i<= steps; i++)
{ float fract = ((float)i) / steps;
float easefract = easeineaseout(PATH_ROTATION_EASE, fract);
llSetRot(slerp(startrot, endrot, easefract));
}
pathdonereply(0, NULL_KEY, pathid);
}
Note use of llCeil, followed by the integer result not behaving like an integer.
WolfGang Senizen
Further this isn't just a string casting bug
list a = [llFloor(20.0)];
llOwnerSay((string)llGetListEntryType(a,0));
Prints
2
which is TYPE_FLOAT