ALU底层方法及计算机整数加减乘除模拟

ALU是计算机CPU的核心,即 算术逻辑单元(arithmetic and logic unit)
ALU有几大功能,是计算机计算最基础的功能:
1.算术运算:包含加法、减法等
2.逻辑运算:主要是布尔运算,逻辑和、或、非、异或等
3.求补器:计算机中,二进制补码极其重要,可以求一个二进制的补码(源码取反得反码,反码加一得补码)
4.移位器:主要有 算术右移、逻辑右移、左移
5.状态标志:一个记录状态的标志。

4 /** 5 以下加法减法等都默认是相同长度的,如果长度不同会报错,当然,我只是懒得处理。 20 */ 21 22 public class ALU { 23 24 /** 25 * 返回一个整数的定长二进制字符串(补码) 26 * 27 * @param len 指定长度 28 */ 29 public String Int2Binary(int n, int len) { 30 // return Integer.toBinaryString(n);//注意,这个方法返回的是无符号的二进制,而且长度随参数而变的,故不可行,但是负数是可行的,负数返回32位 31 String s = ""; 32 for (int i = len - 1; i >= 0; i--) { 33 s += ((n >> i) & 1) == 1 ? "1" : "0"; 34 } 35 return s; 36 } 37 38 /** 39 * 默认长度,即可以满足的最小长度 40 */ 41 public String Int2Binary(int n) { 42 if (n == 0) return "0"; 43 if (n > 0) { 44 return "0" + Integer.toBinaryString(n); 45 } else { 46 return getNegative("0" + Integer.toBinaryString(-n)); 47 } 48 } 49 50 public int binary2Int(String binary) { 51 if(binary.charAt(0)=='0')
return Integer.valueOf(binary,2);
else return -Integer.valueOf(getNegative(binary));
52 } 53 54 /** 55 * 加法器:计算两个二进制的和 56 * 57 * @param binary1 58 * @param binary2 必须相同长度 59 * @return 返回len+1长度: 最高位进位+和 60 */ 61 public String add(String binary1, String binary2) { 62 int[] res = new int[binary1.length()]; 63 int carry = 0; 64 for (int i = binary1.length() - 1; i >= 0; i--) { 65 res[i] = binary1.charAt(i) - '0' + binary2.charAt(i) - '0' + carry; 66 if (res[i] == 2) { 67 carry = 1; 68 res[i] = 0; 69 } else if (res[i] == 3) { 70 carry = 1; 71 res[i] = 1; 72 } else carry = 0;//无进位,前面一个进位置0 73 } 74 String result = ""; 75 for (int i = 0; i < res.length; i++) {//res中存放的是正的顺序,没有反 76 result += res[i]; 77 } 78 return carry + result; 79 } 80 81 public String substract(String a, String b) {//a-b = a+(-b) ,注意,多了一个最高位 82 return add(a, getNegative(b)); 83 } 84 85 public String get01(int n, String zeroORone) { 86 String res = ""; 87 for (int i = 0; i < n; i++) { 88 res += zeroORone; 89 } 90 return res; 91 } 92 93 public String shiftRightLogically(String binary) { 94 return "0" + binary.substring(0, binary.length() - 1); 95 } 96 97 public String shiftLeft(String binary) { 98 return binary.substring(1) + "0"; 99 } 100 101 /** 102 * 算术右移 103 */ 104 public String shiftRight(String binary) { 105 return binary.charAt(0) + binary.substring(0, binary.length() - 1); 106 } 107 108 /** 109 * 取补码(相反数) 110 */ 111 public String getNegative(String binary) { 112 return add(getComplement(binary), get01(binary.length() - 1, "0") + "1").substring(1);//add有一个最高位进位判断,去掉; 113 } 114 115 /** 116 * 取反码 117 */ 118 public String getComplement(String binary) { 119 String res = ""; 120 for (int i = 0; i < binary.length(); i++) { 121 res += (binary.charAt(i) == '1' ? "0" : "1"); 122 } 123 return res; 124 } 125 126 /** 127 * 整数乘法,布思算法 128 */ 129 public String multiply(String Q, String M) { 130 char Q0 = '0'; 131 String A = get01(Q.length(), "0"); 132 for (int i = 0; i < Q.length(); i++) { 133 String QQ0 = Q.charAt(Q.length() - 1) + "" + Q0;//不能把两个char字符放在一起,会变成加 134 System.out.println(QQ0); 135 if (QQ0.equals("10")) { 136 A = substract(A, M).substring(1); 137 } else if (QQ0.equals("01")) { 138 A = add(A, M).substring(1); 139 } 140 String temp = shiftRight(A + Q + Q0); 141 A = temp.substring(0, A.length()); 142 Q = temp.substring(A.length(), 2 * A.length()); 143 Q0 = temp.charAt(temp.length() - 1); 144 } 145 return A + Q; 146 } 147 148 public String[] divide(String a, String b) { // a/b 149 String A = get01(a.length(), a.substring(0, 1));//附加寄存器,存放Q的扩展位,初始化为等位的被除数左扩位(1/0) 150 String Q = a; //被除数算术左扩为2n然后存到寄存器Q,注意A就是扩展位,扩展位不存在Q中,即AQM三个都等长 151 String M = b;//除数放到寄存器M 152 for (int i = 0; i < a.length(); i++) { 153 char A_sign = A.charAt(0); 154 155 //A Q 左移1位 156 String temp = shiftLeft(A + Q); 157 A = temp.substring(0, a.length()); 158 Q = temp.substring(a.length()); 159 160 //判断MA是否同号 161 if (M.charAt(0) == A.charAt(0)) {// A M has same sign 162 A = substract(A, M).substring(1); 163 } 164 else { 165 A = add(A, M).substring(1); 166 } 167 168 //判断A的符号变化没有; 169 if (A_sign == A.charAt(0) || !A.contains("1")) {//A符号没变,或者A=0(不含“1”即全0); 170 Q = Q.substring(0, Q.length() - 1) + "1"; //Q0=1 171 } 172 else {//A的符号变了,且A!=0 173 Q = Q.substring(0, Q.length() - 1) + "0"; //Q0=0 174 A = add(A, M).substring(1); //A =A+M 恢复; 175 } 176 } 177 String[] res = new String[2]; //返回0:商,1:余数 178 res[0] = (a.charAt(0) == b.charAt(0)) ? Q : getNegative(Q);//商在Q中,如果除数被除数不同号,则取补码 179 res[1] = A;//余数在A中 180 return res; 181 } 182 183 public static void main(String[] args) { 184 ALU s = new ALU(); 185 System.out.println(s.Int2Binary(5, 12)); 186 System.out.println(s.add("111", "111")); 187 System.out.println(s.get01(12, "1")); 188 System.out.println(s.shiftLeft("111111")); 189 System.out.println(s.shiftRight("011111")); 190 System.out.println(s.shiftRightLogically("111111")); 191 System.out.println(s.getComplement("111111100011")); 192 System.out.println(s.getNegative("1000100")); 193 System.out.println(s.Int2Binary(-12)); 194 System.out.println(s.multiply("011", "011"));//3X3=9 195 System.out.println(s.multiply("1001", "0101"));//-7X3=-35 196 197 System.out.println(s.divide("01111","00010")[0]+"..."+s.divide("01111","00010")[1]);//15/2=7...1 198 } 199 }

output:

000000000101
1110
111111111111
111110
001111
011111
000000011100
0111100
10100
10
11
01
001001
10
01
00
10
11011101
00111...00001

 

 

 

 

妈的,考完上机,刚才考得差不多都是上面这些内容,只有一个让人看不太懂的加法器,不过还好可以推理出来。

皇天不负有心人啊

 

 

posted @ 2018-12-20 11:39  Edwin_Xu  阅读(1879)  评论(0编辑  收藏  举报