-, , :
" ", , . 1-5 :
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| 0 | 1 | 0<--1<--1<--0<--1 | 0 | -> | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
+---+---+-|-+---+---+---+-^-+---+ +---+---+---+---+---+---+---+---+
| |
+---------------+
" , " :
, , :
- , , ( / );
- , n , k - , , n-k ,
- ;
- .
, ...
, , .
0 - n, 1 n + 1 , 1. . 0-5 ( ):
00111111
... 1:
00000001
... 5 + 1 = 6 :
01000000
... 1, :
00111111
C (1 << (bit + 1)) - 1. , C ( , -, , , , ): ( ) undefined. , 0-7 8- , (1 << 8) - 1, undefined. ( , .) undefined , .
, C unsigned (1 << bit) + (1 << bit) - 1. n- , 2 n , .
( .)
, 0 - msb. lsb - msb, , 0 - (lsb-1), (1 << lsb) - 1. .
00111111 mask for bits 0-5: (1 << 5) + (1 << 5) - 1
- 00000001 mask for bits 0-0: (1 << 1) - 1
-------- -------------------------------
00111110 mask for bits 1-5: (1 << 5) + (1 << 5) - (1 << 1)
, :
mask = (1 << msb) + (1 << msb) - (1 << lsb);
, , :
to_rotate = value & mask;
... , , :
untouched = value & ~mask;
: -, , to_rotate , :
left = (to_rotate << shift) & mask;
, to_rotate (n - shift) , n - , ( n msb + 1 - lsb):
right = (to_rotate >> (msb + 1 - lsb - shift)) & mask;
, untouched, left right:
result = untouched | left | right;
(msb is 5, lsb 1, shift 1):
value = 01011010
mask = 00111110 from (1 << 5) + (1 << 5) - (1 << 1)
01011010 value
& 00111110 mask
----------
to_rotate = 00011010
01011010 value
& 11000001 ~mask (i.e. inverted mask)
----------
untouched = 01000000
00110100 to_rotate << 1
& 00111110 mask
----------
left = 00110100
00000001 to_rotate >> 4 (5 + 1 - 1 - 1 = 4)
& 00111110 mask
----------
right = 00000000
01000000 untouched
00110100 left
| 00000000 right
----------
result = 01110100
16- msb= 15, lsb= 4 shift= 4 ( 3 4- ):
value = 0101011001111000 (0x5678)
mask = 1111111111110000 from (1 << 15) + (1 << 15) - (1 << 4)
0101011001111000 value
& 1111111111110000 mask
------------------
to_rotate = 0101011001110000
0101011001111000 value
& 0000000000001111 ~mask
------------------
untouched = 0000000000001000
0110011100000000 to_rotate << 4
& 1111111111110000 mask
------------------
left = 0110011100000000
0000000001010110 to_rotate >> 8 (15 + 1 - 4 - 4 = 8)
& 1111111111110000 mask
------------------
right = 0000000001010000
0000000000001000 untouched
0110011100000000 left
| 0000000001010000 right
------------------
result = 0110011101011000 = 0x6758