Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Непонятное поведение математики в JS (https://javascript.ru/forum/events/32747-neponyatnoe-povedenie-matematiki-v-js.html)

Teol 28.10.2012 23:40

Непонятное поведение математики в JS
 
Здравствуйте,
делал скрипт для изменения прозрачности в JS (учусь),
вот скрипт:

function opacify(x_opacity, y_opacity, time) {
	var steps = 10,
			time = (!time) ? 1000 : time,
			x_opacity = (!x_opacity) ? 1 : x_opacity,
			y_opacity = (!y_opacity) ? 0 : y_opacity,
			anim_step = (y_opacity - x_opacity) / steps,
			counter = 0,
			new_opacity,
			interval_id = setInterval(
				function() {
					x_opacity += anim_step;
					new_opacity = x_opacity.toFixed(1);
                                        console.log('x_opacity = ' + new_opacity);
					document.getElementById('animation').style.opacity = new_opacity;
					counter++
					if (counter >= steps) { clearTimeout(interval_id)}
			}, time / steps);
}


Мне пришлось изрядно помучится, прежде чем я решил проблему, добавив обработку переменной:
x_opacity += anim_step;					
new_opacity = x_opacity.toFixed(1);


Только в этом случае результат уравнения цикла 1 - ((0-1)/10) стал равен:
0.9
0.8
0.7
...
0.0

Если убрать эту обработку(переменную new_opacity) и поставить напрямую:
document.getElementById('animation').style.opacity = x_opacity;

то результат (из логов консоли) цикла такой:
x_opacity = 0.9
x_opacity = 0.8
x_opacity = 0.7000000000000001
x_opacity = 0.6000000000000001
x_opacity = 0.5000000000000001
x_opacity = 0.40000000000000013
x_opacity = 0.30000000000000016
x_opacity = 0.20000000000000015
x_opacity = 0.10000000000000014
x_opacity = 1.3877787807814457e-16

Считается странно, и соответственно в конце прозрачность не убирается в ноль, а остается еле видной.

Я, повторюсь, что проблема, как таковая решена обработкой через доп. переменную, однако меня интересует совет более опытных разработчиков - почему это происходит и почему приходится ее вводить вообще. А в целом буду рад любым добротным советам.

Спасибо!

Your 29.10.2012 12:05

Number, Math

walik 29.10.2012 12:30

Так же желательно почитать эту статейку, полезно будет.
Основы программной анимации на JavaScript

Teol 30.10.2012 00:33

Дзен-трансгуманист,
большое спасибо за ответ (:
И, да уж, там должен быть clearInterval, - я до этого делал интервал через setTimeout и в запарке написал по-старому. Потом увидел и что-то там нехорошее про себя подумал.

Я пока не понял, почему число не приводилось к округленному сразу в первой переменной, а пришлось вводить вторую, однако сейчас буду переваривать и осмысливать.

И остальным спасибо за ссылки!
Уже читаю и, надеюсь, все вопросы по этой теме отпадут.

Teol 30.10.2012 02:09

Цитата:

Сообщение от Дзен-трансгуманист (Сообщение 212792)
К тому же, если у вас, например, будут аргументы 0.4 и 0.5, то использование toFixed(1) вообще обессмыслит всю функцию.

Отличная подсказка, спасибо еще раз. Вообще очень интересная тема вскрылась.


Часовой пояс GMT +3, время: 18:18.