web-dev-qa-db-ja.com

PHP:10進数の桁数を取得します

PHPでa(n) integer/double値の小数点以下の桁数を決定する簡単な方法はありますか?(つまり、explodeを使用せずに)

41
Erwin
$str = "1.23444";
print strlen(substr(strrchr($str, "."), 1));
69
ghostdog74
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
Kris

あなたはそれを整数にキャストして、それをあなたの数から引いて、残っているものを数えてみることができます。

11
Allyn

以下を使用して、返された値に小数があるかどうかを確認しました(100.00のような小数を表示するようにフォーマットされているだけでなく、実際の小数値)。

if($mynum - floor($mynum)>0) {has decimals;} else {no decimals;} 
3
skips
<?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
2
Sergey

他の開発者の利益のためにロケールを安全に読みたい場合は、次を使用します:

function countDecimalPlacesUsingStrrpos($stringValue){
    $locale_info = localeconv();
    $pos = strrpos($stringValue, $locale_info['decimal_point']);
    if ($pos !== false) {
        return strlen($stringValue) - ($pos + 1);
    }
    return 0;
}

localeconv を参照してください

2
Ian

さまざまな数値形式で動作し、次のアルゴリズムを思いついたソリューションが必要でした。

// 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
Jeremy Worboys

何かのようなもの:

<?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
David Thomas

Int

整数には小数桁がないため、答えは常にゼロです。

ダブル/フロート

倍数または浮動小数点数は近似値です。そのため、定義された小数桁数はありません。

小さな例:

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

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

出力:

float(12.00000000012)
float(1.2000000992884E-10)

ここで2つの問題を確認できます。2番目の数字は科学的表現を使用しており、正確には1.2E-10ではありません。

ストリング

整数/浮動小数点を含む文字列の場合、小数点を検索できます:

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

出力:

int(11)
1
ThW

これはどう?:

$iDecimals = strlen($sFull%1);
1
Anton

末尾のゼロを考慮する関数は次のとおりです。

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

解決

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

説明

パターン "。* \。"は、小数点の前にあるすべての文字を意味します。

この場合、「12。」の3文字の文字列です。

preg_replace関数は、これらの文字を空の文字列に変換します(2番目のパラメーター)。

この場合、次の文字列を取得します: "1234567"。

strlen関数は、上記の文字列の文字数をカウントします。

1
simhumileco
$decnumber = strlen(strstr($yourstr,'.'))-1
1
Young

最初に、strpos関数を使用して小数点の位置を見つけ、strpos位置の値を1増やして小数点以下の桁をスキップしました。

次に、point1から取得した値から文字列全体の長さを減算しました。

3番目に、substr関数を使用して、小数点以下のすべての数字を取得しました。

4番目に、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))) );
    ?>
0
rahul sharma

常に異なるロケールに注意する必要があります。ヨーロッパのロケールでは、千単位の区切り記号にカンマが使用されるため、受け入れられた答えは機能しません。修正されたソリューションについては、以下を参照してください。

 function countDecimalsUsingStrchr($stringValue){
        $locale_info = localeconv();
        return strlen(substr(strrchr($stringValue, $locale_info['decimal_point']), 1));
    }

localeconv を参照してください

0
Ian

これは、科学表記法でも、小数点以下100桁までの精度の任意の数値で機能します。

$float = 0.0000005;

$working = number_format($float,100);
$working = rtrim($working,"0");
$working = explode(".",$working);
$working = $working[1];

$decmial_places = strlen($working);

結果:

7

長いが、複雑な条件なしで機能する。

0
McClint