Пока все обсуждают какие в МТС кривые разработчики я отвечу откуда происходят подобные проблемы.
Так исторически сложилось, что языки программирования плохо умеют в дроби, как итог простое сложение 0.1+0.2 не всегда будет равно 0.3 - JS считает, что это будет равно 0.30000000000000004. Не буду вдаваться почему так происходит. К сожалению эту проблему переняли и базы данных.
Что бы избежать подобных проблем в мире практикуется запись цен не в виде дробей, а в виде целых чисел. Говоря иначе в базу идет запись о балансе не как 500.00, а как 50000, т.е. умножая на 100. В банковском же сегменте сотых долей не хватает и принято держать 4 цифры после точки, т.е. 500.0000, но учитываю проблему долей ее приводят к 5000000.
А теперь, узнав немного больше, я попробую объяснить что могло привести к данной проблеме. Вариантов может быть много, но я возьму один как пример.
Дано:
Стоимость тарифа - 500 денег.
Сумма всех историй платежей (остаток на счете) до момента списания - 520 денег.
Операцию по списанию средств можно привести к простому виду:
Что бы операция прошла как по маслу необходимо, что бы обе базы данных имели единый формат, т.е. либо хранили дроби (500.00), либо целые числа (50000).
Но учитывая, что базы, подобные МТС, могут хранится годами, мы спокойно можем встретить проблему того, что форматы будут отличатся. Как итог появления потребность в приведении данных:
И вот наступает исторический момент, когда в отделе разработки происходит рефакторинг и разрабы решают исправить данный момент и привести все к одному типу. Но по какой то причине забывают убрать приведение.
"Забыли" звучит жестко, в реальной жизни это какие-то более адекватные проблемы - может плохо встала миграция из-за различности конгифов между тестовыми и боевыми серверами, либо пролез левый запрос между запросом на приведение записей в базе и запросом на удаление хэндлера умножения. Но т.к. это вина разрабов, а гуманитарий все равно будет поливать инженеров грязью, то зачем зря распинаться.
Как результат мы имеем следующую картину: