задам вопрос :))
Как хендлить хранение amount * currencyRate?
Проблема:
5 * 0.027 = 0.135 * 100 = 13 (14 ??)
15 * 0.027 = 0.405 * 100 = 40 (41 ??)
13 + 40 = 53
14 + 41 = 55
20 * 0.027 = 0.54 = 54
53 < 54 < 55
что это за формулы
Обновил – добавил текст для ясности
рейты и все остальное храни в целом виде
Ты неправильно округляешь в своих примерах. 13.5 надо округлить до 14, 40.5 до 40. И тогда сумма сойдётся Но вообще проблема в потере точности. Тебе надо работать со значениями без округления до тех пор, пока оно не понадобится. То есть 13.5 + 40.5 = 54 И хранить, и вычислять всё надо в самой мелкой денежной единице (копейки, центы)
вот не могу понять, а к чему это всё, если правильно (как мне кажется), округлять уже конечную сумму, что бы избавится от копеек.. Т.е. сделать так, как делают на кассе в супермаркете (у них явно статистики хватает что бы делать правильно)?
Они просто ещё до сих пор считают, какая погрешность 😂😂
Т.е. условно вместо 15 * 0.027 нужно делать как?
Что такое 15, и что такое 0.027? Не округлять пока не потребуется конечный результат
Хз, похоже на микро-оптимизацию. Т.е на те случаи, когда выбирают что быстрее, цикл или switch\case, когда у тебя 5 страниц, и три условия :)
amount 15, currencyRate 0.027 При создании транзакции я в базу записываю refAmount, который считается путем amount * currencyRate
Эмаунт 15 это 15 центов/копеек?
А, сорян, это 15 центов/копеек, да, результат 0.15 * 100
Эммм… тут ты немного не понимаешь предметную область. Представь себе здание. Длинный коридор, в котором последовательно расположены кабинеты. В одном кабинете тебе начисляют дивиденды, в другом снимают налоги, в третьем кабинете конвертируют твои деньги в валюту другой страны. Ты идешь по коридору с деньгами. 1. Зашел в первый кабинет, там тебе сделали начисления по формуле, если получилось дробное число, округляют и выдают сумму. 2. Ты выходишь из первого кабинета, у тебя на руках сумма кратная копейке, нельзя разрубить копейку на пополам. 3. Когда ты заходишь во второй кабинет, у тебя на руках УЖЕ округленная сумма, между кабинетами, ты носишь уже округленную сумму. Здесь кабинет, это финансовая формула. Внутри кабинета/финансовой формулы, расчеты должны проводиться по полной точности без округления, округляется конечный результат, когда ты собираешься уже выйти из кабинета/формулы. Так вот. Сумма результатов операций A и B может отличаться на 1 копейку от результата операции С, в которой в формулу занесли сумму денег равной A и B. 1 копейка, это немного. Это не расчеты траекторий полета космического корабля, копейки позволительно терять на границах кабинетов/формул/операций.
Понимаю Плюс, у меня эта проблема заметна только в выводе статистики Она меня бесит из-за юнит-тестов, в которых приходится иногда +1 или -1 добавлять, потому решил пофиксить Но самое главное, просто хотел понять правильно ли я делаю такие вещи, ибо опыта ноль Ну и все же при использовании увеличенного мультиплаера, или библиотеки, даже копеечка теряться не будет (в большинстве случаев) :)
Тут важно, какую предметную область ты описываешь. У тебя в голове могут быть всякие формулы. Но есть законодательство, есть всякие регламенты расчетов и т.д. и т.п. Для многих может быть нелогичным, как предметная область описана в регламентирующей документации. Поэтому, тем кто проектирует программные продукты, важно погружаться в предметную область. Да, ты можешь сохранить копейку. Но это убьет бизнес, потому что весь бухучет из за этой копейки сломается у него. Задача программиста оцифровать "бумажную логику" в один один, даже если теряется где то копейка.
Понимаю ваш посыл) Но пока что для меня это ту мач. Я просто фронтендер который педалит пет-проект для своих финансов 😬
Подскажите пожалуйста, а где выход? Длинный коридор - почему-то нии сразу представил. К сожалению, ни ЧАВО
Вообще это не так страшно, округляйте в ту сторону, какую бизнес скажет: в одном случае копейка убавится у бизнеса, во втором - у клиента. Более интересная ситуация возникает, когда появляются всякие скидочки и прочая чепуха, где надо уже применять математику между округленными сконвертированными значениями. Например апишка может возвращать цену без скидки и скидку в евро, а другой эндпоинт этой апишки возвращает конечную цену и скидку. В этом случае, если мы будем делать что-то типа скидка + цена = цена без скидки не будет совпадать со значением цена без скидки - скидка = цена (при условии, что мы работаем с округленными значениями). Для таких случаев я нашел только одно вменяемое решение - использовать одну формулу подсчета во всем приложении. Конечно не совсем подходит к кейсу описанному вами, но проблема много крови попила несколько месяцев назад, поэтому решил излить душу)
Можно пополам округлять, находить разницу, делить на два
Что значит "пополам округлять"?
После запятой что пишет?
Современная финансовая система не предлагает выхода 🙈 П.с. обожаю НИИЧАВО и прочие штукенции его создателей)
Обсуждают сегодня