原碼 反碼 補碼 位運算
http://blog.csdn.net/LM165678/article/details/77030806 關于C中為何一個字節表示有符號數范圍是[-128-127]
-0的原碼[1000 0000]即是-128的原碼[1 1000 0000]被8位截斷后的樣子。凡是-0的,其表示的負數即是 高位添加1之后表示的負數值。
如:若【1000 0000】表示的是負0,則其實際是【1 1000 0000】所表示的負數,即-128.
【新的收獲】 對于有符號的整型,以一個字節為例,0~127【0000 0000 ~ 0111 1111】表示的是它們本身,而128~255【1000 0000 ~ 1111 1111】則表示負數(-128 ~ -1),其對應值如下表所示:
| 無符號值(相當于計算機中存儲的是原碼) | 255 | 254 | 253 | 252 | ... | ... | 131 | 130 | 129 | 128 |
| 有符號值(相當于計算機中存儲的是補碼)【見解釋】 | -1 | -2 | -3 | -4 | ... | ... | -125 | -126 | -127 | -128 |
不難發現規律:上下的絕對值之和等于定值。
第二行的補碼剛好是相應的無符號值的原碼
【解釋】將此補碼按位取反再加一得到了此負數的絕對值的原碼,將最高位換為1即為此負數的原碼.一個特例是絕對值的原碼最高為已經為1了[即-128的絕對值的原碼],此時再高位補上1即為-128的原碼
http://blog.csdn.net/scythe666/article/details/50184273 char c=128;printf("%d",c);問題 解除疑惑
這里記住一點:計算機中用一個字節表示1000 0000的有符號值就相當于 1 10000 0000,即-128.當用4個字節擴展這個值表示有符號的這個值時,擴展為1 0* 1000 0000,即4字節的-128,然后轉換為補碼就是計算機中的存儲值
0,計算機存儲負值以補碼形式存儲。
1,正數的 原碼,反碼,補碼都一樣。
2,負數的反碼: 負數的反碼是其絕對值的原碼按位取反; 負數的補碼:此負數的反碼 +1;
| 例子 | 原碼 | 反碼 | 補碼 | ||
| -2 | 10000010 | 11111101 | 11111110 | ||
3, 補碼的補碼 是原碼。由負數的補碼按位取反再加一得到的是這個負數的絕對值的原碼。由補碼推導原碼兩種方法:1,對此補碼求補碼,2,此補碼 -1然后按位取反(符號位除外)
4,按位非操作的本質:操作數的負值減一。自己推導如下:
正數:
| 2 | 00000010 | 11111101 | 10000010 | 10000011 |
| A | B | D | C |
~A=B(負值的補碼,也即是計算機存儲負值的形式)
B按位取反(符號位不變) =D(D=-A)
D+ 1 = C(負值的原碼) [實際上是D-1=C]
即C=D-1=-A-1
負數:
| 例子 | 原碼 | 反碼 | 補碼 | 按位非 | |
| -2 | 10000010 | 11111101 | 11111110 | 00000001 | |
| A | B | C | D |
負數以補碼C的形式存儲,按位非即對此補碼操作。由補碼的補碼等于原碼=>C按位取反(符號位不變)+1=A。C按位取反(符號位也改變)+1=-A,所以,D=-A-1。
5,左移運算符(<<): 在數值沒有溢出的前提下,左移n位,相當于乘以2的n次方。
這個操作符會將數值的所有位(注意,符號位不會移動,即不會影響操作數的符號位)向左移動指定的位數。向左移后,原數值的右側會多出空位,左移操作會以0來填充這些空位。例子,2<<5 = 64; -2<<5 = -64;
6,有符號的右移運算符(>>):右移n位,相當于除以2的n次方。
這個操作符會將數值的所有位(注意,符號位不會移動)向右移動指定的位數。向右移后,原數值的左側會多出空位(具體位置是在符號位右邊,數值位左邊),有符號的右移操作會用符號位來填充所有空位。
7,無符號的右移(>>>):
這個操作符會將數值的所有位(包括符號位)都向右移動,左側空出來的位用0填充。對正數來說,>>>和>>操作符結果相同,但是對于負數來說就不一樣了,通常負數的>>>操作結果會是個很大的正數。
8,
浙公網安備 33010602011771號