2009-10-31 6 views
7

Dlaczego wynik sqrt nie jest liczbą całkowitą dla "16" w PHP?Pierwiastek kwadratowy w PHP

Przykład

php > $fig = 16; 
php > $sq = sqrt($fig); //should be 4 
php > echo $sq; 
4 
php > echo is_int($sq);   // should give 1, but gives false 
php > 

czuję, że problem jest w wewnętrznej prezentacji, która ukrywa PHP podobnie jak Python. Skąd możesz wiedzieć, kiedy podana liczba jest liczbą całkowitą po zrobieniu pierwiastka kwadratowego?

Jak można rozróżnić między 4 i 4.12323 w PHP bez użycia wyrażenia regularnego?

Odpowiedz

15

Zgodnie z instrukcją PHP, float sqrt (float $arg), sqrt() zawsze zwraca wartość zmiennoprzecinkową. Użycie funkcji is_int() nie rozwiąże problemu, ponieważ sprawdza typ danych i zwraca błąd.

Aby obejść ten problem, można go przetestować za pomocą modułu zamiast: (musi być fmod() dla zmiennoprzecinkowych moduł a nie operatora% dla całkowitej modułu)

if (fmod(sqrt(16), 1) == 0) { 
    // is an integer 
} 

Jeśli używasz PHP 5.2 0,0 lub później, wierzę, że będzie również działać, ale nie zostały wykorzystane w tego typu sytuacji, aby być pewnym:

$result = sqrt(16); 
if (filter_var($result, FILTER_VALIDATE_INT)) { 
    // is an integer 
} 
+0

Twoje pierwsze polecenie nie działa dla mnie, ale ostatnie działa. –

+0

Masz rację. Ten pierwszy działa również teraz. Sprawdziłem to dwukrotnie, zanim opublikowałem edycję. – Jason

+0

Na marginesie, testowanie liczby całkowitej za pomocą (float% 1) działa w JavaScript i MySQL, po prostu nie w PHP, który wymaga fmod() zamiast%. – Jason

2

Ponieważ zawsze zwraca float:

float sqrt(float $arg) 

można oddać go do liczby całkowitej, jeśli chcesz:

intval(sqrt(16)); 

EDIT Ok następnie:

$sqrt = sqrt(16); 

if (strpos($sqrt, '.') !== false) 
{ 
    $sqrt = intval($sqrt); 
} 

else 
{ 
    $sqrt = floatval($sqrt); 
} 

var_dump($sqrt); 
+1

Problem z 'intval' polega na tym, że go zaokrągla. Muszę wiedzieć dokładnie, która jest liczbą całkowitą, która nie jest po zrobieniu pierwiastka kwadratowego. –

5

Mówi to w interfejsie API, typem zwracanym jest float.

http://us2.php.net/sqrt

float sqrt (float $arg ) 

Zwraca pierwiastek kwadratowy z arg.

3

można użyć funkcji floor dostać część całkowitą wartości i odejmij oryginalną wartość. Jeśli różnica wynosi! = 0, to NIE jest liczbą całkowitą. na przykład

if (($sq - floor($sq)) == 0){ 
    YES 
}else{ 
NO 
} 
+1

Jest to również dobra metoda. Dziękuję za wskazanie funkcji Knutha! –

0

Innym sposobem sprawdzenia liczb byłoby odlewania na ciąg i sprawdzając, czy z ctype_digit()

$result = sqrt(16); 
if (ctype_digit((string)$result)) { 
    // is an integer 
} 

Oczywiście jest to nieco dziwne droga w porównaniu z wykorzystaniem modulo kiedy robisz kalkulacje tak. Jest to jednak przydatne przy testowaniu wartości przesłanych z formularza, ponieważ będą one na początku ciągami. Ograniczeniem jest to, że zwróci wartość false dla ujemnej liczby całkowitej.