Проблемы чисел с плавающей точкой
Всем привет, работаю java разработчиком уже 10 лет, в этом посте хотел бы привести пример, почему нужно с опаской подходить к использованию чисел с плавающей точкой. Проблемы возникают из-за двух ограничений:
невозможности представить некоторые дробные числа в конечном виде в двоичной кодировке;
ограниченного объема памяти, выделенного для хранения значения.
В результате может страдать точность, причем в не самых очевидных случаях. Например, сравниваем между собой два маленьких различных числа. Они, очевидно, различны:
double little1 = 0.0000000000000000000000000000000000000001;
double little2 = 0.0000000000000000000000000000000000000002;
print(little1 == little2); //false
Далее попробуем сложить эти два числа с большим, и проверим, совпадают ли суммы:
double big = 10000000000000000000000000000000000000.0;
print(big + little1 == big + little2); //true
Оказывается что суммы равны, хотя интуиция подсказывает обратное. Проблема в том, что число которое имеет много символов до точки и после точки, не может быть достаточно точно представлено в памяти, и его конец обрезается. Из-за чего вычисления приводят к равенству.
Тем кто вынужден работать с нецелыми числами, рекомендую присмотреться к BigDecimal. Всем удачи!
Лига программистов
2.1K постов11.9K подписчика
Правила сообщества
- Будьте взаимовежливы, аргументируйте критику
- Приветствуются любые посты по тематике программирования
- Если ваш пост содержит ссылки на внешние ресурсы - он должен быть самодостаточным. Вариации на тему "далее читайте в моей телеге" будут удаляться из сообщества