對於原碼, 反碼, 補碼而言, 須要注意如下幾點:java
(1).Java中沒有無符號數, 換言之, Java中的數都是有符號的;node
(2).二進制的最高位是符號位, 0表示正數, 1表示負數;數組
(3).正數的原碼, 反碼, 補碼都同樣;函數
(4).負數的反碼=它的原碼符號位不變, 其餘位取反;性能
(5).負數的補碼=它的反碼+1;ui
(6).0的反碼, 補碼都是0;this
(7).在計算機運算的時候, 都是以補碼的方式來運算的.spa
Java中有4個位運算, 分別是按位與&, 按位或|, 按位異或^, 按位取反~, 它們的運算規則爲:code
Java中有3個移位運算符, 分別是算術右移>>, 算術左移<<, 邏輯右移>>>, 它們的運算規則爲:blog
public class Demo1 { public static void main(String[] args) { System.out.println(~2); System.out.println(2&3); System.out.println(2|3); System.out.println(~-5); System.out.println(13&7); System.out.println(5|4); System.out.println(-3^3); } }
運行結果:
-3
2
3
4
5
5
-2
public class Demo2 { public static void main(String[] args) { System.out.println(1>>2); System.out.println(-1>>2); System.out.println(1<<2); System.out.println(-1<<2); System.out.println(3>>>2); } }
運行結果:
0
-1
4
-4
0
位(bit) 一位二進制數,又稱比特
字節(byte) 1B = 8b 內存存儲的最小單元
字長:同一時間內,計算機能處理的二進制位數
字長決定了計算機的運算精度,字長越長,計算機的運算精度就越高。所以,高性能的計算機,其字長較長,而性能較差的計算機,其字長相對要短一些。
其次,字長決定了指令直接尋址的能力。通常機器的字長都是字節的一、二、四、8倍。微機的字長爲8位、16位、32位、64位,如286機爲16位機,386和486是32位機,最新推出的PIII爲64位高檔機。
字長也影響機器的運算速度,字長越長,運算速度越快。
字:是計算機中處理數據或信息的基本單位。一個字由若干字節組成,一般將組成一個字的位數叫作該字的字長。
進制
一位八進制數字能夠用三位二進數來表示,一位十六進制數能夠用四位二進數來表示,因此二進制和八進制、十六進制間的轉換很是簡單
如:將(1010111.01101)2轉換成八進制數
1010111.01101=001 010 111. 011 010
↓ ↓ ↓ ↓ ↓
1 2 7 3 2
因此(1010111.011.1)2=(127.32)8
將(327.5)8轉換爲二進制
3 2 7. 5
↓ ↓ ↓ ↓
011 010 111. 101
因此(327.5)8=(11010111.101)2
將(110111101.011101)2轉換爲十六進制數
(110111101.011101)2=0001 1011 1101. 0111 0100
↓ ↓ ↓ ↓ ↓
1 B D 7 4
因此(110111101.011101)2=(1BD.74)16
將(27.FC)16轉換成二進制數
2 7. F C
↓ ↓ ↓ ↓
0010 0111 1111 1100
因此(27.FC)16=(100111.111111)2
二進制表示
原碼:每一位表示符號
反碼:正數同原碼,負數除符號外其它位相反
補碼:正數同原碼,負數除符號外,反碼+1獲得
地址總線:
地址總線寬度決定了CPU能夠訪問的物理地址空間,簡單地說就是CPU到底可以使用多大容量的內存
8位地址總線:一個8位的二進制數最多能表示2的8次方個數據,從00000000到11111111,十進制爲0-255,這樣,8位地址總線最大能區分的地址是從0到255。咱們說他的尋址能力爲256, 即256字節
16位地址總線:64K
20位: 1M
32位: 4G
上面是不一樣地址總線,能訪問的物理內存。注意:計算時,如16位地址總線的尋址能力不是16個1組成的二進制數的結果,而是要再加上1,由於前面有個00000000000000000
即2的16次方, 而16個1組成的二進制數爲2的16次方減1
其餘:
十進制轉二進制:
用2展轉相除至結果爲1
將餘數和最後的1從下向上倒序寫 就是結果
例如302
302/2 = 151 餘0
151/2 = 75 餘1
75/2 = 37 餘1
37/2 = 18 餘1
18/2 = 9 餘0
9/2 = 4 餘1
4/2 = 2 餘0
2/2 = 1 餘0
故二進制爲100101110
二進制轉十進制
從最後一位開始算,依次列爲第0、一、2...位
第n位的數(0或1)乘以2的n次方
獲得的結果相加就是答案
例如:01101011.轉十進制:
第0位:1乘2的0次方=1
1乘2的1次方=2
0乘2的2次方=0
1乘2的3次方=8
0乘2的4次方=0
1乘2的5次方=32
1乘2的6次方=64
0乘2的7次方=0
而後:1+2+0
+8+0+32+64+0=107.
二進制01101011=十進制107.
1、二進制數轉換成十進制數
由二進制數轉換成十進制數的基本作法是,把二進制數首先寫成加權係數展開式,而後按十進制加法規則求和。這種作法稱爲"按權相加"法。
2、十進制數轉換爲二進制數
十進制數轉換爲二進制數時,因爲整數和小數的轉換方法不一樣,因此先將十進制數的整數部分和小數部分分別轉換後,再加以合併。
1. 十進制整數轉換爲二進制整數
十進制整數轉換爲二進制整數採用"除2取餘,逆序排列"法。具體作法是:用2去除十進制整數,能夠獲得一個商和餘數;再用2去除商,又會獲得一個商和餘數,如此進行,直到商爲零時爲止,而後把先獲得的餘數做爲二進制數的低位有效位,後獲得的餘數做爲二進制數的高位有效位,依次排列起來。
2.十進制小數轉換爲二進制小數
十進制小數轉換成二進制小數採用"乘2取整,順序排列"法。具體作法是:用2乘十進制小數,能夠獲得積,將積的整數部分取出,再用2乘餘下的小數部分,又獲得一個積,再將積的整數部分取出,如此進行,直到積中的小數部分爲零,或者達到所要求的精度爲止。
而後把取出的整數部分按順序排列起來,先取的整數做爲二進制小數的高位有效位,後取的整數做爲低位有效位。
回答者:HackerKinsn - 試用期 一級 2-24 13:31
1.二進制與十進制的轉換
(1)二進制轉十進制<BR>方法:"按權展開求和"
例:
(1011.01)2 =(1×23+0×22+1×21+1×20+0×2-1+1×2-2)10
=(8+0+2+1+0+0.25)10
=(11.25)10
(2)十進制轉二進制
· 十進制整數轉二進制數:"除以2取餘,逆序輸出"
例: (89)10=(1011001)2
2 89
2 44 …… 1
2 22 …… 0
2 11 …… 0
2 5 …… 1
2 2 …… 1
2 1 …… 0
0 …… 1
· 十進制小數轉二進制數:"乘以2取整,順序輸出"
例:
(0.625)10= (0.101)2
0.625
X 2
1.25
X 2
0.5
X 2
1.0
2.八進制與二進制的轉換
例:將八進制的37.416轉換成二進制數:
37 . 4 1 6
011 111 .100 001 110
即:(37.416)8 =(11111.10000111)2
例:將二進制的10110.0011 轉換成八進制:
0 1 0 1 1 0 . 0 0 1 1 0 0
2 6 . 1 4
即:(10110.011)2 =(26.14)8
3.十六進制與二進制的轉換<BR>例:將十六進制數5DF.9 轉換成二進制:
5 D F . 9
0101 1101 1111.1001
即:(5DF.9)16 =(10111011111.1001)2
例:將二進制數1100001.111 轉換成十六進制:
0110 0001 . 1110
6 1 . E
即:(1100001.111)2 =(61.E)16
約瑟夫問題: 設編號爲1,2,3...n的n我的圍坐一圈, 約定編號爲k(1<=k<=n)的人從1開始報數, 數到m的那我的出列, 它的下一位又從1開始報數, 數到m的那我的又出列, 依次類推, 直到全部人出列爲止, 由此產生一個出隊編號的序列.
public class Demo3 { public static void main(String[] args) { CycleLinkList cycleLinkList=new CycleLinkList(); cycleLinkList.setCycleLinkListLength(10); cycleLinkList.initCycleLinkList(); cycleLinkList.Josephu(4, 6); } } /** * 節點結構 */ class Node { //編號 private int number; //指向下一個節點的引用 private Node nextNode=null; //構造函數 public Node(int number) { this.number=number; } //設置nextNode節點 public void setNextNode(Node nextNode) { this.nextNode = nextNode; } //獲得nextNode節點 public Node getNextNode() { return nextNode; } //獲得編號 public int getNumber() { return number; } } /** * 循環鏈表 */ class CycleLinkList { //鏈表的長度 private int length=0; //指向鏈表頭結點的引用 private Node firstNode=null; /** * 設置鏈表的長度 * @param len 鏈表長度 */ public void setCycleLinkListLength(int len) { this.length=len; } /** * 初始化循環鏈表 */ public void initCycleLinkList() { //定義一個臨時節點 Node tempNode=null; for(int i=1;i<=length;i++) { //頭節點 if(1==i) { Node headNode=new Node(i); this.firstNode=headNode; tempNode=headNode; }else { //尾節點 if(length==i) { Node node=new Node(i); tempNode.setNextNode(node); tempNode=node; //將尾節點的nextNode引用指向鏈表的頭節點firstNode tempNode.setNextNode(firstNode); }else { //其它節點 Node node=new Node(i); tempNode.setNextNode(node); tempNode=node; } } } } /** * 打印循環鏈表 */ public void printCycleLinkList() { Node tempNode=this.firstNode; do { System.out.println(tempNode.getNumber()); tempNode=tempNode.getNextNode(); } while (tempNode!=this.firstNode); } /** * 約瑟夫問題 * @param k 從第k我的開始報數 * @param m 數m下 */ public void Josephu(int k, int m) { //判斷k的合法性 if( !(k>=1 && k<=this.length) ) { System.out.println("傳入的k不正確"); System.exit(-1); } //定義一個臨時節點 Node tempNode=this.firstNode; //先找到第k我的 for(int i=1;i<k;i++) { tempNode=tempNode.getNextNode(); } //數m下,將數到m的節點從循環鏈表中刪除 //有兩種狀況須要考慮, //第一種:m=1的情形 //第二種:除了第一種的特殊狀況,其餘的只要找到數到m節點的的前一個節點便可,即數m-1下 //第一種情形 if(1==m) { //從當前節點依次輸出出隊序列 int len=this.length; while( (len--)>0) { System.out.println(tempNode.getNumber()); tempNode=tempNode.getNextNode(); } } //第二種情形 else { //記錄出隊的節點數 int cnt=0; do { //數(m-1)下 for(int j=1;j<(m-1);j++) { tempNode=tempNode.getNextNode(); } //出隊的節點 System.out.println(tempNode.getNextNode().getNumber()); //記錄出隊的節點數 cnt++; //刪除數到m的節點 Node tempNode2=tempNode.getNextNode().getNextNode(); tempNode.setNextNode(tempNode2); //更新tempNode,從數到m的人下一個開始報數 tempNode=tempNode2; } while (cnt!=this.length); } } }
運行結果:
9
5
2
10
8
1
4
3
7
6
======================================================================================
java移位運算符不外乎就這三種:<<(左移)、>>(帶符號右移)和>>>(無符號右移)。
一、 左移運算符
左移運算符<<使指定值的全部位都左移規定的次數。
1)它的通用格式以下所示:
value << num
num 指定要移位值value 移動的位數。
左移的規則只記住一點:丟棄最高位,0補最低位
若是移動的位數超過了該類型的最大位數,那麼編譯器會對移動的位數取模。如對int型移動33位,實際上只移動了33%32=1位。
2)運算規則
按二進制形式把全部的數字向左移動對應的位數,高位移出(捨棄),低位的空位補零。
當左移的運算數是int 類型時,每移動1位它的第31位就要被移出而且丟棄;
當左移的運算數是long 類型時,每移動1位它的第63位就要被移出而且丟棄。
當左移的運算數是byte 和short類型時,將自動把這些類型擴大爲 int 型。
3)數學意義
在數字沒有溢出的前提下,對於正數和負數,左移一位都至關於乘以2的1次方,左移n位就至關於乘以2的n次方
4)計算過程:
例如:3 <<2(3爲int型)
1)把3轉換爲二進制數字0000 0000 0000 0000 0000 0000 0000 0011,
2)把該數字高位(左側)的兩個零移出,其餘的數字都朝左平移2位,
3)在低位(右側)的兩個空位補零。則獲得的最終結果是0000 0000 0000 0000 0000 0000 0000 1100,
轉換爲十進制是12。
移動的位數超過了該類型的最大位數,
若是移進高階位(31或63位),那麼該值將變爲負值。下面的程序說明了這一點: