Неожиданный результат в PHP для типа float to int - PullRequest
13 голосов
/ 02 августа 2010

Я пытаюсь преобразовать число с плавающей точкой в ​​значение типа 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

Ответы [ 4 ]

16 голосов
/ 02 августа 2010

Это потому, что числа, которые имеют конечное представление в базе 10, могут иметь или не иметь точное представление в представлении с плавающей запятой, которое использует PHP.

См

>php -r "echo var_dump(sprintf('%.40F', 39.3 * 100.0));"
string(45) "3929.9999999999995452526491135358810424804688"

Поскольку int всегда округляет число вниз, небольшая ошибка в представлении приводит к тому, что приведенное число округляется на одно число меньше, чем вы ожидаете.

Попробуйте вместо этого использовать round.

7 голосов
/ 08 февраля 2016

Это может быть поздно, но правильный способ сделать это заключается в следующем:

(int) bcmul(39.3, 100.0); // 3930
(int) bcmul(39.2, 100.0); // 3920

и для работы с цифрами / вычисления для чисел с плавающей запятой, или что-нибудь, что связано с денежной транзакцией,Вы никогда не должны использовать прямое умножение / деление + приведение.

, пожалуйста, также обращайтесь к этому:

http://php.net/manual/en/book.bc.php

примечание: приведение в моем ответепросто чтобы преобразовать строку в Int (вам не нужно это делать)

1 голос
/ 11 февраля 2014
// 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));
1 голос
/ 02 августа 2010

Вы должны взглянуть на эту страницу: http://php.net/manual/en/language.types.float.php. В ней описаны подводные камни при работе с числами с плавающей запятой.

...