Intereting Posts
PHP 5.4 vs 5.3 ошибки приложения Переменная проблема не отображается на лицевой стороне Как я могу устранить неполадку, почему мой PHP-скрипт не будет работать в cron, если это произойдет из командной строки? Установите ZendSearch в скелет ZF2 Создавайте числа в массиве, которые суммируются до заданной суммы Передать по ссылке в обратном вызове, когда насмехается в PHPUnit Doctrine – добавьте отметку времени по умолчанию для сущности типа NOW () Когда использовать $ this-> свойство вместо $ property в PHP Должен ли я использовать PHPMailer или SwiftMailer? Кодирование URL-адреса javascript для передачи # (hashtag) Эффективное сохранение загруженных пользователем изображений в файловой системе Twig для цикла и массива с ключом Понять if-Modified-Since HTTP Header Как я могу пригласить людей из MSN, Yahoo в мое приложение? Предупреждение: mysql_select_db () Доступ запрещен для пользователя '' @ 'localhost' (с использованием пароля: НЕТ)

Удаление цифр после двух десятичных знаков без округления значения

У меня есть значение в переменной php

$var='2.500000550'; echo $var 

я хочу удалить все десятичные точки после двух цифр.

как теперь значение переменной будет

 $var='2.50'; echo $var 

имейте в виду, что это значение исходит от mysql databse

но когда я использую round php function я обошел, но мне не нужно раунд, мне просто нужно удалить все цифры после двух десятичных простых.

У меня есть усталость, flot() и много другого варианта.

благодаря

TL; DR:

Собственная функция PHP bcdiv, похоже, делает именно то, что требуется, и правильно.

Просто «усечь» число, bcdiv($var, 1, 2); где 2 – количество десятичных знаков для сохранения (и 1 – деноментор – деление числа на 1 позволяет просто обрезать исходный номер до нужных знаков после запятой)

Полный ответ (для истории)

Это оказывается более неуловимым, чем можно было бы подумать.

После того, как этот ответ был (неправильно) поддержан совсем немного, мне пришло в голову, что даже sprintf будет раунд.

Вместо того, чтобы удалять этот ответ, я превращаю его в более надежное объяснение / обсуждение каждого предлагаемого решения.

number_format – Неправильно. (раунды)
Попробуйте использовать формат чисел :

 $var = number_format($var, 2, '.', ''); // Last two parameters are optional echo $var; // Outputs 2.50 

Если вы хотите, чтобы это было число, то просто введите cast-float в float:

 $var = (float)number_format($var, 2, '.', ''); 

Примечание: как было отмечено в комментариях, это фактически округляет число.

sprintf – неверно. (sprintf также раундов)
Если не округлить число, важно, то в ответе ниже используйте sprintf :

 $var = sprintf("%01.2f", $var); 

пол – не совсем! (отрицательные числа раундов)

пол , с некоторой математикой, приблизится к тому, что вы хотите:

 floor(2.56789 * 100) / 100; // 2.56 

Где 100 представляет точность, которую вы хотите. Если вы хотите, чтобы это было три цифры, тогда:

 floor(2.56789 * 1000) / 1000; // 2.567 

Однако это проблема с отрицательными числами. Отрицательные числа по-прежнему округляются, а не усекаются:

 floor(-2.56789 * 100) / 100; // -2.57 

«Старый» Правильный ответ: функция, использующая пол

Таким образом, полностью надежное решение требует функции:

 function truncate_number( $number, $precision = 2) { // Zero causes issues, and no need to truncate if ( 0 == (int)$number ) { return $number; } // Are we negative? $negative = $number / abs($number); // Cast the number to a positive to solve rounding $number = abs($number); // Calculate precision number for dividing / multiplying $precision = pow(10, $precision); // Run the math, re-applying the negative value to ensure returns correctly negative / positive return floor( $number * $precision ) / $precision * $negative; } 

Результаты вышеуказанной функции:

 echo truncate_number(2.56789, 1); // 2.5 echo truncate_number(2.56789); // 2.56 echo truncate_number(2.56789, 3); // 2.567 echo truncate_number(-2.56789, 1); // -2.5 echo truncate_number(-2.56789); // -2.56 echo truncate_number(-2.56789, 3); // -2.567 

Новый правильный ответ

Используйте встроенную функцию PHP bcdiv

 echo bcdiv(2.56789, 1, 1); // 2.5 echo bcdiv(2.56789, 1, 2); // 2.56 echo bcdiv(2.56789, 1, 3); // 2.567 echo bcdiv(-2.56789, 1, 1); // -2.5 echo bcdiv(-2.56789, 1, 2); // -2.56 echo bcdiv(-2.56789, 1, 3); // -2.567 
 floor(2.500000550 * 100) / 100; 

Это должно выполнить вашу задачу …

попробуйте с помощью number_format :

 echo number_format('2.50000050', 2); // 2.50 

Вы запрашиваете функцию, которая возвращает "2.50" а не 2.5 , поэтому вы не говорите об арифметике здесь, кроме строковых манипуляций . Тогда preg_replace – ваш друг:

 $truncatedVar = preg_replace('/\.(\d{2}).*/', '.$1', $var); // "2.500000050" -> "2.50", "2.509" -> "2.50", "-2.509" -> "2.50", "2.5" -> "2.5" 

Если вы хотите сделать это с помощью арифметики, просто используйте:

 $truncatedVar = intval($var * 100) / 100); // "2.500000050" -> "2.5", "2.599" -> "2.59", "-2.599" -> "2.59" 

использовать sprintf

 sprintf("%01.2f", $var); 

number_format округляет число

 php > echo number_format(128.20512820513, 2)."\n"; 128.21 

Я использовал preg_replace, чтобы действительно отрезать строку

 php > echo preg_replace('/(\.\d\d).*/', '$1', 128.20512820513)."\n"; 128.20 

кто-то опубликовал здесь

пол (2.500000550 * 100) / 100;

 function cutAfterDot($number, $afterDot = 2){ $a = $number * pow(10, $afterDot); $b = floor($a); $c = pow(10, $afterDot); echo "a $a, b $b, c $c<br/>"; return $b/$c ; } echo cutAfterDot(2.05,2); a 205, b 204, c 100 2.04 

поэтому в сыром виде не используйте его … Но если вы добавите немного эпсилон …

 function cutAfterDot($number, $afterDot = 2){ return floor($number * pow(10, $afterDot) + 0.00001) / pow(10, $afterDot); } 

оно работает!

Все решения, которые используют number_format, неверны, потому что number_format выполняет округление.

Функция ниже должна работать на всех числах, вы можете указать десятичный разделитель для тех стран, которые используют «,».

 function truncate_decimal($number, $truncate_decimal_length = 2, $decimal_character = '.', $thousands_character = '') { $number = explode($decimal_character, $number); $number[1] = substr($number[1], 0, $truncate_decimal_length); $number_truncated = implode($decimal_character, $number); return number_format($number_truncated, $truncate_decimal_length, $decimal_character, $thousands_character); } 

Следующее (что я считаю – пожалуйста, исправьте меня, если нет), надежное математическое решение, основанное в основном на информации от нескольких других ответчиков здесь, и небольшое количество от меня

(* Что не означает, что в репличном ответе Liphtier есть что-то неправильное – просто я вижу, как пуристы хотят избежать регулярного выражения для того, что, возможно, является математической проблемой.)

  • sprintf() , number_format()round() , очевидно), все выполняют операцию округления, поэтому не подходят для обрезания без округления, запрошенного в вопросе (по крайней мере, не по своему усмотрению).
  • Вместо функции «из коробки» казалось бы самым элегантным решением был ответ Суджита Агарвала
  • Но из-за способа хранения поплавков нам нужно использовать epsilon – как указано в ответе Дэвида Константина (где он также делает предыдущее решение более общим, используя pow() чтобы получить правильный коэффициент, основанный на заданной точности).
  • Но тогда, как указано в ответе cale_b , любое использование floor() (или предположительно ceil() ) может привести к непредвиденным результатам для негативов без использования abs() .
  • И значение, которое я пытаюсь добавить:
    • Если вы используете деление на abs() чтобы получить коэффициент отрицания, нам нужно учитывать особый случай, когда ввод равен 0.
    • Мы должны динамически создавать эпсилон; Статический закодированный epsilon может быть слишком малым или слишком большим, в зависимости от требуемой точности. Я не видел этого вопроса в других ответах.

Код, который я использую:

 public static function truncate_decimal($number, $leavePlaces = 2) { if ($number == 0) return 0; $negate = $number / abs($number); $shiftFactor = pow(10, $leavePlaces); $epsilon = pow(10, -1 * $leavePlaces); return floor(abs($number) * $shiftFactor + $epsilon) / $shiftFactor * $negate; } 

Простая функция, которая будет следовать, будет «Если больше, чем 0 floor, else ceil», используя множитель, чтобы временно нанести его над десятичной точкой во время выполнения:

 function trim_num($num_in, $dec_places = 2) { $multiplier = pow(10, $dec_places); // 10, 100, 1000, etc if ($num_in > 0) { $num_out = floor($num_in * $multiplier) / $multiplier; } else { $num_out = ceil($num_in * $multiplier) / $multiplier; } return $num_out; } 

Используйте встроенную функцию PHP bcdiv .

Пример:

 echo bcdiv(3.22871, 1, 1); // 3.2 echo bcdiv(3.22871, 1, 2); // 3.22 echo bcdiv(3.22871, 1, 3); // 3.228 echo bcdiv(-3.22871, 1, 1); // -3.2 echo bcdiv(-3.22871, 1, 2); // -3.22 

Для вашего случая:

 $var='2.500000550'; echo $var echo bcdiv($var, 1, 2); // 2.50 
 $num = 118.74999669307; $cut = substr($num, 0, ((strpos($num, '.')+1)+2)); // Cut the string from first character to a length of 2 past the decimal. // substr(cut what, start, ( (find position of decimal)+decimal itself)+spaces after decimal) ) echo $cut;