高精度 加 減 乘 除(C++實現)
阿新 • • 發佈:2019-02-10
如果輸入資料是long long 一下的話, 用這些勉強算是高精度的演算法會比較快
//這是該大數演算法的必須構造的陣列形式
s[1] = a;
while(s[len] >= 10){
s[len + 1] += s[len] / 10;
s[len] %= 10;
++len;
}
乘法(可以算輸入資料為long long時的大數相乘)
#include <iostream> using namespace std; typedef long long ll; ll s[1000]; // 儲存結果 ll len = 1; void multi(ll x){ for(int i = 1; i <= len; ++i){ s[i] *= x; } for(int i = 1; i <= len; ++i){ if(s[i] >= 10){ s[i + 1] += s[i] / 10; s[i] %= 10; } } // 如果最高位有進位的話長度加一 ++len; // 去掉最高位面前的0 如0123 0就可以不要 while(s[len] == 0) --len; } void solve(){ ll a, b; cin >> a >> b; // 先處理一下資料,讓高位聚集在陣列尾部,便於之後的處理 s[1] = a; while(s[len] >= 10){ s[len + 1] += s[len] / 10; s[len] %= 10; ++len; } multi(b); for(int i = len; i >= 1; --i){ cout << s[i]; } } int main(){ solve(); return 0; }
除法(可以算輸入資料為long long時的大數相除, 被除數可以是大數)
#include <iostream> using namespace std; typedef long long ll; ll s[1000]; // 儲存結果 ll len = 1; void divis(ll b){ // 除以單個數 如果不夠除讓高位數和低位相加 for(int i = len; i >= 1; --i){ s[i - 1] += (s[i] % b) * 10; s[i] /= b; } while(s[len] == 0) --len; } void solve(){ ll a, b; cin >> a >> b; s[1] = a; // 讓高位資料聚集在尾部 while(s[len] >= 10){ s[len + 1] += s[len] / 10; s[len] %= 10; ++len; } divis(b); if(len <= 0) cout << 0; else{ for(int i = len; i >= 1; --i) cout << s[i]; } } int main(){ solve(); return 0; }
加法(可以算輸入資料為long long時的大數相除, 被加數可以是大數,減數可以用大數表示,這樣就可以進行更高精度的運算了)
#include <iostream> using namespace std; typedef long long ll; ll s[10000]; int len = 1; void add(ll b){ int i = 1; // b % 10 先取出個位數 跟個位數相加 // b也可以用陣列儲存,這樣數字就不在侷限於long long 了 while(b){ s[i] += b % 10; b /= 10; ++i; } len = max(len, i); for(int i = 1; i <= len; ++i){ if(s[i] >= 10){ s[i + 1] += s[i] / 10; s[i] %= 10; } } ++len; // 如果最高位有進位的話,長度加一 while(s[len] == 0) --len; } void solve(){ ll a, b; cin >> a >> b; // 讓高位的資料聚集在尾部 s[1] = a; while(s[len] >= 10){ s[len + 1] += s[len] / 10; s[len] %= 10; ++len; } add(b); if(len > 0) for(int i = len; i >= 1; --i) cout << s[i]; else cout << 0; } int main(){ solve(); return 0; }
減法(可以算輸入資料為long long時的大數相除, 被減數可以是大數,加數可以用大數表示,這樣就可以進行更高精度的運算了)
#include <iostream>
using namespace std;
typedef long long ll;
int s[1000];
int len = 1;
void sub(ll a){
int i = 1;
// 這個 a取出個位數是可以用 像是儲存大數資料的s[len] 來表示的 這是跟加法相似的
while(a){
s[i] -= a % 10;
a /= 10;
++i;
}
len = max(len, i);
for(int i = 1; i <= len; ++i){
if(s[i] < 0){
// 如果小於0, 要向高位取1, 高位就要減一
s[i] += 10;
--s[i + 1];
}
}
while(s[len] == 0) --len;
}
void solve(){
ll a, b;
cin >> a >> b;
// 讓高位的資料聚集在尾部
s[1] = a;
while(s[len] >= 10){
s[len + 1] += s[len] / 10;
s[len] %= 10;
++len;
}
sub(b);
for(int i = len; i >= 1; --i){
cout << s[i];
}
}
int main(){
solve();
return 0;
}
更高精度的運算速度是會降低的,但是如果資料不是特別大的話,這些已經夠用了。後面更高精度的運算,下篇部落格再寫吧!