Страницы

Поиск по вопросам

суббота, 11 января 2020 г.

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

#javascript #php #битовые_операции


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

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
    


Ответы

Ответ 1



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

Ответ 2



Из курса дискретной математики, помню: Для записи чисел в памяти компьютера используется различная система двоичных кодов... Существует 3 вида: 1)Прямой 2)Обратный 3)Дополнительный (Коды) Ваш компьютер использует для записи чисел - дополнительный код. Это не обычный двоичный код, в нем если первый знак является 1, то это отрицателеное число(то есть числа начинающиеся со знака 1, отрицательные числа) Кстати Вы встретились с очень полезной ошибкой, в плане ваших знаний) Теперь знаете больше, мой совет кроме изучения языков, рассмотрите как работает ваш компьютер (это не в коем случае не наставления, просто совет))) Удачи!

Ответ 3



Ты осуществляешь операции над целыми числами со знаком. Первый бит отвечает за знак. В джаваскрипте операция js 30 << 30 возвращает 10000000000000000000000000000000 - это число в обратном коде (тебе написали выше) соответствует -2147483648 в десятичной. В пхп у тебя 64-битное слово, поэтому ты получается двоичное число с нулем в первом бите 000000000000000000000000000011110000000000000000000000000000000 что соответствует 32212254720 в десятичной. Чтбы перепроверить удобно использовать программисткий калькулятор виндовс. Если ты хочешь выполнить такую операцию на джаваскрипте - тебе нужно 64-битное целое. Используй node-int64 или goog.math.Long.html из closure-library

Комментариев нет:

Отправить комментарий