Проблема округления PHP (5.2.3)? - PullRequest
7 голосов
/ 02 февраля 2010

Мне интересно, нашел ли я проблему с округлением в 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 или я просто сумасшедший?

Редактировать

Спасибо за Ответ Неби Джемини , я решил, что вместо этого я сделаю это:

$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%.

Редактировать

Спасибо за Ответ Игнасио Васкеса-Абрамса , это чтобы показать, в чем проблема:

printf('%.18F', 5.000 / 100 * 0.7);

Ответы [ 3 ]

7 голосов
/ 02 февраля 2010

Плавающие злые.

Цитирование документации PHP по Числа с плавающей точкой :

Поэтому никогда не доверяйте результатам с плавающей запятой последней цифре и никогда не сравнивайте числа с плавающей запятой на равенство. Если требуется более высокая точность, доступны математические функции с произвольной точностью и gmp .

Если вы хотите знать, почему и как работают поплавки, я рекомендую посмотреть:
Все, что вы не хотели знать о числах JavaScript

3 голосов
/ 02 февраля 2010

Python говорит:

>>> repr(5./100*0.7)
'0.034999999999999996'

Это связано с ограничениями точности IEEE754. Используйте тип с фиксированной запятой, если вам нужна точная точность.

0 голосов
/ 02 февраля 2010

Вы можете использовать PHP_ROUND_HALF_UP, но есть проблема, что число само преобразуется в "99999 ..."

...