[英]Understanding the right shift operator with bit shifting
我很難理解正確的移位運算符。 我了解左移,說我們沒有
int n = 11; which is 1011
現在,如果我們將其左移n << 1
,結果是
int a = n << 1 ; so a = 10110; (simply add a 0 to the end)
這很有意義
現在右移是我遇到的困難
int a = n >> 1
我認為答案是01011
(在前面加上0),它將再次是1011,而不是101。我的問題是我們如何松開最后一位數字。
更新:我這樣做的原因可能是假設int是8位,在這種情況下,我們將有int8 n = 1011 =>這是00001011,因此當我們右移1時,它會超過8位int 1,因此最后一位被丟棄,它變成0000101嗎? 這種理解正確嗎?
似乎您對輪班工作方式有誤解。
移位不會添加零的左或右。 您不能只添加數字,只有那么多的位。 讓我們以您的數字,十進制數字11為例。
整數n = 11; 這是1011
這是事實,但只有一半。 看,數字在您的CPU中具有固定大小。 對於整數,多數民眾贊成在32位,但是為了簡化起見,我們假設8位數字。 您的11看起來像這樣:
+-+-+-+-+-+-+-+-+
|0|0|0|0|1|0|1|1|
+-+-+-+-+-+-+-+-+
它有8位。 總是。 現在讓我們左移1:
+-+-+-+-+-+-+-+-+
0|0|0|0|1|0|1|1| |
+-+-+-+-+-+-+-+-+
移位后,第一位“移出”。 沒有空間來存儲該位。 另外,最后一位是“空”,我們不能存儲“空”。 只有一或零。 相反,我們“移入”零。 所以你最終
+-+-+-+-+-+-+-+-+
|0|0|0|1|0|1|1|0|
+-+-+-+-+-+-+-+-+
右移則相反。 我們再次從11開始:
+-+-+-+-+-+-+-+-+
|0|0|0|0|1|0|1|1|
+-+-+-+-+-+-+-+-+
然后右移1:
+-+-+-+-+-+-+-+-+
| |0|0|0|0|1|0|1|1
+-+-+-+-+-+-+-+-+
同樣,每一位都右移1。在左側,有一個空位,就像以前一樣,它變為零。 在右邊,一個被轉移了,沒有空間存儲它了。 它只是迷路了。 我們的最終號碼是:
+-+-+-+-+-+-+-+-+
|0|0|0|0|0|1|0|1|
+-+-+-+-+-+-+-+-+
上面的情況適用於無符號數字,也稱為邏輯右移 。 在二進制補碼系統中,對於帶符號的數字,它使用所謂的算術右移 ,而不是移位零位,而是移位符號位。 即,如果數字為負數,則最高有效位為1,則移位為1,否則為零。
右移后1011
將是101
。 最右邊的部分已從1011
刪除 。
111110101
當右移3時得到111110
,刪除加粗的位111110 101
有幾種方法可以查看它。
首先,整數數值類型(在C,C ++,Java,C#中)具有固定的位數。 所以11實際上是(假設可讀性很少見的8位int):
00001101 (8 digits)
左移一位
000011010 (9 digits?)
但是由於我們的整數只能管理8位,因此最左邊的位會下降。
00011010 (8 digits)
32位整數也會發生同樣的情況:最左邊的位會下降。
右移也會發生同樣的情況:右側的位會掉落。 如果原件是:
00011010 (8 digits)
然后在左側添加一個位,將創建不支持的9位值。 取而代之的是,添加的零將所有位向右推一位,最右邊的位下降,結果是
00001101 (8 digits)
另一種看待它的方式是乘法和除法。 用十進制數表示,當我們乘以10時,在右邊加零。 左移就像乘法,但用於二進制。 當我們除以10時,則刪除最右邊的數字並將其放在小數部分。 正二進制和右移是相同的,我們只是損失了分數。
請注意,對於負數,C ++中的情況更為復雜。 例如, 左移負數是未定義的
假設我們有一個數字(我們將其簡單化,例如00010000
),並且想將其左移,它看起來像這樣:
00010000 << 1 = 00100000
我們取了一個數字,並將每一列的值放在第1
列的左側(因為1是我們放在位移的另一個操作數上的數字)。
到目前為止和我在一起? 好。
現在,右移有什么作用? 好吧,它的作用與此相反。它將每一列的值放在x列的右邊 。 例如:
00010000 >> 1 = 00001000
一些更高級的示例:
01010101 << 1 = 10101010
01010101 >> 1 = 00101010
11111111 << 2 = 11111100
11111111 >> 2 = 00111111
注意:移位將切斷在數據邊界上移位的所有位,例如11111111
的示例,移位后落入邊緣的任何位都將丟失。
您沒有“丟失”最后一位數字。 您只是沒有改變您原本認為的價值。
您從n = 0b1011
。 您將其向左移動了一位,並將結果存儲到 a
,而n
保持不變。 然后,您將n
(仍然值為0b1011
)向右移,得到0b0101
。
如果您將a
移至右側而不是n
,您將看到預期的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.