2012-06-14 27 views
12

Estoy buscando una función que compruebe si un número entero es entero. Hasta ahora lo he entendido:Número entero o número decimal

if (is_numeric($answer3)) { 
    echo "Is triangular\n"; 
} else { 
    echo "Is not triangular\n"; 
} 

Pero esto siempre devuelve "es triangular", incluso cuando answer3 $ es un decimal.

¿Cómo puedo probar un número entero para ver si tiene un decimal?

+0

Solo una nota, PHP es extremadamente flexible con cadenas y números (y cadenas que parecen números). Muchos lo consideran ** demasiado ** flexible.Si esto tiene algún tipo de importancia, no puedo dejar de insistir en la necesidad de probar a fondo tu guión. – jedwards

+1

Para que quede claro: un número entero es siempre un número entero. Lo que probablemente quiera decir es que compruebe si una "cadena" o "flotante" tiene una "parte fraccionaria" o no. – Daan

Respuesta

14

is_numeric volverá cierto para los flotadores también, teniendo en cuenta los flotadores son numéricos

Encuentra si la la variable dada es numérica. Las cadenas numéricas consisten en de signo opcional, cualquier número de dígitos, parte decimal opcional y parte exponencial opcional. Por lo tanto + 0123.45e6 es un valor numérico válido. Se permite la notación hexadecimal (0xFF) pero solo sin signo, parte decimal y exponencial.

Puede intentar is_float(), pero si la entrada es una cadena, no funcionará.

var_dump(is_float('23.5')); // return false 

lo tanto, si se trata de algo que es una representación de cadena de un número a continuación, sólo tiene que buscar un .

if (strpos($answer3, '.') === false) 

Puede añadir is_numeric si necesita

// Make sure its numeric and has no decimal point 
if (is_numeric($answer3) && strpos($answer3, '.') === false) 
1

Si $ answer3 no es una cadena, puede probar usando:

is_float() 

para ver si es un valor de coma flotante, en lugar de un valor numérico.

+0

-1, '10.0' falla mientras todavía * es * triangular. –

+0

Si la entrada es un número de coma flotante, no fallará ... solo si pasa una cadena a is_float. En el texto de OP arriba no está claro qué es $ answer3. Downvote es un poco duro, pero he editado para aclarar. – peacemaker

+0

No lo tome como algo personal, simplemente no creo que la verificación de flotación sea suficiente aquí. Un número triangular es cualquier número de la forma '(n * (n + 1))/2'. Si le doy un valor flotante como '10.000' o' 15,000', ni 'is_float()' ni 'is_int()' se dirigirán correctamente a las necesidades de OP. –

12

¿Debería considerarse 10.0 un número entero o un flotador? Si número entero, que busca fmod():

if (fmod($number, 1) == 0) // $number DOES NOT have a significant decimal part 
{ 
    // is whole number 
} 

De lo contrario, is_int() basta.


EDIT: Otra forma de comprobar la parte decimal insignificante sería:

if (round($number, 0) == $number) 
{ 
    // is whole number 
} 
+0

El segundo parámetro para 'round()' no es necesario: 'if (round ($ number) == $ number)' funcionará bien – yolenoyer

4
  • is_int si también necesita que sea del tipo entero,
  • ctype_digit si está probando cadenas,
  • filter_var($input,FILTER_VALIDATE_INT) para todos.

y buscar en el manual de

0

probar este

  if(!is_numeric($nabtron) || $nabtron != floor($nabtron) || $nabtron < 0){ 
       die('it's not numeric or is a float or a negative number'); 
      } 

o en caso de que tenga resultados positivos:

  if(is_numeric($nabtron) && $nabtron == floor($nabtron) && $nabtron < 0){ 
       echo "it's numeric and not a float and is zero or positive number"; 
      } 
2

que he probado varias respuestas (desde otras páginas, así), pero lo que funcionó mejor en mi caso es este:

$number = floatval($number); 
if ($number == round($number)) { 
    // Number does not have decimals (or .00000) 
}else{ 
    // Number does have decimals 
} 
2

Tal vez esta es la solución más elegante:

if ($answer3 != (int) ($answer3)) { 
+0

This función dará falsos positivos para los siguientes valores: 'array()', ''0x12foo'','' 0xfe'', ''8e2bottles''. – Daan

1

Esta función hace el trabajo para el 99% de las veces para cada entrada se lanza en:

function($number) { 
    (float)(int)$number == (float)$number; 
} 

Nota: comparación estricta no es realmente necesario aquí, porque cuando se lanza a (flotante) ambos son siempre del mismo tipo.

Inspirado por this article about PHP insanity al comparar los valores, me encontré con una pequeña prueba para las siguientes entradas:

Como era de esperar

Estos valores hacer no tienen una parte fraccionaria:

1.0 // TRUE 
'1.0' // TRUE 
true // TRUE 
false // TRUE 
'true' // TRUE 
'false' // TRUE 
10e3 // TRUE 
// TRUE 
null // TRUE 
'test' // TRUE 
1 // TRUE 
0 // TRUE 
1.2e3 // TRUE 
0xfe // TRUE 
0b0 // TRUE 
0b1 // TRUE 
b0 // TRUE 
b1 // TRUE 
-0xfe // TRUE 
'' // TRUE 
'8bottles' // TRUE 
'8.0bottles' // TRUE 
'0foo' // TRUE 
array() // TRUE 
'0x12foo' // TRUE 
'0123' // TRUE 
'0xfe' // TRUE 
new Object // TRUE 

Estos valores do tienen una parte fraccionaria:

'1.1' // FALSE 
1.1 // FALSE 
10e-3 // FALSE 
.9 // FALSE 
0.9 // FALSE 
.1 // FALSE 
0.1 // FALSE 
0123.2 // FALSE 
7E-10 // FALSE 
1.2e-3 // FALSE 

no se esperaba:

'8e2bottles' // FALSE 

Como se explica en el artículo, este valor va a hacer cosas locas y también se producirá un error en mi función. Es porque el lanzamiento a int y float da un valor total diferente. ¡Asi que preparate!

(int)'8e2bottles' // 8 
(float)'8e2bottles' // 800.0 
0

Revisé todas las respuestas y hubo algunas que trataron de verificar la parte flotante. Esa es la forma correcta de hacerlo, excepto que no es una buena idea comparar los números de coma flotante con el mismo signo. La mejor solución sería:

function isIntegerNumber($number){ 
    $floor = floor($number); 
    $fract = abs($number - $floor); 
    return is_numeric($number) && $fract < 1e-16; 
} 

echo var_export(isIntegerNumber("10X"), true).PHP_EOL; 
echo var_export(isIntegerNumber("3.0001"), true).PHP_EOL; 
echo var_export(isIntegerNumber("-23.0001"), true).PHP_EOL; 
echo var_export(isIntegerNumber(-10.01), true).PHP_EOL; 
echo var_export(isIntegerNumber("3.00"), true).PHP_EOL; 
echo var_export(isIntegerNumber("-23.00"), true).PHP_EOL; 
echo var_export(isIntegerNumber(-10.00), true).PHP_EOL; 
echo var_export(isIntegerNumber(5), true).PHP_EOL; 
echo var_export(isIntegerNumber(-5), true).PHP_EOL; 
$tricky = (0.1+0.7)*10.0; 
echo "now something a bit tricky: ".PHP_EOL; 
echo "(0.1+0.7)*10.0 = ".var_export($tricky, true) .' (type: "'.gettype($tricky).'")'.PHP_EOL; 
echo 'is it int: '.var_export(isIntegerNumber($tricky), true).PHP_EOL; 
echo 'is it 8: '.var_export($tricky == 8, true).PHP_EOL; 

resultado:

false 
false 
false 
false 
true 
true 
true 
true 
true 
now something a bit tricky: 
(0.1+0.7)*10.0 = 7.9999999999999991 (type: "double") 
is it int: false 
is it 8: false 
0

Soy un totalmente nuevo en esto, pero lo averigüe que mejor manera de comprobar si un número es flotante o entero en PHP se con simple comprobación:

if ($number == round($number)) { } else { } 

Si es realmente un número entero, será igual.