1. 程式人生 > >任意N位二進制的補碼實現——隊列存放

任意N位二進制的補碼實現——隊列存放

private 數組移位 字符 自己 組織 int() 學習計算機 his site

正在學習計算機組織與結構,為了寫一些底層的算術操作模擬,比如一個二進制補碼數的加減乘除,發現這很麻煩,因為不管是什麽語言,都只提供了8位、32、64位等部分位數的補碼形式,那麽怎麽實現任意任意位的補碼整數呢,由於我們不能利用現有的如Byte、Integer類,所以我們需要一個容器來存儲我們自己編寫的任意位的補碼整數。

數組可以實現,但是數組移位可能比較麻煩,比如如果要實現二進制數的算術右移,必須要移動大部分元素。可以使用鏈表,雖然獲取二進制數某一位的值比較麻煩,但是還是比數組可能更好一點。於是,我們采用基於鏈表的隊列。

  2 
  3 /**
  4  * Created by XuTao on 2018/12/1 15:26
5 * 作用:存儲一個n位二進制數,並實現左右移動,取反等操作(補碼形式) 6 */ 7 public class BinaryQueue { 8 private int size; 9 private Node head = new Node(-1); //head只是一個頭節點,後面才是二進制數,從左到右,從高位到低位的 10 public BinaryQueue(int size){ //創建一個size大小的二進制,他被初始化為00...00 11 this.size = size; 12 Node temp =head;
13 for (int i =0;i<size;i++){ 14 temp .next = new Node(0); 15 temp = temp.next; 16 } 17 } 18 public BinaryQueue(String binary){ //以二進制數創建 19 this.size = binary.length(); 20 Node temp =head; 21 for (int i =0;i<size;i++){
22 temp .next = new Node(binary.charAt(i)-‘0‘); 23 temp = temp.next; 24 } 25 } 26 public void shiftLeft(){ //左移 27 head.next = head.next.next; 28 Node temp = head.next; 29 for (int i=0;i<size;i++){ 30 if (i==size-2) { 31 temp.next = new Node(0); 32 break; 33 } 34 temp = temp.next; 35 } 36 } 37 public void shiftRight(){//右移 38 Node first = head.next; 39 head.next = new Node(0); 40 head.next.next=first; 41 42 Node temp = head; 43 for (int i =0;i<size;i++){ 44 temp = temp.next; 45 } 46 temp.next =null; 47 } 48 public void shiftRightArithmetically(){ //算術右移,符號擴展 49 Node first = head.next; 50 head.next = new Node(first.value); 51 head.next.next=first; 52 53 Node temp = head; 54 for (int i =0;i<size;i++){ 55 temp = temp.next; 56 } 57 temp.next =null; 58 } 59 60 public void reverse(){ 61 Node temp = head.next; 62 for (int i =0;i<size;i++){ 63 temp.value = 1-temp.value; //取反,是1,1-1=0;是0:1-0=1 64 temp = temp.next; 65 } 66 } 67 68 public BinaryQueue add(BinaryQueue bq){ 69 //將兩個隊列中的二進制放入數組中,如果長度不同則需要將短的進行算術擴展, 70 int len = bq.size>size?bq.size:size; 71 int [] arr_bq = new int[len]; 72 int [] arr_this = new int[len]; 73 if (bq.size>size){//bq 長,this擴展 74 String s = bq.getStr(); 75 for (int i =0;i<len;i++){ 76 arr_bq[i] = s.charAt(i)-‘0‘; 77 } 78 String s_this = getStr(); 79 for (int j =0 ;j<len;j++){ 80 if (j<len-size){ 81 arr_this[j] = head.next.value; 82 } 83 else { 84 arr_this[j]= s_this.charAt(j-(len-size))-‘0‘; 85 } 86 } 87 } 88 else { //this 長 ,bq擴展 89 String s = this.getStr(); 90 for (int i =0;i<len;i++){ 91 arr_this[i] = s.charAt(i)-‘0‘; 92 } 93 String s_bq = bq.getStr(); 94 for (int j =0 ;j<len;j++){ 95 if (j<len-size){ 96 arr_bq[j] = bq.head.next.value; 97 } 98 else { 99 arr_bq[j]= s_bq.charAt(j-(len-size))-‘0‘; 100 } 101 } 102 } 103 104 //相加 105 int []res = new int[len]; 106 int carry = 0; //上一次加的進位 107 for (int i = len-1;i>=0;i--){ 108 res[i] = arr_bq[i]+arr_this[i]+carry; 109 if (res[i]==2){//進位1,本位0 110 res[i]=0; 111 carry =1; 112 } 113 else if (res[i]==3){//進位1,本位1 114 res[i]=1; 115 carry =1; 116 } 117 else carry = 0; 118 } 119 String str = ""; 120 for (int i =0;i<len;i++){ 121 str+=res[i]; 122 } 123 return new BinaryQueue(str); 124 } 125 126 public BinaryQueue getOppositeNumber(){//取相反數,就是取反加一 127 String s = ""; 128 for (int i=0;i<size-1;i++){ 129 s+="0"; 130 } 131 s+="1"; 132 reverse();//取反 133 return add(new BinaryQueue(s));//加一 134 } 135 136 public int getInt(){ //獲取二進制所代表的補碼整數 137 if (head.next.value==1){ 138 return -Integer.valueOf(getOppositeNumber().getStr(),2); 139 } 140 return Integer.valueOf(getStr(),2); 141 } 142 143 144 public String getStr(){//獲取二進制的字符串形式 145 String str =""; 146 Node temp = head.next; 147 while (temp!=null){ 148 str+=temp.value; 149 temp =temp.next; 150 } 151 return str; 152 } 153 154 public static void main(String[] args) { 155 BinaryQueue bq = new BinaryQueue("1100000011"); 156 BinaryQueue bq2 = new BinaryQueue("0000000000"); 157 // System.out.println(bq.add(bq2).getStr()); 158 // System.out.println(bq2.getOppositeNumber().getStr()); 159 System.out.println(bq.getInt()); 160 System.out.println(bq2.getInt()); 161 } 162 163 //節點類 164 class Node{ 165 int value; 166 Node next; 167 Node (int value){ 168 this.value = value; 169 } 170 } 171 }

有了我們自己定義的任意N位二進制補碼數後,我們就可能進行一些其他的操作了,比如布思算法、整數除法等。

任意N位二進制的補碼實現——隊列存放