2016-03-02 11 views
8

Scusate per il brutto titolo, ma non so come chiamarlo.Perché php pensa che i grandi int siano float (ma solo qualche volta)?

echo rand(0,10e20) . "\n"; // bad 
echo rand(0,10e19) . "\n"; // bad 
echo rand(0,10e18) . "\n"; // bad 
echo rand(0,10e17) . "\n"; // OK 
echo rand(0,10e16) . "\n"; 
echo rand(0,10e15) . "\n\n"; 

var_dump(10e20); // float 
var_dump(10e15); // float 

uscita:

Attenzione: rand() si aspetta parametro 2 sia integer, float proposta in /srv/webroot-sandbox/index.php(73): eval() 'd codice sulla linea 1

Attenzione: rand() si aspetta parametro 2 per essere integer, float proposta in /srv/webroot-sandbox/index.php(73): eval() 'd code on line 2

Avvertenza: rand() si aspetta un parametro 2 da integer, float dato in /srv/webroot-sandbox/index.php(73): eval() 'd code on line 3

578009006101638016 
69608699344098568 
7596902768127620 

float(1.0E+21) 
float(1.0E+16) 

Qualcuno può spiegare cosa sta succedendo? Questo è PHP 7, ha funzionato bene in PHP 5 (beh, almeno non ho ricevuto alcun avviso).

+2

Ancora in cerca ma POTREBBE essere che superi la dimensione dell'int ... – FirstOne

+0

hmm forse prova a lanciare e fallisce di una certa magnitudine?Ma è buffo che abbia funzionato bene in PHP 5 – MightyPork

+0

secondo il manuale: http://php.net/manual/en/language.types.integer.php Una volta superato il limite, ci si sbaglia. E questo è specifico per PHP7. – durbnpoisn

risposta

11

int PHP sono firmati valori a 64 bit (a meno che non siete su un 32bit installazione), in modo da andare (circa)

-9,223,372,036,854,775,808 -> +9,223,372,036,854,775,808 

Nella notazione scientifica, -9.2e18 -> + 9.2e18

Quindi i tuoi valori "cattivi" sono semplicemente numeri interi troppo grandi per essere memorizzati come numeri interi, e PHP sta convertendo in float per cercare di conservare il maggior valore possibile.

E dal momento che hai 10e18, che è in realtà 1e19, e al di fuori della gamma max_int.

+0

Sarebbe interessante confrontare anche questo con il comportamento di PHP 5, purtroppo ho già aggiornato ... – MightyPork

+1

@MightyPork, il comportamento è lo stesso con qualsiasi sistema, interi a 32 bit max è 2^32/2-1 e il numero intero a 64 bit max è 2^64/2-1. (Unsigned sarebbe 2^32-1, 2^64-1 ma PHP non consente numeri interi senza segno se IIRC) – Devon

+1

le mie partite 5.5.9 di cui sopra. Si noti che in Windows, php5 ha trattato tutti i valori come 32 bit, indipendentemente da quale sia la piattaforma sottostante. per esempio. phpwin 64 bit utilizzava ancora 32 bit. –

6

La tua domanda può essere dipendente dalla piattaforma come la gamma intera di un:

piattaforma
  • 32 bit è la piattaforma po -2,147,483,648-2,147,483,647
  • 64 è -9,223,372,036,854,775,808 al 9,223,372,036,854,775,808

Per me, in esecuzione un sistema a 64 bit dà il seguente risultato.

var_dump(10e20 > PHP_INT_MAX); // true 
var_dump(10e19 > PHP_INT_MAX); // true 
var_dump(10e18 > PHP_INT_MAX); // true 
var_dump(10e17 > PHP_INT_MAX); // false 
var_dump(10e16 > PHP_INT_MAX); // false 
var_dump(10e15 > PHP_INT_MAX); // false 

Questa uscita è direttamente correlato con i risultati e potrebbe spiegare un violino o il vostro hosting per mostrare risultati diversi.

La ragione si comporta in modo diverso su PHP 7 viene spiegato here:

precedenza, funzioni interne sarebbero silenziosamente troncare i numeri prodotte da coazioni float-to-integer quando il galleggiante era troppo grande rappresentare come numero intero. Ora, verrà emesso E_WARNING e verrà restituito NULL .

Problemi correlati