Побитовый сдвиг влево, проблемка

178
22 июля 2019, 18:00

Переписываю некий код с яваскрипта на пхп, должен работать идентично.

Eже разобрался с побитовым ИЛИ, яваскрипт сравнивает числа в 32-битном представлении. Теперь проблемка с побитовым сдвигом влево.

js 30 << 30 возвращает -2147483648
php 30 << 30 возвращает 32212254720

Хорошо, первые 32 бита, 32212254720 % (2 ** 32), получим 2147483648, почти похоже на результат js.

Пытаюсь воссоздать логику js, число 30 в двоичном представлении

11110
00000000000000000000000000011110

Сдвигаю влево на 30 бит, получаю

00000000000000000000000000011110000000000000000000000000000000

Оставляю 32 бита

10000000000000000000000000000000

Конвертирую в десятичное

2147483648

Но откуда в js берется знак минус?

PS

Всем спасибо за помощь, написал 3 функции | << >>>, а потом нашел готовую библиотеку https://github.com/simaguo/javascript-bitwise-operators

Answer 1

Побитовые операторы в JavaScript работают с 32-битными целыми числами в их двоичном представлении.

Число 30 в двоичной форме это 0b00000000000000000000000000011110 (0b - это просто префикс, говорящий о том, что данное за ним число записано в двоичной форме. Так вот, в тридцати двух битном представлении крайняя левая цифра 0 (сразу после 0b и тридцать вторая если считать справа!) - что соответствует знаку + числа идущего за префиксом).

Сдвигаем это число на 30 позиций влево 30 << 30 получаем в десятичном виде -2147483648, а двоичном (32-х битном) 0b10000000000000000000000000000000, где старшая цифра (после префикса 0b) единица, что соответствует знаку минус.

Answer 2

Из курса дискретной математики, помню:

Для записи чисел в памяти компьютера используется различная система двоичных кодов... Существует 3 вида:

1)Прямой 2)Обратный 3)Дополнительный (Коды)

Ваш компьютер использует для записи чисел - дополнительный код. Это не обычный двоичный код, в нем если первый знак является 1, то это отрицателеное число(то есть числа начинающиеся со знака 1, отрицательные числа)

Кстати Вы встретились с очень полезной ошибкой, в плане ваших знаний) Теперь знаете больше, мой совет кроме изучения языков, рассмотрите как работает ваш компьютер (это не в коем случае не наставления, просто совет))) Удачи!

Answer 3

Ты осуществляешь операции над целыми числами со знаком. Первый бит отвечает за знак. В джаваскрипте операция js 30 << 30 возвращает 10000000000000000000000000000000 - это число в обратном коде (тебе написали выше) соответствует -2147483648 в десятичной. В пхп у тебя 64-битное слово, поэтому ты получается двоичное число с нулем в первом бите 000000000000000000000000000011110000000000000000000000000000000 что соответствует 32212254720 в десятичной.

Чтбы перепроверить удобно использовать программисткий калькулятор виндовс.

Если ты хочешь выполнить такую операцию на джаваскрипте - тебе нужно 64-битное целое. Используй node-int64 или goog.math.Long.html из closure-library

READ ALSO
Как перейти на страницу гугл календаря, что бы повторно не входить в гугл

Как перейти на страницу гугл календаря, что бы повторно не входить в гугл

нужно добавить функционал что бы пользователь мог вносить в свой гугл календарь некоторые события, и если пользователь уже вошел в систему...

174
Умножение и вывод суммы mysql php

Умножение и вывод суммы mysql php

Подскажите пожалуйста, есть код

161
Можно ли добавиться в исключения?

Можно ли добавиться в исключения?

Можно ли добавиться (программно себя) в исключения Firewall'a? Пишу аналог BittorrentПостоянно Firewall беспокоится, что-то чует, не знает что

207