PDA

Просмотр полной версии : Интересный вопрос (цикл for)


AlexMatveev
11.06.2004, 14:56
Делаем цикл:

for (var i = 8; i<=10; i += 0.1) {
trace(i);
}

На выходе:

8
8.1
8.2
8.3
8.4
8.5
8.6
8.7
8.8
8.9
9
9.1
9.2
9.3
9.4
9.49999999999999
9.59999999999999
9.69999999999999
9.79999999999999
9.89999999999999
9.99999999999999

ПОЧЕМУ???
Я всегда думал что 9.4+0.1=9.5, а не 9.49999999999999

Nox Noctis
11.06.2004, 15:32
да, есть такие глюки в мат части :(

насколько я понимаю, с этим никак не побороться..
надо учитывать что это есть

Nox Noctis
11.06.2004, 15:42
a = 4;
// a = 5;
// a = 6;
// a = 7;
// a = 8;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);
a += .1;
trace(a);а если начинать считать с a = 3 или c a = 9 - этого косяка уже нет :D :D

Dindin
12.06.2004, 14:15
А вот так - еще веселее :D
for (var i = 8; i<=10; i += 1e-3) {
trace(i);
}

Jlekc
13.06.2004, 16:37
да ладно, чо вы обижаете флеш, будто это его баги
протрейсети это в других апликухах, это баг процесора, и он вылазит под любым языком

Stevee
13.06.2004, 18:02
я помню что это как то объясняется тока не помню как :)
давно слышал

NeZnayKa
14.06.2004, 23:47
в калькуляторах точно так же
корень 0.99999999..... ровняется себе

или я что то не понял ?

kostyanK
15.06.2004, 11:45
вся фишка в том что проц все операции производит в двоичной системе, а дробное число точно перевести в двоичную систему нельзя - можно лишь с заданной точностью.

Например 0.1 (с точностью десять разрядов)= 0.0001100110

а теперь если перевести обратно то 0.0001100110 = 0.99609375

Nox Noctis
15.06.2004, 12:14
это хорошее и логичное объяснение.

только это не объясняет почему в плеере этот глюк вылезает настолько фрагментарно :)
for (var i=-6; i<10; i+=.1) {
trace(i);
}
проверьте, к примеру, то же самое в джаваскрипте

AlexMatveev
16.06.2004, 12:11
Интересно, что думает по этому поводу Macromedia ???

Елё
03.07.2004, 02:18
Интересно что думает макромедия вот по этому поводу:
onClipEvent (enterFrame) {
trace(this._alpha);
if(this._alpha == 100) this.direction = -5;
if(this._alpha == 0) this.direction = 5;
this._alpha += this.direction;
}

Результат:

100
94.921875
89.84375
84.765625
79.6875
74.609375
69.53125
64.453125
59.375
54.296875
49.21875
44.140625
.....

и тд

Или я просто плохо соображаю в час ночи???

Nox Noctis
03.07.2004, 02:30
макромедия об этом вообще-то пишет в хэлпе :))
правда в хэлпе МХ2004 я что-то не наблюдаю упоминаний...

я в своё время тоже порадовался..
http://www.flasher.ru/forum/showthread.php?threadid=38562&highlight=%E2%EE%F0%EE%ED%FB

и вот тут потом
http://www.flasher.ru/forum/showthread.php?postid=297136&t=5930#post297136

только в хэлпе под пятерку и МХ была лажа - написано было про 128 уровней альфы, а их 256 там, судя по полевым испытаниям.

Елё
03.07.2004, 05:05
Да, тормознул таки...
В принципе очевидно конечно, и пока до дома ехал понял, что вряд ли какой нибудь драйвер поддерживает альфу измеряющуюся в процентах
Хотя раз альфа может быть отрицательной значит все эти градации про которые говорит макромедия фигня....

greyshaman
03.07.2004, 13:48
Не убивайтесь, эти грабли смотрятся куда веселее при подсчете чужих денег :)

john
03.07.2004, 14:40
насколько я понимаю, везде, тип double по определеню имеет приблизительное значение,

в Java, к примеру есть специальный класс для работы с числами с плавающей запятой BigDecimal...

так если посмотреть на его внутреннее устройство, он работает с цифрами как со строками, и хранит отдельно что что слева от запятой и что справа,
и представте себе затраты на такую работу с цифрой..... но это единственно возможный вариант,
в делфи чтото похожее, ....

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

Nox Noctis
03.07.2004, 15:12
компадре вчера тестил эту фишку на нескольких системах и процах... и знаете, под виндой всё одинаково - везде одинаково закономерная ошибка (а следовательно это вполне можно считать фичей), а на линухе проглючивает фрагментарно так... где да где нет :)

2john
ты прав, на флэш гнать не стоит, но почему это работает так неравномерно-то? :) не понимаю..

Nox Noctis
03.07.2004, 15:18
Оригинал написал(а) greyshaman
Не убивайтесь, эти грабли смотрятся куда веселее при подсчете чужих денег :) в каком это смысле? :)

greyshaman
04.07.2004, 01:12
в том смысле что при конвертации, купле дензнаков одной страны за дензнаки другой, 0,005 в большинстве случае превращается в 0,0049999 со всеми вытекающими :)
в принципе это всего цент, но вот если его умножить на количество дневных сделок на нашем шарике, то получается весело.

Dindin
04.07.2004, 02:51
Ага. Кто-то злобный уже засел за очередной интернет-магазин на флэше. :D:p:D

BrainSmasher
07.07.2004, 13:06
Господа, все куда как проще!
Не буду вдаваться глубоко в подробности (в инете инфы по этой теме уйма) Эти все глюки растут из FPU (Floating point unit), т.е. математического модуля процессора, который собственно и занимается всеми вычислениями. Так вот у него есть так называемый регистр control word, где каждый битик отвечает за тот или иной аспект поведения этого юнита при различных вычислениях. Всякие там вызывать исключения при делении на 0, и т.п. Среди прочих там есть битики отвечающие за правила округления и точность. Так вот винда устанавливает этот регистр FPU во вполне определенное значение (разные версии винды в разные :) ) и этим объясняются обсуждаемые здесь "глюки". В принципе этот регистр можно менять самому, я это делал под Дельфой, но сомневаюсь что это позволит флеш.
Кстати, что касается суммовых операций то тут все куда проще, смещаем принудительно разрядную сетку на 4 разряда (умножаем все суммы на 10000) а после любых вычислений делаем round результата, в итоге получаем целое число, которое точно представимо всегда (если не выходит за пределы разрядной сетки, но сильно я сомневаюсь что Вы оперируете подобными суммами :) )
Кстати, на этом же принципе сделан и денежный тип currency в той же Дельфи.

2K WebStudio
28.08.2004, 13:37
когда знаешь, что программа глючит - можно поймать её на её же ошибках...

Можно просот округлять... например...

YuriiZelenev
28.08.2004, 20:37
Оригинал написал BrainSmasher
... смещаем принудительно разрядную сетку на 4 разряда (умножаем все суммы на 10000) а после любых вычислений делаем round результата, в итоге получаем целое число, которое точно представимо всегда ...Esli ne trudno, popodrobnee pojaluysta...