您的位置:首页 > 其它

高精度模板

2017-02-18 11:26 197 查看
#include <iostream>
#include <string>
using namespace std;

// 实现大数相加  结果存放在num中

void bigIntergerAdd(string &num, string add) {

int goBit = 0; // 存放进位

// 先交换下顺序  加数的位数要比较少
if (num.length() < add.length()) {

string tmp = num;
num = add;
add = tmp;
}

string tmp (num.length() - add.length(), '0');
add = tmp + add;

// 利用string的+号特性  不采用逆序相加法
int len1 = num.length(), len2 = add.length();
for (int i = len1 -1 ; i>= 0; --i) {

int tmp =  ((num[i] - '0') + (add[i] - '0') + goBit) ;

num[i] = tmp% 10 + '0';

goBit = tmp/10;
}

// 特殊情况处理
if (goBit != 0)
num.insert(0, string(1, (char)goBit +'0'));
}

int main(int argc, char** argv) {

string s1;
string result;
int i =0;
while (cin>> s1) {

if (s1 == "0") {

cout<< result<< endl;
break;
}

if (i ==0) {

i=1;
result = s1;
} else
bigIntergerAdd(result, s1);

}
return 0;
}


参考:http://blog.csdn.net/wu5151/article/details/47100085

----------------------------------------------------------------------------------

大数相乘:总的思路比较简单, 就是模拟手算。 用较短(或相等)长度的数的每一位与较长数一一相乘。要注意的是,相乘所得结果需要补0的细节 。然后就是单纯的大数相加。

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

// 大数相乘

string bigIntegerPlus(string res, string plusN) {

string ret;
if (res.length()< plusN.length()) {

string tmp = res;
res = plusN;
plusN = tmp;
}

int len1 = res.length(), len2 = plusN.length();
for (int i = len2-1; i>=0; --i ) {

string tmp(len1, '0'); // 存放相乘的中间结果
int goBit =0;
for (int j= len1-1; j >=0; --j) {

int mid = (res[j] -'0') * (plusN[i] -'0') + goBit;
tmp[j] = mid%10 + '0';
goBit = mid /10;
}
if (goBit != 0)
tmp.insert(0, string(1,goBit +'0'));

for (int m=0; m< len2 -1-i; ++m)
tmp.push_back('0'); // 补位

// 相乘后就相加  大数相加
if (i == len2-1)
ret = tmp;
else {

int goBit2 =0;
string s(tmp.length() - ret.length() ,'0');
ret = s + ret;
for (int m = tmp.length()-1; m>=0; --m) {

int mid = (tmp[m] -'0')+(ret[m] - '0')  + goBit2;
ret[m] = mid %10 +'0';
goBit2 = mid/ 10;
}

if (goBit2 != 0)
ret.insert(0, string(1,goBit +'0'));
}
}

// 去掉前导0
while (ret.length() >1 && ret[0] == '0')
ret.erase(0,1);

return ret;
}

int main(int argc, char** argv) {

string res, plusN;
while (cin>> res>> plusN) {

cout<< bigIntegerPlus(res, plusN)<< endl;
}

return 0;
}


参考:http://blog.csdn.net/wu5151/article/details/47099971

----------------------------------------------------------------------------------

实现的是大数跟int类型的相除和求余,解题心得: 模拟手算的过程。需要注意的是。其中余数的存放要用long long存放比较好。因为如果采用int类型那么     rem = prem * 10/*向后退一位*/ + src[i] - '0';    这行代码可能会出现溢出问题。

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

void bigDivision(char *src, int num, char sign) {

long long rem = 0; // 存放新余数
long long prem = 0; // 原余数
char  res[10000] ="";
bool flag = true;
int k = 0;
for (int i=0; i< strlen(src); ++i) {

rem = prem * 10/*向后退一位*/ + src[i] - '0';
if (rem / num >0 || rem ==0) {

res[k++] = rem/ num + '0';
prem = rem %num;
flag = false;
}  else {

prem = rem;
if (!flag)
res[k++] = '0';
}
}
if (sign == '%') {

cout<< prem<< endl;
return;
}

for (int i =0; i< k; ++i)
cout<< res[i];
cout<< endl;
}

int main(int argc, char** argv) {

char src[10000] = "";
int num;
char sign;
while (scanf("%s %c %d", src, &sign, &num) != EOF) {

bigDivision(src, num, sign);
}

return 0;
}


参考:http://blog.csdn.net/wu5151/article/details/47100165

----------------------------------------------------------------------------------

高精度问题之大数求幂,解题思路: 因为做了大数相加 ,这题也就没什么好思考的。不同之处就是先去掉小数点,计算结果后在适当位置插入小数点即可。这个算法可以计算更大的数。但必须包含小数点。。。。。。

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

// 求幂  思路: 先变成整数相乘   然后根据小数的位数 结合幂  算出小数点该结果字符串的位置 即可

string bigIntegerPlus(string src, string num) {

string tmp = src;
for (int i =num.length() -1; i >= 0 ; --i) {

string mid(tmp.length(),'0');
int goBit =0;
for (int j =  tmp.length()-1; j >= 0; --j) {

int tm = goBit + (tmp[j] -'0')* (num[i] - '0');
mid[j] = tm% 10 +'0';
goBit = tm  /10;
}

for (int q = num.length()-1; q> i; --q)
mid.push_back('0');
if (goBit != 0)
mid.insert(0, string(1, (char)goBit +'0'));

// 加法运算
if (i == num.length()-1)
src = mid;
else {

goBit =0;
string s(mid.length() - src.length(), '0');
src = s + src;
for (int j = mid.length()-1; j>=0; --j) {

int tm = (mid[j] - '0') +(src[j] - '0') + goBit;
src[j] = tm %10 + '0';
goBit = tm /10;
}

if (goBit !=0)
src.insert(0, string(1, (char)goBit +'0'));
}
}
return src;
}

int main(int argc, char** argv) {

string str;
while ( getline(cin, str)) {

// 分割出待积数 和 幂  以及小数点位置
int i =0;
int index = 0;// 小数位置
int count = 0;//幂次数
string num;
while ( i< str.length()) {

if ( str[i] != ' ') {

if (str[i] == '.')
index = i;
else
num.push_back(str[i]);
++i;
continue;
}
while ( !isdigit(str[i]))
++i;

if (i + 1 == str.length())
count = str[i] - '0';
else
count = (str[i] - '0') * 10 + str[i+1] - '0';
break;
}

index = num.length() - index;

string res = num;
for (int i =0; i< count-1; ++i) {

res = bigIntegerPlus( res, num);
}
index = index * count;

res.insert(res.length() - index, string("."));

while (res.length() >1 && res[0] == '0')
res.erase(0, 1);

for (int i =res.length()-1; i>=0; --i) {

if (res[i] == '0' )
res.erase(i, i+1);
else
break;
}
cout<< res<< endl;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: