2012-06-14 23 views
12

Sto cercando una funzione che verifica se un intero è un numero intero. Finora ho questo:Numero intero o numero decimale

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

Ma questo restituisce sempre "è triangolare", anche quando $ answer3 è un decimale.

Come posso verificare un numero intero per vedere se ha un decimale?

+0

Solo una nota, PHP è estremamente flessibile con stringhe e numeri (e stringhe che sembrano numeri). Molti lo considerano ** troppo ** flessibile.Se questo è di qualsiasi importanza, non posso sottolineare abbastanza la necessità di testare accuratamente il tuo script. – jedwards

+1

Giusto per essere chiari: un numero intero è sempre un numero intero. Quello che probabilmente intendi è verificare se una "stringa" o "float" ha una "parte frazionaria" o meno. – Daan

risposta

14

is_numeric restituirà true per carri troppo, carri in considerazione sono numerici

Finds se il la variabile data è numerica. Le stringhe numeriche consistono in di segno opzionale, qualsiasi numero di cifre, parte decimale facoltativa e parte esponenziale opzionale . Quindi + 0123.45e6 è un valore numerico valido. La notazione esadecimale (0xFF) è consentita anche ma solo senza segno, parte decimale ed esponenziale.

Puoi provare is_float(), ma se l'input è una stringa, non funzionerà.

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

Quindi, se avete a che fare con qualcosa che è una rappresentazione stringa di un numero, allora basta guardare per un .

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

È possibile aggiungere is_numeric se avete bisogno di

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

Se $ answer3 non è una stringa, si può provare a utilizzare:

is_float() 

per vedere se è un valore in virgola mobile, piuttosto che solo un valore numerico.

+0

-1, '10.0' non riesce mentre è ancora * è * triangolare. –

+0

Se l'input è un numero in virgola mobile, non fallirà ... solo se si passa una stringa a is_float. Nel testo dell'OP sopra non è chiaro cosa sia $ answer3. Il downvote è un po 'duro ma ho modificato per chiarire. – peacemaker

+0

Non prenderlo sul personale, non penso che il controllo del float sia sufficiente qui. Un numero triangolare è un qualsiasi numero della forma '(n * (n + 1))/2'. Se ti do un valore float come '10.000' o' 15.000', né 'is_float()' o 'is_int()' risponderanno correttamente alle necessità dell'OP. –

12

Se 10.0 deve essere considerato come un numero intero o un valore? Se intero, siete alla ricerca di fmod():

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

In caso contrario, is_int() sufficiente rilevare.


EDIT: Un altro modo per verificare la presenza di una parte decimale insignificante sarebbe:

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

Il 2 ° parametro per 'round()' non è necessario: 'if (round (numero $) == numero $)' funzionerà bene – yolenoyer

4
  • is_int se è necessario che sia del tipo intero,
  • ctype_digit se si testano le stringhe,
  • filter_var($input,FILTER_VALIDATE_INT) per tutti.

e cercare il manuale di

0

provare questo

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

o nel caso in cui avete bisogno di risultati positivi:

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

che ho provato più risposte (da altre pagine come pure), ma ciò che ha funzionato meglio nel mio caso è questo:

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

Forse questa è soluzione più elegante:

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

Questo la funzione darà falsi positivi per i seguenti valori: 'array()', ''0x12foo'','' 0xfe'', ''8e2bottles''. – Daan

1

Questa funzione fa il lavoro per il 99% del tempo per ogni ingresso si gettano in:

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

Nota: Confronto Strict non è davvero necessario qui, perché quando si esegue il casting su (float) entrambi sono sempre dello stesso tipo.

Ispirato this article about PHP insanity quando si confrontano valori, ho fatto un piccolo test per i seguenti ingressi:

Come previsto

Questi valori non hanno una parte frazionaria:

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 

Questi valori do hanno una parte frazionaria:

'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 

non ci si aspetta:

'8e2bottles' // FALSE 

Come spiegato in questo articolo, questo valore farà cose folli e fallirà anche nella mia funzione. È perché il casting su int e float fornisce un valore totale diverso. Quindi preparati!

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

Ho controllato tutte le risposte e c'erano pochi tentativi di verificare la parte mobile. Questo è il modo corretto di fare, tranne che non è una buona idea confrontare i numeri in virgola mobile usando il segno di uguale. La migliore soluzione sarebbe:

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; 

risultato:

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

Sono completamente nuovo in questa, ma io capirlo che modo migliore per verificare se un numero è float o intero in PHP è con un semplice controllo:

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

Se è veramente un numero intero sarà uguale.