PDA

Просмотр полной версии : Почему выражение "n/2 == Math.round(n/2)" принимает значение "false"?


burdich
26.04.2008, 22:49
Почему выражение n/2 == Math.round(n/2) принимает значение "false", даже если "n" равно целым чётным числам (2,4,6...).

Пример кода наглядно это демонстрирующего:
var n:Number=0;
onEnterFrame = function () {
trace ("a="+n/2);
trace ("b="+Math.round(n/2));
trace ("c="+(n/2 == Math.round(n/2)));
n+=0.2
}

iNils
26.04.2008, 23:20
У флеша есть погрешность при сложении дробных чисел не кратных (0.5, 0.25, 0.125, 0.0625 и тд).
Поэтому со временем накапливается ошибка при сложении.
И реально, при многократном вызове n+=0.2, вместо 4 оказывается число 4.000000000000000888178419700125

Вторая проблема заключается в том, что при таком малом значении дробной части, в трейс выводится только целая часть, что может вызывать кучу проблем и вопросов, вроде сраниваем
trace (n +" == 4 -->" + (n== 4))
//// 4 == 4 --> false
а получается, что 4 не равно 4.
Увидеть данную проблему можно так:
trace (n - 4)
//// 8.88178419700125e-16

burdich
27.04.2008, 13:31
Спасибо огромное за адекватный и развёрнутый ответ!

В принципе я что то подобное подозревал, а есть ли тогда еще какой способ проверки числа на кратность другому, любому числу. Допустим у меня есть переменная-счетчик "x += n" (где n - любое число), и мне нужно отслеживать кратность "x" чилсу "y".

Пример:
var x:Number = 0;
onEnterFrame = function () {
if (x кратно 7) {
trace (true);
}
x += 0.1
}

Заранее спасибо.

Fernando Costa
27.04.2008, 14:11
if(Math.abs(a-b)< 0,0000001) trace('равно')

iNils
27.04.2008, 16:37
Если числа целые, то
n = 4;
trace (n % 2 == 0);
//// true
n = 5;
trace (n % 2 == 0);
//// false
n = 6;
//// true
trace (n % 3 == 0);
n = 7;
//// false (n % 3 == 0);

burdich
28.04.2008, 13:44
Точно, смотреть по остатку. Спасибо еще раз, я думаю это пригодиться не только мне.