1

Проверяю: если число больше 8 знаков после запятой, то нужно обрезать до 8 знаков. Пробую так

number_format('0.599999999',8);

Выводит

0.60000000

round(0.599999999,8);

Вывод

0.6

round(0.599999994,8);

Вывод

0.59999999

то есть округляется в большую сторону. Пожалуйста, подскажите, как решить проблему?

5 ответов 5

2

Да не с числом вы работаете на этом уровне, а со строкой

$number = '0.599999999999999999';
$precision = 8; //количество оставляемых символов
$pos = strrpos($number, '.'); // при необходимости заменить на просто strpos
if ($pos !== false) {
    $number = substr($number, 0, $pos + 1 + $precision);
}
var_dump($number); //string(10) "0.59999999"
1
$chislo=0.5999999994; 
$chislo=floor($chislo*100000000)/100000000; // переносим запятую на 8 знаков вправо, отбрасываем дробную часть и переносим запятую обратно
5
  • floor поддерживает параметры?
    – shogun
    24 апр 2014 в 16:15
  • какие параметры?
    – ZooMka
    24 апр 2014 в 16:17
  • floor(0.599999994,8); -- Warning: floor() expects exactly 1 parameter, 2 given on line 1
    – shogun
    24 апр 2014 в 16:28
  • нужно обрезать, округлить число 0.599999999 в меншую сторону до 8 знаков невозможно математически
    – shogun
    24 апр 2014 в 16:29
  • Да, я ошибся, он округляет только до целых в большую/меньшую сторону. Тогда можно сделать так: $chislo=0.5999999994; $chislo=floor($chislo*100000000)/100000000; // переносим запятую на 8 знаков вправо, отбрасываем дробную часть и переносим запятую обратно
    – ZooMka
    24 апр 2014 в 18:34
1

Предложу и свой велосипед, т. к. что-то стандартных ф-й нна ум не приходит:

function get_truncate($num, $precision)
{
    $tmp = sprintf("%.".($precision + 2)."s", $num - (int)$num); // + 2 так как "0." также надо учесть в кол-ве, num - (int)num просто отбрасывает целую часть (нужно для правильной обработки чисел с целой частью > 9, типа 55555.9999999999)
    return $tmp + (int)$num;
}
echo get_truncate(125.59999999,8);

http://ideone.com/wp2D6n

0
$num = 0.599999999;

$fig = (int) str_pad('1', 9, '0');
$result = (floor($num * $fig) / $fig);

var_dump($result); //float(0.59999999) 
0

По поводу решения пользователя @etki: Данное решение не работает с экспоненциальными числами. Иначе говоря, если вы указываете в качестве вводного значения результат вычисления дробных чисел:

$number = '0.16831356174533' - '0.16832176570967'; // 8.2039643400089E-6
$precision = 8;
$pos = strrpos($number, '.');
if($pos !== false) $number = substr($number, 0, $pos + 1 + $precision);
var_dump($number); // string(11) "-8.20396434"

То в функцию substr передастся экспоненциальное значение: 8.2039643400089E-6, и обрезаться будет уже оно. Иначе говоря, решение не работает, и с малыми дробными значениями может выдасть совсем не желаемый результат. Прокоментировать ответ не мог, так как не позволяла репутация, поэтому указал новым ответом.

Возможное решение

Используйте функцию bcdiv, она как раз-таки не округляет, а обрезает дробное число, однако у нее та же проблема - она не может работать с экспоненциальными числами, но, по крайней мере, она работает с остальными дробными значениями:

$number = '0.16839';
var_dump(number_format($number, 4)); // string(6) "0.1684"
var_dump(bcdiv($number, 1, 4)); string(6) "0.1683"

Ваш ответ

By clicking “Отправить ответ”, you agree to our terms of service and acknowledge you have read our privacy policy.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками или задайте свой вопрос.