бинарный — почему не целые числа «underflow» в PHP?

Если я сделаю это в PHP:

echo (int)9223372036854775808;

Выходное значение равно -9223372036854775808, что делает его идеальным, поскольку с 9223372036854775807 в двоичном виде:

0111 ... 1

то есть 0, а затем 63. И, очевидно, 1 в двоичном виде это всего лишь 1, поэтому, когда я добавляю их, я получаю 1000 … 0 (1 с 63 0s после него), что составляет -9223372036854775808 в 2-й записи дополнения.

Поэтому я ожидаю, что если я сделаю что-то вроде добавления -1 к -9223372036854775808, я получу обратно 9223372036854775807. Аналогия в 4-битном двоичном коде будет выглядеть так:

1000   (-8)
1111   (-1)
----
0111   (7)

Я понимаю, что не могу просто присвоить -9223372036854775809 переменной, потому что ее нет в 64-битных целых числах со знаком, но почему это не работает:

$smallest_int = (int)-9223372036854775808;

echo (int)($smallest_int-1); //similar to 1000+1111 in 4 bit

Когда я запускаю это, выход все еще -9223372036854775808. Почему это происходит? Это как-то связано со слабой типизацией PHP? Это происходит на других языках (я знаю, что это точно не происходит в C)?

2

Решение

Это правда, что 9223372036854775808 становится -9223372036854775808, но это не так просто, как просто «обтекание целых чисел». Вот еще несколько сопоставлений (найденных экспериментально):

  • 9223372036854775809 → неподвижно -9223372036854775808 (не -9223372036854775807)
  • 9223372036854775810 → неподвижно -9223372036854775808 (не -9223372036854775806)

Так что вы можете подумать, что цифры за пределами int диапазон все отображается на -9223372036854775808 — но подождите! :

  • 9323372036854775810 → -9123372036854775808
  • 92233720368547758080 → 0

Все это кажется мне совершенно произвольным. Я думаю, что происходит то, что значения длиной более 18 цифр (и, следовательно, легко распознаваемые как находящиеся вне целочисленного диапазона) по существу отбрасываются и заменяются нулями, тогда как значения длиной 18 цифр анализируются только в том случае, если они находятся в диапазоне, но используя логику, которая не предназначена и не предназначена для согласования значений, выходящих за пределы допустимого диапазона.

0

Другие решения

Я предполагаю, что поскольку число не набрано, PHP фактически конвертирует ваше число в плавающее, а затем в математических вычислениях теряется -1.

-1

По вопросам рекламы [email protected]