acm1001 Exponentiation

题目是求一个实数R的n次方,其中(0.0<R<99.999 0<n<=25)。

这道题目的提议很明显,是一个精度问题,要想精确的表示精度,最好的方法就是用字符串去存储结果。思路很简单,就是要写一个能够计算两个字符串相乘的函数,然后根据n的大小来计算调用的次数。代码如下(本人水平有限,代码会有一定的冗余,仅供参考):

#include <iostream> #include <string> #include <cmath> using namespace std; void addStr(string s1, string &s2) { if(s2.empty()) { s2 = s1; return ; } int size_s1 = s1.size(); int size_s2 = s2.size(); int len = (size_s1 > size_s2) ? size_s2 : size_s1; int carry = 0; int i; for(i = 0; i < len; i++) { int x = s1[i] - '0'; int y = s2[i] - '0'; int value = x + y; if(carry) { value += carry; } if(value > 9) { carry = 1; value %= 10; } else { carry = 0; } s2[i] = '0' + value; } if(size_s1 == size_s2) { if(carry) { s2 += '0' + 1; } } else if(size_s1 > size_s2) { for(int j = len; j < size_s1; j++) { int value = s1[j] - '0'; if(carry) { value += carry; } if(value > 9) { carry = 1; value = value % 10; } else { carry = 0; } char valueChar = '0' + value; s2 += valueChar; if(j == size_s1 - 1) { if(carry) { valueChar = '0' + carry; s2 += valueChar; } } } } else { for(int j = len; j < size_s2; j++) { int value = s2[j] - '0'; if(carry) { value += carry; } if(value > 9) { carry = 1; value = value % 10; } else { carry = 0; } char valueChar = '0' + value; s2[j] = valueChar; if(j == size_s2 - 1) { if(carry) { valueChar = '0' + carry; s2 += valueChar; } } } } } string multiplyStr(string str1, string str2) { int dot1 = str1.size() - str1.find('.') - 1; int dot2 = str2.size() - str2.find('.') - 1; int dot = dot1 + dot2; string retStr; string tmpStr; for(int i = str2.size() - 1; i >= 0; i--) { if(str2[i] == '.') { continue; } int m2 = str2[i] - '0'; int carry = 0; for(int k = 0; k < str2.size() - i - 1; k++) { tmpStr += '0'; } if((str2.size() - i - 1) > dot2) { tmpStr = tmpStr.substr(0, tmpStr.size() - 1); } for(int j = str1.size() - 1; j >= 0; j--) { if(str1[j] != '.') { int m1 = str1[j] - '0'; int value = m1 * m2; if(carry) { value += carry; } if(value > 9) { carry = value / 10; value = value % 10; } else { carry = 0; } char valueChar = '0' + value; tmpStr += valueChar; if(j == 0 && carry) { char carryStr = '0' + carry; tmpStr += carryStr; } } } addStr(tmpStr, retStr); tmpStr.clear(); } string ret; for(int k = retStr.size() - 1; k >= 0; k--) { ret += retStr[k]; } if(dot >= retStr.size()) { int count = dot - retStr.size(); cout << "count=" << count; for(int l = 0; l < count; l++) { ret = "0" + ret; } ret = "." + ret; ret = "0" + ret; return ret; } else { ret.insert(retStr.size()- dot, "."); return ret; } } int main() { string s; double power; double d = 2; while(cin >> s >> power) { string s_copy = s; int num = log(power) / log(d); // 求log2(x) for(int i = 0; i < num; i++) { s = multiplyStr(s, s); } if(power > pow(d, num)) { for(int j = 0; j < power - pow(d, num); j++) { s = multiplyStr(s, s_copy); } } if(s[0] == '0') { s = s.substr(1, s.size() - 1); } int zeroCount = 0; for(int p = s.size() - 1; p >= 0; p--) { if(s[p] == '0') { zeroCount++; } else { break; } } s = s.substr(0, s.size() - zeroCount); if(s[s.size()-1] == '.') { s = s.substr(0, s.size() - 1); } cout << s << endl; } return 0; }

你可能感兴趣的:(String,存储)