原碼,補碼,反碼
-
在計算機中,用8位來儲存一個子節,就是8bit=1byte(位元組)
現在計算機一般是64位的,是以是8個子節
- 我現在用-2來舉例說明原碼,補碼和反碼
- 原碼:10000010
-
反碼:
其中正數的反碼和補碼是一樣的
負數的反碼就是:将原碼的除了符号位不變,其他位按照位來取反,
是以-2的反碼就是:11111101
-
補碼:
其中正數的補碼和原碼還是一樣的
負數的補碼就是對應的反碼+1
-2的補發就是:11111110
-
在計算機裡面是使用補碼的方式來儲存資料的,但是為什麼呢?
因為計算機裡面有個加法器,計算機使用加法器可以實作數值的加法,但是我們不想在計算機中再做一個減法器,想使用加法器來實作減法,是以就讓計算機使用補碼來存儲資料,這樣加法器可以實作減法,但是為什麼可以實作呢?我們使用1-1來做例說明一下:
1-1=1+(-1)=0
我們有三種方式儲存資料,是以現在有三種解決的方案
1)使用原碼:1+(-1)=00000001+1000001=100000010=-2 /顯然這種解決方案不行
2)使用反碼:1+(-1)=00000001+11111110=1111111
這樣計算出來的是反碼,我們将它轉化成原碼就是:10000000,這樣表示1-1=-0,這樣我們就使用了兩種方式來表示0,其中10000000表示-0,00000000表示+0,這樣我們覺得還是不合理,
3)使用補碼:1+(-1)=00000001+11111111=00000000
這個是補碼,但是它是正數,是以補碼和原碼相同,是以就是0
是以因為上面,計算機裡面存儲的資料都是使用補碼來存放的
位運算
-
位運算符包括:
1.1數值1<<數值2
//左移,數值1的二進制數向左邊移動數值2個位,相當于數值1*2^數值2 比如:3<<2=12
1.2(數值1>>數值2) //這裡在浏覽器上(>>)轉義了,是以我加了()才能顯示,右移高位空出的位置,如果本來最高位是0就補0,如果高位是1就全部補1,比如:3>>1=1
1.3>>> //無符号右移,注意點,就是無符号右移是右移後空出的高位裡面一律補0 比如:3>>>1=1
1.4 & //與運算,就是将兩邊的數字的二進制(因為計算機儲存數值的方式就是二進制)的每一個位都進行與運算,就是11的結果才是1,10,01,00的結果都是0 ,比如:6&3=2
1.5 | //或運算,也是二進制每個位的或,有一個1結果就是1,比如:6|3=7
1.6 ^ //異或運算,顧名思義,就是不同才是1,相同就是0 ,比如:6^3=5
1.7 ~ //取反運算,就是二進制按位取反 ,比如:~6=-7,這裡也可以看到為什麼原碼取反後+1才是補碼
-
在Java中一些對于進制轉換的函數:
2.1 Integer.toBinaryString(int) //這就是傳回二進制的補碼
2.2 (byte)Integer.parseInt(String) //就是将String轉化成二進制
練習
package test;
/*
* 需求是這樣:将n和m兩個數進行交換
*/
public class Binarytest
{
public static void main(String[] args)
{
method1();
method2();
method3();
}
//提供一個臨時變量
public static void method1()
{
int m=10,n=20;
int temp;
temp=m;
m=n;
n=temp;
System.out.println("m="+m+" n="+n);
}
//沒有提供臨時變量,但是當兩個數較大的時候會出現精度損失
public static void method2()
{
int m=10,n=20;
m=m+n;
n=m-n;
m=m-n;
System.out.println("m="+m+" n="+n);
}
//這裡就是一個兩全其美的方法
//這裡使用了一個結論,就是異或運算的結論:
//當(m^n)^n時,就時m本身
public static void method3()
{
int m=10,n=20;
m=m^n;
n=m^n;//(m^n)^n=m
m=m^n;//(m^n)^m=n
System.out.println("m="+m+" n="+n);
}
}
這裡還有一個其他應用示例,就是數字1和數字2進行與運算,就可以去出數字1中對應數字2的位數個數的位
例如:60&15就是取出60對應最低位4位的對應的值