问题:
给定一个浮点数R (0.0 < R < 99,999) 和整数n (0 < n <= 25),求R的n次幂
例子:
R = 95.123 , n = 12 ,则结果为:548815620517731830194541.899025343415715973535967221869852721
思路:
1.n次幂的结果超过了c++语言内置float数的界限,考虑用string来存储,并提供求n次幂功能
2.求n次幂:可以通过string的乘法迭代乘以自身 n-1来达到
3.两个sring相乘:需要提供string的加法和string乘以n(0<=n<=10)的功能
4.string加法:从最右边开始遍历,遍历string,将字符转为数字,相加,需要处理进位
5.string乘以n(0<=n<=10):遍历string,将字符转为数字,相乘,需要处理进位
6. 小数点处理:先忽略掉小数点,全部按整数处理,最后根据小数点位数,对结果进行插入小数点和补0处理
c++代码:
/*
Author: yongbo.zou@gmail.com
转载请注明出处
*/
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
struct ValuePair {
float r;
int n;
};
void getInput(istream& is, vector<ValuePair>& values)
{
ValuePair p;
while (is >> p.r >> p.n) {
values.push_back(p);
}
}
void printInput(const vector<ValuePair>& values)
{
for(size_t i = 0; i < values.size(); ++i) {
cout << values[i].r << " " << values[i].n << endl;
}
}
// 两个长整数相加
string sum(const string& a, const string& b)
{
string str;
int i = a.length() - 1;
int j = b.length() - 1;
int v1 = 0;
int v2 = 0;
int v = 0;
int carry = 0;
while (1) {
if (i < 0 && j < 0) {
break;
}
if(i >= 0) {
v1 = a[i] - '0';
}
else {
v1 = 0;
}
if(j >= 0) {
v2 = b[j] - '0';
}
else {
v2 = 0;
}
v = (v1 + v2 + carry) % 10;
carry = (v1 + v2 + carry) / 10;
str.insert(0, 1, char(v + '0'));
i--;
j--;
}
if (carry != 0) {
str.insert(0, 1, char(carry + '0'));
}
//cout << a.c_str() << " + " << b.c_str() << " = " << str.c_str() << endl;
return str;
}
// 长整数*单个数字, 0 <= b <= 10
string multi_num(const string& a, int num)
{
string str = "";
if(num <= 0 || num > 10) {
}
else if (num == 10) {
str = a;
str.append(1, '0');
}
else {
int v1 = 0;
int v2 = 0;
int v = 0;
int carry = 0;
for(int i = a.length()-1; i >= 0; --i) {
v1 = a[i] - '0';
v2 = num;
v = (v1 * v2 + carry) % 10;
carry = (v1 * v2 + carry) / 10;
str.insert(0, 1, char(v + '0'));
}
if (carry != 0) {
str.insert(0, 1, char(carry + '0'));
}
}
//cout << a.c_str() << " * " << num << " = " << str.c_str() << endl;
return str;
}
// 两个长整数相乘
string multi(const string& a, const string& b)
{
string str = "";
string tmp = a;
for(int i = b.length()-1; i >= 0; --i) {
str = sum(str, multi_num(tmp, b[i] - '0'));
tmp = multi_num(tmp, 10);
}
//cout << a.c_str() << " * " << b.c_str() << " = " << str.c_str() << endl;
return str;
}
string insertDot(const string& a, int afterDotNum)
{
if(afterDotNum == 0) {
return a;
}
// 需要补0
string str = a;
if (afterDotNum > a.length()) {
str.insert(0, afterDotNum - a.length(), '0');
str.insert(0, ".");
}
else {
str.insert(a.length()-afterDotNum, 1, '.');
}
//cout << a.c_str() << " right move " << afterDotNum << " = " << str.c_str() << endl;
return str;
}
string calcExponent(const ValuePair& value)
{
std::ostringstream buff;
buff << value.r;
string s1 = buff.str();
// 获取小数点位数
int bits = 0;
bool afterDot = false;
string tmp;
for(int i = 0; i < s1.length(); ++i) {
if (s1[i] == '.') {
afterDot = true;
}
else {
if (afterDot) {
bits++;
}
tmp.append(1, s1[i]);
}
}
string str = tmp;
for(int i = 0; i < value.n - 1; ++i) {
str = multi(str, tmp);
}
str = insertDot(str, bits * value.n);
//cout << s1.c_str() << " ^ " << value.n << " = " << str.c_str() << endl;
return str;
}
int main(int argc, char** argv)
{
vector<ValuePair> values;
if (argc >= 2) {
ifstream is("input.txt");
getInput(is, values);
}
else {
getInput(cin, values);
}
for(size_t i = 0; i < values.size(); ++i) {
cout << calcExponent(values[i]).c_str() << endl;;
}
}