正數
正數的原碼、反碼、補碼都是該數字的二進位制表示。
首先我們需要知道,計算機中的移位運算都是以二進位制補碼形式進行的,就像我們的integer.tobinarystring(num)
,其轉化出來的數字就是補碼的形式。在計算機中是沒有正負號的,正數用0表示,負數用1表示。像int,我們知道他是佔32位的,但是他的最大數是2^31 - 1,原因就是他有乙個是符號位。下面先看幾個極限值
system.out.println((1<<31) - 1); //2147483647
system.out.println(1<<31); //-2147483648
int m = -2147483648;
system.out.println(integer.tobinarystring(m)); //10000000000000000000000000000000
由於int型在日常中比較常用,下面就以int型進行講解。
這裡以55進行舉例,為了好理解,我以8位進行講解。
int a = 55;
system.out.println(integer.tobinarystring(a)); //110111
55的原碼是00110111,其中符號位是前面的0,其反碼和補碼也是00110111。
負數
負數的原碼是該數字的二進位制表示,反碼是符號位不變數值位取反,補碼是符號位不變數值位在反碼的基礎上加1
我們以-83進行講解,這裡也是用8位進行表示,其實前面還有24位1。
int n = -83;
system.out.println(integer.tobinarystring(n)); //11111111111111111111111110101101
可以看出,輸出的是10101101,這裡是補碼的形式,其中高位的1是符號位。
-83的原碼是 11010011,其中第一位的1是符號位,表示是負數。
-83的反碼是 10101100,其中第一位的1是符號位,表示是負數。
-83的補碼是 10101101,其中第一位的1是符號位,表示是負數。
正數
了解了補碼之後,移位運算就簡單多了,這裡的右移,也是有符號右移,其移位運算就是用的補碼形式。這裡還是用8位的55舉例。
int a = 55;
system.out.println(integer.tobinarystring(a)); //110111
a = a >> 2;
system.out.println(integer.tobinarystring(a)); //1101
system.out.println(a); //13
55的補碼是00110111,右移之後是補碼是00001101,原碼和反碼也是00001101即是13。
負數
負數的有符號右移,這裡還用-83進行講解。
int b = -83;
system.out.println(integer.tobinarystring(b)); //11111111111111111111111110101101
b = b >> 2;
system.out.println(integer.tobinarystring(b)); //11111111111111111111111111101011
system.out.println(b); // -21
-83的原碼是11010011,反碼是10101100,補碼是10101101,所以補碼右移2位後是11101011
11101011轉化為反碼是11101010,轉化為原碼是10010101,即是-21,我們可以看到,移位之後,其位數是不變的,也就是前面的符號位是不變的。
正數
>>>
是無符號右移,這裡還是以55講解
int a = 55;
system.out.println(integer.tobinarystring(a)); //110111
a = a >>> 2;
system.out.println(integer.tobinarystring(a)); //1101
system.out.println(a); //13
對於正數而言,有符號右移和無符號右移是一樣的,因為,有符號右移,移動之後是補了符號位0,而無符號右移也是補了0,著重講解負數。
負數
負數還是以-83來進行講解
int b = -83;
system.out.println(integer.tobinarystring(b)); //11111111111111111111111110101101
b = b >>> 2;
system.out.println(integer.tobinarystring(b)); //111111111111111111111111101011
system.out.println(b); // 1073741803
看到這個結果是不是很意外,下面來進行細說一下,你就覺得很合理了。
首先-83的原碼是11010011,反碼是10101100,補碼是10101101,這是我們上面以8位進行表示的,很正常,但是在這裡就不能簡單的用8位來表示了,因為其在無符號右移的時候,前面移出了0,而0取反之後變為了1,所以導致數值變得不敢相信。
這裡進行32位詳細模擬
-83的原碼是 11111111111111111111111111010011
-83的反碼(原碼數值位取反)是 11111111111111111111111110101100
-83的補碼(反碼數值位加1)是 11111111111111111111111110101101
無符號右移2位之後補碼形式是00111111111111111111111111101011,
而其反碼(補碼數值位減1)是01000000000000000000000000010100,
其補碼(反碼數值位取反)是01000000000000000000000000010011
int x = 0b01000000000000000000000000010011;
system.out.println(x); //1073741843
經過檢驗,果然是1073741843
對於左移的話就比較簡單了,因為他不牽扯到符號的問題,符號位不變就行了,由於這個原因,所以就沒有《符號了。
這裡還是以55和-83進行講解
int c = 55;
system.out.println(integer.tobinarystring(c)); //110111
c = c << 2;
system.out.println(integer.tobinarystring(c)); //110111100
system.out.println(c); //220
可以看出,左邊的符號位沒有動,只是在左移2位的時候後面新增了兩個0而已
int d = -83;
system.out.println(integer.tobinarystring(d)); //11111111111111111111111110101101
d = d << 2;
system.out.println(integer.tobinarystring(d)); //11111111111111111111111010110100
system.out.println(d); // -332
也是符號位不變,在左移2位的時候,後面新增了兩個0
有符號:左移1位,相當於乘2,右移動一位相當於除以2
無符號:那真得好好推推了。
原碼 反碼 補碼
正數 原碼 反碼 補碼一樣 7 原 0 0000111 b 7 反 0 0000111 b 7 補 0 0000111 b 負數 原碼就是原來的表示方法 反碼是除符號位 最高位 外取反 補碼 反碼 1 7 原 1 0000111 b 7 反 1 1111000 b 7 補 1 1111001 b 當...
原碼 反碼 補碼
正數 原碼 反碼 補碼一樣 7 原 0 0000111 b 7 反 0 0000111 b 7 補 0 0000111 b 負數 原碼就是原來的表示方法 反碼是除符號位 最高位 外取反 補碼 反碼 1 7 原 1 0000111 b 7 反 1 1111000 b 7 補 1 1111001 b 當...
原碼 反碼 補碼
數值在計算機中表示形式為機器數 計算機只能識別0和1,使用的是二進位制,而在日常生活中人們使用的 是十進位制,正如亞里斯多德早就指出的那樣,今天十進位制的廣泛採用,只不過我們絕大多數人生來具有10個手 指頭這個解剖學事實的結果.儘管在歷史上手指計數 5,10進製 的實踐要比二或三進製計數出現的晚.摘...