Вопрос решен. Использовать
int предпочтительнее и по скорости и по размеру данных, которые могу в нем храниться. Ниже подробности.
Давайте попробуем раз и навсегда обсудить и понять как хранить и работать с денежными суммами.
Я изучил вопрос и понял, что люди разделились на два лагеря:
1) Хранение в int
2) Хранение в decimal
Допустим, что мне достаточно вести биллинг в рублях с точности до копеек.
Хранение в bigint
Плюсы:
- Нет плавающей точки — меньше неточностей
- Можно производить стандартные мат. операции и не бояться, что потеряешь где-то копейки
- mithraen: Мат. операции идут быстрее (От автора вопроса — я проверил. Расчеты ниже)
- gleb_kudr: Вот международный стандарт по денежным единицам en.wikipedia.org/wiki/ISO_4217
Там видно, что число знаков после запятой у них может быть разное. А значит для простоты разработки, все стоит хранить в минимальной дробной денежной единице валюты, осущеставляя конвертацию при выводе (т.е. в int)
Минусы:
- Надо помнить о постоянном умножении/делении на 100
Хранение в Deciamal/Numeric
Плюсы:
- Храниться в естественном виде
- Не надо дополнительно париться при выводе
Минусы:
- При неаккуратной работе (не через bcmath) можно ошибиться при умножении или делении
- Работа через bcmath медленее
- У разной валюты разное кол-во знаков поле запятой — если у вас мультивалютная система, будет избыточность данных. Придется делать более 2 знаков после запятой, но они будут нужны не всем
- Роберт Мартин: «Использовать числа с плавающей точкой для представления денежных сумм — почти преступление»
Призываю всех в обсуждение, а я буду добавлять пункты. Очень хочется покончить с этим вопросом. И в одном и в другом подходе есть неудобные вещи.
Замеры скорости
Примеры приведу на языке php.
Работа с плавающей точкой
<?php
$a = 1.2;
$b = 3.4;
for ($i=0;$i<1000000;$i++) {
$c = bcdiv($a,$b,2);
}
Запускаем:
arturgspb@debian:/home$ time php 1.php
real 0m3.490s
user 0m3.468s
sys 0m0.020s
Работа с Int
<?php
$a = 11.2;
$b = 3.4;
$a *= 100;
$b *= 100;
for ($i=0;$i<1000000;$i++) {
$c = $a/$b;
// Избавляемся от лишних чисел
$c *= 100;
$c = (int)$c;
$c /= 100;
}
Запускаем:
arturgspb@debian:/home$ time php 2.php
real 0m0.562s
user 0m0.540s
sys 0m0.020s
Разница скорости в 6 раз очевидна.