高精度的算法,想不到的是输出竟然是.25而不是0.25!
这个我已经改得很完善了,再变态的数据我都不怕!
我的程序代码:
/********************************************************************************
HighPrecision.h(Simple_Edition)
Function Introduction:
支持以string类为存放格式的正整数的多精度运算(包括+、-、*、Div(整除、取余),部分允许string式的"整型"与int型混合运算,结果一律用string 型存放(多精度对单精度取余(用int)除外!)
Usage:
1. 所用的长整型(string存放)只能包含数字字符,而且必须为正数;开头不能有多余的零;
2. 长整型可以和int型混合加、减、乘运算,但int必须在后;
3. 若直接用 "541" 等字符串常量,必须显式使用构造函数string转化,方可参加运算:
eg: string s="4554343645476767446";
cout<<s+string("541")<<endl;
4. 包含本.h后,std::string 的 + 功能丧失,请用 += 、string::insert() 等代替!!!
5. 目前还不支持多精度除多精度,请慎用!
6. 多精度除以单精度,调用Div函数,可同时得到整商(返回值)和余数(residue引用返回).
7. 注意,重载运算符不影响优先级和结合性,可以做四则运算!
8. 注意:用Div做除法时 s 和 a 必须都是正数 !!!
9. 注意:减法要保证大数减去小数!!!
Designed, coded and revised by:
Heskey (2003.10)
********************************************************************************/
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
using namespace std;
const int MAXRESULT=1000; // 结果最长位数!
//-------------------------------------------------------------------
string operator+(string s1, string s2);
string operator+(string s, int a);
string operator-(string s1, string s2);
string operator-(string s, int a);
string operator*(string s1, string s2);
string operator*(string s, int a);
string Div(string s, int a, int &residue);
string IntToString(int a);
//-------------------------------------------------------------------
string operator+(string s1, string s2)
{
string result;
result.reserve(MAXRESULT);
if(s1.length() < s2.length())
s1.swap(s2);
s2.insert(s2.begin(), s1.length()-s2.length(), '0');
int cf=0;
for(int i=s1.length()-1; i>=0; --i)
{
cf += s1[i]+s2[i]-2*'0';
result += cf%10+'0';
cf /= 10;
}
if(cf>0)
result += cf+'0';
reverse(result.begin(), result.end());
return result;
}
//-------------------------------------------------------------------
string operator+(string s, int a)
{
return s + IntToString(a);
}
//-------------------------------------------------------------------
string operator-(string s1, string s2) // s1必须大于s2
{
if(s1 == s2)
return "0";
string result;
result.reserve(MAXRESULT);
s2.insert(s2.begin(), s1.length()-s2.length(), '0');
int cf=0;
for(int i=s1.length()-1; i>=0; --i)
{
if(s1[i] >= s2[i]+cf)
{
result += s1[i]-s2[i]-cf+'0';
cf=0;
}
else
{
result += 10+s1[i]-s2[i]-cf+'0';
cf=1;
}
}
reverse(result.begin(), result.end());
int pos=result.find_first_not_of('0');
result.erase(result.begin(), result.begin()+pos);
return result;
}
//-------------------------------------------------------------------
string operator-(string s, int a)
{
return s - IntToString(a);
}
//-------------------------------------------------------------------
string operator*(string s1, string s2)
{
string result="0";
result.reserve(MAXRESULT);
for(int i=s2.length()-1; i >= 0; --i)
{
string temp = s1*(s2[i]-'0');
temp.insert(temp.end(), s2.length()-1-i, '0');
result = result+temp;
}
return result;
}
//-------------------------------------------------------------------
string operator*(string s, int a) // 注意:a must less than 2*10^8
{
string result;
result.reserve(MAXRESULT);
if(a==0)
return string("0");
int cf=0;
for(int i=s.length()-1; i>=0; --i)
{
cf += a*(s[i]-'0');
result += (cf%10+'0');
cf /= 10;
}
while(cf>0)
{
result += (cf%10+'0');
cf /= 10;
}
reverse(result.begin(), result.end());
return result;
}
//-------------------------------------------------------------------
string Div(string s, int a, int &residue) // 注意:s 和 a 必须都是正数 !!!
{
string result;
result.reserve(MAXRESULT);
int res=0;
for(int i=0; i<s.length(); i++)
{
res = 10*res+s[i]-'0';
result += res/a+'0';
res %= a;
}
residue=res; // 余数!
int pos=result.find_first_not_of('0');
result.erase(result.begin(), result.begin()+pos);
return result;
}
//-------------------------------------------------------------------
string IntToString(int a)
{
ostringstream oss;
oss<<a;
return oss.str();
}
int main()
{
int n,i,j,len,w,flag,s,k,g;
char ch[10];
while(cin>>ch>>n)
{
string D,T,S1,S2,Temp("1");
i=0;
s=0;
flag=0;
k=0;
if(ch[0]=='0')
{
len=strlen(ch);
for(j=0;j<len;j++)
if(ch[j]=='.')
break;
if(j!=2)
{
k=0;
while(ch[k]=='0')
{
k++;
}
j=k;
k=0;
while(j!=len)
{
if(ch[j]=='.')
{
flag=1;
j++;
continue;
}
if(!flag)
k++;
s*=10;
s+=(ch[j]-'0');
j++;
if(flag)
i++;
}
flag=1;
}
if(!flag)
{
j=2;
i++;
while(ch[j]=='0')
{
j++;
i++;
}
if(j!=2)
i--;
len=strlen(ch);
while(j!=len)
{
if(ch[j]=='.')
{
j++;
continue;
}
s*=10;
s+=(ch[j]-'0');
j++;
i++;
}
i--;
}
}
else
{
j=0;
flag=0;
k=0;
len=strlen(ch);
while(j!=len)
{
if(ch[j]=='.')
{
j++;
flag=1;
continue;
}
if(!flag)
k++;
if(flag)
i++;
s*=10;
s+=(ch[j]-'0');
j++;
}
}
g=1;
while(!(s%10)&&(i!=0||k!=0))
{
if(k>1)
{
g=1;
for(j=1;j<k;j++)
g*=10;
}
if(((s%g)||g==s))
break;
s/=10;
i--;
}
if(s==0)
i=0;
if(i==0&&k==0)
s=0;
flag=0;
D=Temp*s;
S1=Temp*1;
w=0;
for(j=0;j<n;j++)
{
S1=S1*D;
w+=i;
}
len=S1.size();
flag=0;
if(i==0)
cout<<S1;
else if(w>=len)
{
cout<<".";
for(j=0;j<w-len;j++)
cout<<"0";
cout<<S1;
}
else
{
for(j=0;j<len;j++)
{
if(j==len-w&&!flag)
{
flag=1;
cout<<".";
j--;
continue;
}
cout<<S1[j];
}
}
cout<<endl;
}
return 0;
}