Verifique se a variável é um número inteiro

Eu tenho esse código PHP:

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

O que eu quero saber é, como verificar se $ entityElementCount é um número inteiro (2, 6, …) ou parcial (2.33, 6.2, …).

Obrigado!

 $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"; } 
 if(floor($number) == $number) 

Eu sei que isso é antigo, mas pensei que compartilharia algo que acabei de encontrar:

Use fmod e verifique por 0

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

fmod é diferente de%, porque se você tiver uma fração,% não parece funcionar para mim (retorna 0 … por exemplo, echo 9.4 % 1; emitirá 0 ). Com fmod, você receberá a fração. Por exemplo:

echo fmod(9.4, 1);

Produzirão 0.4

A maneira básica, como disse Chacha é

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

No entanto, os tipos de ponto flutuante não podem armazenar com precisão números, o que significa que 1 pode ser armazenado como 0,999999997. Isso, naturalmente, significará que a verificação acima falhará, porque será arredondada para baixo para 0, mesmo que para seus propósitos seja próximo o suficiente para 1 ser considerado um número inteiro. Portanto tente algo como isto:

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

Se você sabe que será numérico (o que significa que nunca será um casting inteiro como uma string, como "ten" ou "100" , você pode usar is_int() :

 $entityElementCount = (-($highScore-$totalKeywordCount))/0.29; $entityWholeNumber = is_int($entityElementCount); echo ($entityWholeNumber) ? "Whole Number!" : "Not a whole number!"; 

Eu usaria a function intval como esta:

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

Testes:

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

Outras soluções

1)

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

Testes:

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

2)

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

Caso de canto:

 $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)) { 

Testes:

 var_dump(ctype_digit("0x539")); // prints "bool(false)" var_dump(ctype_digit(10)); // prints "bool(false)" var_dump(ctype_digit(0x53)); // prints "bool(false)" 
 if(floor($number) == $number) 

Não é um algoritmo estável. Quando um valor é matematicamente 1.0, o valor numérico pode ser 0.9999999. Se você aplicar floor () nele será 0, o que não é igual a 0.9999999.

Você deve adivinhar um raio de precisão, por exemplo, 3 dígitos

 if(round($number,3) == round($number)) 
 (string)floor($pecahformat[3])!=(string)$pecahformat[3] 

Testei todas as soluções propostas com muitos valores problemáticos mencionados, todos falhavam para pelo menos um dos casos de teste. Comece a verificar se o $value é um número usando is_numeric($value) reduz o número de falhas para muitas soluções, mas não transforma qualquer solução em uma última:

 $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"; } 

Eu acho que soluções como as propostas por @Aistina e @Notinlist são as melhores porque usam um limiar de erro para decidir se um valor é um número inteiro. É importante notar que eles funcionaram como esperado para a expressão (-(4.42-5))/0.29 , enquanto todos os outros falharam nesse caso de teste.

Eu decidi usar a solução @ Notinlist por causa de sua legibilidade:

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

Eu preciso testar se os valores são números inteiros, moeda ou porcentagem, acho que 2 dígitos de precisão são suficientes, então a solução da @ Notinlist se adapta às minhas necessidades.

Execução deste teste:

 $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"; } 

Produz o seguinte resultado:

 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 
 floor($entityElementCount) == $entityElementCount 

Isso será verdade se este for um número inteiro

O que parece uma abordagem simples seria usar o módulo (%) para determinar se um valor é total ou não.

 x = y % 1 

se y for qualquer outra coisa, então um número inteiro o resultado não é um zero (0). Um teste então seria:

 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. 

Concedido, isso verá um número negativo como um número inteiro, então então envolva ABS () em torno de y para testar sempre o positivo.

Eu sempre uso typecasting para verificar se as variables ​​contêm um número inteiro, útil quando você não conhece a origem ou o tipo do valor.

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

Em seu caso particular, eu usaria is_int ()

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

Uma solução simples para números inteiros positivos apenas. Isso pode não funcionar para tudo.

 $string = '0x539'; $ceil = ceil($string); if($ceil < 1){ $ceil = FALSE; // or whatever you want ie 0 or 1 } echo $ceil; // 1337 

Você pode usar floor () em vez de ceil () se assim desejar.

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

Se você deseja verificar os números inteiros e decimais, você pode fazer o seguinte:

 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 } 

Isso verificará corretamente seu número sem arredondá-lo, lançando-o para int (que, no caso de um número decimal, perderá a parte decimal), ou fazendo qualquer matemática. Se, no entanto, você quer tratar 1.00 como um número inteiro, então é uma história completa.

Intereting Posts