ALU是计算机CPU的核心,即 算术逻辑单元(arithmetic and logic unit)
ALU有几大功能,是计算机计算最基础的功能:
1.算术运算:包含加法、减法等
2.逻辑运算:主要是布尔运算,逻辑和、或、非、异或等
3.求补器:计算机中,二进制补码极其重要,可以求一个二进制的补码(源码取反得反码,反码加一得补码)
4.移位器:主要有 算术右移、逻辑右移、左移
5.状态标志:一个记录状态的标志。 /**
5 以下加法减法等都默认是相同长度的,如果长度不同会报错,当然,我只是懒得处理。 */ public class ALU { /**
* 返回一个整数的定长二进制字符串(补码)
*
* @param len 指定长度
*/
public String Int2Binary(int n, int len) {
// return Integer.toBinaryString(n);//注意,这个方法返回的是无符号的二进制,而且长度随参数而变的,故不可行,但是负数是可行的,负数返回32位
String s = "";
for (int i = len - 1; i >= 0; i--) {
s += ((n >> i) & 1) == 1 ? "1" : "0";
}
return s;
} /**
* 默认长度,即可以满足的最小长度
*/
public String Int2Binary(int n) {
if (n == 0) return "0";
if (n > 0) {
return "0" + Integer.toBinaryString(n);
} else {
return getNegative("0" + Integer.toBinaryString(-n));
}
} public int binary2Int(String binary) {
if(binary.charAt(0)=='0')
return Integer.valueOf(binary,2);
else return -Integer.valueOf(getNegative(binary));
} /**
* 加法器:计算两个二进制的和
*
* @param binary1
* @param binary2 必须相同长度
* @return 返回len+1长度: 最高位进位+和
*/
public String add(String binary1, String binary2) {
int[] res = new int[binary1.length()];
int carry = 0;
for (int i = binary1.length() - 1; i >= 0; i--) {
res[i] = binary1.charAt(i) - '0' + binary2.charAt(i) - '0' + carry;
if (res[i] == 2) {
carry = 1;
res[i] = 0;
} else if (res[i] == 3) {
carry = 1;
res[i] = 1;
} else carry = 0;//无进位,前面一个进位置0
}
String result = "";
for (int i = 0; i < res.length; i++) {//res中存放的是正的顺序,没有反
result += res[i];
}
return carry + result;
} public String substract(String a, String b) {//a-b = a+(-b) ,注意,多了一个最高位
return add(a, getNegative(b));
} public String get01(int n, String zeroORone) {
String res = "";
for (int i = 0; i < n; i++) {
res += zeroORone;
}
return res;
} public String shiftRightLogically(String binary) {
return "0" + binary.substring(0, binary.length() - 1);
} public String shiftLeft(String binary) {
return binary.substring(1) + "0";
} /**
* 算术右移
*/
public String shiftRight(String binary) {
return binary.charAt(0) + binary.substring(0, binary.length() - 1);
} /**
* 取补码(相反数)
*/
public String getNegative(String binary) {
return add(getComplement(binary), get01(binary.length() - 1, "0") + "1").substring(1);//add有一个最高位进位判断,去掉;
} /**
* 取反码
*/
public String getComplement(String binary) {
String res = "";
for (int i = 0; i < binary.length(); i++) {
res += (binary.charAt(i) == '1' ? "0" : "1");
}
return res;
} /**
* 整数乘法,布思算法
*/
public String multiply(String Q, String M) {
char Q0 = '0';
String A = get01(Q.length(), "0");
for (int i = 0; i < Q.length(); i++) {
String QQ0 = Q.charAt(Q.length() - 1) + "" + Q0;//不能把两个char字符放在一起,会变成加
System.out.println(QQ0);
if (QQ0.equals("10")) {
A = substract(A, M).substring(1);
} else if (QQ0.equals("01")) {
A = add(A, M).substring(1);
}
String temp = shiftRight(A + Q + Q0);
A = temp.substring(0, A.length());
Q = temp.substring(A.length(), 2 * A.length());
Q0 = temp.charAt(temp.length() - 1);
}
return A + Q;
} public String[] divide(String a, String b) { // a/b
String A = get01(a.length(), a.substring(0, 1));//附加寄存器,存放Q的扩展位,初始化为等位的被除数左扩位(1/0)
String Q = a; //被除数算术左扩为2n然后存到寄存器Q,注意A就是扩展位,扩展位不存在Q中,即AQM三个都等长
String M = b;//除数放到寄存器M
for (int i = 0; i < a.length(); i++) {
char A_sign = A.charAt(0); //A Q 左移1位
String temp = shiftLeft(A + Q);
A = temp.substring(0, a.length());
Q = temp.substring(a.length()); //判断MA是否同号
if (M.charAt(0) == A.charAt(0)) {// A M has same sign
A = substract(A, M).substring(1);
}
else {
A = add(A, M).substring(1);
} //判断A的符号变化没有;
if (A_sign == A.charAt(0) || !A.contains("1")) {//A符号没变,或者A=0(不含“1”即全0);
Q = Q.substring(0, Q.length() - 1) + "1"; //Q0=1
}
else {//A的符号变了,且A!=0
Q = Q.substring(0, Q.length() - 1) + "0"; //Q0=0
A = add(A, M).substring(1); //A =A+M 恢复;
}
}
String[] res = new String[2]; //返回0:商,1:余数
res[0] = (a.charAt(0) == b.charAt(0)) ? Q : getNegative(Q);//商在Q中,如果除数被除数不同号,则取补码
res[1] = A;//余数在A中
return res;
} public static void main(String[] args) {
ALU s = new ALU();
System.out.println(s.Int2Binary(5, 12));
System.out.println(s.add("111", "111"));
System.out.println(s.get01(12, "1"));
System.out.println(s.shiftLeft("111111"));
System.out.println(s.shiftRight("011111"));
System.out.println(s.shiftRightLogically("111111"));
System.out.println(s.getComplement("111111100011"));
System.out.println(s.getNegative("1000100"));
System.out.println(s.Int2Binary(-12));
System.out.println(s.multiply("011", "011"));//3X3=9
System.out.println(s.multiply("1001", "0101"));//-7X3=-35 System.out.println(s.divide("01111","00010")[0]+"..."+s.divide("01111","00010")[1]);//15/2=7...1
}
} output:

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

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

皇天不负有心人啊

 

ALU底层方法及计算机整数加减乘除模拟的更多相关文章

  1. jQuery 源码分析(十六) 事件系统模块 底层方法 详解

    jQuery事件系统并没有将事件监听函数直接绑定到DOM元素上,而是基于数据缓存模块来管理监听函数的,事件模块代码有点多,我把它分为了三个部分:分底层方法.实例方法和便捷方法.ready事件来讲,好理 ...

  2. Java 实现大整数加减乘除

    自己用Java实现的大整数加减乘除运算.还有可以改进的地方,有兴趣的童鞋可以加以改进.仅供参考,请勿转载! package barrytest; import java.util.ArrayList; ...

  3. c#实现生成PDF的底层方法

    在用uwp生成pdf的时候,发展此类类库有限,有的也需要钱,我最后实现pdf的底层方法生成pdf,代码如下 private async void GeneratePdf() { var file = ...

  4. Powermockito 针对方法中new 对象的模拟,以及属性中new 对象的模拟

    PowerMocker 是一个功能逆天的mock 工具. 一,Powermockito 针对方法中new 对象的模拟 // 如何才能mock掉 WeChatConfigUtil 这个类,让 weCha ...

  5. 二进制补码除法——计算机底层整数除法模拟之Java实现

    前面讲到布思算法的计算机底层模拟的时候,我们是借助于一个可以储存.表示任意N位的二进制补码的BinaryQueue实现的,现在我们模拟计算机底层整数除法还是要借助于它: BinaryQueue类代码: ...

  6. 更新 | 2019年9月计算机二级office模拟题库

    随着2019年上半年计算机二级考试的完美落幕,紧接着的便是9月份的考试了. 到目前为止,下半年9月份计算机二级考试报名开通时间在6月前后,现在也基本结束. 2019年9月(56次)全国计算机等级考试( ...

  7. Java LinkedList特有方法程序小解 && 使用LinkedList 模拟一个堆栈或者队列数据结构。

    package Collection; import java.util.LinkedList; /* LinkedList:特有的方法 addFirst()/addLast(); getFirst( ...

  8. 使用PowerMockito和Mockito进行模拟测试,包括静态方法测试,私有方法测试等,以及方法执行的坑或者模拟不成功解决

    依赖:这个很重要,不同版本用法也有点区别: <dependency> <groupId>org.mockito</groupId> <artifactId&g ...

  9. cocos2dx 通过jni调用安卓底层方法

    cocos2dx通过封装JniHelper类来调用安卓api底层函数,该文件在cocos/platform/android/jni/JniHelper.h,使用方法如下: 打开eclipse,导入co ...

随机推荐

  1. (haut oj 1261 ) 地狱飞龙 利用不定积分求值

    题目链接:http://218.28.220.249:50015/JudgeOnline/problem.php?id=1261 题目描述 最近clover迷上了皇室战争,他抽到了一种地狱飞龙,很开心 ...

  2. 父元素高度设置为min-height,子元素高度设置为100%,但实际上子元素高度你知道是多少吗?

    前言 给父元素一个min-height,子元素设置height:100%. 代码 <!DOCTYPE html> <html> <head> <title&g ...

  3. json文件格式详解

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Programming Lan ...

  4. 关于rem布局

    实际UI设计稿给过来为了在手机屏幕上显示清晰,设计稿通常为实际标准手机页面的2倍,一般为640px(以ip5的屏幕尺寸320px设计)或者750px(以ip6的屏幕尺寸为375px设计),这是前提. ...

  5. 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)

    [BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...

  6. Java【第六篇】面向对象基础

    类和对象 面向对象的概念 面向过程 核心是过程二字,过程指的是解决问题的步骤,设计一条流水线,机械式的思维方式: 面向对象 核心就是对象二字,对象就是特征与技能的结合体,利用“类”和“对象”来创建各种 ...

  7. Ubuntu18.04 安装32bit库后出现问题

    ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared ob ...

  8. jdbc增删改查进行封装

    jdbc封装 1 dao (代码分层) com.aaa.dao 存放dao相关的类型 例如 StudentDAOImpl 处理 数据库的链接 存取数据 com.aaa.servlet 存放servle ...

  9. 海亮OI学习游记

    这只是一篇纯洁的游记,这里将要记录我在海亮十天集训的生活与被虐的历史QWQ...... Day1(2.10)刚来到海亮,嗯,这的环境真的不错. 来到机房,woc这机房的配置好高啊...这里都能打守望屁 ...

  10. 1.3浅谈Spring(IOC容器的实现)

    这一节我们来讨论IOC容器到底做了什么. 还是借用之前的那段代码 ClassPathXmlApplicationContext app = new ClassPathXmlApplicationCon ...