Комментарии 11
Базовые вещи компьютерной инженерии! Независимо от того, на чем пишут — будь то Ассемблер, старый добрый Си, плюсы, джава, дотнет, или скриптовые языки. Все это должно в голове программиста быть прожжено перемычками на всю жизнь. Проверьте себя, прочитав этот пост — так ли это, или перемычки подзаросли, и пора программатором освежить? ;)
ну для вас — базовые, а для баранов-разработчиков (например, для меня, джуна с годом опыта на Yii2) содержимое статьи как откровение. Так что к вариантам «перемычки на месте» и «перемычки подзаросли» нужно добавить ещё один пункт — «пишу на пхп без перемычек»))
Статья интересная, но вот пара замечаний:
- Не указано, что PHP смещает биты вправо, оставляя шлейф из левого бита. Арифметический сдвиг, а так хотелось бы иметь ещё и логический, да?
- Отрицательные числа хранятся не так как описано в статье: не достаточно просто выставить левый бит в единицу. У нас они хранятся в обратном представлении. Для 64бит значение -1 будет представлено в памяти в виде 64 единиц.
- Вы забыли про замечательные функции
decbin()
,dechex()
,decoct()
(и обратные). Распаковывать и вывести первые 2 байта можно было бы кратче:dechex(unpack('S', $soi)[1])
Огромное спасибо за замечание, что оператор >> оставляет шлейф слева! Вот уж воистину неочевидный подводный камень. 8-\
эм, что значит оставляет шлейф из левого бита? Можно пример, пожалуйста?
> printf("%064b \n %064b", PHP_INT_MAX, PHP_INT_MAX >> 2);
0111111111111111111111111111111111111111111111111111111111111111
0001111111111111111111111111111111111111111111111111111111111111
> printf("%064b \n %064b", PHP_INT_MIN, PHP_INT_MIN >> 2);
1000000000000000000000000000000000000000000000000000000000000000
1110000000000000000000000000000000000000000000000000000000000000
> var_dump(1 === ( (1 << 63) >> 63 ));
bool(false)
Спасибо!
Т.е получается "шлейф" присутствует только для отрицательных чисел?
при сдвиге вправо уходящий бит исчезает, не влияя на оставшиеся биты, а на месте появившегося бита устанавливается бит, соответствующий знаку
Формат хранения чисел в PHP подразумевает, что если левый бит === 1, то число отрицательное. "Шлейф" (надо было мне такое ляпнуть...) из единиц будет только для отрицательных. Из нулей — для положительных.
Здорово, что такие, вроде понятные вещи проясняют для большинства, кому-то как раз это может пригодится. Спасибо за статью
поэкспериментировать с собственной реализацией формата сериализации MessagePackЕсли интересно, можно также взглянуть на готовую реализацию.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Двоичные и побитовые операции в PHP