PHP Добавление 2 десятичных чисел (деньги) дает неверные результаты в общей сумме

У меня есть таблица счетов клиентов в моей базе данных 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 десятичных знака:

  1. умножить значение на 100
  2. делать свои операции
  3. разделите на 100 и, если необходимо, используйте 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) 

Я рекомендую делать вычисления на SQL-уровне с запросами или представлениями.

Во-первых, использование 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.

ИСПОЛЬЗОВАТЬ SQL