У меня есть таблица счетов клиентов в моей базе данных MySQL с полем DECIMAL (10,2), называемым ценой.
При получении этих значений в php и вычислении суммы суммы,
ex: в скрипте
$totalAmount = 0; // initialised them to while(records){ $amount = $inv_amount - ($pay_amount + $onamount); //float i guess. 2.22, 14.22 $totalAmount = $totalAmount + $amount; //float i guess. 2.22, 14.22 ..etc }
когда echo $totalAmount;
он имеет небольшую ошибку в конечной величине 0,01, однако при работе с большими массивами данных около 20 000 эта ошибка становится очень значительной, например, 200+
Каков самый безопасный способ сделать это при работе с ценами и т. д. с этими цифрами в PHP? Или я получу потенциальные ошибки округления и такие вещи, которые характерны при работе с типами данных с плавающей запятой?
использует
round number_format
является наиболее подходящим решением для такого типа финансовой заявки?
Действительно, числа с плавающей запятой не точны.
Либо вычисляйте в cent (умножьте на 100 и вычислите в целые числа), либо вычислите в строках, используя BC Math .
Если вам нужна точность в 2 десятичных знака:
number_format
Попробуй это:
$totalAmount = number_format($totalAmount, 2, '.', '');
вы пытались
round(totalAmount, 2, PHP_ROUND_HALF_ODD);
он должен увидеть последнее десятичное число – если он нечетный – округляется, если даже – вверх
Ну, для начала, зачем суммировать в php-цикле, когда вы можете сделать это в mysql? Кроме того, просто используйте целое число, умноженное на 100, а затем разделите на 100, как только вам понадобится конечный результат.
Вы можете использовать number_format
Пример: (для двух десятичных знаков)
$number = 12345.5667; echo $result = number_format($number, 2);
Или вы можете использовать round
функцию в MySql:
ROUND(number,2)
Во-первых, использование 64-битных целых чисел на PHP является рискованным, потому что; при переполнении он переключается на float и вы теряете точность. Когда это деньги, проблема более серьезная. Вы должны вычислить столбец с sql и просто получить значение оттуда. Деньги – это длинный тип, и он часто будет конвертироваться в float на php, и ваши люди потеряют или выиграют некоторые центы в зависимости от настроения php-движка. Вы не можете работать с десятичным типом на php, даже если умножить на 100 и сохранить его как целое число, длинные числа с переполнением будут автоматически преобразованы в float. Вычислите свои значения на MYSQL, если вы хотите использовать десятичные числа или преобразовать свое поле в int.
Если ваш сервер имеет 32-разрядный процессор, длина WORD составляет 32 бит, поэтому целые числа в php-движке 32-битные целые числа. Это повышает вероятность переполнения. В 64-битной системе вы можете работать более комфортно.
В этом случае использование круглой функции по денежной стоимости является смешной и непрофессиональной. Не делай этого.
Чтение этого документа поможет вам.
php-документация целых чисел
Целочисленное переполнение
Если PHP встречает число за пределами целочисленного типа, оно будет интерпретироваться как float. Кроме того, операция, которая приводит к числу за пределами целочисленного типа, вместо этого возвращает float.
Вычисление на уровне SQL гарантирует точность для типа денег. Получение типа денег в php приведет к поплавковому значению, и вы можете умножить его на 100 и делить на 100 позже, но он снова увеличит риск переполнения, поскольку php будет использовать 32-битный номер с плавающей точкой для хранения. Если вы используете 32-битный float, почему поле данных десятичное? Так что это непоследовательно, если вы это сделаете. 32-битное число i уже не так велико, а 32-битный float теряет часть своей емкости с плавающей запятой, поэтому более вероятно, что он достигнет большей емкости при умножении на 100.