poj1001

本文介绍了一种使用字符串形式处理数学运算的方法,包括加法、乘法及幂运算等,并特别关注了浮点数的处理方式。文章通过具体的C++实现代码展示了如何避免浮点运算带来的精度误差。
#include<iostream>
#include<string>


using namespace std;


/**
 计算字符串s和字符ch的乘积值 
*/


string mutiple_ch(string s,char ch){
    string ans;
    int jinwei = 0;
    int jieguo = 0;
    for(int i=s.length()-1;i>=0 ;i--){
        int temp = (s.at(i)- '0') * (ch-'0') + jinwei;
        jinwei = temp/10;
        jieguo = temp%10;
        ans.insert(0,1,char(jieguo+'0'));
    }  
    if(jinwei != 0){
        ans.insert(0,1,char(jinwei+'0'));
    }      
    return ans;



/**
计算字符串s1和字符串s2的和值,x为s1的偏移数 
*/ 
string add_x(string s1,string s2, int x){
    string ans;
    /**for(int i=0;i<x;i++)
      s1.append(1,'0');*/
    s1.append(x,'0');
    int len = s1.length()>s2.length()?s1.length():s2.length();
    s1.insert(0,len-s1.length(),'0');
    s2.insert(0,len-s2.length(),'0');
    int jinwei = 0;
    int jieguo = 0;
    for(int i=len-1;i>=0;i--){
         int temp = (s1.at(i)- '0') + (s2.at(i)- '0') + jinwei;
        jinwei = temp/10;
        jieguo = temp%10;
        ans.insert(0,1,char(jieguo+'0'));
    } 
    if(jinwei != 0){
        ans.insert(0,1,char(jinwei+'0'));
    }    
    return ans;   
   
}       


/**
计算字符串s1和字符串s2的乘积 
*/


string mutiple(string s1,string s2){
    string fs1=s1,fs2=s2;//标准化后的字符串,去掉小数点
    //并记录s1,s2的小数点位数 
    
     
    int p1 = -1,p2 = -1;
    for(int i=0;i<s1.length();i++){
        if(s1.at(i) == '.')
         p1 = i;
    }   
    for(int i=0;i<s2.length();i++){
        if(s2.at(i) == '.')
         p2 = i;
    }   
    if(p1 != -1)
       fs1 = fs1.erase(p1,1);  
    if(p2 != -1)
       fs2 = fs2.erase(p2,1);  
    
    //修正前面为0的可能 
    int pos = 0 ;
    while(fs1.at(pos) == '0'){
        fs1 = fs1.erase(0,1); 
    }   
    while(fs2.at(pos) == '0'){
        fs2 = fs2.erase(0,1); 
    }   
    
      
    string ans = mutiple_ch(fs2,fs1.at(fs1.length()-1));
    for(int i=fs1.length()-2;i>=0;i--){
        string temp = mutiple_ch(fs2,fs1.at(i));
        ans = add_x(temp,ans,fs1.length()-1-i);
    }
    
    //累计两个小数的小数点位数 
    if(p1 != -1){
        p1 = s1.length()-1 - p1;
    }   
    if(p2 != -1){
        p2 = s2.length()-1 - p2 ;
    } 
    //cout<<p1<<" "<<p2<<endl;
    //当没有小数点时,特殊情况 
    if(p1 == -1){
        p1 = 0;
    }    
    if(p2 == -1 ){
        p2 = 0;
    }     
    //
    int ppos =  ans.length()-p2-p1;
    //cout<<ppos<<endl;
    //小数点可能要超出 位数前面补领 
    //修正计算结果,首先补0 ,然后补小数点 
     
     int hasp = 0;//是否有小数点 
    if(ppos < 0){
        ans.insert(0,0-ppos,'0');
        //ans.insert(ppos,1,'.'); 
        ans.insert(0,1,'.'); 
        hasp = 1; 
    }    
    else if(ppos < ans.length()){
      ans.insert(ppos,1,'.'); 
      hasp = 1;
   }    
     else {}
          
    //如果有后置零也要去掉
    while(hasp == 1 && ans.at(ans.length()-1) == '0'){
        ans.erase(ans.length()-1,1);
    }
    //去掉最后一个可能的小数点 
    if(ans.at(ans.length()-1) == '.'){
       ans.erase(ans.length()-1,1);
    }         
    return ans;
}    


/**
计算字符串s的a幂次方 
*/ 
string powerm(string s, int a){
    string ans = s;
    if(a == 1){
        //当a == 1是也需要检查,不能直接输出 
      while(ans.at(0) == '0'){
          ans.erase(0,1); 
      } 
      int flag = 0;
      for(int i=0;i<ans.length();i++){
          if(ans.at(i) == '.')
            flag = 1;
      }
      while(flag == 1 &&ans.at(ans.length() -1 ) == '0'){
          ans.erase(ans.length() -1,1);
      }       
      while(ans.at(ans.length() -1 ) == '.'){
          ans.erase(ans.length() -1,1);
      }    
      return ans;
    }    
    else{
        for(int i=0;i<a-1;i++){
            ans = mutiple(ans , s);
        }    
    } 
    return ans;   
}    


int main(void){
    string s;
    int n;
    while(cin>>s>>n){
        if(n<=0 || n>25)
         return 0; 
        cout<<powerm(s,n)<<endl;
    }    
    //system("pause");
  return 0;   
}    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值