PHP floor возвращает два разных результата, когда формула одинакова?

#php #division #multiplication #floor

#php #разделение #умножение #floor

Вопрос:

 echo 'For the month of January-2019';
echo'<hr>';
echo $basicValue = floor((250000 / 31) * 31);

echo '<br>';

echo $allowance = (30000 / 31) * 31;
echo '<br>';
echo $house_rent=floor($allowance);
echo'<hr>';
echo 'For the month of February-2019';
echo'<hr>';
echo $basicValue = floor((250000 / 28) * 28);

echo '<br>';

echo $allowance = (30000 / 28) * 28;
echo '<br>';
echo $house_rent=floor($allowance); // This is return 29999 that is wrong???
  

Комментарии:

1. Прочитайте документацию. php.net/ floor = php.net/floor : Returns the next lowest integer value (as float) by rounding down value if necessary.

Ответ №1:

Это потому, что $allowance является float и floor возвращает int.

Для вашего ожидаемого результата я предлагаю использовать round() для округления float значения.

http://php.net/manual/ro/function.round.php

Смотрите: https://3v4l.org/skrQC

Вывод :

 echo 'For the month of January-2019';
echo "n";
echo $basicValue = floor((250000 / 31) * 31);

echo "n";

echo $allowance = (30000 / 31) * 31;
echo "n";
var_dump($allowance);
$allowance = intval($allowance);
echo "n";
var_dump($allowance);
echo "n";
echo $house_rent=floor($allowance);
echo "n";
echo 'For the month of February-2019';
echo "n";
echo $basicValue = floor((250000 / 28) * 28);

echo "n";

echo $allowance = (30000 / 28) * 28;
echo "n";
var_dump($allowance);
$allowance = intval($allowance);
echo "n";
var_dump($allowance);
echo $house_rent=floor($allowance); // This is return 29999 that is wrong???
  

является:

 For the month of January-2019
250000
30000
float(30000)

int(30000)

30000
For the month of February-2019
250000
30000
float(30000)

int(29999)
29999
  

Ответ №2:

Значение 30000 / 28 не является целым числом и не может быть представлено точно. Возникает небольшая ошибка округления. Значение, представленное в компьютере, немного меньше точного математического значения выражения. При умножении на 28 результат немного меньше, чем 30000 и floor() делает то, что должен делать: игнорирует десятичную часть и возвращает только целочисленную часть, которая является 29999 .

Значение 30000 / 28 * 28 в том виде, в каком оно представлено на компьютерах, приблизительно 29999.9999999999963620211929082870 .

Прочитайте больше о представлении с плавающей запятой и проблемах, с которыми вы можете столкнуться при его использовании: https://floating-point-gui.de /


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

Обычно мы считаем, что это 1/3 равно 0.333333333333333... , но независимо от того, сколько 3 мы ставим после десятичной точки, умножение на 3 не дает точного результата 1 .