二進制溢出後怎麼得到正确數值?今天看到一些關于右移和無符号右移的博客解釋,發現好多都要麼沒有實踐随意說,有的甚至亂說,說無符号右移補啥的都有.就自己整理了一下.看本文之前,你需要對二進制、十進制及其運算有一定的概念基礎.,我來為大家科普一下關于二進制溢出後怎麼得到正确數值?以下内容希望對你有幫助!
今天看到一些關于右移和無符号右移的博客解釋,發現好多都要麼沒有實踐随意說,有的甚至亂說,說無符号右移補啥的都有.就自己整理了一下.看本文之前,你需要對二進制、十進制及其運算有一定的概念基礎.
同為1得1,否則為0;
有1得1,其他為0;
相異得1,否則得0;
如1-0得1,0-1得1.
1變0,0變1;
x<<n;x * 2^n左移(符号位不動,正負數皆右補0)
x>>n;x /2^n丢棄右邊指定位數,左邊補上符号位(0正,1負,符号位位于最左位置)
正數時候和右移是一樣的.丢棄右邊指定位數,左邊全是補上0
負數舉例:
System.out.println(-2>>1);
System.out.println(-2>>>1);
# 結果:
-1
2147483647
為了說清無符号右移,需要知道原碼、反碼和補碼;
原碼:一個整數,按照絕對值大小轉換成的二進制數,稱為原碼。
反碼:将二進制數按位取反,所得的新二進制數稱為原二進制數的反碼。
補碼:反碼加1稱為補碼。
負數以其正值的補碼形式表達.
驗證一下:
System.out.println(Integer.toBinaryString(2));
// 對2取反,得到:
System.out.println(Integer.toBinaryString(~2));
// 取-2,可以看到,就是2取反後 1的結果
System.out.println(Integer.toBinaryString(-2));
// 再看一下5和-5的
System.out.println(Integer.toBinaryString(5));
System.out.println(Integer.toBinaryString(~5));
System.out.println(Integer.toBinaryString(-5));
# 2 -2的結果
10
11111111111111111111111111111101
11111111111111111111111111111110
# 5 -5的結果
101
11111111111111111111111111111010
11111111111111111111111111111011
先再解釋一下符号位:我們知道int占用4字節大小,數值範圍-2147483648~2147483647,轉成二進制,就是10000000000000000000000000000000 ~ 01111111111111111111111111111111,可以清晰看到,第一位符号位,是決定的這個數的正負.
前面知道了-2的二進制表示是11111111 11111111 11111111 11111110,那麼右移1位,那就是把最右邊的0擠掉了,得到1111111 11111111 11111111 11111111,這樣少了一位,右移的概念說補符号位,-2是負數,那就是在最左補一個1,得到11111111 11111111 11111111 11111111(如果還有空位的話要補0,這裡隻移了一位,沒空位了).
簡單驗證一下,1的二進制是00000000000000000000000000000001,取反:11111111111111111111111111111110,再取補碼,顯然就是我們剛做-2>>1得到的結果,也就是-1.(計算器,編程語言,好像都沒有一個直接把負的二進制數轉十進制或直接運算的!).(實際上,做個逆運算,把得到的11111111 11111111 11111111 11111111減去1,再取反,就得到其正數時的值1,也可以知道,我們算出來的結果是-1.)
上面隻是驗證了右移..再看無符号位移,為什麼-2>>>1的結果是2147483647,先看一下這個結果的二進制數01111111111111111111111111111111(最大的一個int).這個通過概念比較好理解,前面右移的那裡,我們知道-2的二進制表示,也知道右移一位後的結果,區别是,前面不是補符号位,而是補0,補0,那就是01111111111111111111111111111111,也就是2147483647.
所以你理解一下,無符号右移的無符号,指的就是正負符号,全名可以理解為:無視正負符号的右移,左邊全部補0,所以你是不是也可以回答:為什麼無符号右移,得到必是非負數這類問題了?
左移和右移,可以在做一些做2的倍次運算時使用,提高你的運算效率.無符号右移的應用,我們比較熟悉hashCode()中就用到了.
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
思考一下,為什麼沒有無符号左移?
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!