C + + implementation of addition and subtraction of arbitrary binary long integers

Posted by superhoops on Mon, 20 Sep 2021 02:13:24 +0200

The first small project after learning C + + refers to some good codes on the Internet. A and a in any binary system are regarded as a number, so the highest 36 binary system, but it is also easy to change this small place to 10 + 26 + 26 binary system.

Firstly, the addition and subtraction of decimal long integers are realized. Since they are long integers, it is finally decided that string string can be used as the format for storing long integers

addition

string jia(string a, string b) {
    string str1 = a;
    string str2 = b;
    int len = max(str1.size(), str2.size());
    string result;
    reverse(str1.begin(), str1.end());
    reverse(str2.begin(), str2.end());
    int jinwei = 0;
    for (int i = 0; i < len; ++i) {
        int str1_i = i < str1.size() ? str1[i] - '0' : 0;
        int str2_i = i < str2.size() ? str2[i] - '0' : 0;
        int val = (str1_i + str2_i + jinwei) % 10;
        jinwei = (str1_i + str2_i + jinwei) / 10;
        result.insert(result.begin(), val + '0');
    }
    if (jinwei == 1) result.insert(result.begin(), '1');
    if (result[0] == '0') result[0] = ' ';
    return result;
} 

subtraction

string jian(string a,string b)
{
    string s1 = a;
    string s2 = b;
    if(s1==s2) {
		return "0";
	}
	string s3;
	bool flag=false;
	if(s1.length()<s2.length() || (s1.length()==s2.length() && s1<s2)) {
		std::string s=s1;
		s1=s2;
		s2=s;
		flag=true;
	} else {
		s3="";
	}
	while(s2.length()<s1.length()) {
		s2="0" + s2;
	}
	int k,down=0;
	for(int i=s1.length()-1; i>=0; i--) {
		k=s1[i] -s2[i] +down;
		if(k<0) {
			down=-1;
			k=10+k;
		} else {
			down=0;
		}
		s3=(char)('0' + k) + s3;
	}
	k=0;
	while(s3[k]=='0' ) {
		k++;
	}
	s3=s3.substr(k);
	if(flag)
		s3="-"+s3;
	return s3;
 }

Then, the input string is converted into decimal system according to the input decimal system. The string multiplication operation is constructed by using the addition loop, and the estimation efficiency will not be very high:

​
string otherToDec(int a, string str)
{
    int tmp = 0;            
    string c = to_string(1);
	string c_ = to_string(1);         
    string result(1, '0');
    for (int i = str.size() - 1; i >= 0; i--)
    {
        int x = 0;
        bool fling = true;
        bool ori = true;
		string tmp_(1, '0');         
        if (str[i] >= 'A' && str[i] <= 'Z'){
            x = str[i] - 'A' + 10;
            ori = false;
        }         
        else if (str[i] >= 'a' && str[i] <= 'z'){
            x = str[i] - 'a' + 10;
            ori = false;
        }              
        else if (str[i] >= '1' && str[i] <= '9'){
            x = str[i] - '0';
            ori = false;
        }   
        else if (str[i] == '0' && ori) {
            fling = false;
            if(i == str.size() - 1) ;
            else {    
                result.insert(result.begin(), '0');
            }
        }
        if (fling) {
            for (int j = 0 ; j < x; j++) tmp_ = jia(tmp_, c);  //tmp += x*c 
            result = jia(result, tmp_);     
        }
		for (int k = 0 ; k < a-1; k++) c_ = jia(c_,c);    //c =c*a 
		c = c_;  
    }       
    return result;
}

​

Then, after the addition and subtraction of the string, the decimal string after the operation is converted to any base. Because the remainder method is used here, a string division is introduced

string chu(string a,string b)
{
	if(b.length()==1&&b.at(0)==48) return "error";
	long int i,j;
	string c1,c2,d,e;
	if(judge(a,b)==0) return "1";
	if(judge(a,b)==-1)
	{
		return "0";
	}
	c1=dezero(a);
	c2=dezero(b);
	d="";
	e="";
	for(i=0;i<c1.length();i++)
	{
		j=0;
		d=d+c1.at(i);
		d=dezero(d);
		while(judge(d,b)>=0)
		{
			d=jian(d,b);
			d=dezero(d);
			j++;
		}
		e=e+"0";
		e.at(i)=j;
	}
	for(i=0;i<e.length();i++)
	{
		if(e.at(i)>=10) e.at(i)+=87;
		if(e.at(i)<10) e.at(i)+=48;
	}
	e=dezero(e);
	return e;
}

//The required judge and dezero functions are as follows
string dezero(string a)
{
	long int i;
	for(i=0;i<a.length();i++)
	{
		if(a.at(i)>48) break;
	}
	if(i==a.length()) return "0";
	a.erase(0,i);
	return a;
}
int judge(string a,string b)
{
	if(a.length()>b.length()) return 1;
	if(a.length()<b.length()) return -1;
	long int i;
	for(i=0;i<a.length();i++)
	{
		if(a.at(i)>b.at(i)) return 1;
		if(a.at(i)<b.at(i)) return -1;
	}
	return 0;
}

The specific code of binary conversion is as follows. The large string else if is written foolishly, but each element in the string is of char * type. For the results of 12 and 13, it is not good to directly convert them to char (when writing this, I thought it might be written in the idea of converting to decimal), and then I felt that I could consider saving them as char [] to write, but my brain was stupid to do so first, There must be a lot of room for optimization in the code.

string decToOther(string str, int b)
{
    int i = 0;
    string re_;
	//char s[1000] = {'0'};
    while (str != "0")            
    {
        string temp;
        string yushu;
        temp = chu(str, to_string(b)); //temp = str/b
		string tmp_ = temp;
        for(int i = 0; i<(b-1); i++) temp = jia(temp,tmp_) ;//temp = (temp)*b
        yushu = jian(str, temp); //yushu = str-tmp
		if (tmp_ == "0"){
			yushu = str;		
		}
		//char *yushu_=(char*)yushu.data();
		if(yushu == "1" || yushu == "2"|| yushu == "3"|| yushu == "4"|| yushu == "5"
		|| yushu == "6"|| yushu == "7"|| yushu == "8"|| yushu == "9" || yushu == "0" )  re_ = yushu + re_;
		else if (yushu == "10") re_ = "A" + re_;else if (yushu == "11") re_ = "B" + re_;
		else if (yushu == "12") re_ = "C" + re_;else if (yushu == "13") re_ = "D" + re_;
		else if (yushu == "14") re_ = "E" + re_;else if (yushu == "15") re_ = "F" + re_;
		else if (yushu == "16") re_ = "G" + re_;else if (yushu == "17") re_ = "H" + re_;
		else if (yushu == "18") re_ = "I" + re_;else if (yushu == "19") re_ = "J" + re_;
		else if (yushu == "20") re_ = "K" + re_;else if (yushu == "21") re_ = "L" + re_;
		else if (yushu == "22") re_ = "M" + re_;else if (yushu == "23") re_ = "N" + re_;
		else if (yushu == "24") re_ = "O" + re_;else if (yushu == "25") re_ = "P" + re_;
		else if (yushu == "26") re_ = "Q" + re_;else if (yushu == "27") re_ = "R" + re_;
		else if (yushu == "28") re_ = "S" + re_;else if (yushu == "29") re_ = "T" + re_;
		else if (yushu == "30") re_ = "U" + re_;else if (yushu == "31") re_ = "V" + re_;
		else if (yushu == "32") re_ = "W" + re_;else if (yushu == "33") re_ = "X" + re_;
		else if (yushu == "34") re_ = "Y" + re_;else if (yushu == "35") re_ = "Z" + re_; 
        str = tmp_;
        i++;
    }
    
    return re_;
}

Since the operation process may be preceded by a sign or with 0 at the beginning, the following code is the specific operation process, in which jinzhi_in and jinzhi_out is the input base and the output base respectively:

string yunsuan(string a, string b ,int jinzhi_in, int jinzhi_out)
{
    string re_;
    bool eq = false;
    bool ng = false;
    if (a[0] == '-'){
        a.erase(0,1);
        //const char* p = a.data();
        a = otherToDec(jinzhi_in, a, 10);
        if (b[0] == '-'){
            b.erase(0, 1);
            b = otherToDec(jinzhi_in, b, 10);
            re_ = jia(a, b);
            re_.insert(re_.begin(), '-');
        }
        else if (b[0] == '+'){
            b.erase(0, 1);
            b = otherToDec(jinzhi_in, b, 10);
            if (a == b) eq = true;
            re_ = jian(b, a);
        }
        else {
            b = otherToDec(jinzhi_in, b, 10);
            re_ = jian(b, a);
        }      
    }
    else if (a[0] == '+'){
        a.erase(0, 1);
        a = otherToDec(jinzhi_in, a, 10);
        if (b[0] == '-'){
            b.erase(0, 1);
            b = otherToDec(jinzhi_in, b, 10);
            re_ = jian(a, b);
            if (a == b) eq = true;
        }
        else if (b[0] == '+'){
            b.erase(0, 1);
            b = otherToDec(jinzhi_in, b, 10);
            re_ = jia(a, b);
        }
        else{
            b = otherToDec(jinzhi_in, b, 10);
            re_ = jia(a, b);
        }
    }
    else{
        a = otherToDec(jinzhi_in, a, 10);
        if (b[0] == '-'){
            b.erase(0, 1);
            b = otherToDec(jinzhi_in, b, 10);
            re_ = jian(a, b);
        }
        else if (b[0] == '+'){
            b.erase(0, 1);
            b = otherToDec(jinzhi_in, b, 10);
            re_ = jia(a, b);
        }
        else {
            b = otherToDec(jinzhi_in, b, 10);
            re_ = jia(a, b);
        }
    }
    if (re_[0] == '-') {
        re_.erase(0,1);
        ng = true;
    }
    re_ = decToOther(re_, jinzhi_out);
    if (eq) re_ = '0';
    if (ng) re_.insert(re_.begin(), '-');
    return re_;
}

Finally, the main function of int main() uses the method of file reading

int main()
{
    ifstream fp;
    string a;  //First long integer
    string b;  //Second long integer
    string c;  //Operation result
    int jinzhi_in;  //Input base
    int jinzhi_out; //Output hexadecimal
    fp.open("./data.txt",std::ios::in);
    if(!fp.is_open()){
       cout<<"Failed to open file!!\n"<<endl;;
       return 1;     
    }
    fp>>jinzhi_in>>jinzhi_out>>a>>b>>c;
    while ( jinzhi_in < 2 || jinzhi_in > 36 || jinzhi_out < 2 || jinzhi_out > 36)//Verify that the input is correct
    {
        cout << "Please enter one in 2-36 Integer between" << endl;
        return 1;
    }
    while (panduan(a, jinzhi_in) || panduan(b, jinzhi_in))//Verify that the input is correct
    {   
        cout << "The input string does not match the base value!!" << endl;
        return 1;
    }
    string re_ = yunsuan(a,b,jinzhi_in,jinzhi_out);
    cout << re_ << endl;
    if (re_ == c)  cout << "right" << endl; 
    //system("pause");
    return 0;
}

Oh, I also forgot a panduan function to judge whether the input is correct. The code is as follows

bool panduan(string x, int y)
{
    int len = x.size();
    for (int i = 0; i < len; ++i)
    {
        int temp = (int)x[i];
        int thre_1 = y - 10 + 97;  //Lowercase letters
        int thre_2 = y - 10 + 65;  //capital
        if (i == 0){
            if (x[i] == '+' || x[i] == '-' || (temp >= 48 && temp <= 57)) continue;
            else if (y > 10){  
                if ((temp >= 48 && temp <= 57) || (temp >= 97 && temp <= thre_1) || (temp >= 65 && temp <= thre_2)) continue;
                else ;
                }
            else {
                return 1;
                break;
            }
        }
        else{
            if (y <= 10) {
                if (temp >= 48 && temp <= 57) continue;
                else {
                    return 1;
                    break;
                }
            }
            else if (y > 10) {
                if (temp >= 48 && temp <= 57) continue;
                else if (temp >= 97 && temp <= thre_1) continue;
                else if (temp >= 65 && temp <= thre_2) continue;
                else {
                    return 1;
                    break;
                }
            }
        }
        
    }
    return 0;
}

Topics: C++ Algorithm