PDA

Просмотр полной версии : Бред какой-то!!! 18==18 //output :: false


~~~
24.04.2007, 12:35
Всем извесно, что квадрат гипотинузы равен сумме квадратов катитов (ещё в школе учили:)).

a = 3;
b = 3;
c = Math.sqrt((a*a)+(b*b));
trace(c*c+" = kvadrat gipotinuzy");
trace((a*a)+(b*b)+" = summa kvadratov katitov");
trace(c*c == (a*a)+(b*b));

etc
24.04.2007, 13:00
3*3+3*3 = 9+9 = 18. Квадратный корень из 18 ограничен по числу знаков. В AS3 точность выше и мы на выходе получаем 17.999999999999996, а не 18. Т.е. нужно округлять c*c до целого.

motor4ik
24.04.2007, 13:01
trace(String(c*c) == String((a*a)+(b*b)));

т.к. при trace (c*c) вы видете 18 а это именно String(c*c)

etc
24.04.2007, 13:05
Видимо, во внутреннем представлении все же идет на разделение операций с плавающей запятой и целочисленных.

0xFFFFFF
24.04.2007, 13:11
trace(Math.round(c*c) == Math.round((a*a)+(b*b))); // true

~~~
24.04.2007, 13:18
a = 3;
b = 3;
c = Math.sqrt((a * a) + (b * b));
trace(c * c + " = kvadrat gipotinuzy");
trace((a * a) + (b * b) + " = summa kvadratov katitov");
trace(String(c * c) == String((a * a) + (b * b)));-естественно true, а вотtrace(Number(c * c) == Number((a * a) + (b * b)));-false
При таком раскладе к вычислению добавляется ещё строчка :(c = Math.sqrt(Number(((a * a) + (b * b)).toString()));Или это уже бред?

Math.round - не гарантирует идеальной точности вычислений, а хотелось бы к этой идеальности приблизиться:)

etc
24.04.2007, 13:30
Пример:

a = 4.24264068711928*4.24264068711928;
b = 18;
c = 18;
trace(a==b); // false
trace(b==c); // true
В декомпиле:

a = 18;
b = 18;
c = 18;
trace (a == b);
trace (b == c);
В реальности:
constants 'a', 'b', 'c'
push 'a', 18.00
setVariable
push 'b', 18
setVariable
push 'c', 18
setVariable
push 'a'
getVariable
push 'b'
getVariable
equals
trace
push 'b'
getVariable
push 'c'
getVariable
equals
trace
end

Как видим, 18.00 и 18 совсем не равны.

В байт коде:

push 'a', 18.00 это:
960B00080006FFFF3140F4FFFFFF
А push 'b', 18 это:
96070008010712000000
И, наконец, push 'c', 18 это:
96070008020712000000

Как видно, последние два push имеют тип 07h, т.е. integer, целое число. А в первом случае 06h (видимо, double 64bit). В общем, особо не разбирался да и лень.
Идеальной точности не добиться. Особенно при работе с корнями.

~~~
24.04.2007, 13:41
__etc, супер, всё, прям, популярнинько разложил! Спасибо!
А я чего-то сам на байт-код не додумался взглянуть...

iNils
24.04.2007, 14:26
Cамый простой пример:
a = 3;
b = 3;
c = Math.sqrt ((a * a) + (b * b));
trace (18 - c * c);
trace (18 - (a * a) + (b * b));Проблемы с точностью вычислений (причем это касается не только флеша, но и яваскрипт и пхп) уже не раз на форуме обсуждалась.

wvxvw
24.04.2007, 14:50
Math class are emulated using approximations and might not be as accurate as .... blah-blah
Эта строчка присутствует в описании практически всех методов Math... Так что, нас предупреждали =)

iNils
24.04.2007, 14:54
Эта строчка присутствует в описании практически всех методов Math... Так что, нас предупреждали =)Дело не только в Math, такие проблемы и с обычными +- есть.