![]() |
Number изменяется на 0.999999999999999
Здравствуйте.
Прибавляю к переменной типа Number, число [0.1]. В результате иногда прибавляется [0.1], а иногда [0.999999999999999]. Тоже самое с уменьшением. Пример кода: Код AS3:
Код:
0.4 |
Это совершенно нормальное поведение.
|
Все нормально, это вещественные числа. В компутере всегда так.
|
Числа в компьютере хранятся в двоичной системе счисления. В ней 0.1 - бесконечная периодическая дробь (как 1/3 = 0.333333... в десятичной). И так же, как при сложении и вычитании 0.3333333333 в десятичной вы бы не получали точные числа в десятичной (там ещё и последний знак округляется) - так же вы их не получаете проводя вычисления в двоичной.
|
http://habrahabr.ru/post/112953/ http://habrahabr.ru/post/130272/ Такое поведение не просто есть, а оно строго регламентировано стандартом, имя ему IEEE 754. И на самом деле, процессор даже ему не следует обычно, но делает что-то похожее. Чтобы сторого следовать стандарту надо сказать об этом процессору и тогда операции будут медленнее но строго соответствовать стандарту(но не вашим ожиданиям) т.к. некоторые значения конечных дробей в десятичной системе в двоичной бесконечны, и наоборот. Кстати из экшнскрипта заставить процессор строго следовать стандарту не получится.
Добавлено через 1 минуту http://habrahabr.ru/post/123883/ вот ещё, комменты тоже полезны Добавлено через 6 минут Более того, от порядка вычисления зависит результат. Код AS3:
Код:
false 0.7142857142857143 0.7142857142857142Это непосредственно следует из того что точность чисел с плавающей точкой зависит от размера хранимого числа, т.е. на очень маленьких (сильно близких к нулю) и на очень больших (близких к положительной или отрицательной границе типа(часто, но ошибочно, называют бесконечностями, обозначаются +inf и -inf)) точность плохая. Так вот точность всегда плавает от размера хранимого значения, и в примере выше промежуточные результаты имеют разное значение, в первом случае пятёрка делится на 7, а во втором 2 и 3, и оба деления результаты меньше 1. Иногда совпадают, а иногда и нет. Обратите внимание в каком знаке отличие и нужна ли вам такая точность? Как правило нет. А вот если нужна то тогда применяют числа с фиксированной запятой. При том же объёме занимаемой памяти они могут хранить сильно меньший диапазон значений, но в то же время их точность фиксирована и предсказуема, а операции детерминированы(но от порядка вычислений тоже может зависеть результат, если на промежуточных значениях будут разные выходы за пределы точности). Например фиксированная запятая применяется в видеообработке для задания частоты кадров, т.к. если она будет плавать видно этого сразу не будет но видео будет плохо восприниматься. В частности в формате swf фреймрейт записан именно в формате с фиксированной запятой, что гарантирует ожидаемую точность без подвохов. Никак и ничто не может быть представлено с абсолютной точностью, вопрос в том какая будет ошибка и насколько она предсказуема. Добавлено через 20 минут Собственно формат то называется плавающая точка потому что точность плавает. Потому что когда вы считаете миллиарды +- одна тысячная обычно не важна, а если считаете около единицы, то одна тысячная как правило важнее. |
| Часовой пояс GMT +4, время: 07:00. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.