arithmetic versus logical shift
Shifting bits to the right looks innocent — slide every bit one place toward the low end and something falls off the bottom — but it hides a real decision: what new bit do you bring in at the TOP? The two answers give two different operations, the arithmetic shift and the logical shift, and choosing the wrong one quietly corrupts negative numbers.
A LOGICAL right shift fills the vacated top bits with zeros, always. It treats the value as a plain bag of bits, so 1000 0000 shifted right by one becomes 0100 0000 — clean and simple. An ARITHMETIC right shift instead copies the original sign bit into the top, a trick called sign extension. The reason is to preserve the value's sign when you intend the shift as a division: shifting a two's-complement negative number right should keep it negative and roughly halve it. So the 8-bit value 1111 1000 (which is -8) arithmetically shifted right by one becomes 1111 1100 (which is -4) — the sign bit is copied in, and -8 divided by 2 is indeed -4. Done logically instead, the same bits would become 0111 1100, a large positive number, which is wrong for a signed division. (Left shifts do not have this split; both fill the low end with zeros.)
In C the rule is tied to the type: right-shifting an UNSIGNED value is always logical (zero-fill), while right-shifting a SIGNED value is, in practice on every common compiler, arithmetic (sign-extending) — though the standard historically left signed right shift of negatives as implementation-defined, so the truly portable habit is to shift unsigned values when you want predictable bit behaviour. Two more honest cautions: shifting by an amount greater than or equal to the type's width, or by a negative amount, is undefined behavior, not a wrap; and never assume a right shift of a signed negative rounds the same way as integer division — it rounds toward negative infinity, not toward zero.
8-bit 1111 1000 is -8. Arithmetic >> 1 copies the sign bit: 1111 1100 = -4 (a correct halving). Logical >> 1 fills zero: 0111 1100 = 124 (wrong for a signed value).
Arithmetic shift preserves sign; logical shift always fills zeros.
Shifting by more than or equal to the type's bit width (e.g. a 32-bit value by 32) is undefined behavior in C, not a defined zero or wrap; and shifting a signed value right rounds toward negative infinity, unlike division's round-toward-zero.