任意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位二进制的补码实现——队列存放的主要内容,如果未能解决你的问题,请参考以下文章

整型数据在内存中的存放形式

剑指offer11:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。(进制转换,补码反码)

原码反码补码

php基础的一点注意事项

如何理解补码

16位二进制补码有符号整数信号数据的位平面分解?