Groups | Blog | Home
all groups > flash actionscript > october 2005 >

flash actionscript : BUG: passing float type Numbers to the function by value


Jeckyl
10/23/2005 12:00:00 AM
There is no bug. It is the nature of floating point (non-whole) numbers in
computers. They cannot exactly represent 0.1 as a floating point number ..
its only an approximation, with a very small error. However, everytime you
add, the error increases, until it makes a big enough difference to be
noticed.

Basically, you need to take into account that nature of floating point
numbers and not even rely on exact calculations for floating point numbers.
Always test for a range of values (eg. Math.abs(x-y) < 0.001 instead of x ==
y etc). Or use whole numbers (which do not have that 'problem').

[quoted text, click to view]

then you'll look like a fool, because there is no problem with the 'function
command' .. if you can remove it, I suggest you do so.
--
Jeckyl


unAbacus
10/23/2005 12:00:00 AM
Weird... probably has something to do with rounding errors. this code echos true

trace(0.6000000000000001 == (6 * 0.1))

when it should be below that echos true

trace(0.6 == (6 * 0.1))

even using === it's wrong

probably sorted in flash 8 tho.
kglad
10/23/2005 12:00:00 AM
unAbacus
10/23/2005 12:00:00 AM
Really? i would be interested to know how it occurs... that would be cool. only
ever paid enough attention to binary in my education to get what i needed to
get done. So it isn't a rounding error. kgad can you explain it? cheers
kglad
10/23/2005 12:00:00 AM
Derils
10/23/2005 10:48:27 AM
Hello,

my freand sent me his fla complaining that his program fail to work.
by analyzing the sourse ifound bug in flash.
if you try to pass real type number to the function after some time flash
makes little error.
this error is little enough now show itself.. but error ruins all logic.

I wrote an example..
loop add 0.1 nine times and cheks the logical operations : ">" "==" "<"

output goes as folows:

(_root.betas_test):0.1 # (1*0.1):0.1 :: (>)false (==)true (<)false
(_root.betas_test):0.2 # (2*0.1):0.2 :: (>)false (==)true (<)false
(_root.betas_test):0.3 # (3*0.1):0.3 :: (>)false (==)true (<)false
(_root.betas_test):0.4 # (4*0.1):0.4 :: (>)false (==)true (<)false
(_root.betas_test):0.5 # (5*0.1):0.5 :: (>)false (==)true (<)false
(_root.betas_test):0.6 # (6*0.1):0.6 :: (>)false (==)false (<)true
(_root.betas_test):0.7 # (7*0.1):0.7 :: (>)false (==)false (<)true
(_root.betas_test):0.8 # (8*0.1):0.8 :: (>)false (==)false (<)true
(_root.betas_test):0.9 # (9*0.1):0.9 :: (>)false (==)false (<)true


0.5 == 0.5 returns true...
and
0.6 == 0.6 returns false.. insted - 0.6 < 0.6 returns true.


I sujested t ofreand. to pass interger numbers in function by value insted of
real type.. and program started to work..

As flash developer and programer i want to know why flash makes such mistakes?
will it be fixed?

I work with geometry and angles a lot. and am using functions to pass real
numbers a lot.
now i converted all data to interger and convert back in the function body to
avaid mistakes.
its a big discomfort.

I also added live doc note abaut the function command.

_root.test = 0;
_root.clickcount = 0;
function funkcija(kintamasis) {
_root.test += kintamasis;
_root.clickcount++;
trace("(_root.betas_test):"+_root.test+" #
("+_root.clickcount+"*0.1):"+(_root.clickcount*0.1)+" ::
(>)"+(_root.test>(_root.clickcount*0.1))+" (==)"+(_root.test ==
(_root.clickcount*0.1))+" (<)"+(_root.test<(_root.clickcount*0.1)));
}
for (i=1; i<10; i++) {
funkcija(0.1);
}
Jeckyl
10/24/2005 12:00:00 AM
I already explained .. 0.1 cannot be expressed exactly in binary .. just
like 1/7 cannot be expressed exactly in decimal.

So if it snot exactly represented, there is an error .. and every time you
perform operations on numbers, the error increases until it becomes big
enough to make a difference .. for things like equality checks .. where the
entire bit representation of the number must be identical .. this doesn't
take much.

That is why you should not (and cannot) rely on exact equality checks when
working with floating point numbers.

Whole numbers, however, don't have that problem, as all whole numbers (that
aren't huge) can be represented exactly.
--
Jeckyl

Derils
10/24/2005 8:30:11 AM
hi all. thanks for answers.

then problem is that trace shows 0.6 .. insted of
0.6000000000000001
why is that?

unAbacus
10/24/2005 8:45:36 AM
ah cool - cheers Jeckl, i've worked with computers for years and never knew
that - i'm not really a maths guy tho...

yeah it's odd that flash doesn't show the real number - or at least there
isn't a way to get at it - but if it is a problem with binary mathematics,
they'll just round it up to avoid confusion - best thing by the sounds of it is
to always Math.round your floating points to a certain decimal place or not use
them for ways such as this...
Derils
10/24/2005 1:12:07 PM
i also fail to understand why 0.1 canot be coded to binary exactly.
eny article on how the flash codes real numbers?
usualy it takes some bites to code the point location.. and rest bites is used
for number.
kglad
10/24/2005 2:54:45 PM
Jeckyl
10/24/2005 11:23:23 PM
[quoted text, click to view]

try it .. you'll find out .. its just like 1/3 = 0.333333... or 1/7 =
0.142857142857142857... are not exactly/finitely represented in decimal.

[quoted text, click to view]

eh?

Flash uses fixed point (ie whole numbers internally) for coordinates .. it
stores them internally as a whole number of twips (a twip is 1/20 of a
pixel), So 2.3 is 46 twips. But these values get converted to/from
floating point when accessed from script. That won't cause a problem as the
conversion rounds to the nearest twip.
--
Jeckyl

AddThis Social Bookmark Button