任意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位二进制补码数后,我们就可能进行一些其他的操作了,比如布思算法、整数除法等。

原文地址:https://www.cnblogs.com/XT-xutao/p/10050518.html

时间: 2024-10-19 21:22:32

任意N位二进制的补码实现——队列存放的相关文章

二进制、补码和移位

在计算机中,有符号数是以补码表示的. 1. 原码 原码的第一位是符号位,其余位表示值.比如8位二进制: [+1]原=0000 0001 [- 1]原=1000 0001 2. 补码 正数的补码就是它本身,负数的补码是在原码的基础上,符号位不变,其余各位取反+1. [+1]补=0000 0001 [- 1]补=1111 1111 补码转换为原码的规则依然是符号位不变,其余各位取反+1. 3. 移位 有符号数移位时,都是按照补码的形式移位: 右移:最右边的一位舍弃,最左边补符号位. 左移:最左边的一

如何用adc的芯片来强化学习——二进制的补码

部分参考了https://www.cnblogs.com/songdechiu/p/5397070.html 一.补码的优点 1.可以将减法转化为加法,在计算机中只保留加法 2.将符号位参与运算 二.如何实现? 我们先以钟表为例子,假设现在的标准时间为4点整,而有一个钟的时间为7点整.我们可以将时针逆时针旋转3格,或者将时针顺时针旋转9格,如图. 7-3=7+9=4 mod(12) 上述式子为一个同余式,同余式的标准定义为 a ≡b (mod n) 即同余式两边的数值,对n进行取余后的数值相等.

8086汇编——作业总结1——ASCII码0~9转为8位二进制输出

思路: 将ASCII码转为数字->将数字的8位二进制一位一位转为ASCII输出 MOV AH,01H INT 21H  ;输入的ASCII存入AL ASCII码转为数字:SUB AL,30H 数字一位一位转为ASCII码:(加个循环) MOV DL,0 SAL AL,1 ;高位先输出,算数左移,高位移进CF ADC DL,30H ;全加,加CF位,结果‘0’或‘1’,即30H或31H,存入DL ;ASCII码7位 MOV AH,02H :输出的值存入DX INT 21H

(一一五)利用NSKeyedArchiver实现任意对象转为二进制

[应用背景] 在数据库中存储数据时,如果对象过于复杂,又不必要创建复杂的表,可以直接把整个对象转化为二进制存入数据库字段,然后取出后再还原即可. [实现方法] 在PHP中,使用序列化和反序列化可以实现这样的功能. 在OC中,使用NSKeyedArchiver和NSKedUnarchiver可以实现对象转二进制和二进制转对象,要实现转化,必须遵循NSCoding协议,并且实现encodeWithCoder方法用来转化数据为二进制,实现initWithCoder实现二进制数据还原成类对象,OC的常见

将32位MD5摘要串转换为128位二进制字符串

将32为MD5摘要串转换为128位二进制字符串: 1 /// <summary> 2 /// 将字符串转成二进制 3 /// </summary> 4 /// <param name="s">源字符串</param> 5 /// <returns>二进制串</returns> 6 internal static string ConvertStringToBinary(string s) 7 { 8 if (s.I

用4位二进制同步可逆计数器74LS191构成“12翻1”小时计数器

用4位二进制同步可逆计数器74LS191构成“12翻1”小时计数器 原文地址:https://www.cnblogs.com/chunk998/p/11824499.html

任意类型和二进制互转工具类

1 public class SerializeUtil { 2 /** 3 * 任意类型和二进制互转 4 * @param obj 5 * @return 6 */ 7 public static byte [] serialize(Object obj){ 8 ObjectOutputStream obi=null; 9 ByteArrayOutputStream bai=null; 10 try { 11 bai=new ByteArrayOutputStream(); 12 obi=ne

C语言 打印变量在内存中的二进制形式(补码)

void show_bits(int n) { int i = 0; for(i=0;i<32;i++) printf("%d",(n&(1u<<(31-i)))!=0?1:0); putchar('\n'); } 整数的原码 = 整数的补码 负数的补码:(原码)->(反码)->(反码+1) 负数的原码:(补码-1)->最高位符号位别动其余均转反码

关于非二进制的补码与反码

关于名称 补码应该叫Diminished Radix Complement,而反码则是Radix Complement.最常见的所谓1's complement与2's complement其实是是相对于2进制而言. 也就是说,对于2进制,Diminished Radix Complement可称1's complement,Radix Complement可称2's complement.那么对于8进制,Diminished Radix Complement应称作7's complement而