2009-06-13 18 views
23

En PHP 5, uso intval() cada vez que obtengo números como entrada. De esta forma, quiero asegurarme de no obtener cadenas o números flotantes. Mis números de entrada deberían ser números enteros. Pero cuando obtengo números> = 2147483647, se cruza el límite entero con signo.PHP: intval() equivalente para números> = 2147483647

¿Qué puedo hacer para tener un intval() equivalente para números en todos los tamaños?

Esto es lo que yo quiero tener:

<?php 
$inputNumber = 3147483647.37; 
$intNumber = intvalEquivalent($inputNumber); 
echo $intNumber; // output: 3147483647 
?> 

muchas gracias de antemano!

Editar: Basado en algunas respuestas, he intentado codificar una función equivalente. Pero no funciona exactamente como todavía lo hace intval(). ¿Cómo puedo mejorarlo? ¿Qué tiene de malo?

function intval2($text) { 
    $text = trim($text); 
    $result = ctype_digit($text); 
    if ($result == TRUE) { 
     return $text; 
    } 
    else { 
     $newText = sprintf('%.0f', $text); 
     $result = ctype_digit($newText); 
     if ($result == TRUE) { 
      return $newText; 
     } 
     else { 
      return 0; 
     } 
    } 
} 
+0

Entonces, ¿qué no funciona en él y lo que está mal con otras soluciones aquí, incluido el regex one? –

Respuesta

20

Pruebe esta función, eliminará correctamente cualquier decimal como lo hace intval y eliminará cualquier carácter no numérico.

<?php 
function bigintval($value) { 
    $value = trim($value); 
    if (ctype_digit($value)) { 
    return $value; 
    } 
    $value = preg_replace("/[^0-9](.*)$/", '', $value); 
    if (ctype_digit($value)) { 
    return $value; 
    } 
    return 0; 
} 

// SOME TESTING 
echo '"3147483647.37" : '.bigintval("3147483647.37")."<br />"; 
echo '"3498773982793749879873429874.30872974" : '.bigintval("3498773982793749879873429874.30872974")."<br />"; 
echo '"hi mom!" : '.bigintval("hi mom!")."<br />"; 
echo '"+0123.45e6" : '.bigintval("+0123.45e6")."<br />"; 
?> 

Aquí es la salida producida:

"3147483647.37" : 3147483647 
"3498773982793749879873429874.30872974" : 3498773982793749879873429874 
"hi mom!" : 0 
"+0123.45e6" : 0 

Espero que ayude!

+0

Muchas gracias, eso es exactamente lo que estaba buscando. – caw

+2

Esta función es potencialmente dañina cuando se trata de números negativos: while 'intval (-100) == -100',' bigintval (-100) == 0'. – Ferenjito

2

O bien utilizar number_format($inputNumber, 0, '', '')

O si sólo desea comprobar si es un número entero a continuación, utilizar ctype_digit($inputNumber)

No utilice la propuesta is_numeric, como también los flotadores son numéricos. p.ej. "+ 0123.45e6" es aceptado por is_numeric

+0

float aún desbordará esto. –

+0

El desbordamiento de flotador no importa, por lo que parece ser útil. Por favor, mira mi edición en la pregunta. – caw

2

Además de Number_format, puede utilizar sprintf:

sprintf("%.0f", 3147483647.37) // 3147483647 

Sin embargo, ambas soluciones sufren de desbordamiento de flotación, por ejemplo:

sprintf("%.0f", 314734534534533454346483647.37) // 314734534534533440685998080 
+0

¡Gracias! Por favor, eche un vistazo a mi edición en la pregunta. ¿Es esta una buena función equivalente? – caw

+1

@Artem: no solo sufre desbordamiento de flotador, sino que también redondea. sprintf ("%. 0f", 1.5) devuelve 2, mientras que intval (1.5) devuelve 1. – mercator

6

también puede usar expresiones regulares para eliminar todo después de las partes numéricas iniciales:

<?php 
$inputNumber = "3147483647.37"; 
$intNumber = preg_replace('/^([0-9]*).*$/', "\\1", $inputNumber); 
echo $intNumber; // output: 3147483647 
?> 
+0

Creo que hay un error con tu expresión regular, tu código no arroja nada en absoluto. – defines

+0

lo siento. ha sido arreglado – SztupY

+0

¡Gracias! :) Tu respuesta fue importante ya que Dustin Fineout usó tu expresión regular ... – caw

0

Si desea manejar números de precisión arbitraria, necesitará usar la extensión gmp. La función gmp_init(), por ejemplo, convierte una cadena en un objeto de recurso gmp. el inconveniente es que debe usar otras funciones de esa extensión para procesar aún más ese objeto. La conversión de nuevo a una cadena se hace usando gmp_strval(), por ejemplo.

$gmpObject = gmp_init($string, 10); 
if ($gmpObject === FALSE) { 
    # The string was not a valid number, 
    # handle this case here 
} 
echo gmp_strval($gmpObject); 

Es posible que desee solamente verificar que la cadena está representando un número válido y utilizar la propia cadena, si no tiene intención de hacer cualquier operación sobre el valor. Eso se puede hacer usando una expresión regular:

$containsInt = preg_match('/^\d+$/', $string); 
# Or for floating point numbers: 
$containsFloat = preg_match('/^\d+(.\d+)?$/', $string); 
echo $string; 

Otra opción es utilizar is_numeric(). Pero esa función genera más conversiones de las que te gustaría.Citando documentos de esa función:

... + 0123.45e6 es un valor numérico válido ...

0
<?php 
$a = 453453445435.4; 

echo $bigint = floor($a); 
Cuestiones relacionadas