您的位置:首页 > 其它

POJ1001 Exponentiation

2017-01-09 22:17 253 查看
超越double,高精度实数求幂运算

大二的时候写过大整数的运算,这道acm题目则是实数高精度运算。

分步的思想,先将小数点删除作为大整数运算,模拟一遍手算乘法的过程小数点位置,只需要通过看是几位小数乘几位小数即可,大部分借鉴了他人的代码,理解就花了很长时间,但做了多余条件的删选,不失为一个实用的轮子。

另,这里是用字符串接受输入,要通过ascii码转化,看了java版本好像更精炼。

#include <iostream>
#include <string>

using namespace std;

int main()
{
string mlp;     //乘数
int power;     //乘数的幂
int r[151];    //保存结果
int hdot;
while(cin>>mlp>>power)
{
hdot=0;       //小数点位置,从右侧计起
//初始化存放结果,每一位都为1
for(int t=0;t<150;t++)
{
r[t]=-1;
}
//存在小数点的情况
if(mlp.find(".")!=string::npos)
hdot=mlp.length()-mlp.find(".")-1;
//itr迭代器的指向末尾字母
string::iterator itr=mlp.end()-1;
//小数点不在0位,开始迭代
while(hdot>0&&itr>=mlp.begin())
{
//若小数点存在数字间,去掉末尾的无效零
if(*itr!='0')
{
break;
}
//否则,后移
hdot--;
itr--;
}
int cn=0;
//迭代器前移
//r数组从0开始存放临时结果,0为最低位。cn为临时结果的下标
while(itr>=mlp.begin())
{
if(*itr!='.')
{
r[cn]=*itr-'0';
cn++;
}
itr--;
}
int k=cn-1;   //下标从cn-1开始,cn-1为最高位
int m=0;     //保存临时数;
while(k>-1)
{
m=m*10+r[k];
k--;
}
for(int i=1;i<power;i++)
{
int j=0;
while(r[j]>-1)
{
r[j]=r[j]*m;
j++;
}
j=0;
while(r[j]>-1)
{
//j+1位置上仍是-1,把大于10的部分进位
if(r[j+1]==-1&&r[j]>=10)
r[j+1]=r[j]/10;
else
r[j+1]+=r[j]/10;
r[j]=r[j]%10;
j++;
}
}
//小数点的位置
hdot=hdot*power;
int cnt=0;
while(r[cnt]>-1)
{
cnt++;
}
if(hdot>=cnt)
{
cout<<".";
while(hdot>cnt)
{
cout<<"0";
hdot--;
}
//小数点位置置为0
hdot=0;
}
for(k=cnt-1;k>=0;k--)
{
//当前位的前一位为小数点位
if((k+1)==hdot)
cout<<".";
cout<<r[k];
}
cout<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm ascii