Java implements 64-bit fixed-point integer complement addition and subtraction


There are already many articles related to Java, and many seniors have also shared many programming experiences and techniques. This article is based on my thoughts while learning Java. The code implements the process of adding and subtracting fixed-point integers in groups. I hope it will be helpful to readers.
This topic requires writing a program:
① Input: two long integers
② Output: sum and difference of two numbers
③ Using Java, the calculation process should simulate the hand calculation process of 64-bit fixed-point integer addition and subtraction, and use character arrays to store binary machine numbers.

Technical points

True value converted to 64-bit complement

To get the complement code, you must first convert the decimal value of the true value into the 64-bit original code, thereby obtaining the 64-bit complement code, and finally obtain the 64-bit complement code.
Therefore, the following functional modules are included:

  • Convert decimal to binary: Use the remainder method of dividing by 2.
result[i] = num % 2 == 0 ? '0' : '1';
num /= 2;
  • Binary completion is the 64-bit original code: the sign bit is filled with 1 and 0 according to the sign, and the empty bit is filled with 0.
  • Invert each bit of the 64-bit original code to get the 64-bit complement code: use a loop and logical negation.
result[i] = result[i] == '1' ? '0' : '1';
  • Add 1 to the last bit of the 64-bit complement code to get the 64-bit complement: Develop a full adder to add 1 to the last bit.
temp = FullAdder.getS(result[i], '0', c);
c = FullAdder.getC(result[i], '0', c);
result[i] = temp;

Binary machine code to hexadecimal

The 64-bit binary machine code can be said to be quite lengthy and inconvenient for developers to debug. Therefore, it is necessary to develop a method to output the binary machine code on the terminal in hexadecimal form.
According to the method of manually converting binary to hexadecimal, divide every four digits into one group, calculate a hexadecimal number for each group, and accumulate the strings.

final static char[] hexCharacters = "0123456789ABCDEF".toCharArray();
private static String BtoH(char[] chars) {
    
    
        String result = "0x";
        for (int i = 0; i <= 15; i++) {
    
    
            int tag = 0;
            for (int j = 0; j <= 3; j++) {
    
    
                tag += chars[4 * i + j] == '1' ? Math.pow(2, 3 - j) : 0;
            }
            result += hexCharacters[tag];
        }
        return result;
    }

Implementation of a one-bit full adder

In the principle of computer composition, we learned the functions and logical expressions of the one-bit full adder 74LS181:
S i = A i ⊕ B i ⊕ C i C i + 1 = A i B i + ( A i + B i ) C i S_i=A_i\oplus B_i \oplus C_i \\C_{i+1}=A_iB_i+(A_i+B_i)C_i Si=AiBiCiCi+1=AiBi+(Ai+Bi)Ci
因此必到到 S i , C i + 1 S_i, C_{i+1} SiCi+1, you only need to write two methods respectively according to two logical expressions.

S i S_i Si

return x=='1'^y=='1'^c=='1'?'1':'0';

C i + 1 C_{i+1} Ci+1

return (x=='1'&&y=='1')||((x=='1'||y=='1')&&c=='1')?'1':'0';

Modulo four's complement addition

The double sign bit of modulo four's complement addition makes overflow judgment simple.
After the calculation is completed, if the double sign bits are
11 or 00: no overflow
10: underflow Since a character array of size 64 is used, to implement dual sign bits, you only need to declare an additional syn variable as the highest sign bit. Can. When judging overflow, you only need to compare syn with the highest bit of the character array and judge.
01: Overflow

char syn = FullAdder.getS(xChar[0], yChar[0], c);
        //00或11
        if (result[0] == syn) {
    
    
            System.out.println("结果未溢出\n");
        } 
        //10
        else if (syn == '1')
            System.out.println("结果下溢出\n");
        //01
        else
            System.out.println("结果上溢出\n");

64-bit complement conversion to decimal truth value

The result of complement addition is a complement. The complement must be converted into the original code first, and then the original code is converted into a true value.
Converting the complement code to the original code has been implemented. You only need to apply the method of converting the original code to the complement code without changing a word.
To convert the original code to the true value, you only need to multiply the weight by bits and then accumulate.

num += result[i] == '1' ? Math.pow(2, 63 - i) : 0;

Code

Implementation of a one-bit full adder

FullAdder.java

public class FullAdder {
    
    
    public static char getS(char x,char y,char c){
    
    
        return x=='1'^y=='1'^c=='1'?'1':'0';
    }//得到Si
    public static char getS(char x,char y){
    
    
        return getS(x,y,'0');
    }
    public static char getC(char x,char y,char c){
    
    
        return (x=='1'&&y=='1')||((x=='1'||y=='1')&&c=='1')?'1':'0';
    }//得到进位位Ci
    public static char getC(char x,char y){
    
    
        return getC(x,y,'0');
    }
}

Implementation of conversion and calculation functions

public class BinaryComputing {
    
    
    final static char[] hexCharacters = "0123456789ABCDEF".toCharArray();
    //二进制转十六进制
    private static String BtoH(char[] chars) {
    
    
        String result = "0x";
        for (int i = 0; i <= 15; i++) {
    
    
            int tag = 0;
            for (int j = 0; j <= 3; j++) {
    
    
                tag += chars[4 * i + j] == '1' ? Math.pow(2, 3 - j) : 0;
            }
            result += hexCharacters[tag];
        }
        return result;
    }
	//输入十进制真值得到原码的二进制形式
    private static char[] getTrueFormBinary(long num) {
    
    
        char[] result = new char[64];
        //符号位
        result[0] = num >= 0 ? '0' : '1';
        if (num < 0) num = -num;
        //除2取余
        for (int i = 63; i > 0; i--) {
    
    
            result[i] = num % 2 == 0 ? '0' : '1';
            num /= 2;
        }
        return result;
    }
	//输入十进制真值得到补码的二进制形式
    private static char[] getCompletionFormBinary(long num) {
    
    
        char[] result = getTrueFormBinary(num);
        return getCompletionFormBinary(result);
    }
	//输入十进制真值得到补码的二进制形式
    private static char[] getCompletionFormBinary(char[] result) {
    
    
    	//原码为正数时,无需操作
        if (result[0] == '0') return result;
        //按位取反得到反码
        for (int i = 1; i < 64; i++) {
    
    
            result[i] = result[i] == '1' ? '0' : '1';
        }
        //使用一位全加器进行末位加1操作
        char c = '1', temp;
        for (int i = 63; i > 0; i--) {
    
    
            temp = FullAdder.getS(result[i], '0', c);
            c = FullAdder.getC(result[i], '0', c);
            result[i] = temp;
            if (c == '0') break;
        }
        return result;
    }
	//输入二进制原码得到十进制真值
    public static long trueFormToNum(char[] result) {
    
    
        long num = 0;
        for (int i = 1; i < 64; i++) {
    
    
            num += result[i] == '1' ? Math.pow(2, 63 - i) : 0;
        }
        return result[0] == '0' ? num : -num;
    }
	//输入二进制补码得到十进制真值
    public static long completionFormToNum(char[] result) {
    
    
        result = getCompletionFormBinary(result);
        return trueFormToNum(result);
    }
	//输入十进制真值得到十六进制原码
    public static String getTrueFormHex(long num) {
    
    
        return BtoH(getTrueFormBinary(num));
    }
	//输入十进制真值得到十六进制补码
    public static String getCompletionFormHex(long num) {
    
    
        return BtoH(getCompletionFormBinary(num));
    }
	//加法器
    public static long adder(long x, long y) {
    
    
        char[] xChar = getCompletionFormBinary(x), yChar = getCompletionFormBinary(y);
        char[] result = new char[64];
        System.out.println("转换得到x补码为" + BtoH(xChar) + "\n");
        System.out.println("转换得到y补码为" + BtoH(yChar) + "\n");
        char c = '0';
        for (int i = 63; i >= 0; i--) {
    
    
        	//利用一位全加器进行串行加法计算
            result[i] = FullAdder.getS(xChar[i], yChar[i], c);
            c = FullAdder.getC(xChar[i], yChar[i], c);
        }
        //声明syn变量作为拓展符号位
        char syn = FullAdder.getS(xChar[0], yChar[0], c);
        //判断溢出情况
        if (result[0] == syn) {
    
    
            System.out.println("结果未溢出\n");
        }
        else if (syn == '1')
            System.out.println("结果下溢出\n");
        else
            System.out.println("结果上溢出\n");
        System.out.println("结果的补码(16进制)为:" + BtoH(result) + "\n");
        //补码转真值
        return completionFormToNum(result);
    }
    //减法器:x-y=x+(-y)
    public static long subtractor(long x,long y){
    
    
        return adder(x,-y);
    }
}

test sample

Test1.java

import java.util.Scanner;

public class Test1 {
    
    
    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        String scIn;
        long a, b;
            System.out.println("请输入x、y:\n");
            a = sc.nextLong();
            b = sc.nextLong();
            System.out.println("\nx+y:\n");
            System.out.println("结果为"+BinaryComputing.adder(a, b)+"\n");
            System.out.println("\nx-y:\n");
            System.out.println("结果为"+BinaryComputing.subtractor(a, b)+"\n");
    }
}

enter

-23 59

output

请输入x、y:

-23 59

x+y:

转换得到x补码为0xFFFFFFFFFFFFFFE9

转换得到y补码为0x000000000000003B

结果未溢出

结果的补码(16进制)为:0x0000000000000024

结果为36


x-y:

转换得到x补码为0xFFFFFFFFFFFFFFE9

转换得到y补码为0xFFFFFFFFFFFFFFC5

结果未溢出

结果的补码(16进制)为:0xFFFFFFFFFFFFFFAE

结果为-82

Hope it helps readers

Guess you like

Origin blog.csdn.net/BuleFACE_Zhang/article/details/128631720