PHP: получить количество десятичных цифр - PullRequest
41 голосов
/ 12 марта 2010

Существует ли простой способ определения количества десятичных разрядов в (n) целых / двойных значениях в PHP? (то есть без использования explode)

Ответы [ 17 ]

67 голосов
/ 12 марта 2010
$str = "1.23444";
print strlen(substr(strrchr($str, "."), 1));
11 голосов
/ 12 марта 2010
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
11 голосов
/ 12 марта 2010

Вы можете попробовать привести его к int, вычесть это из своего числа и затем посчитать, что осталось.

3 голосов
/ 02 мая 2012

Я использовал следующее, чтобы определить, имеет ли возвращаемое значение какие-либо десятичные дроби (действительные десятичные значения, а не просто отформатированные для отображения десятичных дробей, например, 100,00):

if($mynum - floor($mynum)>0) {has decimals;} else {no decimals;} 
2 голосов
/ 04 марта 2015

Мне нужно решение, которое работает с различными числовыми форматами, и предложило следующие алгоритмы:

// 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
2 голосов
/ 12 марта 2010

Что-то вроде:

<?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()

?>

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

2 голосов
/ 21 сентября 2012
<?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
1 голос
/ 23 декабря 2016

Решение

$num = "12.1234567";
print strlen(preg_replace("/.*\./", "", $num)); // 7

Объяснение

Шаблон ". * \. " означает все символы до десятичной точки с его.

В данном случае это строка из трех символов: " 12. ".

preg_replace функция преобразует эти символы в пустую строку (второй параметр).

В этом случае мы получаем следующую строку: " 1234567 ".

strlen Функция подсчитывает количество символов в приведенной выше строке.

1 голос
/ 26 февраля 2015

Int

Целые числа не имеют десятичных цифр, поэтому ответ всегда равен нулю.

Double / Float

Двойные числа или числа с плавающей запятой являются приблизительными. Таким образом, они не имеют определенного количества десятичных цифр.

Небольшой пример:

$number = 12.00000000012;
$frac = $number - (int)$number;

var_dump($number);
var_dump($frac);

Выход:

float(12.00000000012)
float(1.2000000992884E-10)

Вы можете увидеть две проблемы здесь, второе число использует научное представление, и оно не совсем 1.2E-10.

Строка

Для строки, содержащей целое число / число с плавающей запятой, вы можете искать десятичную точку:

$string = '12.00000000012';
$delimiterPosition = strrpos($string, '.');
var_dump(
  $delimiterPosition === FALSE ? 0 : strlen($string) - 1 - $delimiterPosition
);

Выход:

int(11)
1 голос
/ 14 февраля 2014

Вот функция, которая учитывает конечные нули:

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; 
}
...