В моем заявлении есть процедура, которая связана с изменением финансового баланса, и поэтому она включена в транзакцию.
И в конце операции, непосредственно перед совершением транзакции, у меня есть небольшая проверка — чтобы убедиться, что баланс был изменен правильно.
public function setBalance($amount) {
// ......
// Updating balance code, nothing worst attention
// ......
$balance = $this->getBalance(false);
if ($amount != $balance) {
throw new Exception('Error updating balance! ' . $balance . " instead of " . $amount);
}
Этот простой код вызывает исключение. Это говорит, что 386,57 не равно 386,57. В самом деле.
Я пытался проверить, в чем разница, используя мой любимый var_dump
а также die
,
var_dump($balance - $amount);
die();
Вывод еще более удивительный:
float(-2.8421709430404E-13)
Оба числа $balance
а также $amount
являются float
,
Может кто-нибудь объяснить это странное поведение и почему это происходит? Есть ли какая-то ошибка?
Это нормально при использовании поплавков. Попробуйте использовать этот код:
if (abs($amount-$balance) > 0.001) {
throw new Exception('Error updating balance! ' . $balance . " instead of " . $amount);
}
Если вы пойманы этим, не забудьте правильно округлить. Это НЕ легко. Когда округлять и как округлять, многие люди делают по-разному. Обратите внимание, что PHP round()
Функция теперь позволяет выбрать тип округления. Как это:
round($Value,2,PHP_ROUND_HALF_EVEN);
Других решений пока нет …