PHP, расчет денег

LONGMAN

Dark Side of the Moon..
Думаю лучше хранить сумму в центах/копееках, как выше и подсказали
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
обычно в расчетах денег помогает после операций прибавлять 0.00001
 

Dovg

Продвинутый новичок
Лучше вычитать, как в одном голливудском фильме ;)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
результат операций над флоатами обычно немного меньше, чем надо
а отказ от округлений - просто округление к низу по последнему разряду

я не говорю, что это абсолютно правильное решение, но операции вроде x+y я пишу как round( x+y+0.00001 , 2 )
средняя погрешность операций по всему приложению получается меньше, чем простое x+y без явного округления
 

Dovg

Продвинутый новичок
ИМХО:
Для работы с деньгами должна быть ровно одна точка входа.
Причем там, где можно работать с данными, имеющими определенную точность.

Мне вообще нравится реализация биллинга целиком в базе.
Там по крайней мере достаточно легко решается проблема конкурентного доступа.

ps. Мы храним деньги в numeric(16,6), при отображении делаем ceil до копеек.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
в серьезном приложении так и должно быть
но не все приложения серьезные, иногда можно и забить на пол-копейки :)
 

korpus

злой бобёр
флоппик, почему не надо?
Код:
$presision=4;
$a=10.56;
$b=7.02;
$c=$a+$b;
....
$c=round($c, $presision);
Таким образом можно работать с заранее заданной точностью. Как по другому реализовать работу с деньгами? Делить деньги отдельно на целые рубли и целые копейки неправильно, так как есть ограничение на максимальный int.

-~{}~ 17.09.10 18:17:

Дополнение. Округление можно делать не часто, а в конце скрипта и перед занесением данных в базу. В остальных операциях оперировать теми числами, что есть
 

Dovg

Продвинутый новичок
>есть ограничение на максимальный int.
korpus
Код:
dovg@habahaba:~$ php -r 'echo PHP_INT_MAX."\n";'
9223372036854775807
бюджет США меньше ,чем int на 64-разрядных машинах.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
:) Гейтс писал, что ему из налоговой периодически присылали штраф за недоимку по налогам, а потом извинялись, что это в компьютере было превышение разрядности
 

флоппик

promotor fidei
Команда форума
Партнер клуба
ps. Мы храним деньги в numeric(16,6), при отображении делаем ceil до копеек.
глупый вопрос -на**я?
у тебя же не может быть 0.1 копейка. 16,2 будет достаточно за глаза. Зачем делать странные ceil() - деньги это ЦЕЛОЧИСЛЕННЫЙ тип. Просто с разными величинами - вы же метры не храните во float, хоть они и состоят из сантиметров и даже миллиметров.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
С., курс - это не деньги. Курс - это соотношение двух цифр, не являющейся суммой.
 

korpus

злой бобёр
подсчёты надо делать, даже если у тебя до 0.0001 копейки идёт счёт. А при выставлении счёта округлять до копеек в большую сторону. Вроде так надо делать.
 

Dovg

Продвинутый новичок
флоппик
Отлично споришь, не зная наших бизнес требований ;)

Код:
# SELECT min(amount) from fact_transaction ;
   min    
----------
 0.000075
(1 row)
 

С.

Продвинутый новичок
флоппик: курс - это не деньги. Курс - это соотношение двух цифр, не являющейся суммой.
Так и деньги это не монеты и банкноты, а некий ценовой эквивалент. Доли копеек -- самое обычное явление в бухгалтерских расчетах.
 
Сверху