Предполагая 2-дополнение, только бит сдвига дивиденд эквивалентно определенного рода деление: не условное деление, где мы обогнуть дивиденд следующего кратного делителя к нулю. Но другой вид, где мы крутим дивиденд к отрицательной бесконечности. Я заново открыл это в Smalltalk, см. http://smallissimo.blogspot.fr/2015/03/is-bitshift-equivalent-to-division-in.html.
Например, давайте разделим -126 на 8. Традиционно, мы должны написать
-126 = -15 * 8 - 6
Но если мы округляем к бесконечности, мы получим положительный остаток и записать его:
-126 = -16 * 8 + 2
бит-сдвиг выполняет вторую операцию в отношении битовых шаблонов (предположительно 8 бит длиной int для краткости):
1000|0010 >> 3 = 1111|0000
1000|0010 = 1111|0000 * 0000|1000 + 0000|0010
Итак, что, если мы хотим традиционное деление с округлением до нуля и остатком того же знака, что и дивиденд? Простой, нам просто нужно добавить 1 к частному - тогда и только тогда, когда дивиденд отрицательный, а деление неточно.
Вы видели, что x>>31
соответствует первому условию, дивиденд отрицательный, если int имеет 32 бита.
Второй термин соответствует второму условию, если деление неточно.
Посмотрите, как закодированы -1, -2, -4, ... в двух частях: 1111 | 1111, 1111 | 1110, 1111 | 1100. Таким образом, отрицание n-й степени двух имеет n конечных нулей.
Когда дивиденд имеет n конечных нулей, и мы делим на 2^n, то не нужно добавлять 1 к конечному частному. В любом другом случае нам нужно добавить 1.
Что ((1 < < n) + ~ 0) делает создание маски с n конечными.
n последних бит не имеет значения, потому что мы собираемся сдвинуться вправо и просто выбросить их. Итак, если деление является точным, n конечных бит дивидендов равны нулю, и мы просто добавляем n 1s, которые будут пропущены. Напротив, если деление неточно, то один или несколько из n конечных бит дивиденда равны 1, и мы обязательно вызываем перенос в позицию n + 1 бит: так мы добавляем 1 к частному (мы добавляем 2^п к дивиденду). Объясняет ли это это немного больше?
двух дополнений. Но вы правы, ответ ничего не объясняет. Теперь вы получаете downvotes, когда вы это делаете ... –
'x + ~ 0' - это забавный способ написать' x - 1', просто усечь эту скругленную маску на 'n' bits – harold
1) Обеспокоена делением отрицательных чисел ? 2) Обеспокоена делением отрицательных чисел переносимо? 3) Забота об обработке 'x == INT_MIN'?4) что относительно степеней 2, которые соответствуют/превосходят ширину бита 'int'? В противном случае цель настолько узкая, что она не так полезна за пределами узкой идеи о возможности или диапазоне и деталях 'int'. – chux