Просмотр полной версии : Бред какой-то!!! 18==18 //output :: false
Всем извесно, что квадрат гипотинузы равен сумме квадратов катитов (ещё в школе учили:)).
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));
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)
Видимо, во внутреннем представлении все же идет на разделение операций с плавающей запятой и целочисленных.
0xFFFFFF
24.04.2007, 13:11
trace(Math.round(c*c) == Math.round((a*a)+(b*b))); // true
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 - не гарантирует идеальной точности вычислений, а хотелось бы к этой идеальности приблизиться:)
Пример:
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). В общем, особо не разбирался да и лень.
Идеальной точности не добиться. Особенно при работе с корнями.
__etc, супер, всё, прям, популярнинько разложил! Спасибо!
А я чего-то сам на байт-код не додумался взглянуть...
Cамый простой пример:
a = 3;
b = 3;
c = Math.sqrt ((a * a) + (b * b));
trace (18 - c * c);
trace (18 - (a * a) + (b * b));Проблемы с точностью вычислений (причем это касается не только флеша, но и яваскрипт и пхп) уже не раз на форуме обсуждалась.
Math class are emulated using approximations and might not be as accurate as .... blah-blah
Эта строчка присутствует в описании практически всех методов Math... Так что, нас предупреждали =)
Эта строчка присутствует в описании практически всех методов Math... Так что, нас предупреждали =)Дело не только в Math, такие проблемы и с обычными +- есть.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.