php – почему слово округляет целое число?

Я смущен, почему:

echo log10(238328) / log10(62); 

результаты 3

но

 echo floor(log10(238328) / log10(62)); 

результаты 2

Я знаю, что слово округляется, но я думал, что это только для десятичных чисел.

Как я могу получить ответ из 3 из последнего статута, пока он все еще нормально округляется?

PHP использует числа с плавающей запятой с двойной точностью. Ни один из результатов двух логарифмов не может быть представлен точно, поэтому результат их деления не является точным. Результат, который вы получаете, близок к, но немного меньше 3. Это округляется до 3 при форматировании echo . floor , однако возвращает 2.

Вы можете избежать неточного деления, воспользовавшись тем, что log(x, b) / log(y, b) эквивалентен log(x, y) (для любой базы b ). Это дает вместо этого log(238328, 62) выражения log(238328, 62) , который имеет результат с плавающей запятой ровно 3 (правильный результат с 238328 равен pow(62, 3) ).

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

См. Запись чисел плавающей запятой PHP Manual для получения дополнительной информации.

Обходной путь состоит в том, чтобы выполнить floor(round($value, 15)); , Выполнение этого гарантирует, что ваш номер будет отполирован достаточно точно.

Если вы var_dump, вы увидите, что «3» на самом деле является плавающей точкой. Это означает, что он, вероятно, близок к 3 и округляется. Если вам нужно 3, вам нужно будет использовать функцию сестры, ceil.

Вы можете получить лучшие результаты с помощью функции round () и / или явно направить его на int, а не полагаться на ceil (). Дополнительную информацию смотрите здесь: http://php.net/manual/en/language.types.integer.php

За счет небольшой производительности вы можете принуждать ее, уменьшая точность до более полезного диапазона путем округления или форматирования строки:

 echo floor(round(log10(238328)/log10(62), 4)); echo floor(sprintf('%.4f', log10(238328)/log10(62))); // output: // 3 // 3 

Вы должны пойти с минимальной точностью, которая вам нужна. Больше точности не то, что вы хотите. Возможно, округление без полов может быть более правильным, результаты различаются в зависимости от точности.

 echo floor(round(log10(238328)/log10(62), 16)); echo round(log10(238328)/log10(62), 16); // output: // 2 // 3 

там три функции для выполнения почти одинаковых:

  • ceil -> ceil(0.2)==1 && ceil(0.8)==1
  • floor -> floor(0.2)==0 && floor(0.8)==0
  • round -> round(0.2)==0 && round(0.8)==1