国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++中如何處理超長的數(shù)字(long long類型的整數(shù)都無法存儲(chǔ)的)

這篇具有很好參考價(jià)值的文章主要介紹了C++中如何處理超長的數(shù)字(long long類型的整數(shù)都無法存儲(chǔ)的)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

C++中如何處理超長的數(shù)字(long long類型的整數(shù)都無法存儲(chǔ)的)

在 C++中,如果數(shù)字超出了 long long 類型的范圍,可以考慮使用字符串或第三方庫(如 Boost.Multiprecision)來表示和處理超長數(shù)字。要使用第三方庫需要下載并安裝所需的第三方庫,在此就不介紹了。

在此介紹使用字符串表示和處理超長數(shù)字。本文將介紹使用C++字符串實(shí)現(xiàn)超長的數(shù)字加法、減法、乘法和除法運(yùn)算。

1.判斷一個(gè)非負(fù)的超大數(shù)是奇數(shù)還是偶數(shù),源碼如下:

#include <iostream>  
#include <string>
using namespace std;  

int main() {  
//string s = "123456789123456789123456789";
cout << "請(qǐng)輸入一個(gè)正整數(shù):" << endl;
    cin >> s;
    // s.size()是字符串的長度,即由多少字符組成的, 字符串的最后一位字符即s[s.size() - 1]
    char c = s[s.size() - 1];
    cout << "最后一位數(shù)字是" << c << endl;  
    // 將一個(gè)整數(shù)數(shù)字字符變成整數(shù),我們只需要將它減字符'0'
    int i = c - '0';
    if (i % 2 == 0) {
        cout << s << "是偶數(shù)";
    } else {
        cout << s << "是奇數(shù)";
    }
        
    return 0;  
}

2.判斷兩個(gè)超大正整數(shù)的大小

#include <iostream>  
#include <string>  
  
using namespace std;  
  
bool Lower(string str1, string str2){     
    //長度長的一定大(這里假設(shè)除了0以外,都沒有前導(dǎo)0),長度相等則字典序小的數(shù)字更小
    return str1.size()<str2.size()||(str1.size()==str2.size()&&str1<str2);
} 
  
int main() {  
    cout << "請(qǐng)輸入兩個(gè)超大正整數(shù):" << endl;
	string a, b; 
	cin >> a >> b; 
    if (Lower(a, b)){
    	cout << a << "小于" << b << endl;
	}
	else{
		cout << a << "大于" << b << endl;
	}
	  
    return 0;  
}

下面分別介紹加法、減法、乘法和除法運(yùn)算的實(shí)現(xiàn)方法。特別說明,加減運(yùn)算僅限非負(fù)整數(shù)的運(yùn)算,因?yàn)樨?fù)數(shù)的加減運(yùn)算可以等價(jià)為某種形式的加法或者減法運(yùn)算,故不做考慮;乘除運(yùn)算只考慮大整數(shù)運(yùn)算,不考慮小數(shù)的計(jì)算;除法只考慮大整數(shù)運(yùn)算,計(jì)算結(jié)果精確到6位小數(shù)(6位小數(shù)后直接舍去)。

參考https://blog.songjiahao.com/archives/382

3. 非負(fù)大整數(shù)的加法

大數(shù)加法的實(shí)現(xiàn),模仿了我們列豎式的計(jì)算方法,從個(gè)位開始,一位一位的相加,每次考慮進(jìn)位即可。由于讀入的字符串0號(hào)位置為最高位,所以我們采用逆序的辦法訪問字符串,然后每位計(jì)算即可。同樣的,因?yàn)橛?jì)算時(shí)候得到的每一位都是逆序的,最后的結(jié)果要進(jìn)行逆置。

加法,可能導(dǎo)致最終位數(shù)多一位(最高位的進(jìn)位),所以要記得處理。

最后,我們來考慮一些特殊情況,比如兩個(gè)數(shù)字都是0,或者其中有一個(gè)是0,我們就可以快速得到結(jié)果,省去了遍歷過程。

實(shí)現(xiàn)代碼

#include <iostream>  
#include <string>  
#include <algorithm>

using namespace std; 

//判斷是否為0,全部為0的數(shù)字就是0,比如00000
bool CheckZero(const string &str){      //檢查是否等于0
    int size=str.size();                //如果全是0則為0,這里假設(shè)不會(huì)有帶符號(hào)的+00000或者-00000作為輸入
    for(int i=0;i<size;i++)
        if(str[i]!='0') return false;
    return true;
}

string Add(string str1, string str2){
    //關(guān)于0的處理
    if(CheckZero(str1)&&CheckZero(str2)) return "0";    //如果都是0
    else if(CheckZero(str1)) return str2;               //如果有個(gè)一為0
    else if(CheckZero(str2)) return str1;
    string ans;
    int i=str1.size()-1,j=str2.size()-1;
    int flag=0;                                         //進(jìn)位標(biāo)記
    while(i>=0||j>=0||flag){
        int numa=i>=0?str1[i--]-'0':0;                  //如果所有位都訪問完畢,對(duì)應(yīng)的位置用0代替
        int numb=j>=0?str2[j--]-'0':0;
        flag=numa+numb+flag;                            //計(jì)算兩位的和
        ans+='0'+flag%10;                               //取個(gè)位保存在答案中
        flag/=10;                                       //計(jì)算進(jìn)位
    }
    reverse(ans.begin(),ans.end());
    return ans;
}

int main(){
	cout << "請(qǐng)輸入兩個(gè)正整數(shù):" << endl;
	string a, b;
	cin >> a >> b;
	string result = Add(a, b);  
    cout << "和:" << result << endl;  
    return 0;  
}

4. 非負(fù)大整數(shù)的減法

大數(shù)減法的實(shí)現(xiàn),也模仿了我們列豎式的計(jì)算方法。從個(gè)位起,每次計(jì)算一位,首先根據(jù)后一位是否借位,先減去借位,然后判斷當(dāng)前位是否夠減,如果需要借位,則向前一位借位后在減,直到運(yùn)算完畢。同樣的,因?yàn)槲覀円獜膫€(gè)位開始計(jì)算,所以計(jì)算得到的結(jié)果必然是逆序的,最終要記得將結(jié)果逆置。

減法,可能出現(xiàn)前導(dǎo)0,要記得清除前導(dǎo)零。

最后,我們來考慮一些特殊情況,比如兩個(gè)數(shù)相同或者有一個(gè)數(shù)字為0,我們可以直接得到結(jié)果,從而避免了復(fù)雜的處理過程。

實(shí)現(xiàn)代碼

#include <iostream>  
#include <string>  
#include <algorithm>

using namespace std; 

//判斷兩個(gè)超大正整數(shù)的大小 
bool Lower(string str1, string str2){     
    //長度長的一定大(這里假設(shè)除了0以外,都沒有前導(dǎo)0),長度相等則字典序小的數(shù)字更小
    return str1.size()<str2.size()||(str1.size()==str2.size()&&str1<str2);
} 

//判斷是否為0,全部為0的數(shù)字就是0,比如00000
bool CheckZero(const string &str){      //檢查是否等于0
    int size=str.size();                //如果全是0則為0,這里假設(shè)不會(huì)有帶符號(hào)的+00000或者-00000作為輸入
    for(int i=0;i<size;i++)
        if(str[i]!='0') return false;
    return true;
}

string Sub(string str1, string str2){
    //處理0的情況
    if(str1==str2||(CheckZero(str1)&&CheckZero(str2))) return "0";  //如果兩數(shù)相等或者都是0
    else if(CheckZero(str1)) return "-"+str2;                       //如果第一個(gè)數(shù)字為0
    else if(CheckZero(str2)) return str1;                           //如果第二個(gè)數(shù)字為0
    //定正負(fù)
    int negative=0;                     //結(jié)果的正負(fù)號(hào)
    if(Lower(str1,str2)){
        swap(str1,str2);                //保證str1大于str2
        negative=1;                     //如果str1小于str2,則結(jié)果過為負(fù)值
    }
    string ans;
    int i=str1.size()-1,j=str2.size()-1;//逆序開始處理
    int flag=0;                         //借位標(biāo)記
    while(i>=0||j>=0){
        int numa=i>=0?str1[i--]-'0':0;  //取每一位,因?yàn)殚L度可能不同所以當(dāng)某一個(gè)已經(jīng)讀取完畢時(shí)對(duì)應(yīng)位置取0
        int numb=j>=0?str2[j--]-'0':0;
        numa-=flag;                     //先減去借位
        if(numa<numb){                  //如果不夠減則向上一位借位(只可能借一位)
            numa+=10;                   //借位并記錄借位
            flag=1;
        }
        else flag=0;                    //如果不借位,則借位標(biāo)記為0
        ans+='0'+numa-numb;             //計(jì)算當(dāng)前位置并保存
    }
    i=ans.size()-1;
    while(ans[i]=='0') i--;
    ans=ans.substr(0,i+1);              //去除前導(dǎo)0,如111-110=1
    if(negative) ans+='-';              //如果計(jì)算結(jié)果是負(fù)數(shù),添加負(fù)數(shù)符號(hào)
    reverse(ans.begin(),ans.end());     //因?yàn)槭悄嫘蛴?jì)算得到的結(jié)果,所以需要翻轉(zhuǎn)一下
    return ans;
}

int main(){
	cout << "請(qǐng)輸入兩個(gè)正整數(shù):" << endl;
	string a, b;
	cin >> a >> b;
	string result = Sub(a, b);  
    cout << "差: " << result << endl;     
    return 0;  
}

5.大整數(shù)的乘法

大數(shù)乘法的實(shí)現(xiàn),還采用我們豎式計(jì)算的方法。從個(gè)位開始,每次計(jì)算被乘數(shù)和乘數(shù)一位的積,然后借助我們寫好的大數(shù)加法實(shí)現(xiàn)最終結(jié)果的累加。但是大數(shù)乘法需要考慮正負(fù)的問題,所以需要對(duì)正負(fù)號(hào)進(jìn)行處理,對(duì)兩個(gè)數(shù)的符號(hào)使用異或最終可以確定乘積結(jié)果的正負(fù)。

乘法,因?yàn)槌藬?shù)的每一位都有相應(yīng)的權(quán)值(個(gè)十百千萬),因此我們對(duì)于乘數(shù)每一位的積進(jìn)行運(yùn)算時(shí)要考慮該位置的權(quán)值,在積的后邊補(bǔ)充相應(yīng)個(gè)數(shù)的零即可。

最后,我們考慮一些特殊情況,比如兩個(gè)數(shù)字中只要有一個(gè)是0,則結(jié)果就是0。

實(shí)現(xiàn)代碼

#include <iostream>  
#include <string>  
#include <algorithm>

using namespace std; 

//判斷兩個(gè)超大正整數(shù)的大小 
bool Lower(string str1, string str2){     
    //長度長的一定大(這里假設(shè)除了0以外,都沒有前導(dǎo)0),長度相等則字典序小的數(shù)字更小
    return str1.size()<str2.size()||(str1.size()==str2.size()&&str1<str2);
} 

//判斷是否為負(fù),只需要判斷第一位是不是負(fù)號(hào)即可,這里不考慮正號(hào)的存在,即認(rèn)為不使用正號(hào)
bool CheckNegative(const string &str){  //檢查是否為負(fù)數(shù)
    return str[0]=='-';
}

//判斷是否為0,全部為0的數(shù)字就是0,比如00000
bool CheckZero(const string &str){      //檢查是否等于0
    int size=str.size();                //如果全是0則為0,這里假設(shè)不會(huì)有帶符號(hào)的+00000或者-00000作為輸入
    for(int i=0;i<size;i++)
        if(str[i]!='0') return false;
    return true;
}

string Add(string str1, string str2){
    //關(guān)于0的處理
    if(CheckZero(str1)&&CheckZero(str2)) return "0";    //如果都是0
    else if(CheckZero(str1)) return str2;               //如果有個(gè)一為0
    else if(CheckZero(str2)) return str1;
    string ans;
    int i=str1.size()-1,j=str2.size()-1;
    int flag=0;                                         //進(jìn)位標(biāo)記
    while(i>=0||j>=0||flag){
        int numa=i>=0?str1[i--]-'0':0;                  //如果所有位都訪問完畢,對(duì)應(yīng)的位置用0代替
        int numb=j>=0?str2[j--]-'0':0;
        flag=numa+numb+flag;                            //計(jì)算兩位的和
        ans+='0'+flag%10;                               //取個(gè)位保存在答案中
        flag/=10;                                       //計(jì)算進(jìn)位
    }
    reverse(ans.begin(),ans.end());
    return ans;
}

string Mul(string str1, string str2){
    if(CheckZero(str1)||CheckZero(str2)) return "0";    //如果有一個(gè)為0,則結(jié)果為0
 
    int negative=0,negastr1=0,negastr2=0;               //定正負(fù)
    if(CheckNegative(str1)){                            //確定正負(fù)號(hào)標(biāo)記,并且去掉-字符
        negastr1=1; str1=str1.substr(1,str1.size()-1);
    }
    if(CheckNegative(str2)){
        negastr2=1; str2=str2.substr(1,str2.size()-1);
    }
    negative=negastr1^negastr2;                         //異或運(yùn)算確定結(jié)果的正負(fù)號(hào)
 
    string ans;
    if(Lower(str1,str2)) swap(str1,str2);               //保證str1大于等于str2
    int size1=str1.size(),size2=str2.size();
    for(int i=size2-1;i>=0;i--){                        //遍歷較小數(shù)字的每一位
        string temp(size2-1-i,'0');                     //temp為str1乘以str2[i]的積,根據(jù)str2[i]的權(quán)重(個(gè)十百千萬,補(bǔ)充對(duì)應(yīng)個(gè)數(shù)的0)
        int flag=0;                                     //進(jìn)位標(biāo)記
        for(int j=size1-1;j>=0;j--){                    //temp
            flag+=(str1[j]-'0')*(str2[i]-'0');
            temp.push_back('0'+(flag%10));
            flag/=10;
        }
        if(flag) temp.push_back('0'+flag);              //如果最高位還有進(jìn)位
        reverse(temp.begin(),temp.end());
        ans=Add(ans,temp);                              //將計(jì)算結(jié)果累加到最終的結(jié)果上
    }
    if(negative) ans="-"+ans;                           //處理結(jié)果的正負(fù)號(hào)
    return ans;
}

int main(){
	cout << "請(qǐng)輸入兩個(gè)整數(shù):" << endl;
	string a, b;
	cin >> a >> b;
	string result = Mul(a, b);  
    cout << "積:" << result << endl;     
    return 0;  
}

6. 大整數(shù)的除法,計(jì)算結(jié)果精確到6位小數(shù)(6位小數(shù)后直接舍去)

如商3.700014[5800933124]

大數(shù)除法的實(shí)現(xiàn),同樣采用我們除法式子的方法進(jìn)行計(jì)算。首先,使用異或的方法確定結(jié)果的正負(fù)號(hào)。兩個(gè)數(shù)字相除的時(shí)候,如果第一個(gè)數(shù)字大于等于第二個(gè)數(shù)字,則結(jié)果一定是大于等于1的,否則小于1。于是,為了實(shí)現(xiàn)小于1的結(jié)果表示,我們?yōu)榻Y(jié)果精確到小數(shù)點(diǎn)后6位。這里采用的方法為:事先確定是否為純小數(shù),然后在第一個(gè)數(shù)字的末尾加上6個(gè)0,然后使用我們除法式子的方法進(jìn)行計(jì)算。從第一個(gè)數(shù)字的頭部開始,找到第一個(gè)長度能夠進(jìn)行商運(yùn)算的數(shù)字開始,計(jì)算商并將臨時(shí)的余數(shù)補(bǔ)足一位進(jìn)行下一位商的計(jì)算,直到計(jì)算完畢。

除法,可能遇到除數(shù)為0的情況,因此需要在計(jì)算的時(shí)候提前進(jìn)行判定。另外計(jì)算過程中,計(jì)算商的方法使用大數(shù)的減法操作,因此可能會(huì)遇到0堆積的情況(長度增大),會(huì)影響到大小的比較判定,要注意處理。

最后,我們考慮一些特殊情況,比如被除數(shù)為0的時(shí)候,可以直接輸出結(jié)果0.000000。

實(shí)現(xiàn)代碼

#include <iostream>  
#include <string>  
#include <algorithm>

using namespace std; 

//判斷兩個(gè)超大正整數(shù)的大小 
bool Lower(string str1, string str2){     
    //長度長的一定大(這里假設(shè)除了0以外,都沒有前導(dǎo)0),長度相等則字典序小的數(shù)字更小
    return str1.size()<str2.size()||(str1.size()==str2.size()&&str1<str2);
} 

//判斷是否為負(fù),只需要判斷第一位是不是負(fù)號(hào)即可,這里不考慮正號(hào)的存在,即認(rèn)為不使用正號(hào)
bool CheckNegative(const string &str){  //檢查是否為負(fù)數(shù)
    return str[0]=='-';
}

//判斷是否為0,全部為0的數(shù)字就是0,比如00000
bool CheckZero(const string &str){      //檢查是否等于0
    int size=str.size();                //如果全是0則為0,這里假設(shè)不會(huì)有帶符號(hào)的+00000或者-00000作為輸入
    for(int i=0;i<size;i++)
        if(str[i]!='0') return false;
    return true;
}

//大數(shù)減法
string Sub(string str1, string str2){
    //處理0的情況
    if(str1==str2||(CheckZero(str1)&&CheckZero(str2))) return "0";  //如果兩數(shù)相等或者都是0
    else if(CheckZero(str1)) return "-"+str2;                       //如果第一個(gè)數(shù)字為0
    else if(CheckZero(str2)) return str1;                           //如果第二個(gè)數(shù)字為0
    //定正負(fù)
    int negative=0;                     //結(jié)果的正負(fù)號(hào)
    if(Lower(str1,str2)){
        swap(str1,str2);                //保證str1大于str2
        negative=1;                     //如果str1小于str2,則結(jié)果過為負(fù)值
    }
    string ans;
    int i=str1.size()-1,j=str2.size()-1;//逆序開始處理
    int flag=0;                         //借位標(biāo)記
    while(i>=0||j>=0){
        int numa=i>=0?str1[i--]-'0':0;  //取每一位,因?yàn)殚L度可能不同所以當(dāng)某一個(gè)已經(jīng)讀取完畢時(shí)對(duì)應(yīng)位置取0
        int numb=j>=0?str2[j--]-'0':0;
        numa-=flag;                     //先減去借位
        if(numa<numb){                  //如果不夠減則向上一位借位(只可能借一位)
            numa+=10;                   //借位并記錄借位
            flag=1;
        }
        else flag=0;                    //如果不借位,則借位標(biāo)記為0
        ans+='0'+numa-numb;             //計(jì)算當(dāng)前位置并保存
    }
    i=ans.size()-1;
    while(ans[i]=='0') i--;
    ans=ans.substr(0,i+1);              //去除前導(dǎo)0,如111-110=1
    if(negative) ans+='-';              //如果計(jì)算結(jié)果是負(fù)數(shù),添加負(fù)數(shù)符號(hào)
    reverse(ans.begin(),ans.end());     //因?yàn)槭悄嫘蛴?jì)算得到的結(jié)果,所以需要翻轉(zhuǎn)一下
    return ans;
}

string Div(string str1, string str2){
    //處理除數(shù)為0的情況和被除數(shù)為0的情況
    if(CheckZero(str2)) return "The divisor cannot be zero!";
    else if(CheckZero(str1)) return "0.000000";
 
    int negative=0,negastr1=0,negastr2=0;               //定正負(fù)
    if(CheckNegative(str1)){                            //確定正負(fù)號(hào)標(biāo)記,并且去掉-
        negastr1=1; str1=str1.substr(1,str1.size()-1);
    }
    if(CheckNegative(str2)){
        negastr2=1; str2=str2.substr(1,str2.size()-1);
    }
    negative=negastr1^negastr2;                         //異或運(yùn)算確定結(jié)果的正負(fù)號(hào)
 
    int point=0;                                        //結(jié)果是否為純小數(shù)
    if(Lower(str1,str2)) point=1;                       //如果str1小于str2,則計(jì)算為純小數(shù)
    string ans;                                         //計(jì)算結(jié)果
    str1+=string(6,'0');                                //補(bǔ)足6個(gè)0,用于計(jì)算小數(shù)位
 
    int size1=str1.size(),size2=str2.size();
    int i=size2-1;                                      //商第一位的位置
    string temp=str1.substr(0,i);                       //從str1上取size2-1個(gè)字符
    for(i;i<size1;i++){
        temp+=str1[i];                                  //從后邊拿出一位,預(yù)先處理可以防止結(jié)尾處越界
        int cnt=0;                                      //當(dāng)前位的商,也就是temp中包含了多少個(gè)str2,使用減法                                          //如果temp不為0,則計(jì)算商
        while(Lower(str2,temp)||temp==str2){            //如果當(dāng)前位商不為0,則計(jì)算商
            temp=Sub(temp,str2);
            cnt++;
        }
        if(temp=="0") temp.clear();                     //如果某次計(jì)算結(jié)果為0,則清空,避免0的堆積,比如111000 111
        ans.push_back('0'+cnt);                         //保存商
    }
    i=0;
    while(ans[i]=='0') i++;
    ans=ans.substr(i,ans.size()-i);                     //去除前導(dǎo)0
    if(point){                                          //如果是純小數(shù),補(bǔ)足6位并添加小數(shù)點(diǎn)
        int len=6-ans.size();
        ans="0."+string(len,'0')+ans;
    }
    else ans.insert((ans.end()-6),'.');                 //如果不是小數(shù),則只需要插入小數(shù)點(diǎn)       
    if(negative) ans="-"+ans;                           //最后一步驟,如果是負(fù)數(shù)帶上負(fù)號(hào)
    return ans;
}

int main(){
	cout << "請(qǐng)輸入兩個(gè)整數(shù):" << endl;
	string a, b;
	cin >> a >> b;
	string result = Div(a, b);  
    cout << "商(6位小數(shù)后直接舍去):" << result << endl;     
    return 0;  
}

7.最后,整合為大數(shù)四則運(yùn)算

加減運(yùn)算僅限非負(fù)整數(shù)的運(yùn)算,因?yàn)樨?fù)數(shù)的加減運(yùn)算可以等價(jià)為某種形式的加法或者減法運(yùn)算,故不做考慮;乘除運(yùn)算只考慮大整數(shù)運(yùn)算,不考慮小數(shù)的計(jì)算;除法只考慮大整數(shù)運(yùn)算,計(jì)算結(jié)果精確到6位小數(shù)(6位小數(shù)后直接舍去)。源碼如下:

#include <iostream>  
#include <string>  
#include <algorithm>
  
using namespace std;  
  
//大數(shù)四則運(yùn)算,兩個(gè)參數(shù)都不能為空
string Add(string str1, string str2);       //大數(shù)加法
string Sub(string str1, string str2);       //大數(shù)減法
string Mul(string str1, string str2);       //大數(shù)乘法
string Div(string str1, string str2);       //大數(shù)除法
bool Lower(string str1, string str2);       //大數(shù)比較(小于)
bool CheckZero(const string &str);          //檢查是不是0,比如0000認(rèn)為是0
bool CheckNegative(const string &str);      //檢查是不是負(fù)數(shù)
void ShowMenu();                            //提示菜單
void ShowMenu(char choice);                 //二級(jí)菜單
int main(){
    string a,b;
    char ch;
    ShowMenu();
    while(cin>>ch&&ch!='q'){                //循環(huán)打印菜單并提示用戶輸入
        ShowMenu(ch);
        cin>>a>>b;
        switch(ch){
            case 'a':cout<<a<<" + "<<b<<" = "<<Add(a,b)<<endl;break;
            case 'b':cout<<a<<" - "<<b<<" = "<<Sub(a,b)<<endl;break;
            case 'c':cout<<a<<" * "<<b<<" = "<<Mul(a,b)<<endl;break;
            case 'd':cout<<a<<" / "<<b<<" = "<<Div(a,b)<<endl;break;
        }
        ShowMenu();
    }
    return 0;
}
string Add(string str1, string str2){
    //關(guān)于0的處理
    if(CheckZero(str1)&&CheckZero(str2)) return "0";    //如果都是0
    else if(CheckZero(str1)) return str2;               //如果有個(gè)一為0
    else if(CheckZero(str2)) return str1;
    string ans;
    int i=str1.size()-1,j=str2.size()-1;
    int flag=0;                                         //進(jìn)位標(biāo)記
    while(i>=0||j>=0||flag){
        int numa=i>=0?str1[i--]-'0':0;                  //如果所有位都訪問完畢,對(duì)應(yīng)的位置用0代替
        int numb=j>=0?str2[j--]-'0':0;
        flag=numa+numb+flag;                            //計(jì)算兩位的和
        ans+='0'+flag%10;                               //取個(gè)位保存在答案中
        flag/=10;                                       //計(jì)算進(jìn)位
    }
    reverse(ans.begin(),ans.end());
    return ans;
}
string Sub(string str1, string str2){
    //處理0的情況
    if(str1==str2||(CheckZero(str1)&&CheckZero(str2))) return "0";  //如果兩數(shù)相等或者都是0
    else if(CheckZero(str1)) return "-"+str2;                       //如果第一個(gè)數(shù)字為0
    else if(CheckZero(str2)) return str1;                           //如果第二個(gè)數(shù)字為0
    //定正負(fù)
    int negative=0;                     //結(jié)果的正負(fù)號(hào)
    if(Lower(str1,str2)){
        swap(str1,str2);                //保證str1大于str2
        negative=1;                     //如果str1小于str2,則結(jié)果過為負(fù)值
    }
    string ans;
    int i=str1.size()-1,j=str2.size()-1;//逆序開始處理
    int flag=0;                         //借位標(biāo)記
    while(i>=0||j>=0){
        int numa=i>=0?str1[i--]-'0':0;  //取每一位,因?yàn)殚L度可能不同所以當(dāng)某一個(gè)已經(jīng)讀取完畢時(shí)對(duì)應(yīng)位置取0
        int numb=j>=0?str2[j--]-'0':0;
        numa-=flag;                     //先減去借位
        if(numa<numb){                  //如果不夠減則向上一位借位(只可能借一位)
            numa+=10;                   //借位并記錄借位
            flag=1;
        }
        else flag=0;                    //如果不借位,則借位標(biāo)記為0
        ans+='0'+numa-numb;             //計(jì)算當(dāng)前位置并保存
    }
    i=ans.size()-1;
    while(ans[i]=='0') i--;
    ans=ans.substr(0,i+1);              //去除前導(dǎo)0,如111-110=1
    if(negative) ans+='-';              //如果計(jì)算結(jié)果是負(fù)數(shù),添加負(fù)數(shù)符號(hào)
    reverse(ans.begin(),ans.end());     //因?yàn)槭悄嫘蛴?jì)算得到的結(jié)果,所以需要翻轉(zhuǎn)一下
    return ans;
}
string Mul(string str1, string str2){
    if(CheckZero(str1)||CheckZero(str2)) return "0";    //如果有一個(gè)為0,則結(jié)果為0
 
    int negative=0,negastr1=0,negastr2=0;               //定正負(fù)
    if(CheckNegative(str1)){                            //確定正負(fù)號(hào)標(biāo)記,并且去掉-字符
        negastr1=1; str1=str1.substr(1,str1.size()-1);
    }
    if(CheckNegative(str2)){
        negastr2=1; str2=str2.substr(1,str2.size()-1);
    }
    negative=negastr1^negastr2;                         //異或運(yùn)算確定結(jié)果的正負(fù)號(hào)
 
    string ans;
    if(Lower(str1,str2)) swap(str1,str2);               //保證str1大于等于str2
    int size1=str1.size(),size2=str2.size();
    for(int i=size2-1;i>=0;i--){                        //遍歷較小數(shù)字的每一位
        string temp(size2-1-i,'0');                     //temp為str1乘以str2[i]的積,根據(jù)str2[i]的權(quán)重(個(gè)十百千萬,補(bǔ)充對(duì)應(yīng)個(gè)數(shù)的0)
        int flag=0;                                     //進(jìn)位標(biāo)記
        for(int j=size1-1;j>=0;j--){                    //temp
            flag+=(str1[j]-'0')*(str2[i]-'0');
            temp.push_back('0'+(flag%10));
            flag/=10;
        }
        if(flag) temp.push_back('0'+flag);              //如果最高位還有進(jìn)位
        reverse(temp.begin(),temp.end());
        ans=Add(ans,temp);                              //將計(jì)算結(jié)果累加到最終的結(jié)果上
    }
    if(negative) ans="-"+ans;                           //處理結(jié)果的正負(fù)號(hào)
    return ans;
}
string Div(string str1, string str2){
    //處理除數(shù)為0的情況和被除數(shù)為0的情況
    if(CheckZero(str2)) return "The divisor cannot be zero!";
    else if(CheckZero(str1)) return "0.000000";
 
    int negative=0,negastr1=0,negastr2=0;               //定正負(fù)
    if(CheckNegative(str1)){                            //確定正負(fù)號(hào)標(biāo)記,并且去掉-
        negastr1=1; str1=str1.substr(1,str1.size()-1);
    }
    if(CheckNegative(str2)){
        negastr2=1; str2=str2.substr(1,str2.size()-1);
    }
    negative=negastr1^negastr2;                         //異或運(yùn)算確定結(jié)果的正負(fù)號(hào)
 
    int point=0;                                        //結(jié)果是否為純小數(shù)
    if(Lower(str1,str2)) point=1;                       //如果str1小于str2,則計(jì)算為純小數(shù)
    string ans;                                         //計(jì)算結(jié)果
    str1+=string(6,'0');                                //補(bǔ)足6個(gè)0,用于計(jì)算小數(shù)位
 
    int size1=str1.size(),size2=str2.size();
    int i=size2-1;                                      //商第一位的位置
    string temp=str1.substr(0,i);                       //從str1上取size2-1個(gè)字符
    for(i;i<size1;i++){
        temp+=str1[i];                                  //從后邊拿出一位,預(yù)先處理可以防止結(jié)尾處越界
        int cnt=0;                                      //當(dāng)前位的商,也就是temp中包含了多少個(gè)str2,使用減法                                          //如果temp不為0,則計(jì)算商
        while(Lower(str2,temp)||temp==str2){            //如果當(dāng)前位商不為0,則計(jì)算商
            temp=Sub(temp,str2);
            cnt++;
        }
        if(temp=="0") temp.clear();                     //如果某次計(jì)算結(jié)果為0,則清空,避免0的堆積,比如111000 111
        ans.push_back('0'+cnt);                         //保存商
    }
    i=0;
    while(ans[i]=='0') i++;
    ans=ans.substr(i,ans.size()-i);                     //去除前導(dǎo)0
    if(point){                                          //如果是純小數(shù),補(bǔ)足6位并添加小數(shù)點(diǎn)
        int len=6-ans.size();
        ans="0."+string(len,'0')+ans;
    }
    else ans.insert((ans.end()-6),'.');                 //如果不是小數(shù),則只需要插入小數(shù)點(diǎn)       
    if(negative) ans="-"+ans;                           //最后一步驟,如果是負(fù)數(shù)帶上負(fù)號(hào)
    return ans;
}
bool Lower(string str1, string str2){                   //長度長的一定大(這里假設(shè)除了0以外,都沒有前導(dǎo)0),長度相等則字典序小的數(shù)字更小
    return str1.size()<str2.size()||(str1.size()==str2.size()&&str1<str2);
}
bool CheckZero(const string &str){      //檢查是否等于0
    int size=str.size();                //如果全是0則為0,這里假設(shè)不會(huì)有帶符號(hào)的+00000或者-00000作為輸入
    for(int i=0;i<size;i++)
        if(str[i]!='0') return false;
    return true;
}
bool CheckNegative(const string &str){  //檢查是否為負(fù)數(shù)
    return str[0]=='-';
}
void ShowMenu(){
    cout<<"請(qǐng)選擇要進(jìn)行的大數(shù)運(yùn)算:\n"
        <<"a) 加法          b) 減法\n"
        <<"c) 乘法          d) 除法\n"
        <<"q) 退出\n"
        <<"請(qǐng)輸入你的選擇: ";
}
void ShowMenu(char choice){
    cout<<"請(qǐng)輸入要計(jì)算的兩個(gè)數(shù)字";
    switch(choice){
        case 'a':cout<<"(僅支持非負(fù)整數(shù)加法計(jì)算): "<<endl;break;
        case 'b':cout<<"(僅支持非負(fù)整數(shù)減法計(jì)算): "<<endl;break;
        case 'c':cout<<"(僅支持整數(shù)乘法計(jì)算): "<<endl;break;
        case 'd':cout<<"(僅支持整數(shù)除法計(jì)算,計(jì)算結(jié)果保留6位小數(shù),之后的直接舍棄): "<<endl;break;
    }
}

附錄、進(jìn)一步學(xué)習(xí)了解

https://blog.csdn.net/weixin_44668898/article/details/96763177

https://blog.csdn.net/wyqxii/article/details/131965735文章來源地址http://www.zghlxwxcb.cn/news/detail-708897.html

到了這里,關(guān)于C++中如何處理超長的數(shù)字(long long類型的整數(shù)都無法存儲(chǔ)的)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【ArcGIS Pro微課1000例】0055:Pro中如何處理個(gè)人數(shù)據(jù)庫(.mdb)

    使用ArcGIS Pro的用戶應(yīng)該已經(jīng)發(fā)現(xiàn)個(gè)人地理數(shù)據(jù)庫(.mdb)不能使用了。隨著ESRI的軟件技術(shù)革新,在ArcGIS Pro中不再支持且將來也不會(huì)支持個(gè)人地理數(shù)據(jù)庫(.mdb)。這個(gè)確實(shí)很煩人,很多項(xiàng)目還是在使用mdb數(shù)據(jù)庫的。不過ESRI也給出了一些解決辦法,不過這些只是暫時(shí)的,后面也

    2024年02月04日
    瀏覽(36)
  • 在PostgreSQL中如何處理大對(duì)象(Large Objects),例如存儲(chǔ)和檢索二進(jìn)制文件?

    在PostgreSQL中如何處理大對(duì)象(Large Objects),例如存儲(chǔ)和檢索二進(jìn)制文件?

    PostgreSQL 提供了對(duì)大對(duì)象(Large Objects)的支持,這是一種特殊的數(shù)據(jù)類型,用于存儲(chǔ)大量數(shù)據(jù),通常用于存儲(chǔ)二進(jìn)制文件或大型文本數(shù)據(jù)。大對(duì)象存儲(chǔ)在數(shù)據(jù)庫外部,但在數(shù)據(jù)庫內(nèi)部進(jìn)行管理,從而允許您像處理普通數(shù)據(jù)庫對(duì)象一樣處理它們。 以下是在 PostgreSQL 中處理大對(duì)象

    2024年04月27日
    瀏覽(155)
  • 【解決方法】numpy.float64類型數(shù)據(jù)無法被解釋為整數(shù)

    【解決方法】numpy.float64類型數(shù)據(jù)無法被解釋為整數(shù) 在使用Python語言進(jìn)行數(shù)據(jù)處理時(shí),經(jīng)常需要用到NumPy庫中的各種數(shù)據(jù)類型和數(shù)學(xué)函數(shù)。其中,Numpy.float64是一種十分常見的數(shù)據(jù)類型。 然而,有時(shí)候我們會(huì)遇到這樣的錯(cuò)誤提示:【numpy.float64 object cannot be interpreted as an integer】

    2024年02月16日
    瀏覽(26)
  • 【Java】阿拉伯?dāng)?shù)字轉(zhuǎn)漢字(完全符合中文閱讀習(xí)慣)(支持所有整數(shù)類型)

    【Java】阿拉伯?dāng)?shù)字轉(zhuǎn)漢字(完全符合中文閱讀習(xí)慣)(支持所有整數(shù)類型)

    網(wǎng)上看過很多實(shí)現(xiàn),但都有 BUG,不是多余0沒有處理,就是很多生成的漢字字符串根本不符合中文閱讀習(xí)慣(各位代碼寫完測(cè)試的時(shí)候用例多搞一點(diǎn)?。?剛好公司有個(gè)項(xiàng)目就要實(shí)現(xiàn)這個(gè)小功能,顧把自己的實(shí)現(xiàn)分享出來 看代碼前,先觀察一下結(jié)果是否滿足各位的預(yù)期 用例輸

    2024年02月09日
    瀏覽(22)
  • 39 C++ 模版中的參數(shù)如果 是 vector,list等集合類型如何處理呢?

    在前面寫的例子中,模版參數(shù)一般都是 int,或者一個(gè)類Teacher,假設(shè)我們現(xiàn)在有個(gè)需求:模版的參數(shù)要是vector,list這種結(jié)合類型應(yīng)該怎么寫呢? map情況下的處理,好像不管咋寫都有build error,這塊先剩下,如果有網(wǎng)友知道怎么寫,請(qǐng)幫忙在留言中指導(dǎo)一下

    2024年01月25日
    瀏覽(31)
  • 表達(dá)式必須包含整數(shù)或枚舉類型 - Visual Studio C++ 錯(cuò)誤

    在使用 Visual Studio C++ 進(jìn)行編程時(shí),有時(shí)你可能會(huì)遇到錯(cuò)誤消息:“表達(dá)式必須包含整數(shù)或枚舉類型”。這個(gè)錯(cuò)誤通常是由于在表達(dá)式中使用了錯(cuò)誤的數(shù)據(jù)類型導(dǎo)致的。在本文中,我們將詳細(xì)解釋這個(gè)錯(cuò)誤的原因,并提供一些可能的解決方案。 錯(cuò)誤原因: 當(dāng)你在 C++ 程序中使

    2024年02月05日
    瀏覽(20)
  • Visual Studio 2010 C++編譯錯(cuò)誤“表達(dá)式必須包含整數(shù)或枚舉類型“

    Visual Studio 2010 C++編譯錯(cuò)誤\\\"表達(dá)式必須包含整數(shù)或枚舉類型\\\" 在使用Visual Studio 2010編寫C++代碼時(shí),有時(shí)候會(huì)出現(xiàn)這樣的編譯錯(cuò)誤:“表達(dá)式必須包含整數(shù)或枚舉類型”。這個(gè)錯(cuò)誤通常是因?yàn)槲覀冊(cè)趯懘a時(shí)使用了錯(cuò)誤的數(shù)據(jù)類型或者運(yùn)算符導(dǎo)致的。 下面我們來看一個(gè)例子: 在

    2024年02月08日
    瀏覽(22)
  • java Long 類型如何比較

    Java 中的 Long 類型可以使用下列方法進(jìn)行比較: 使用 compareTo 方法: 使用三目運(yùn)算符: 使用 Long.valueOf 和 equals 方法: 請(qǐng)注意,如果要比較兩個(gè) Long 對(duì)象的值,則應(yīng)使用 equals 方法,而不是使用 == 運(yùn)算符。

    2024年02月16日
    瀏覽(15)
  • MongoDB Long 類型 shell 查詢

    MongoDB Long 類型 shell 查詢

    1、某數(shù)據(jù)ID為Long類型,JAVA 定義實(shí)體類 @Id Long id 2、查詢數(shù)據(jù)庫,此數(shù)據(jù)存在 3、使用 shell 查詢,查不到數(shù)據(jù) 4、JAVA代碼查詢Query.query 不受任何影響 long 在 mongo中為 int64 類型,因此直接傳遞參數(shù),會(huì)丟失精度,所以想到加上引號(hào)嘗試解決 失敗原因 加上雙引號(hào)以后,變成了字

    2024年02月11日
    瀏覽(33)
  • Java中比較Long類型是否相等

    Java中,比較Long類型是否相等,可以使用“==”和“equals()”方法。 在Java中,\\\"==\\\"用于比較兩個(gè)基本數(shù)據(jù)類型或兩個(gè)引用數(shù)據(jù)類型是否指向同一對(duì)象。對(duì)于Long類型的封裝類,由于它們的值在-128到127之間時(shí)會(huì)被緩存,因此這些值相同的Long型對(duì)象會(huì)指向同一個(gè)對(duì)象,使用\\\"==\\\"比較會(huì)

    2024年02月05日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包