http://poj.org/problem?id=1001
刚接触高精度不久,就去poj找了一道题做,这道题,其实不用写成高精度乘高精度,可以把问题解析称几个小问题,逐一解决.首先注意到,他是幂运算,所以,而且原数位数固定为
6位,所以,只用写高精度乘一个低位数即可,而高精乘一个6位数,可以解析乘高精乘一个1位数,在相加 :
a∗123456=a∗100000+a∗20000+a∗3000+a∗400+a∗50+a∗6
其次,还有小数如何处理,可以先移动原数的小数点使其为整数,得到的结果,在计算要移动的小数点位数,然后在移动还原
所以:可以分成几个问题解决:
1.高精度加法
2.高精度称一个1位数
3.高精度成一个多位数
4.多位数的幂相当于一个高精不断乘一个多位数
5.小数点还原:记录原数移动到成整数移动的小数点位数l,最终移动的位数为幂
n∗l
6.前导的0和末尾的0的消除,还要注意如果移动的小数点位数大于最后高精数位数,要在前面补0, 例如 123456789, 但要移动着12位, 则结果为0.000123456789
/*
Name: 1001
Copyright: POJ
Author: boyce
Date: 02/07/16 23:28
Description:
*/
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
using namespace std;
string add(string a, string b) {
if (a.size() < b.size()) return add(b, a);
int carry = 0;
string ret = "0";
ret += a;
for (int i = ret.size() - 1, j = b.size() - 1; j >= 0; i--, j--) {
int sum = ret[i] - '0' + b[j] - '0' + carry;
carry = sum / 10;
ret[i] = sum % 10 + '0';
}
for (int i = ret.size() - b.size() - 1; i >= 0; i--) {
int sum = carry + ret[i] - '0';
carry = sum / 10;
ret[i] = sum % 10 + '0';
}
if (ret[0] == '0') ret.erase(0, 1);
return ret;
}
string multiple_1(string a, int b) {
string ret = "0";
ret += a;
int carry = 0;
for (int i = ret.size() - 1; i >= 0; i--) {
int sum = carry + (ret[i] - '0')*b;
carry = sum / 10;
ret[i] = sum % 10 + '0';
}
if (ret[0] == '0') ret.erase(0, 1);
return ret;
}
string multiple_2(string a, string b) {
int bit = 0;
string ret = "0";
for (int i = b.size() - 1; i >= 0; i--) {
int num = b[i] - '0';
string tmp = a;
tmp.append(bit, '0');
tmp = multiple_1(tmp, num);
ret = add(ret, tmp);
bit++;
}
return ret;
}
string power(string a, int n) {
string ret = a;
for (int i = 0; i < n - 1; i++) {
ret = multiple_2(ret, a);
}
return ret;
}
int main() {
string s;
int n;
while(cin >> s >> n) {
string num = s;
int l = num.find('.');
int back; // 小数点移动位移
if (l != string::npos) {
back = (num.size() - 1 - l)*n; //小数点后的位数
num.erase(l, 1);
} else back = 0;
num = power(num, n);
if (back > 0) {
int pos = num.size() - back ; //
if (pos >= 0) num.insert(pos, ".");
else {
for (int i = 0; i < (-pos); i++) num.insert(0, "0");
num.insert(0, ".");
}
}
int cut_l = 0;
for (int i = 0; i < num.size(); i++) {
if (num[i] == '0') cut_l++;
else break;
}
num.erase(0, cut_l);
cut_l = 0;
for (int i = num.size() - 1; i >= 0; i--) {
if (num[i] == '0') cut_l++;
else break;
}
num.erase(num.size() - cut_l, cut_l);
if (num[num.size() - 1] == '.') num.erase(num.size() - 1, 1); // 针对这种特殊情况: 12.0 2 >> 144. >> 144
if (!num.empty()) cout << num << endl;
else cout << 0 << endl; // num == "" >> cout << 0
}
return 0;
}