PHP: obtenir le nombre de décimales
Existe-t-il un moyen simple de déterminer le nombre de décimales dans un(n) Entier/double valeur en PHP? (qui est, sans l'aide de explode
)
16 réponses
$str = "1.23444";
print strlen(substr(strrchr($str, "."), 1));
vous pouvez essayer de le lancer à un int, en soustrayant cela de votre nombre et puis en comptant ce qui reste.
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);
}
Sorties:
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
j'ai utilisé ce qui suit pour déterminer si une valeur retournée a des décimales (valeurs décimales réelles, pas seulement formatées pour afficher des décimales comme 100.00):
if($mynum - floor($mynum)>0) {has decimals;} else {no decimals;}
quelque Chose comme:
<?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()
?>
ceci est procédural, kludgy et je ne conseillerais pas de l'utiliser dans le code de production. Mais il devrait vous obtenir a commencé.
<?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;
}
Sorties:
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
j'avais besoin d'une solution qui fonctionne avec différents formats de nombres et j'ai trouvé les algorithmes suivants:
// 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);
}
Résultats:
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
Voici une fonction qui prend en compte les zéros suivants:
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;
}
Int
les nombres entiers n'ont pas de décimales, donc la réponse est toujours zéro.
Double / Flottant
les nombres doubles ou flottants sont des approximations. Ils n'ont donc pas un nombre défini de décimales.
Un petit exemple:
$number = 12.00000000012;
$frac = $number - (int)$number;
var_dump($number);
var_dump($frac);
Sortie:
float(12.00000000012)
float(1.2000000992884E-10)
vous pouvez voir deux problèmes ici, le deuxième nombre utilise la représentation scientifique et il n'est pas exactement 1.2 E-10.
Chaîne
Pour une chaîne qui contient un entier/float vous pouvez rechercher le point décimal:
$string = '12.00000000012';
$delimiterPosition = strrpos($string, '.');
var_dump(
$delimiterPosition === FALSE ? 0 : strlen($string) - 1 - $delimiterPosition
);
Sortie:
int(11)
si vous voulez la lisibilité pour le bénéfice des autres devs, locale safe, utiliser:
function countDecimalPlacesUsingStrrpos($stringValue){
$locale_info = localeconv();
$pos = strrpos($stringValue, $locale_info['decimal_point']);
if ($pos !== false) {
return strlen($stringValue) - ($pos + 1);
}
return 0;
}
voir localeconv
tout d'abord j'ai trouvé l'emplacement de la décimale en utilisant strpos
fonction et incrémentation de la strpos
valeur de la position par 1 pour sauter la décimale.
seconde j'ai soustrait toute la longueur de la chaîne de la valeur que j'ai obtenue à partir du point1.
Troisième, j'ai utilisé substr
fonction pour obtenir tous les chiffres après la virgule.
quatrième j'ai utilisé le strlen
fonction pour obtenir la longueur de la chaîne de caractères après la virgule.
C'est le code qui effectue les étapes décrites ci-dessus:
<?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))) );
?>
Solution
$num = "12.1234567";
print strlen(preg_replace("/.*\./", "", $num)); // 7
Explication
".*\. " signifie Tous les caractères avant le point décimal Avec its.
dans ce cas, c'est une chaîne avec trois caractères: " 12.".
preg_replace la fonction convertit ces caractères en chaîne vide (second paramètre).
Dans ce cas, nous obtenons cette chaîne: " 1234567".
strlen la fonction compte le nombre de caractères dans la chaîne ci-dessus.
Vous devriez toujours faire attention aux différents endroits. Les locales européennes utilisent une virgule pour le séparateur de milliers, de sorte que la réponse acceptée ne fonctionnerait pas. Voir ci-dessous pour une version révisée de la solution:
function countDecimalsUsingStrchr($stringValue){
$locale_info = localeconv();
return strlen(substr(strrchr($stringValue, $locale_info['decimal_point']), 1));
}
voir localeconv
$value = 182.949;
$count = strlen(abs($value - floor($value))) -2; //0.949 minus 2 places (0.)