Итак, я решил проблему и многое узнал о PHP (по крайней мере, в том, как он обрабатывает переполнение целых чисел).
1) Это полностью зависело от того, на какой платформе установлена машина, какая версия PHP, работает ли на ней Suhosin Hardened PHP и сколько битов было скомпилировано (32 или 64). 6 машин вели себя так, как я ожидал (что на самом деле было неправильно, по крайней мере неправильно в соответствии с их документацией), а 3 машины вели себя так, как я до сих пор не могу объяснить, и 3 машины вели себя в соответствии с тем, что говорит команда intval в документация.
2) Intval должен возвращать PHP_MAX_INT, когда int> PHP_MAX_INT (не int & 0xffffffff), но это происходит только в некоторых версиях PHP4 и PHP5. Различные версии PHP возвращают разные значения, когда int> PHP_MAX_INT.
3) Следующий код может вернуть 3 разных результата (см. 1):
<?php
echo "Php max int: ".PHP_INT_MAX."\n";
echo "The Val: ".(-1580033017 + -2072974554)."\n";
echo "Intval of the val: ".intval(-3653007571)."\n";
echo "And 0xffffffff of the val: ".(-3653007571 & 0xffffffff)."\n";
?>
Может возвращаться (что кажется правильным для Intval, но неверным для & 0xffffff)
Php max int: 2147483647
The Val: -3653007571
Intval of the val: -2147483648
And of the val: -2147483648
И он может возвращаться (что противоречит документации PHP для intval):
Php max int: 2147483647
The Val: -3653007571
Intval of the val: -641959725
And of the val: -641959725
И на 64-битных машинах он возвращает (что правильно):
Php max int: 2147483647
The Val: -3653007571
Intval of the val: -3653007571
And of the val: -641959725
Решение
Так или иначе, мне нужно было решение, которое работало бы на всех этих платформах и не зависело от особенностей конкретной версии PHP, скомпилированной с конкретным Max int. Таким образом, я использую следующую кросс-PHP функцию тридцатьTwoBitIntval:
function thirtyTwoBitIntval($value)
{
if ($value < -2147483648)
{
return -(-($value) & 0xffffffff);
}
elseif ($value > 2147483647)
{
return ($value & 0xffffffff);
}
return $value;
}
Комментарий
Я думаю, что разработчики PHP должны были сказать, что Int - это 32-битное Int, независимо от того, работает ли оно на 32-, 64- или 128-битном компьютере (например, в DotNet CLR), и не преобразовывало случайным образом с повышением частоты. это число с плавающей запятой в зависимости от количества битов, под которым PHP компилятор.