任意N位二进制的补码实现——队列存放
Posted xt-xutao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了任意N位二进制的补码实现——队列存放相关的知识,希望对你有一定的参考价值。
正在学习计算机组织与结构,为了写一些底层的算术操作模拟,比如一个二进制补码数的加减乘除,发现这很麻烦,因为不管是什么语言,都只提供了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位二进制的补码实现——队列存放的主要内容,如果未能解决你的问题,请参考以下文章