Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Бред какой-то!!! 18==18 //output :: false (http://www.flasher.ru/forum/showthread.php?t=94956)

~~~ 24.04.2007 12:35

Бред какой-то!!! 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));


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... Так что, нас предупреждали =)


Часовой пояс GMT +4, время: 01:19.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.