2012-06-14 16 views
12

Szukam funkcji, która sprawdza, czy liczba całkowita jest liczbą całkowitą. Do tej pory mam to:Ogólna liczba lub liczba dziesiętna

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

Ale to zawsze zwraca „trójkątny”, nawet gdy $ answer3 jest dziesiętny.

Jak mogę przetestować liczbę całkowitą, aby zobaczyć, czy ma ona dziesiętny?

+0

Po prostu uwaga, PHP jest bardzo elastyczny w odniesieniu do łańcuchów i liczb (i ciągów, które wyglądają jak cyfry). Wielu uważa to za zbyt elastyczne.Jeśli ma to jakiekolwiek znaczenie, nie mogę wystarczająco podkreślić konieczności dokładnego przetestowania twojego skryptu. – jedwards

+1

Po prostu, aby było jasne: liczba całkowita jest zawsze liczbą całkowitą. Prawdopodobnie chodzi o sprawdzenie, czy "ciąg" lub "unoszący się" ma "część ułamkową", czy też nie. – Daan

Odpowiedz

14

is_numeric zwróci true dla pływaków też, biorąc pod uwagę pływaki są numeryczne

Znajduje czy podana zmienna jest numeryczna. Ciągi liczbowe składają się z opcjonalnego znaku, dowolnej liczby cyfr, opcjonalnej części dziesiętnej i opcjonalnej części wykładniczej. Tak więc + 0123.45e6 jest prawidłową wartością numeryczną. Zapis szesnastkowy (0xFF) jest dozwolony, ale tylko bez znaku, część dziesiętna i wykładnicza.

Możesz wypróbować is_float(), ale jeśli wejście jest ciągiem, to nie zadziała.

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

Więc jeśli masz do czynienia z czymś, co jest reprezentacją ciąg wielu to po prostu spojrzeć na .

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

Możesz dodać is_numeric jeśli trzeba

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

Jeśli $ answer3 nie jest ciągiem znaków, można spróbować użyć:

is_float() 

aby zobaczyć, czy jest wartością zmiennoprzecinkową, a nie tylko wartość liczbową.

+0

-1, '10.0' kończy się niepowodzeniem, gdy nadal * jest * trójkątne. –

+0

Jeśli dane wejściowe są liczbami zmiennoprzecinkowymi, nie zawiedzie ... tylko wtedy, gdy przekazujesz ciąg do is_float. W powyższym tekście PO nie jest jasne, jaka jest $ answer3. Downvote jest nieco trudny, ale zredagowałem go, aby wyjaśnić. – peacemaker

+0

Nie traktuj tego jako osobistego, po prostu nie sądzę, że wystarczy tutaj sprawdzanie pływania. Liczba trójkątna to dowolna liczba postaci '(n * (n + 1))/2'. Jeśli podam ci wartość zmiennoprzecinkową, taką jak '10.000' lub' 15.000', to ani 'is_float()' ani 'is_int()' nie poprawią poprawnie potrzeb PO. –

12

Należy 10.0 należy uznać za liczbę całkowitą lub float? W przypadku całkowitej, szukasz fmod():

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

Inaczej is_int() wystarczy.


EDIT: Innym sposobem sprawdzenia nieznacznej części dziesiętnych byłoby:

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

Drugi parametr dla 'round()' nie jest potrzebny: 'if (round ($ number) == $ number)' będzie działać dobrze – yolenoyer

4
  • is_int jeśli jest również potrzebna, aby być typu całkowitego,
  • ctype_digit jeśli testujesz ciągi znaków,
  • filter_var($input,FILTER_VALIDATE_INT) dla wszystkich.

i przeszukiwać instrukcja

0

spróbować to

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

lub w przypadku trzeba wyniki pozytywne:

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

Próbowałem kilka odpowiedzi (z innych stron, jak również), ale najlepsze w moim przypadku było to:

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

Może to jest najbardziej eleganckie rozwiązanie:

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

funkcja da fałszywe alarmy dla następujących wartości: 'array()', ''0x12foo'','' 0xfe''' '' 8e2bottles''. – Daan

1

Funkcja ta ma zadanie do 99% czasu dla każdego wejścia rzucasz w:

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

Uwaga: Ścisłe porównanie nie jest naprawdę konieczne tutaj, ponieważ podczas rzucania do (float) oba są zawsze tego samego typu.

Zainspirowany this article about PHP insanity przy porównywaniu wartości, wpadłem mały test dla następujących wejść:

jak oczekiwano

Te wartości nie mieć część ułamkową:

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 

Te wartości do mają ułamkową część:

'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 

Nie oczekuje:

'8e2bottles' // FALSE 

Jak wyjaśniono w artykule, wartość ta będzie robić szalone rzeczy, a także nie w mojej funkcji. Dzieje się tak dlatego, że rzutowanie na int i float daje całkowitą inną wartość. Więc bądź przygotowany!

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

Sprawdziłem wszystkie odpowiedzi i było kilka prób sprawdzenia części pływającej. To jest właściwy sposób, z wyjątkiem tego, że nie jest dobrym pomysłem porównywanie liczb zmiennoprzecinkowych z użyciem znaku równości. Najlepszym rozwiązaniem byłoby:

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; 

wynik:

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

Jestem całkowicie nowy w tym, ale ja zrozumieć to, że najlepszym sposobem, aby sprawdzić, czy liczba jest liczbą całkowitą lub pływaka w PHP jest przez proste sprawdzenie:

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

Jeśli rzeczywiście jest liczbą całkowitą, będzie równa.