Доброго времени суток. Как Говориться, краткость — сестра таланта, поэтому статья будет четкой и максимально информативной.
Введение
Когда начал изучать Python, я наткнулся на очень любопытную, раннюю неизвестную мне тему 'Как устроены вещественные числа'. В ней говорилось про мантиссу, экспоненту и прочие детали вроде отведение битов на хранение числа.

Оказывается, компьютеру не составляет никаких проблем посчитать целые числа, но, когда мы доходим до вещественных, начинается интересная часть.
Суть проблемы
Из-за способа представления чисел с плавающей точкой операции с ними имеют не абсолютную точность. В этот момент меня, как новичка, просто поразило, как самая точная, совершенная машина не в состоянии посчитать точно даже банальные вещественные числа. Тем более мы все знаем, на что способны компьютеры в наше время, неужели такое может быть? Да, действительно, программа не в состоянии сложить два вещественных числа, которые без труда посчитает школьник в пятом классе:
x = 0.1
y = 0.2
print(x + y) # 0.30000000000000004
Ну, почти точно, скажете вы. Кому важен 17 знак после запятой (P.S. иногда важен). Сейчас представьте, что вам нужно посчитать не два числа, а допустим, двадцать, и подумайте, какая погрешность будет из-за того, что она будет возрастать каждый раз в геометрической прогрессии.
Решение
Как разрешить эту проблему мне пришло в голову следующим образом: надо всего лишь заставить программу считать такие числа как человек. То есть оперировать строго целыми числами. Ведь мы делаем так же.
На бумаге идея представлялось довольно легко, осталось только реализовать практически.
При написании кода возникали ошибки различного типа, но в итоге получилось создать именно то, что и хотелось — функцию, которая будет складывать и вычитать числа как человек, то есть, опять повторюсь, оперируя только целыми числами.
Конечная функция состоит из 3 алгоритмов:
- Решает задачу сложения положительных вещественных чисел
- Решает задачу сложения отрицательных вещественных чисел
- Сочетает в себе два предыдущих, позволяя складывать и вычитать любые положительные и отрицательные числа с плавающей точкой.
Общий итог
Любой учитель математики скажет вам, что точность — самое главное в исчислении. По моему мнению, в программировании она не менее важна. Инженерное дело, фотонная, атомная физика, биология — всем этим областям важная самая максимальная точность, где даже незначительная погрешность приведет к неверным результатам.
Примеры исчисления
Функция принимает на вход строки, в которых записаны вещественные числа, на выходе тоже возращает число, представленное type: <class 'str'>
Посчитаем что-то очень большое:
print(plum('0.01230000000000081038091823910983901308129838123891182391273819381981213120043',
'-1.0917498000000007327647819830913901312318238911238173123719237892749023421'))
# -1.07944979999999992238386374398155111815052550988490548845918559545509021089957
print(0.01230000000000081038091823910983901308129838123891182391273819381981213120043
-1.0917498000000007327647819830913901312318238911238173123719237892749023421)
# -1.0794498
И что-нибудь поменьше:
print(plum('0.002130031201237', '-1.905771892300819', '47.088812039793')) # 45.185170178693418
print(0.002130031201237 - 1.905771892300819 + 47.088812039793) # 45.18517017869342
Данный метод позволяет устранить погрешности при вычитании и сложении с вещественными числами. Пускай он не совершенен, зато он может внести свой вклад для дальнейшего развития точного исчисления чисел с плавающей точкой в будущем и применяться для существующих задач уже сегодня.