Мне интересно, нашел ли я проблему с округлением в PHP, в частности 5.2.3 (я не уверен в других версиях на данный момент):
$t = 0; $taxAmount = (5.000 / 100) * 0.7; $t += $taxAmount; var_dump($t); // float(0.035) var_dump(round($t, 2)); // float(0.03) var_dump(number_format($t, 2)); // string(4) "0.03"
Для меня 0.035 должен округлять до 0,04 или я просто сумасшедший?
редактировать
Ответ Thxs на NebyGemini , я подумал, что я сделаю это вместо этого:
$t = 0; $taxAmount = bcmul(bcdiv(5.000, 100, 3), 0.7, 3); $t += $taxAmount; var_dump($t); // float(0.035) var_dump(round($t, 2)); // float(0.04) var_dump(number_format($t, 2)); // string(4) "0.04"
Это работает отлично.
Кстати, я рассчитываю налог в корзине покупок. Сумма заказа составляет 0,70 (70 центов), а налог составляет 5%.
редактировать
Thxs к ответу Игнасио Васкес-Абрамса , это должно показать, где проблема:
printf('%.18F', 5.000 / 100 * 0.7);
Поплавки – это зло.
Цитирование справочной документации PHP по номерам плавающей запятой :
Поэтому никогда не доверяйте действию чисел с плавающим числом до последней цифры и никогда не сравнивайте числа с плавающей запятой для равенства. Если требуется более высокая точность, доступны произвольные математические функции точности и функции gmp .
Если вы хотите знать, почему и как работают поплавки, я рекомендую посмотреть:
Все, что вы не хотели знать о номерах JavaScript
Python говорит:
>>> repr(5./100*0.7) '0.034999999999999996'
Это связано с ограничениями точности IEEE754. Используйте тип с фиксированной точкой, если вам нужна точная точность.
Вы можете использовать PHP_ROUND_HALF_UP, но есть проблема с тем, что число self преобразуется в «99999 …»