Что значит 'х



что означает 'x


Я понимаю, что побитовое SHIFT операции это:



x << y AS x * 2y


и Тильды ~ оператор:



~x AS -(x+1)


Итак, я предполагаю следующее:



5 << ~3 AS 5 * 2-4 or 5 * Math.pow(2, -4)


это должно привести к 0.3125.



но, когда я запускаю 5 << ~3 в результате 1342177280.



что такое пошаговое объяснение? Как и почему эта комбинация операций приводит к 1342177280 вместо 0.3125?



(этот вопрос похож на вопрос переполнения стека что такое побитовые операторы? о побитовый SHIFT оператора.)

567   5  

5 ответов:

x << -n равна x << (32 - n)
~3 == -4 так
5 << ~3 ===5 << (32 - 4) ===5 << 28 что это 1,342,177,280

чтобы быть точным X 11111)

                   3 = 00000000000000000000000000000011  
                  ~3 = 11111111111111111111111111111100
       0x1f (the mask) 00000000000000000000000000011111
                       --------------------------------
            ~3 & 0x1f  00000000000000000000000000011100 = 28

когда величина меньше 32, это точно так же, как то, что я написал выше, хотя

битовые операции работают с 32 битными целыми числами. Отрицательные битовые сдвиги бессмысленны, поэтому они обернуты в положительные 32-битные целые числа

как оператора работает

rhs преобразуется в 32-битное целое число без знака - как описано здесь ToUInt32

ToUint32 в основном принимает число и возвращает число по модулю 2^32

The ~ оператор переставляет биты элемента, в то время как << - побитовый сдвиг влево. Вот что происходит в двоичном шаг за шагом. обратите внимание, что самый левый бит 1 означает отрицательное число, этот формат двоек комплимент:

3         // (00000000000000000000000000000011 => +3 in decimal)
// ~ flips the bits
~3        // (11111111111111111111111111111100 => -4 in decimal)
// The number 5 (..00101) shifted by left by -4 (-4 unsigned -> 28)
5         // (00000000000000000000000000000101 => +5 in decimal)
5 << -4   // (01010000000000000000000000000000 => +1342177280 in decimal)

в последней строке биты сдвигаются и" поворачиваются " в другую сторону, что приводит к большому положительному числу. На самом деле сдвиг на отрицательное число, похожий на вращение побитового (переполненные биты поворачиваются на другую сторону), где сдвиг на положительные числа не имеет такого поведения. Недостатком является то, что не вращающиеся биты игнорируются. По сути это означает, что 5 << -4 - это то же, что делать 5 << (32 - 4), а поворот на самом деле большой сдвиг.

причина этого заключается в том, что битовые сдвиги составляют всего 5 бит без подписи целое число. Так что двоичное число в двойках комплимент-4 (11100) без знака будет 28.

ваш анализ верен, за исключением того , что вы не должны интерпретировать ~3 (11100) (битовое дополнение 3 (00011)) как -4, а как беззнаковое (то есть неотрицательное) 5-битное целое число, а именно 28 = 16 + 8 + 4 (11100).

Это объясняется в стандарт ECMAScript (NB в большинстве современных машин, положительные и отрицательные целые числа представляются в памяти с помощью дополнение представительство):

12.8.3 Сдвиг Влево Оператор (

Примечание выполняет побитовую операцию сдвига влево для левого операнда на величину, указанную правым операндом.

12.8.3.1 Семантика Выполнения: Оценка

ShiftExpression: ShiftExpression

  1. пусть lref является результатом оценки ShiftExpression.
  2. пусть lval будет GetValue (lref).
  3. ReturnIfAbrupt (lval).
  4. пусть rref будет результат оценки аддитивного выражения.
  5. пусть rval будет GetValue (rref).
  6. ReturnIfAbrupt (rval).
  7. пусть lnum будет ToInt32 (lval).
  8. ReturnIfAbrupt (lnum).
  9. пусть rnum будет ToUint32 (rval).
  10. ReturnIfAbrupt (rnum).
  11. пусть shiftCount будет результатом маскировки всех, кроме наименее значимых 5 бит rnum, то есть вычислить rnum & 0x1F.
  12. вернуть результат слева сдвиг lnum по битам shiftCount. Этот результатом является 32-разрядное целое число.

~x обратит битовое представление вашего значения x (32-битное знаковое значение с дополнением двух).

x << y - оператор сдвига влево (здесь слева). Ваша математическая интерпретация верна:)

вы можете прочитать больше о побитовых операциях здесь:побитовые операторы в Javascript

5 << ~3 дает тот же результат, что и 5 << -4, вы правы.

главное: смещение x действительно приводит к x * 2y, но это не прямое использование, это просто полезный побочный эффект.
Кроме того, если у вас есть отрицательный y, это не работает таким же образом.

Comments

    Ничего не найдено.