web-dev-qa-db-fra.com

PHP: obtenir le nombre de chiffres décimaux

Existe-t-il un moyen simple de déterminer le nombre de décimales dans a(n) entier/double valeur en PHP? (c’est-à-dire sans utiliser explode)

40
Erwin
$str = "1.23444";
print strlen(substr(strrchr($str, "."), 1));
65
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);
}

Les 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
11
Kris

Vous pouvez essayer de le convertir en int, de le soustraire de votre nombre et de compter ensuite ce qui reste.

11
Allyn

J'ai utilisé ce qui suit pour déterminer si une valeur renvoyée a des décimales (valeurs décimales réelles, pas seulement formatées pour afficher des décimales telles que 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;
}

Les 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
2
Sergey

J'avais besoin d'une solution fonctionnant avec différents formats de nombres et proposant 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
2
Jeremy Worboys

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

?>

C'est procédural, kludgy et je ne conseillerais pas de l'utiliser en code de production. Mais cela devrait vous aider à démarrer.

2
David Thomas

Int

Les entiers n'ayant pas de chiffres décimaux, la réponse est toujours zéro.

Double/Float

Les nombres doubles ou flottants sont approximatifs. Donc, ils n'ont pas un nombre défini de chiffres décimaux.

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 ce n'est pas exactement 1.2E-10. 

Chaîne

Pour une chaîne contenant 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)
1
ThW

Si vous voulez de la lisibilité au profit d'autres développeurs, respectez les paramètres régionaux, utilisez:

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

1
Ian

Que dis-tu de ça?:

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

Voici une fonction qui prend en compte les zéros de fin:

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
Robert James Reese

Solution

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

Explication

Le motif ". * \. " signifie tous les caractères précédant le point décimal avec son. 

Dans ce cas, c'est une chaîne avec trois caractères: " 12. ".

preg_replace function convertit ces caractères en une chaîne vide (second paramètre).

Dans ce cas, nous obtenons cette chaîne: " 1234567 ".

strlen function compte le nombre de caractères dans la chaîne ci-dessus.

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

J'ai d'abord trouvé l'emplacement de la décimale à l'aide de la fonction strpos et incrémenté la valeur de la position strpos de 1 pour ignorer la décimale.

Deuxièmement, j'ai soustrait toute la longueur de la chaîne de la valeur du point1.

Troisièmement, j'ai utilisé la fonction substr pour obtenir tous les chiffres après la virgule.

Quatrièmement, j'ai utilisé la fonction strlen pour obtenir la longueur de la chaîne après la décimale.

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))) );
    ?>
0
rahul sharma

Vous devriez toujours faire attention à différents endroits. Les paramètres régionaux européens utilisent une virgule pour séparer les milliers, de sorte que la réponse acceptée ne fonctionne pas. Voir ci-dessous pour une solution révisée:

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

voir localeconv

0
Ian

Cela fonctionnera pour tous les nombres, même en notation scientifique, avec une précision allant jusqu'à 100 décimales.

$float = 0.0000005;

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

$decmial_places = strlen($working);

Résultat:

7

Longue mais fonctionne sans condition complexe.

0
McClint