Ответы RenaPot , IsisCode , goredwards не верны.
Из-за того, как float работает в компьютерах (в целом), float не точен.
Чтобы повторить проблему:
floor(19.99 * 100); // Outputs 1998 instead of 1999
floor( 5.10 * 100); // Outputs 509 instead of 510
Внутри PHP внутри 19.99 * 100
получается что-то вроде 1998.999999999999999
, что, когда мы делаем floor
, мы получаем 1998
.
Решение:
Решение 1: Используйте библиотеку bcmath (предложено @SamyMassoud), если она установлена (некоторые серверы общего хостинга могут не устанавливать ее по умолчанию). Вот так:
//floor(19.99 * 100);// Original
floor(bcmul(19.99, 100));// Outputs 1999
Решение 2: Манипуляции со строками (моя рекомендация):
// Works with positive and negative numbers, and integers and floats and strings
function withoutRounding($number, $total_decimals) {
$number = (string)$number;
if($number === '') {
$number = '0';
}
if(strpos($number, '.') === false) {
$number .= '.';
}
$number_arr = explode('.', $number);
$decimals = substr($number_arr[1], 0, $total_decimals);
if($decimals === false) {
$decimals = '0';
}
$return = '';
if($total_decimals == 0) {
$return = $number_arr[0];
} else {
if(strlen($decimals) < $total_decimals) {
$decimals = str_pad($decimals, $total_decimals, '0', STR_PAD_RIGHT);
}
$return = $number_arr[0] . '.' . $decimals;
}
return $return;
}
// How to use:
withoutRounding(19.99, 2);// Return "19.99"
withoutRounding(1.505, 2);// Return "1.50"
withoutRounding(5.1, 2);// Return "5.10"