web-dev-qa-db-fra.com

PHP vérifier si la variable est un nombre entier

J'ai ce code PHP:

$entityElementCount = (-($highScore-$totalKeywordCount))/0.29;

Ce que je veux savoir, c'est comment vérifier si $ entityElementCount est un nombre entier (2, 6, ...) ou partiel (2.33, 6.2, ...).

Je vous remercie!

26
spacemonkey
$entityElementCount = (-($highScore-$totalKeywordCount))/0.29;
if (ctype_digit($entityElementCount) ){
    // (ctype_digit((string)$entityElementCount))  // as advised.
    print "whole number\n";
}else{
    print "not whole number\n";
}
19
ghostdog74
if (floor($number) == $number)
38
Tyler Carter

Je sais que c'est vieux, mais je pensais partager quelque chose que je viens de trouver:

Utilisez fmod et vérifiez 0

$entityElementCount = (-($highScore-$totalKeywordCount))/0.29;
if (fmod($entityElementCount,1) !== 0.0) {
    echo 'Not a whole number!';
} else {
    echo 'A whole number!';
}

fmod est différent de% parce que si vous avez une fraction,% ne semble pas fonctionner pour moi (il renvoie 0 ... par exemple, echo 9.4 % 1; générera 0). Avec fmod, vous aurez la fraction. Par exemple:

echo fmod(9.4, 1);

Affichera 0.4

33
Joseph

Comme le dit Chacha, le moyen de base est

if (floor($number) == $number)

Toutefois, les types à virgule flottante ne peuvent pas stocker les nombres avec précision, ce qui signifie que 1 peut être stocké sous la forme 0.999999997. Cela signifiera bien sûr que la vérification ci-dessus échouera, car elle sera arrondie à 0, même si pour les besoins de votre assez proche à 1 pour être considéré comme un nombre entier. Par conséquent, essayez quelque chose comme ceci:

if (abs($number - round($number)) < 0.0001)
9
Aistina

Je voudrais utiliser intval fonction comme ceci:

if($number === intval($number)) {

}

Tests:

var_dump(10 === intval(10));     // prints "bool(true)"
var_dump("10" === intval("10")); // prints "bool(false)"
var_dump(10.5 === intval(10.5)); // prints "bool(false)"
var_dump("0x539" === intval("0x539")); // prints "bool(false)"

Autres solutions

1)  

if(floor($number) == $number) {   // Currently most upvoted solution: 

Tests:

$number = true;
var_dump(floor($number) == $number); // prints "bool(true)" which is incorrect.

2)  

if (is_numeric($number) && floor($number) == $number) {

Coin cas:

$number = "0x539";
var_dump(is_numeric($number) && floor($number) == $number); // prints "bool(true)" which depend on context may or may not be what you want

3)

if (ctype_digit($number)) {

Tests: 

var_dump(ctype_digit("0x539")); // prints "bool(false)"
var_dump(ctype_digit(10)); // prints "bool(false)"
var_dump(ctype_digit(0x53)); // prints "bool(false)"
8
Martin Vseticka

Si vous savez qu'il sera numérique (ce qui signifie qu'il ne s'agira jamais d'un entier converti en chaîne, telle que "ten" ou "100", vous pouvez simplement utiliser is_int():

$entityElementCount = (-($highScore-$totalKeywordCount))/0.29;
$entityWholeNumber = is_int($entityElementCount);

echo ($entityWholeNumber) ? "Whole Number!" : "Not a whole number!";
6
Anthony

J'ai testé toutes les solutions proposées avec de nombreuses valeurs problématiques mentionnées, elles ont toutes échoué pour au moins un des cas de test. Commencez à vérifier si $value est un nombre en utilisant is_numeric($value) réduit le nombre d'échecs pour de nombreuses solutions, mais ne transforme aucune solution en ultime:

$test_cases = array(0.29, 2, 6, 2.33, 6.2, '10.00', 1.4, 10, "10", 10.5, "0x539", true,
    false, 0x53, 9.4, "ten", "100", 1, 0.999999997, 0, 0.0001, 1.0, 0.9999999,
    (-(4.42-5))/0.29);

function is_whole_number($value) {
    // Doing this prevents failing for values like true or "ten"
    if (!is_numeric($value)) {
        return false;
    }

    // @ghostdog74's solution fails for "10.00"
    // return (ctype_digit((string) $value));

    // Both @Maurice's solutions fails for "10.00"
    // return ((string) $value === (string) (int) $value);
    // return is_int($value);

    // @j.hull's solution always returns true for numeric values
    // return (abs($value) % 1 == 0 ? true : false);

    // @ MartyIX's solution fails for "10.00"
    // return ($value === intval($value));

    // This one fails for (-(4.42-5))/0.29
    // return (floor($value) == $value);

    // This one fails for 2
    // return ctype_digit($value);

    // I didn't understand Josh Crozier's answer

    // @joseph4tw's solution fails for (-(4.42-5))/0.29
    // return !(fmod($value, 1) != 0);

    // If you are unsure about the double negation, doing this way produces the same
    // results:
    // return (fmod($value, 1) == 0);

    // Doing this way, it always returns false 
    // return (fmod($value, 1) === 0);

    // @Anthony's solution fails for "10.00"
    // return (is_numeric($value) && is_int($value));

    // @Aistina's solution fails for 0.999999997
    // return (abs($value - round($value)) < 0.0001);

    // @Notinlist's solution fails for 0.999999997
    // return (round($value, 3) == round($value));
}

foreach ($test_cases as $test_case) {
    var_dump($test_case);
    echo ' is a whole number? ';
    echo is_whole_number($test_case) ? 'yes' : 'no';
    echo "\n";
}

Je pense que les solutions telles que celles proposées par @Aistina et @Notinlist sont les meilleures, car elles utilisent un seuil d'erreur pour décider si une valeur est un nombre entier. Il est important de noter qu'ils ont fonctionné comme prévu pour l'expression (-(4.42-5))/0.29, alors que tous les autres ont échoué dans ce cas de test.

J'ai décidé d'utiliser la solution de @ Notinlist en raison de sa lisibilité:

function is_whole_number($value) {
    return (is_numeric($value) && (round($value, 3) == round($value)));
}

Je dois tester si les valeurs sont des nombres entiers, une devise ou un pourcentage. Je pense que la précision est de 2 chiffres, donc la solution de @ Notinlist répond à mes besoins.

Lancer ce test:

$test_cases = array(0.29, 2, 6, 2.33, 6.2, '10.00', 1.4, 10, "10", 10.5, "0x539", true,
    false, 0x53, 9.4, "ten", "100", 1, 0.999999997, 0, 0.0001, 1.0, 0.9999999,
    (-(4.42-5))/0.29);

function is_whole_number($value) {
    return (is_numeric($value) && (round($value, 3) == round($value)));
}

foreach ($test_cases as $test_case) {
    var_dump($test_case);
    echo ' is a whole number? ';
    echo is_whole_number($test_case) ? 'yes' : 'no';
    echo "\n";
}

Produit la sortie suivante:

float(0.29)
 is a whole number? no
int(2)
 is a whole number? yes
int(6)
 is a whole number? yes
float(2.33)
 is a whole number? no
float(6.2)
 is a whole number? no
string(5) "10.00"
 is a whole number? yes
float(1.4)
 is a whole number? no
int(10)
 is a whole number? yes
string(2) "10"
 is a whole number? yes
float(10.5)
 is a whole number? no
string(5) "0x539"
 is a whole number? yes
bool(true)
 is a whole number? no
bool(false)
 is a whole number? no
int(83)
 is a whole number? yes
float(9.4)
 is a whole number? no
string(3) "ten"
 is a whole number? no
string(3) "100"
 is a whole number? yes
int(1)
 is a whole number? yes
float(0.999999997)
 is a whole number? yes
int(0)
 is a whole number? yes
float(0.0001)
 is a whole number? yes
float(1)
 is a whole number? yes
float(0.9999999)
 is a whole number? yes
float(2)
 is a whole number? yes
(string)floor($pecahformat[3])!=(string)$pecahformat[3]
3
Artron
if(floor($number) == $number)

N'est pas un algorithme stable. Lorsqu'une valeur correspond à 1,0, la valeur numérique peut être 0,9999999. Si vous appliquez floor (), il sera 0, ce qui n’est pas égal à 0,9999999.

Vous devez deviner un rayon de précision, par exemple 3 chiffres

if(round($number,3) == round($number))
3
Notinlist

Ce n'est pas une tentative de répondre à cette question autant. Leur beaucoup de réponse déjà. Si vous faites des statistiques comme le suggère la question, je pense que la réponse de @ antonio-vinicius-menezes-medei vous conviendra le mieux. Cependant, j'avais besoin de cette réponse pour valider la saisie. J'ai trouvé cette vérification plus fiable pour valider une chaîne d'entrée est un nombre entier:

is_numeric($number) && preg_match('/^[0-9]+$/', $number)

Le 'is_numeric' corrige simplement pour "true" la conversion en "1" dans preg_match.

Donc, en jouant sur la réponse @ antonio-vinicius-menezes-medei. J'ai écrit un script pour tester cela ci-dessous. Notez la ini_set('precision', 20). preg_match convertira l'argument en chaîne. Si votre précision est définie en dessous de la longueur des valeurs de float, elles seront simplement arrondies à la précision donnée. Similaire à @ antonio-vinicius-menezes-medei, ce réglage de précision forcera une longueur d'estimation similaire.

  ini_set('precision', 20);
  $test_cases = array(0.29, 2, 6, 2.33, 6.2, '10.00', 1.4, 10, "10", 10.5, "0x539", true,
    false, 0x53, 9.4, "ten", "100", 1, 0.999999997, 0, 0.0001, 1.0, 0.9999999,
    (-(4.42-5))/0.29);

  foreach ($test_cases as $number)
  {
    echo '<strong>';
    var_dump($number);
    echo '</strong>';
    echo boolFormater(is_numeric($number) && preg_match('/^[0-9]+$/', $number));
    echo '<br>';
  }

  function boolFormater($value)
  {
    if ($value)
    {
      return 'Yes';
    }
    return 'No';
  }

Qui produit cette sortie:

float (0.28999999999999998002) Non
int (2) Oui
int (6) Oui
float (2.3300000000000000711) Non
float (6.2000000000000001776) Non
string (5) "10.00" No
float (1.3999999999999999112) Non
int (10) Oui
string (2) "10" Oui
float (10.5) No
string (5) "0x539" Non
bool (true) Non
bool (false) Non
int (83) Oui
float (9.4000000000000003553) Non
string (3) "dix" Non
string (3) "100" Oui
int (1) Oui
float (0.9999999969999999997382) Non
int (0) Oui
float (0.00010000000000000000479) Non
float (1) Oui
float (0.99999990000000005264) Non
float (2.0000000000000004441) Non 

1
danielson317
floor($entityElementCount) == $entityElementCount

Cela sera vrai s'il s'agit d'un nombre entier

1
José Mélançon

Je sais que c’est un très vieux post, mais c’est une fonction simple qui renvoie un nombre entier valide et le jette dans un int. Retourne false si cela échoue.

function isWholeNumber($v)
{
    if ($v !='' && is_numeric($v) && strpos($v, '.') === false) {
        return (int)$v;
    }
    return false;
}

Utilisation: 

$a = 43;
$b = 4.3;
$c = 'four_three';

isWholeNumber($a) // 43
isWholeNumber($b) // false
isWholeNumber($c) // false
0
spice

Juste pour partager ma solution avec une chaîne/un nombre localisé, ce combo a fonctionné à merveille pour moi.

public static function isWholeNumber ($input, $decimalDelimiter = ',')
{
    if (is_string($input)){
        $input = str_replace($decimalDelimiter, '.', $input);
        $input = floatval($input);
    }

    if (fmod($input,1) !== 0.0) {
        return false;
    }

    return true;
}
0
The Vojtisek
$entityElementCount = (-($highScore-$totalKeywordCount))/0.29;

Method 1-
    By using ctype_digit() function. 

    if ( ctype_digit($entityElementCount )) { 
        echo "Whole Number\n"; 
    } else { 
        echo "Not a whole Number\n"; 
    } 


Method 2-
    By using is_float() function. 

    if (is_float($entityElementCount )) { 
        echo "Not a Whole Number\n"; 
    } else { 
        echo "Whole Number\n"; 
    } 


Method 3-
    By using is_int() function. 

    if (is_int($entityElementCount )) { 
        echo "Whole Number\n"; 
    } else { 
        echo "Not a whole Number\n"; 
    } 


Method 5-
    By using fmod() function. 

    It needs 2 parameters one dividend and other is divisor
    Here $dividend=$entityElementCount and divisor=1
    if (fmod($dividend,$divisor) !== 0.0) {
        echo 'Not a whole number!';
    } else {
     echo 'A whole number!';
    }

there are some more function like intval(), floor(),... can be used to check it`enter code here`
0
sanjaya

Une solution simple pour les nombres entiers positifs seulement. Cela peut ne pas fonctionner pour tout.

$string = '0x539';
$ceil = ceil($string);

if($ceil < 1){
  $ceil = FALSE; // or whatever you want i.e 0 or 1
}

echo $ceil; // 1337

Vous pouvez utiliser floor () au lieu de ceil () si vous le souhaitez. 

0
toystory
function isInteger($value)
{
    // '1' + 0 == int, '1.2' + 0 == float, '1e2' == float
    return is_numeric($value) && is_int($value + 0);
}

function isWholeNumber($value)
{
    return is_numeric($value)
        && (is_int($value + 0)
            || (intval($value + 0) === intval(ceil($value + 0))));
}

Si vous souhaitez vérifier les nombres entiers et décimaux, vous pouvez procéder comme suit:

if (isInteger($foo))
{
    // integer as int or string
}
if (isWholeNumber($foo))
{
    // integer as int or string, or float/double with zero decimal part
}
else if (is_numeric($foo))
{
    // decimal number - still numeric, but not int
}

Cela vérifiera correctement votre nombre sans l’arrondir, le lançant en int (ce qui dans le cas d’un nombre décimal perdra la partie décimale), ou en effectuant des calculs. Si, toutefois, vous voulez traiter 1.00 comme un nombre entier, alors c'est une toute autre histoire.

0
jurchiks

Ce qui semble une approche simple serait d’utiliser le module (%) pour déterminer si une valeur est entière ou non. 

x = y % 1  

si y est autre chose qu'un nombre entier, le résultat n'est pas un zéro (0). Un test serait alors:

if (y % 1 == 0) { 
   // this is a whole number  
} else { 
   // this is not a whole number 
}

var isWhole = (y % 1 == 0? true: false);  // to get a boolean return. 

Accordé, cela affichera un nombre négatif sous forme de nombre entier, puis encapsulera simplement ABS () autour de y pour toujours tester le positif.

0
j.hull

J'utilise toujours le transtypage pour vérifier si les variables contiennent un nombre entier, ce qui est pratique lorsque vous ne connaissez pas l'origine ou le type de la valeur.

if ((string) $var === (string) (int) $var) {
    echo 'whole number';
} else {
    echo 'whatever it is, it\'s something else';
}

Dans votre cas particulier, je voudrais utiliser is_int ()

if (is_int($var) {
    echo 'integer';
}
0
Maurice