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

4

В моей базе данных MySQL есть таблица счетов клиентов с полем DECIMAL (10,2), которое называется цена.

При получении этих значений в PHP и расчета суммы суммы,

пример: в сценарии

$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 она имеет небольшую ошибку, однако при работе с большими наборами данных около 20000 эта ошибка становится очень значительной, например 200+

Какой самый безопасный способ сделать это при работе с ценами и так далее с этими числами в PHP? Или я в конечном итоге буду иметь потенциальные ошибки округления и тому подобное, которые часто встречаются при работе с типами данных с плавающей запятой?

использует

round 
number_format

самое подходящее решение для этого типа финансового приложения?

stackoverflow.com/questions/211345/… Bailey Parker
Может быть безопаснее использовать значение * 100 в качестве целого числа, поскольку в числе с плавающей запятой может быть ошибка точности Alvin Wong
напечатать ваши значения с эхо. не ленись. Uğur Gümüşhan

Ваш Ответ

7   ответов
0

number_format

Пример: (для двух десятичных знаков)

$number = 12345.5667;
echo $result = number_format($number, 2);

Или вы могли бы использоватьround функция в MySql:

ROUND(number,2)
0

для начала, зачем суммировать в цикле php, когда вы можете сделать это в mysql? Кроме того, просто используйте целое число, умноженное на 100, а затем разделите на 100, как только вам понадобится конечный результат.

0

ты пытался

round(totalAmount, 2, PHP_ROUND_HALF_ODD);

он должен видеть последнее десятичное число - если оно нечетное - округляется вниз, если четное - вверх

2

multiply value by 100 do your operations divide by 100 and use number_format where appropriate
3

$totalAmount = number_format($totalAmount, 2, '.', '');
Исправит ли форматирование числа ошибку +/- $ 200?
8


Либо рассчитать в центах (умножить на 100 и вычислить в целых числах), либо рассчитать в строках, используяДо н.э..

+1 за предложение до н.э.
0
I recommend doing calculations on SQL Level with queries or views.

использование 64-битных целых чисел в PHP рискованно, потому что; при переполнении он переключается на плавание, и вы теряете точность. Когда это деньги, проблема более серьезна. Вы должны вычислить столбец с помощью sql и просто получить значение оттуда. Деньги - это длинный тип, и они часто превращаются в плавающие на php, и ваши люди проигрывают или выигрывают несколько центов в зависимости от настроения движка php. Вы не можете работать с десятичным типом на php, даже если вы умножите на 100 и сохраните его как целое число, длинные числа с переполнением будут автоматически преобразованы в число с плавающей точкой. Рассчитайте свои значения на MYSQL, если вы хотите использовать десятичные числа или преобразовать поле в int.

Если ваш сервер имеет 32-битный процессор, длина WORD составляет 32 бита, поэтому целые числа в движке php - это 32-битные целые числа. Это повышает вероятность переполнения. В 64-битной системе вы можете работать более комфортно.

Использование функции округления на денежной стоимости в этом случае смешно и непрофессионально. Не делай этого.

чтениеэтот документ вам очень поможет.

PHP документацияцелых чисел говорит

Integer overflow

If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.

Расчет на уровне SQL обеспечит точность для типа денег. Получение типа денег в php приведет к получению значения с плавающей запятой, и вы можете умножить его на 100 и поделить на 100 позже, НО это снова увеличивает риск переполнения, поскольку php будет использовать 32-разрядное число с плавающей запятой для хранения. Если вы используете 32-разрядное число с плавающей запятой, почему поле данных является десятичным? Так что это непоследовательно, если вы сделаете это. 32-разрядное число i уже не так велико, а 32-разрядное число с плавающей запятой теряет часть своей емкости с плавающей запятой, поэтому вероятность его превышения превышает вероятность при умножении на 100.

USE SQL
@PhpMyCoder, который перемещает данные между узлами в многоуровневой арт-текстуре, а не делает это в одном месте. Зачем вам загружать все данные, если вас интересует их сумма? Пожалуйста, подумайте об этом.
@PhpMyCoder у вас есть веские аргументы для этого, или вы с юмором.
@PhpMyCoder, о котором этот парень говорит о написании своего собственного класса для типа numeric2, я говорю о решении, таком как добавление в запрос двух столбцов, вероятно, займет одну или две строки.
Использование MySQL для выполнения ваших вычислений - это все равно, что вводить основную математику в поиске Google вместо использования физического калькулятора рядом с вашим компьютером. База данных предназначена для хранения, запроса и возврата данных. Приложение предназначено для обработки этих данных.
Перемещение вычислений на уровень SQL иногда не является лучшей идеей, поскольку работа сервера SQL состоит в том, чтобы запрашивать и возвращать данные. Задача сервера приложений - обрабатывать эти данные. Для обработки больших чисел в PHP см.stackoverflow.com/questions/211345/…

Похожие вопросы