Существует ли простой способ определения числа десятичных знаков в (n) целочисленном/двойном значении в PHP? (то есть без использования взрывов)
Спасибо,
Эрвин
Существует ли простой способ определения числа десятичных знаков в (n) целочисленном/двойном значении в PHP? (то есть без использования взрывов)
Спасибо,
Эрвин
$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 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
и увеличив значение strpos
postion на 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 подсчитывает количество символов в приведенной выше строке.