В моем сценарии php я делаю расчет записей из базы данных MySQL. Соответствующие поля в БД определены как decimal(10,3)
, Это бухгалтерская платформа, где я должен проверять, есть ли в каждой записи дебет = кредит.
Я делаю это с помощью следующей операции:
$sumupNet = 0;
$sumup = 0;
foreach($val['Record'] as $subkey => $subval)
{
$sumupNet = $sumupNet + $subval['lc_amount_net'];
$sumup = $sumup + $subval['lc_amount_debit'] - $subval['lc_amount_credit'];
}
Теперь мы говорим, что каждая запись корректна, тогда $ sumupNet и $ sumup приводят к 0
, В большинстве случаев это работает. Но в некоторых случаях результат выглядит примерно так: -1.4432899320127E-15
или это -8.8817841970013E-15
, Если я вычислю эти значения вручную, результат 0
, Я предполагаю (не уверен), что приведенные выше результаты являются числами около 0 и выводятся в виде экспоненты.
Поэтому я думаю, что должен что-то конвертировать, или мой расчет неверен. Но что? Я пытался floatval () в некоторых моментах, но не работал. Если у кого-нибудь есть подсказка, я очень вам благодарен.
Вы получаете это, потому что вы делаете математику со значениями с плавающей точкой. Прочитайте немного теории об этом.
Вы действительно не хотите рассчитывать такие деньги, потому что у вас могут возникнуть странные проблемы с округлением, которые вы не можете сделать, чтобы что-то исправить.
Для PHP существует множество библиотек, которые помогут вам избежать этой проблемы, таких как До н.э., или же GMP.
Другим решением было бы вычислить все значения, используя наименьшее денежное значение, которое имеет валюта (например, центы), поэтому вы всегда используете целые числа.
Это проблемы округления. Это совершенно нормально, когда мы говорим о поплавках. Чтобы дать вам повседневный пример,
1/3 = 0,3333333333333333 … 333333333 … 3333 …
Причина: 10 относительно простое число с 3. Вы можете задаться вопросом, откуда 10. Мы используем 10-значный для чисел, то есть, когда мы говорим о числе, его цифры представляют 10-значные экспоненциальные значения. Компьютер работает с двоичными числами, то есть с 2-мя базовыми числами. Это означает, что деление с такими числами часто приводит к бесконечным последовательностям цифр. Например, 1/3 как двоичное число выглядит так:
0,010101010101010101010101010101010101010101010101010101 …
Десятичные типы представляют собой десятичные числа, то есть 10 базовых чисел. Вы используете три цифры для части после. Давайте добавим, что ваш номер заканчивается так:
.хуг
это означает:
XYZ / 1000
Однако 1000 можно разделить на следующие простые числа:
2 и 5.
Поскольку 5 является относительным простым числом с 2, всякий раз, когда вы представляете результат деления на 5 как двоичное число, существует вероятность того, что результатом будет бесконечный цикл цифр. 1/5 как двоичное число выглядит так:
0,0011001100110011001100110011001100110011001100110011 …
Поскольку компьютер не может хранить бесконечные цифры, он должен округлить число, то есть найти число, близкое к его значению, которое можно представить более простым способом. Если число a округляется до b и два числа не равны, то теряется определенная точность, и это является причиной упомянутой вами ошибки.
Вы можете решить эту проблему следующим образом: когда вы выбираете значения из базы данных, умножаете их на 1000 (таким образом, преобразовывая их в целые числа), а затем проверяйте операции. В конце разделите на 1000.