La risposta a questa è "sorprendentemente" semplice:
Innanzitutto, come molti di voi sapranno, un numero intero a 32 bit varia da -2,147,483,648 a 2,147,483,647 . Quindi, cosa succede se PHP ottiene un risultato, che è più grande di questo?
Di solito, ci si aspetterebbe un "Overflow" immediato, facendo sì che 2.147.483.647 + 1 si trasformino in -2.147.483.648 . Tuttavia, NON è così. Se PHP incontra un numero maggiore, restituisce FLOAT anziché INT.
Se PHP incontra un numero oltre i limiti del tipo intero, verrà invece interpretato come float. Inoltre, un'operazione che risulta in un numero oltre i limiti del tipo intero restituirà invece un valore float.
http://php.net/manual/en/language.types.integer.php
Detto questo, e sapendo che l'implementazione di PHP FLOAT sta seguendo il formato IEEE 754 a doppia precisione, significa che PHP è in grado di gestire numeri fino a 52 bit, senza perdere precisione. (Su un sistema a 32 bit)
Quindi, nel punto in cui la somma raggiunge 9.007.199.254.740.992 (ovvero 2 ^ 53 ), il valore Float restituito dalla matematica PHP non sarà più sufficientemente preciso.
E:\PHP>php -r "$x=bindec(\"100000000000000000000000000000000000000000000000000000\"); echo number_format($x,0);"
9.007.199.254.740.992
E:\PHP>php -r "$x=bindec(\"100000000000000000000000000000000000000000000000000001\"); echo number_format($x,0);"
9.007.199.254.740.992
E:\PHP>php -r "$x=bindec(\"100000000000000000000000000000000000000000000000000010\"); echo number_format($x,0);"
9.007.199.254.740.994
Questo esempio mostra il punto in cui PHP sta perdendo precisione. Innanzitutto, l'ultimo bit significativo verrà eliminato, facendo sì che le prime 2 espressioni producano un numero uguale, cosa che non sono.
Da ora in poi, l'intera matematica andrà male, quando si lavora con tipi di dati predefiniti.
• È lo stesso problema per altri linguaggi interpretati come Python o Perl?
Io non la penso così. Penso che questo sia un problema di lingue che non hanno sicurezza del tipo. Mentre un overflow di numeri interi come menzionato sopra si verificherà in ogni lingua che utilizza tipi di dati fissi, le lingue senza sicurezza del tipo potrebbero tentare di intercettarlo con altri tipi di dati. Tuttavia, una volta colpito il loro confine "naturale" (dato dal sistema), potrebbero restituire qualsiasi cosa, ma il risultato giusto.
Tuttavia, ogni lingua può avere thread diversi per tale scenario.