2009-06-13 6 views
23

En PHP 5, j'utilise intval() chaque fois que je reçois des nombres en entrée. De cette façon, je veux m'assurer que je n'ai pas de chaînes ou de nombres flottants. Mes nombres d'entrée devraient tous être en nombres entiers. Mais quand j'obtiens des nombres> = 2147483647, la limite entière signée est franchie.PHP: intval() équivalent pour les nombres> = 2147483647

Que puis-je faire pour avoir un équivalent intval() pour les nombres dans toutes les tailles?

Voici ce que je veux avoir:

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

Merci beaucoup à l'avance! Edit: Basé sur certaines réponses, j'ai essayé de coder une fonction équivalente. Mais cela ne fonctionne pas exactement comme le fait intval(). Comment puis-je l'améliorer? Qu'est-ce qui va pas avec ça?

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

Alors qu'est-ce exactement fonctionne pas en elle et ce qui ne va pas avec d'autres solutions ici, y compris l'un regex? –

Répondre

20

Essayez cette fonction, elle supprimera correctement toute décimale comme le fait intval et supprimera tous les caractères non numériques.

<?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 />"; 
?> 

Voici la sortie produit:

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

Hope that helps!

+0

Merci beaucoup, c'est exactement ce que je cherchais. – caw

+2

Cette fonction est potentiellement dangereuse quand il s'agit de nombres négatifs: while = intval (-100) == -100', 'bigintval (-100) == 0'. – Ferenjito

2

Soit utiliser number_format($inputNumber, 0, '', '')

Ou si vous voulez seulement vérifier si son un nombre entier puis utilisez ctype_digit($inputNumber)

Ne pas utiliser le projet is_numeric, ainsi que des flotteurs sont numériques. par exemple. "+ 0123.45e6" est acceptée par is_numeric

+0

float débordera encore cela. –

+0

Le dépassement de flottement n'a pas d'importance, il semble donc utile. S'il vous plaît voir mon edit dans la question. – caw

2

En plus de number_format, vous pouvez utiliser sprintf:

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

Cependant, les deux solutions souffrent de trop-plein de flotteur, par exemple:

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

Merci! S'il vous plaît jeter un oeil à mon édition dans la question. Est-ce une bonne fonction équivalente? – caw

+1

@Artem: Non seulement il souffre d'un débordement flottant, mais il arrondit également. sprintf ("%. 0f", 1.5) renvoie 2, tandis que intval (1.5) renvoie 1. – mercator

6

vous pouvez également utiliser des expressions régulières pour enlever tout ce qui suit les parties numériques intial:

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

Je pense qu'il y a une erreur avec votre regex, votre code ne renvoie rien du tout. – defines

+0

désolé. il a été corrigé. – SztupY

+0

Merci! :) Votre réponse était importante puisque Dustin Fineout a utilisé votre expression rationnelle ... – caw

0

Si vous voulez gérer les numéros de précision arbitraire, vous aurez besoin d'utiliser l'extension gmp. La fonction gmp_init(), par exemple, convertit une chaîne en un objet de ressource gmp. l'inconvénient est que vous devez utiliser d'autres fonctions de cette extension pour continuer à traiter cet objet. La conversion en une chaîne se fait en utilisant gmp_strval(), par exemple.

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

Vous pouvez seulement vérifier que la chaîne représente un nombre valide et utiliser la chaîne elle-même, si vous ne comptez pas faire des opérations sur la valeur. Cela peut être fait en utilisant une expression régulière:

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

Une autre option consiste à utiliser is_numeric(). Mais cette fonction fait plus de conversion que vous ne le souhaiteriez.Je cite docs de cette fonction:

... + 0123.45e6 est une valeur numérique valide ...

0
<?php 
$a = 453453445435.4; 

echo $bigint = floor($a);