Я пытаюсь преобразовать float в значение int в php:
var_dump((int)(39.3 * 100.0)); //Returns 3929 but should be 3930! var_dump((int)(39.2 * 100.0)); //Returns 3920
Я могу использовать ceil, чтобы он работал, но может ли кто-нибудь объяснить это мне?
var_dump((int)ceil(39.3 * 100.0)); //Returns 3930
Это связано с тем, что числа, которые имеют конечное представление в базе 10, могут иметь или не иметь точного представления в представлении с плавающей запятой, которое использует PHP.
Видеть
> php -r "echo var_dump (sprintf ('% .40F', 39.3 * 100.0)); строка (45) "3929.9999999999995452526491135358810424804688"
Поскольку int
всегда округляет число вниз, небольшая ошибка в представлении делает бросок вокруг него одним числом вниз, которое вы ожидали бы в противном случае.
Вместо этого подумайте об использовании round
.
Это может быть поздно, но правильный способ сделать это выглядит следующим образом:
(int) bcmul(39.3, 100.0); // 3930 (int) bcmul(39.2, 100.0); // 3920
и для обработки цифр / вычислений для поплавков или всего, что связано с денежными транзакциями, вы никогда не должны использовать прямое умножение / деление + литье.
см. также:
http://php.net/manual/en/book.bc.php
обратите внимание: кастинг в моем ответе – это просто преобразовать String в Int (вам не нужно это делать)
Вы должны посмотреть на эту страницу: http://php.net/manual/en/language.types.float.php . Он описывает подводные камни, работающие с числами с плавающей запятой.
// gives: int(3930) var_dump(intval((39.3 * 100.0) . ''));
или, для использования с функцией:
function floatToInteger ($fValue) { return (intval(($fValue + 0) . '')); } // gives: int(3930) var_dump(floatToInteger(39.3 * 100.0));