2009-06-13 9 views
23

W PHP 5 używam intval(), gdy tylko otrzymam liczby jako dane wejściowe. W ten sposób chcę się upewnić, że nie otrzymuję żadnych ciągów ani liczb zmiennoprzecinkowych. Moje numery wejściowe powinny być w liczbach całkowitych. Ale gdy otrzymam liczby> = 2147483647, znak liczby całkowitej zostanie przekroczony.PHP: intval() odpowiednik dla liczb> = 2147483647

Co mogę zrobić, aby mieć odpowiednik intval() dla liczb we wszystkich rozmiarach?

Oto, co chcę mieć:

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

Dziękuję bardzo z góry!

Edycja: Na podstawie niektórych odpowiedzi próbowałem zakodować równoważną funkcję. Ale to nie działa dokładnie tak, jak jeszcze intval(). Jak mogę to poprawić? Co jest z tym nie tak?

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

Więc co dokładnie nie działa w nim i co się dzieje z innymi rozwiązaniami tutaj, łącznie z regex? –

Odpowiedz

20

Wypróbuj tę funkcję, to poprawnie usunie dziesiętny, jak to czyni intval i usunie wszelkie nie-numeryczne znaki.

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

Oto produkowane wyjście:

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

nadzieję, że pomoże!

+0

Dziękuję bardzo, dokładnie tego właśnie szukałem. – caw

+2

Ta funkcja jest potencjalnie szkodliwa w przypadku liczb ujemnych: while 'intval (-100) == -100',' bigintval (-100) == 0'. – Ferenjito

2

Albo użyć number_format($inputNumber, 0, '', '')

Lub jeśli chcesz tylko sprawdzić, jeśli jego cały szereg następnie użyć ctype_digit($inputNumber)

Nie stosować proponowane is_numeric, jak również pływaki są numeryczne. na przykład "+ 0123.45e6" zostanie zaakceptowana przez is_numeric

+0

float będzie nadal przepełniał to. –

+0

Przepełnienie pływaka nie ma znaczenia, więc wydaje się przydatne. Zobacz moją edycję w pytaniu. – caw

2

Oprócz number_format, można użyć sprintf:

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

Jednak oba rozwiązania cierpią pływaka przelewem, na przykład:

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

Dziękujemy! Proszę spojrzeć na moją edycję w pytaniu. Czy to odpowiednia funkcja? – caw

+1

@Artem: Nie tylko ma przepełnienie pływaka, ale także zaokrąglenia. sprintf ("%. 0f", 1.5) zwraca 2, podczas gdy intval (1.5) zwraca 1. – mercator

6

możesz również użyć wyrażeń regularnych, aby usunąć wszystko po początkowych numerycznych częściach:

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

Myślę, że wystąpił błąd z twoim wyrażeń regularnych, twój kod nie generuje niczego. – defines

+0

Przepraszam. zostało to naprawione. – SztupY

+0

Dziękujemy! :) Twoja odpowiedź była ważna, ponieważ Dustin Fineout używał Twojego wyrażeń ... – caw

0

Jeśli chcesz obsługiwać dowolne liczby precyzyjne, musisz użyć rozszerzenia gmp. Funkcja gmp_init(), na przykład, konwertuje ciąg do obiektu zasobu gmp. wadą jest to, że musisz użyć innych funkcji tego rozszerzenia do dalszego przetwarzania tego obiektu. Konwersja z powrotem na ciąg znaków odbywa się na przykład za pomocą gmp_strval().

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

Może chcesz tylko zweryfikować że ciąg reprezentuje prawidłowy numer i używać sam ciąg, jeśli nie zamierzamy wykonywać żadnych operacji na wartości. Co można zrobić za pomocą wyrażenia regularnego:

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

Inną opcją jest użycie is_numeric(). Ale ta funkcja wykonuje więcej konwersji, niż by ci się spodobało.Cytując docs tej funkcji:

... + 0123.45e6 jest prawidłową wartością numeryczną ...