(-1>> 1) ==-1 - Почему?

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

$(function(){
  if(window.Touch) {
    touch_detect.auto_detected();
  } else {
    document.ontouchstart = touch_detect.surface;
  }
}); // End loaded jQuery
var touch_detect = {
  auto_detected: function(event){
    /* add everything you want to do onLoad here (eg. activating hover controls) */
    alert('this was auto detected');
    activateTouchArea();
  },
  surface: function(event){
    /* add everything you want to do ontouchstart here (eg. drag & drop) - you can fire this in both places */
    alert('this was detected by touching');
    activateTouchArea();
  }
}; // touch_detect
function activateTouchArea(){
  /* make sure our screen doesn't scroll when we move the "touchable area" */
  var element = document.getElementById('element_id');
  element.addEventListener("touchstart", touchStart, false);
}
function touchStart(event) {
  /* modularize preventing the default behavior so we can use it again */
  event.preventDefault();
}

7
задан Frank V 26 June 2009 в 01:37
поделиться

5 ответов

Поскольку целые числа со знаком представлены в нотации с дополнением до двух .

-1 будет 11111111 (если это было 8-битное число).

-1 >> 1 очевидно, что знак расширяется, так что он остается 11111111 . Это поведение зависит от компилятора, но для Microsoft при сдвиге числа со знаком вправо ( >> ) знаковый бит копируется, а сдвиг числа без знака вправо вызывает 0 для установки в крайний левый бит.

23
ответ дан 6 December 2019 в 04:58
поделиться

Когда вы сдвигаете вправо и крайний левый бит равен 1, некоторые платформы / компиляторы вводят 0, а некоторые сохраняют 1 и делают новый крайний левый бит равным 1. Это сохраняет знак числа, поэтому отрицательное число остается отрицательным и называется расширением знака.

Вы увидите разницу, если попробуете ((unsigned) -1) >> 1 , что сделает беззнаковое право shift и поэтому всегда будет сдвигаться в 0 бит.

3
ответ дан 6 December 2019 в 04:58
поделиться

расширение знака.

1
ответ дан 6 December 2019 в 04:58
поделиться

Сдвиг битов на отрицательное число - это поведение реализации в C. Результаты будут зависеть от вашей платформы и теоретически могут быть совершенно бессмысленными. Из стандарта C99 (6.5.7.5):

Результат E1 >> E2 - E1 битовые позиции E2 со смещением вправо. Если E1 имеет беззнаковый тип или если E1 имеет знаковый тип и неотрицательное значение, ценность результата - это неотъемлемая часть частного E1 / 2 ^ E2. Если E1 имеет подписанный тип и отрицательное значение, результирующее значение определяется реализацией.

Причина, по которой это происходит, скорее всего, заключается в том, что ваш компилятор использует инструкцию x86 SAR (Shift Arithmetic Right) для реализации >>. Это означает, что произойдет расширение знака - самый старший бит будет реплицирован в новый MSB после смещения значения. Из руководств Intel :

Арифметический сдвиг вправо (SAR) и инструкции сдвига логического вправо (SHR) сдвинуть биты назначения операнд вправо (в сторону меньшего значимые биты). Для каждого количество сдвигов, младший бит операнда назначения сдвигается в флаг CF, и большинство значащий бит либо установлен, либо очищается в зависимости от инструкции тип. Инструкция SHR очищает старший бит (см. рисунок 7-8 в Intel® 64 и IA-32 Архитектура Разработчик программного обеспечения Руководство, том 1); инструкция SAR устанавливает или очищает наиболее важные бит соответствует знаку (большинство значащий бит) исходного значения в операнде назначения. Фактически, инструкция SAR заполняет пустую сдвинутое значение позиции бита с знак несмещенного значения (см. Рисунок 7-9 в Intel® 64 и IA-32 Архитектура Разработчик программного обеспечения Руководство, Том 1).

5
ответ дан 6 December 2019 в 04:58
поделиться

Арифметический сдвиг вправо сохранит знак при сдвиге числа со знаком :

11111111 (-1) will stay 11111111 (-1) 

Напротив, логический сдвиг вправо не сохраняет знак:

11111111 (-1) will become 01111111 (127)

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

Также обратите внимание, что 11111111 может иметь два разных значения в зависимости от представления. Это также влияет на способ их сдвига.

  • Если без знака, 11111111 представляет 255. Сдвиг вправо не сохранит знак, поскольку MSB не является битом знака.
  • Если подписано, 11111111 представляет -1. Арифметический сдвиг вправо сохранит знак.
11
ответ дан 6 December 2019 в 04:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: