Alexey Posted March 23, 2017 Share Posted March 23, 2017 (edited) Сегодня затрону важную проблему, о которой не знают многие новички. Это не секретная информация и про это написано достаточно много, но новички так стремятся "в бой", что пропускают кучу важной информации. А потом удивляются, почему программа работает не так, как они хотят. Итак, сегодня рассмотрим две проблемы.A): Подумайте что выведет это код? (не проверяйте через компьютер только) console.log(6.6+3.3); console.log(0.1+0.2); console.log(0.3-0.1); 9.9; 0.3; 0.2? Неправильно! Ответы: 9.899999999999999 0.30000000000000004 0.19999999999999998 Логично, что и (6.6+3.3) === 9.9 будет false Почему так? Прочитайте про IEEE 754 и всё поймёте. Хотите знать как с этим бороться? Хорошо, дам 2 метода. 1): Не используйте операции с десятичными дробями. Храните исключительно целые числа и делайте их дробными прямо перед использованием. 2): Используйте toFixed. Значение 10 решает 99% проблем с дробями (у вас, конечное, будет только 10 знаков после запятой). Значение 5 решает 99.9999% всех проблем с дробями. Короче, чем ближе значение к 0, тем меньше проблем будет у вас с дробями (и тем меньше будет знаков после запятой). console.log(+(6.6+3.3.toFixed(5))); B):Подумайте, что выведет этот код(не проверяйте через компьютер только) console.log(9999999999999999); console.log(279999999999999448); Ответы: 10000000000000000 279999999999999460 Как с этим бороться? Очень просто! Не используйте слишком большие числа. Используйте числа от −2147483648 до 2147483647 и проблем не будет 100% (можно и немного большие/меньшие числа использовать, но и этого диапозона всем хватает обычно).Меня бесят всякие ошибки в вычислениях в JS (их явно больше, чем 2 описанные), что мне делать? Если точные вычисления вам важны, то в JS храните все числа в String типе, а вычисления проводите с помощью плагинов (нормальными статически типизированными языками; Есть куча специальных языков для вычислений).Вот так вот, за все удобства JS приходится платить точностью, но как только появляется точность, то тут же улетучивается всё удобство! Edited March 23, 2017 by Alexey 3 Link to comment Share on other sites More sharing options...
ctaciv Posted May 10, 2017 Share Posted May 10, 2017 Отличный пост, думаю новичкам пригодиться. Link to comment Share on other sites More sharing options...
N1kS Posted June 25, 2017 Share Posted June 25, 2017 http://mathjs.org/ вам в помощь, господа. Link to comment Share on other sites More sharing options...
MaxRaimer Posted June 15, 2018 Share Posted June 15, 2018 var sum1; var sum2; var firstcomp = 1000; var secondcomp = 0.7; var thirdcomp = -0.5; var fourthcomp = -5; var sum1 = firstcomp * (secondcomp + thirdcomp) / fourthcomp; log.debug(sum1); var sum2 = 1000 * (0.7 - 0.5) / -5; log.debug(sum2); В 23.03.2017 в 13:49, Alexey сказал: Не используйте операции с десятичными дробями. Храните исключительно целые числа и делайте их дробными прямо перед использованием. Вроде как все работает... и там и там ответы -39.(9) Может я что то не так понял? Link to comment Share on other sites More sharing options...
Alexey Posted July 5, 2018 Author Share Posted July 5, 2018 В 15.06.2018 в 17:43, MaxRaimer сказал: var sum1; var sum2; var firstcomp = 1000; var secondcomp = 0.7; var thirdcomp = -0.5; var fourthcomp = -5; var sum1 = firstcomp * (secondcomp + thirdcomp) / fourthcomp; log.debug(sum1); var sum2 = 1000 * (0.7 - 0.5) / -5; log.debug(sum2); Вроде как все работает... и там и там ответы -39.(9) Может я что то не так понял? Ты неправильно понял. Первый способ заключается в том, чтобы перед операцией представить дробное число как целое. Например 0.2 мы можем представить как 2*10^(-1) и т.д. Конечно такое способ не рекомендуется, ибо слишком много операций будет выполнять компьютер. Вообще можно даже округление не использовать (и лучше не использовать), так как суперточные вычисления мало где сильно нужны (а где нужны там как раз и можно будет заморочиться). Главно никогда не использовать при сравнениях float (дробных) чисел == или === . Нужно <= или >= . Также не используй != !== Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now