Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

integer math error

Ravanne Sullivan
Pole Dancer Extraordinair
Join date: 10 Dec 2005
Posts: 674
11-17-2008 15:14
default
{
state_entry()
{
}

touch_start(integer total_number)
{
llSay(0, (string)(200 * .7));
llSay(0, (string)((integer)(200 * .7)));
}
}


Casting 140.000000 to an integer = 139? I have found this round down error with other numbers also and it is causing a serious problem with some scripts.
_____________________
Ravanne's Dance Poles and Animations

Available at my Superstore and Showroom on Insula de Somni
http://slurl.com/secondlife/Insula de Somni/94/194/27/
Ralph Doctorow
Registered User
Join date: 16 Oct 2005
Posts: 560
11-17-2008 15:20
From: Ravanne Sullivan
default
{
state_entry()
{
}

touch_start(integer total_number)
{
llSay(0, (string)(200 * .7));
llSay(0, (string)((integer)(200 * .7)));
}
}


Casting 140.000000 to an integer = 139? I have found this round down error with other numbers also and it is causing a serious problem with some scripts.

Welcome to floating point math. The problem is that the 200 *.7 doesn't result in an exact number due to the limited precision of floats. It will be something like 139.9999999999. When you cast it to an integer, it's not a round, it's a truncate that drops the fractional part so the result is 139.

The first llSay doesn't show all the precision so it does a round to display the closest number, but that's almost always not what's internally stored.

There is an llRound function that might help, but in general don't rely on floats for exact values.
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
11-17-2008 15:31
One workaround is to do it like this which returns 140:

CODE

default {
state_entry() {
llSay(0, (string) (200 * 7 / 10));
}
}
_____________________
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
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
11-18-2008 14:05
Note that the rounding problem in this case starts not with the multiplication but with the constant 0.7, which has no exact binary representation. In binary it would have the representation 0.10110_0110_ (meaning that the sequence 0110 is repeated). The closest 32-bit floating point number to that is the value rounded down to binary 0.101100110011001100110011 which, when converted back to decimal, is 0.699999988079. That will produce a result which is slightly less than 140, and since all fractional parts are truncated when converting to an integer....
Viktoria Dovgal
Join date: 29 Jul 2007
Posts: 3,593
11-18-2008 14:21
This is not quite the usual rounding thing, it is actually an LSL Mono bug. You will get 140 for both if compiled with old LSL, but 140 and 139 with Mono.

The bug should be fixed when the 1.25 server finally rolls out.

http://jira.secondlife.com/browse/SVC-3328
Viktoria Dovgal
Join date: 29 Jul 2007
Posts: 3,593
11-18-2008 15:18
Just confirming the fix , Ravanne's sample script prints 140 under both LSO and Mono under 1.25.1 on the beta grid.
Ravanne Sullivan
Pole Dancer Extraordinair
Join date: 10 Dec 2005
Posts: 674
11-18-2008 15:32
Glad to hear they fixed it, just hope the 1.25 version doesn't introduce too many new bugs.
_____________________
Ravanne's Dance Poles and Animations

Available at my Superstore and Showroom on Insula de Somni
http://slurl.com/secondlife/Insula de Somni/94/194/27/
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
11-18-2008 16:51
Bah. This should NOT be "fixed." It is correct behavior according to the IEEE standard and thus it is the old LSL that was actually broken. See the comment I put in SVC-3328.
Viktoria Dovgal
Join date: 29 Jul 2007
Posts: 3,593
11-18-2008 17:27
LSL behavior seems to be following a float to int assignment as seen in gcc. The string representations follow %d and %f from the printf family.
Ralph Doctorow
Registered User
Join date: 16 Oct 2005
Posts: 560
11-18-2008 18:24
The original point still remains however. Relying on exact values for floats or chained operations behaving as if they had infinite precision is very bad programming practice.
Jeredin Denimore
Romani Ite Domum
Join date: 5 Jul 2008
Posts: 95
11-19-2008 07:03
From: Hewee Zetkin
Bah. This should NOT be "fixed." It is correct behavior according to the IEEE standard and thus it is the old LSL that was actually broken. See the comment I put in SVC-3328.

From: Ralph Doctorow
The original point still remains however. Relying on exact values for floats or chained operations behaving as if they had infinite precision is very bad programming practice.


Yup, yup :)
Wouter Hobble
Registered User
Join date: 25 Mar 2008
Posts: 21
11-20-2008 04:05
As a general note, it is better not to cast if you can properly use a function to say what you want, e.g. round, floor, ceiling.

The discussion about how the casts work is valid, but better coding practice is to make sure your script is not as susceptible to compiler differences. In short, just use llRound.

I only cast from float to int if I do not care so much, like with llFrand to get a channel.