Есть ли простой способ определения числа десятичных знаков в (n) целочисленном / двойном значении в PHP? (то есть без использования взрывов)
Благодаря,
Erwin
$str = "1.23444"; print strlen(substr(strrchr($str, "."), 1));
Вы можете попробовать применить его к int, вычитая это из вашего номера, а затем подсчитывая, что осталось.
function numberOfDecimals($value) { if ((int)$value == $value) { return 0; } else if (! is_numeric($value)) { // throw new Exception('numberOfDecimals: ' . $value . ' is not a number!'); return false; } return strlen($value) - strrpos($value, '.') - 1; } /* test and proof */ function test($value) { printf("Testing [%s] : %d decimals\n", $value, numberOfDecimals($value)); } foreach(array(1, 1.1, 1.22, 123.456, 0, 1.0, '1.0', 'not a number') as $value) { test($value); }
Выходы:
Testing [1] : 0 decimals Testing [1.1] : 1 decimals Testing [1.22] : 2 decimals Testing [123.456] : 3 decimals Testing [0] : 0 decimals Testing [1] : 0 decimals Testing [1.0] : 0 decimals Testing [not a number] : 0 decimals
Я использовал следующее, чтобы определить, имеет ли возвращаемое значение любые десятичные числа (фактические десятичные значения, а не только отформатированные для отображения десятичных знаков, например, 100,00):
if($mynum - floor($mynum)>0) {has decimals;} else {no decimals;}
Что-то вроде:
<?php $floatNum = "120.340304"; $length = strlen($floatNum); $pos = strpos($floatNum, "."); // zero-based counting. $num_of_dec_places = ($length - $pos) - 1; // -1 to compensate for the zero-based count in strpos() ?>
Это процедурный, kludgy, и я бы не советовал использовать его в производственном коде. Но это должно заставить вас начать.
<?php test(0); test(1); test(1.234567890); test(-123.14); test(1234567890); test(12345.67890); function test($f) { echo "f = $f\n"; echo "i = ".getIntCount($f)."\n"; echo "d = ".getDecCount($f)."\n"; echo "\n"; } function getIntCount($f) { if ($f === 0) { return 1; } elseif ($f < 0) { return getIntCount(-$f); } else { return floor(log10(floor($f))) + 1; } } function getDecCount($f) { $num = 0; while (true) { if ((string)$f === (string)round($f)) { break; } if (is_infinite($f)) { break; } $f *= 10; $num++; } return $num; }
Выходы:
f = 0 i = 1 d = 0 f = 1 i = 1 d = 0 f = 1.23456789 i = 1 d = 8 f = -123.14 i = 3 d = 2 f = 1234567890 i = 10 d = 0 f = 12345.6789 i = 5 d = 4
$decnumber = strlen(strstr($yourstr,'.'))-1
Как насчет этого?:
$iDecimals = strlen($sFull%1);
Вот функция, которая учитывает конечные нули:
function get_precision($value) { if (!is_numeric($value)) { return false; } $decimal = $value - floor($value); //get the decimal portion of the number if ($decimal == 0) { return 0; } //if it's a whole number $precision = strlen($decimal) - 2; //-2 to account for "0." return $precision; }
Целые числа не имеют десятичных цифр, поэтому ответ всегда равен нулю.
Двойные или плавающие числа являются приблизительными. Таким образом, у них нет определенного количества десятичных цифр.
Небольшой пример:
$number = 12.00000000012; $frac = $number - (int)$number; var_dump($number); var_dump($frac);
Вывод:
float(12.00000000012) float(1.2000000992884E-10)
Здесь вы можете увидеть две проблемы, второе число использует научное представление, и это не совсем 1.2E-10.
Для строки, содержащей целое число / float, вы можете искать десятичную точку:
$string = '12.00000000012'; $delimiterPosition = strrpos($string, '.'); var_dump( $delimiterPosition === FALSE ? 0 : strlen($string) - 1 - $delimiterPosition );
Вывод:
int(11)
Мне нужно решение, которое работает с различными форматами чисел и разработало следующие алгоритмы:
// Count the number of decimal places $current = $value - floor($value); for ($decimals = 0; ceil($current); $decimals++) { $current = ($value * pow(10, $decimals + 1)) - floor($value * pow(10, $decimals + 1)); } // Count the total number of digits (includes decimal places) $current = floor($value); for ($digits = $decimals; $current; $digits++) { $current = floor($current / 10); }
Результаты:
input: 1 decimals: 0 digits: 1 input: 100 decimals: 0 digits: 3 input: 0.04 decimals: 2 digits: 2 input: 10.004 decimals: 3 digits: 5 input: 10.0000001 decimals: 7 digits: 9 input: 1.2000000992884E-10 decimals: 24 digits: 24 input: 1.2000000992884e6 decimals: 7 digits: 14
$value = 182.949; $count = strlen(abs($value - floor($value))) -2; //0.949 minus 2 places (0.)
Сначала я нашел местоположение десятичной дроби с помощью функции strpos
увеличил значение postposstpos на 1, чтобы пропустить десятичное место.
Во-вторых, я вычитал всю длину строки из значения, которое я получил из точки 1.
В-третьих, я использовал функцию substr
для получения всех цифр после десятичной.
В-четвертых, я использовал функцию strlen
для получения длины строки после десятичной точки.
Это код, который выполняет описанные выше действия:
<?php $str="98.6754332"; echo $str; echo "<br/>"; echo substr( $str, -(strlen($str)-(strpos($str, '.')+1)) ); echo "<br/>"; echo strlen( substr( $str, -(strlen($str)-(strpos($str, '.')+1))) ); ?>
$num = "12.1234567"; print strlen(preg_replace("/.*\./", "", $num)); // 7
Шаблон " . * \. " Означает все символы перед десятичной точкой с его.
В этом случае это строка с тремя символами: « 12. ».
Функция preg_replace преобразует эти символы в пустую строку (второй параметр).
В этом случае мы получаем эту строку: « 1234567 ».
Функция strlen подсчитывает количество символов в приведенной выше строке.