在c#入門經典一書中,最為糟糕的一節就是位移了,完全沒有講明白,也沒有說全,似乎只是輕輕點了一下何為位移,帶了兩次原碼和補碼,完全不理會是否明白不明白。這一點這本書很差。因為此書說了,在大多數應用開發中,除了數學應用,這個功能不是很好常用。
位移,是對運算元的二進位制進行操作,計算中,二進位制是以補碼方式計算
何為 原碼,補碼。
原碼:數字的二進位制
補碼,計算機系統中數值的儲存方式,二進位制的特殊計算方式,也就是正數的負數形式,負數均已補碼形式儲存。計算過程:正數的反碼與其原碼相同;負數的反碼是對其原碼逐位取反,但符號位除外,末尾+1,按照二進位制計算方式計算
反碼:計算機系統中數值的儲存方式,二進位制的特殊計算方式。計算過程:正數的反碼與其原碼相同;負數的反碼是對其原碼逐位取反,但符號位除外。
原碼和補碼,反碼是存在關係的,三者之間是可以互相轉換。
原碼變補碼,原碼變反碼
正數:正數的原碼和補碼,反碼是一樣。
9的二進位制:1001 原碼0000 1001 補碼0000 1001,反碼0000 1001
負數 :
原碼:就是二進位制,最高位位1。
補碼:過程最高位1表示符號,其他位按位取反,1變成0,0變成1。最後整個數加1.
反碼:除了最高位表述符號,1位負數【-】,0為正數【+】,之外每一位按位取反,1變成0,0變成1
-9 原碼0000 1001(上面說過,負數的二進位制,均已正數的二進位制的補碼出現,-9的正數也就是9,二進位制原碼也就是9的二進位制),補碼1111 0111, 反碼1111 0110
補碼的過程:先是最高位表示符號【1是負數,0是正數】,其他位按位取反,1變成0,0變成1也就是: 1111 0110,之後整個數字+1,
1111 0110+1=1111 0111就ok了
反碼的過程:先是最高位表示符號【1是負數,0是正數】,其他位按位取反,1變成0,0變成1也就是: 1111 0110 也就ok了,【補碼和反碼之間的關係是,反碼的末尾+1】
補碼,反碼求原碼
正數:正數的原碼,補碼,反碼是一樣的,一樣的!
2:原碼0000 0010,反碼:0000 0010,補碼0000 0010
負數:補碼求原碼:除了最高位表示符號不變之外,其他位按位取反,1變0,0變1,最後+1【按二進位制計算方法計算】
反碼求原碼:除了最高位表示符號不變之外,其他位按位取反
-2 補碼 1111 1110 反碼1111 1101 原碼0000 0010【正數的2,因為計算機的負數均已正數的二進位制的補碼形式儲存或者變現,負數的原碼也即是此負數的去符號的數】
ok了,搞明白什麼是原碼,補碼,反碼,咱就看看 位移運算子
下表列出了 c# 支援的位運算子。假設變數a的值為 60,變數b的值為 13,則:
運算子名字
描述例項
&位邏輯與運算
如果同時存在於兩個運算元中,二進位制 and 運算子複製一位到結果中。
(a & b) 將得到 12,即為 0000 1100
|位邏輯或運算
如果存在於任一運算元中,二進位制 or 運算子複製一位到結果中。
(a | b) 將得到 61,即為 0011 1101
^位邏輯異或運算
如果存在於其中乙個運算元中但不同時存在於兩個運算元中,二進位制異或運算子複製一位到結果中。
(a ^ b) 將得到 49,即為 0011 0001
~位邏輯非運算
二進位制補碼運算子是一元運算子,具有"翻轉"位效果,即0變成1,1變成0。
(~a ) 將得到 -61,即為 1100 0011,乙個有符號二進位制數的補碼形式。
<<
二進位制左移運算子。左運算元的值向左移動右運算元指定的位數。
a << 2 將得到 240,即為 1111 0000
>>
二進位制右移運算子。左運算元的值向右移動右運算元指定的位數。
a >> 2 將得到 15,即為 0000 1111
<<=
左移且賦值運算子
a <<= 2 等同於 a = a << 2
>>=
右移且賦值運算子
a >>= 2 等同於 a = a >> 2
&=按位與且賦值運算子
a &= 2 等同於 a= a & 2
^=按位異或且賦值運算子
a ^= 2 等同於 a = a ^ 2
|=按位或且賦值運算子
a |= 2 等同於 a = a | 2
解釋一下較為理解苦難的地方
下面這個列表,是對運算子按照位運算的方式,建議配合下面的解釋閱讀ab
a& b
a | b
a ^ b00
0000
1011
1111
0100
111、位邏輯與運算
位邏輯與運算將兩個運算物件按位進行與運算。與運算的規則:1與1等於1,1與0等於0,0與0等於0。
比如:1001 0001(二進位制)&1111 0000等於1001 0000(二進位制)。
2、位邏輯或運算
位邏輯或運算將兩個運算物件按位進行或運算。或運算的規則是:1或1等1,1或0等於1,
0或0等於0。比如1001 0001(二進位制)| 1111 0000(二進位制)等於1111 0001(二進位制)。
3、位邏輯異或運算
位邏輯異或運算將兩個運算物件按位進行異或運算。異或運算的規則是:1異或1等於0,
1異或0等於1,0異或0等於0。即:相同得0,相異得1。
比如:1001 0001(二進位制)^1111 0000(二進位制)等於0110 0001(二進位制)。
4、位邏輯非運算
位邏輯非運算是單目的,只有乙個運算物件。位邏輯非運算按位對運算物件的值進行非運算,即:如果某一位等於0,就將其轉變為1;如果某一位等於1,就將其轉變為0。
比如,對二進位制的1001 0001進行位邏輯非運算,結果等於0110 1110,用十進位制表示就是:
~145等於110;對二進位制的01010101進行位邏輯非運算,結果等於10101010。用十進位制表示就是~85等於176。
剩下就是 左移 右移 【<<】【>>】
a=10 二進位制:0000 1010
運算子結果
<<
二進位制左移運算子。左運算元的值向左移動右運算元指定的位數。
a << 2 將得到 40,即為 0010 1000
>>
二進位制右移運算子。左運算元的值向右移動右運算元指定的位數。
a >> 2 將得到 2,即為 0000 0010
位移,是對運算元的二進位制進行操作,計算中,二進位制是以補碼方式計算
左移運算子:<< 格式 x《列子:
20 二進位制 0000 0000 0000 0000 0000 0000 0001 0100【操作型別預設為int ,int是32位,所以二進位制也是32】
20<<3 也就是 0000 0000 0000 0000 0000 0000 1010 0000 ,十進位制等於160
-10二進位制 1111 1111 1111 1111 1111 1111 1111 0110【負數均已正數的補碼形式儲存或者表示】
-10 <<5 : 1111 1111 1111 1111 1111 1110 1100 0000 轉換成十進位制 -320
也就是右移運算子:>> 格式x>>n,
x的型別只能是int,uint、long或ulong,n的型別只能是int,n的型別只能是int,或者顯示轉換為這些型別之一,否則變異程式時會出現錯誤。
列子:正數
54 二進位制:0000 0000 0000 0000 0000 0000 0011 0110
54>>4 0000 0000 0000 0000 0000 0000 0000 0011 十進位制 3
負數-24 補碼 1111 1111 1111 1111 1111 1111 1110 1000
-24>>2 1111 1111 1111 1111 1111 1111 1111 1010 十進位制-6
ok
c 位移運算子
左移運算子 將第乙個運算元向左移動第二個運算元指定的位數,空出的位置補0。例如 1100100 2 110010000,1100100左移兩位後為 1100100口口,補0後為110010000。右移運算子 將第乙個運算元向右移動第二個運算元所指定的位數,空出的位置補0。例如 1100100 2 0...
位移運算子
位移運算子 直接操作二進位制數,運算速率更快。按位非 not 把1變成0,把0變成1 超出運算範圍,變成負數 var a 25 var b a b 25的 二進位制數 00000000000011001 轉化後 11111111111100010 結果為 26 總結非運算 乙個數與自身的取反值相加等...
java 位移運算子
import org.junit.test 1 左移運算子 2 右移運算子 測試正數 3 右移運算子 測試負數 4 無符號右移 測試正數 5 無符號右移 測試負數 public class weiyitest 右移運算子 測試正數 1010001001 test public void test2 ...