Ответ на этот вопрос «на удивление» прост:
Во-первых, как многие из вас знают, 32-разрядное целое число колеблется от -2 147 483 648 до 2 147 483 647 . Итак, что произойдет, если PHP получит результат, который БОЛЬШЕ, чем этот?
Обычно можно ожидать немедленного «переполнения», в результате которого 2 147 483 647 + 1 превратится в -2 147 483 648 . Тем не менее, это не так. Если PHP встречает большее число, он возвращает FLOAT вместо INT.
Если PHP встречает число за пределами целочисленного типа, оно будет интерпретироваться как число с плавающей точкой. Кроме того, операция, результатом которой является число, выходящее за пределы целочисленного типа, вместо этого возвращает число с плавающей запятой.
http://php.net/manual/en/language.types.integer.php
Это говорит о том, что знание того, что реализация PHP FLOAT соответствует формату двойной точности IEEE 754, означает, что PHP может работать с числами до 52 бит без потери точности. (В 32-битной системе)
Таким образом, в точке, где ваша сумма достигает 9 007 199 254 740 992 (что составляет 2 ^ 53 ), значение Float, возвращаемое PHP Maths, больше не будет достаточно точным.
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
В этом примере показана точка, в которой PHP теряет точность. Во-первых, последний значащий бит будет сброшен, в результате чего первые два выражения приведут к равному числу, а это не так.
С этого момента вся математика будет работать неправильно при работе с типами данных по умолчанию.
• Это та же проблема для другого интерпретируемого языка, такого как Python или Perl?
Я так не думаю. Я думаю, что это проблема языков, которые не имеют безопасности типов. Хотя целочисленное переполнение, как упомянуто выше, будет происходить на каждом языке, который использует фиксированные типы данных, языки без безопасности типов могут попытаться перехватить это с другими типами данных. Однако, как только они достигнут своей «естественной» (заданной системой) границы - они могут вернуть что угодно, но правильный результат.
Однако каждый язык может иметь разные потоки для такого сценария.