PHPでa(n) integer/double値の小数点以下の桁数を決定する簡単な方法はありますか?(つまり、explode
を使用せずに)
$str = "1.23444";
print strlen(substr(strrchr($str, "."), 1));
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
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
他の開発者の利益のためにロケールを安全に読みたい場合は、次を使用します:
function countDecimalPlacesUsingStrrpos($stringValue){
$locale_info = localeconv();
$pos = strrpos($stringValue, $locale_info['decimal_point']);
if ($pos !== false) {
return strlen($stringValue) - ($pos + 1);
}
return 0;
}
localeconv を参照してください
さまざまな数値形式で動作し、次のアルゴリズムを思いついたソリューションが必要でした。
// 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
何かのようなもの:
<?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()
?>
これは手続き型であり、気が遠く、本番コードで使用することはお勧めしません。しかし、それはあなたが始めるはずです。
整数には小数桁がないため、答えは常にゼロです。
倍数または浮動小数点数は近似値です。そのため、定義された小数桁数はありません。
小さな例:
$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)
これはどう?:
$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;
}
$num = "12.1234567";
print strlen(preg_replace("/.*\./", "", $num)); // 7
パターン "。* \。"は、小数点の前にあるすべての文字を意味します。
この場合、「12。」の3文字の文字列です。
preg_replace関数は、これらの文字を空の文字列に変換します(2番目のパラメーター)。
この場合、次の文字列を取得します: "1234567"。
strlen関数は、上記の文字列の文字数をカウントします。
$decnumber = strlen(strstr($yourstr,'.'))-1
最初に、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))) );
?>
常に異なるロケールに注意する必要があります。ヨーロッパのロケールでは、千単位の区切り記号にカンマが使用されるため、受け入れられた答えは機能しません。修正されたソリューションについては、以下を参照してください。
function countDecimalsUsingStrchr($stringValue){
$locale_info = localeconv();
return strlen(substr(strrchr($stringValue, $locale_info['decimal_point']), 1));
}
localeconv を参照してください
これは、科学表記法でも、小数点以下100桁までの精度の任意の数値で機能します。
$float = 0.0000005;
$working = number_format($float,100);
$working = rtrim($working,"0");
$working = explode(".",$working);
$working = $working[1];
$decmial_places = strlen($working);
結果:
7
長いが、複雑な条件なしで機能する。