大数减法

string BigNum :: BigSub(string s1, string s2)
{
 int b, f, f1, i, j, t, t1, t2, l, l1, l2;
 char ct;
 string s11, s12, s21, s22, st, st1, st2;

 //cin>>s1;
 //cin>>s2;

 l1 = s1.size();
 l2 = s2.size();

 for(i=0, f=0, b=0; i<l1; ++i)
 {
  if(b==0)
  {
   if(s1[i]=='0'&&i<l1&&s1[i+1]!='.')// 被减数整数部分除前0--保留小数点前一个0
   {
    continue;
   }
   else
   {
    b = 1;
   }
  }

  if(s1[i]=='.')
  {
   f = 1;
   continue;
  }

  if(f==0)// 整数部分
  {
   s11 += s1[i];
  }
  else// 小数部分
  {
   s12 += s1[i];
  }
 }

 for(i=0, f=0, b=0; i<l2; ++i)
 {
  if(b==0)
  {
   if(s2[i]=='0'&&i<l2&&s2[i+1]!='.')// 减数整数部分除前0--保留小数点前一个0
   {
    continue;
   }
   else
   {
    b = 1;
   }
  }

  if(s2[i]=='.')
  {
   f = 1;
   continue;
  }

  if(f==0)// 整数部分
  {
   s21 += s2[i];
  }
  else// 小数部分
  {
   s22 += s2[i];
  }
 }

 s1.erase(0, l1);
 s2.erase(0, l2);
 
 l1 = s11.size();
 l2 = s21.size();
 f1 = 0;

 if(l1<l2)// 被减数整数小
 {
  f1 = 1;
 }
 else if(l1==l2)// 被减数整数和减数整数部分长度相等
 {
  for(i=0; i<l1; ++i)// 比较整数部分的每一位
  {
   if(s11[i]>s21[i])
   {
    f1 = -1;
    break;
   }

   if(s11[i]<s21[i])// 被减数整数小
   {
    f1 = 1;
    break;
   }
  }

  if(f1==0)// 整数部分相等--比较小数部分
  {
   l1 = s12.size();
   l2 = s22.size();

   for(i=0; i<l1&&i<l2; ++i)// 比较小数部分的每一位(取较小长度)
   {
    if(s12[i]>s22[i])
    {
     f1 = -1;
     break;
    }

    if(s12[i]<s22[i])
    {
     f1 = 1;
     break;
    }
   }

   if(f1==0)// 比较小数长度
   {
    if(l1<l2)
    {
     f1 = 1;
    }
   }
  }

  if(f1==-1)
  {
   f1 = 0;
  }
 }

 if(f1==1)// 被减数整数小则换位
 {
  st = s11;
  s11 = s21;
  s21 = st;
  st = s12;
  s12 = s22;
  s22 = st;
 }

 l1 = s12.size()-1;
 l2 = s22.size()-1;
 b = 0;
 f = 0;

 while(l1>=0||l2>=0)// 小数部分减法
 {
  if(l1>l2)// 被减数小数部分长度大--直接减(除小数末尾0)
  {
   if(b==1)
   {
    st2 += s12[l1];
   }
   else
   {
    if(s12[l1]!='0')// 除小数末尾0
    {
     st2 += s12[l1];
     b = 1;
    }
   }
   
   --l1;
   continue;
  }
  else if(l1<l2)// 被减数小数部分长度小
  {
   if(b==1)// 进行运算
   {
    t2 = s22[l2] - '0';
    t = 10 - t2 + f;
    f = -1;
    itoa(t, &ct, 10);// 整型数字转换为字符型数字
    st2 += ct;
   }
   else
   {
    if(s22[l2]!='0')// 除小数末尾0--并进行相应运算
    {
     t2 = s22[l2] - '0';
     t = 10 - t2 + f;
     f = -1;
     itoa(t, &ct, 10);// 整型数字转换为字符型数字
     st2 += ct;
     b = 1;
    }
   }

   --l2;
   continue;
  }
  else
  {
   t1 = s12[l1] - '0';// 字符型数字转换为整型数字
   t2 = s22[l2] - '0';// 字符型数字转换为整型数字
   --l1;
   --l2;

   t = t1 - t2 + f;// 两数相减(包括借位符)
   f = 0;

   if(t<0)// 数差小于0--借位
   {
    f = -1;
    t = t + 10;
   }
   
   itoa(t, &ct, 10);// 整型数字转换为字符型数字
   st2 += ct;
  }
 }

 for(i=s11.size()-1, j=s21.size()-1; i>=0||j>=0; --i, --j)// 整数部分减法
 {
  if(i>=0)// 被减数整数部分还有数
  {
   t1 = s11[i] - '0';// 字符型数字转换为整型数字
  }
  else// 被减数整数部分没有数则补0
  {
   t1 = 0;
  }

  if(j>=0)// 减数整数部分还有数
  {
   t2 = s21[j] - '0';// 字符型数字转换为整型数字
  }
  else
  {
   t2 = 0;// 减数整数部分没有数则补0
  }

  t = t1 - t2 + f;// 两数相减(包括借位符)
  f = 0;

  if(t<0)// 数差小于0--借位
  {
   f = -1;
   t = t + 10;
  }

  itoa(t, &ct, 10);// 整型数字转换为字符型数字
  st1 += ct;
 }

 if(f1==1)// 经过交换
 {
  st1 += '-';
 }

 l = st1.size();

 for(i=l-1, b=0; i>=0; --i)// 整数部分和入s1
 {
  if(b==0)
  {
   if(st1[i]=='-')// 符号入s1
   {
    s1 += st1[i];
   }

   if(st1[i]!='0'&&st1[i]!='-')// 除整数首0
   {
    s1 += st1[i];
    b = 1;
   }
  }
  else
  {
   s1 += st1[i];
  }
 }

 l = st2.size();

 if(l>0)// 有小数
 {
  if(f1==1&&s1.size()==1)// 整数为0时在小数点前添0--有'-'
  {
   s1 += '0';
  }

  if(f1==0&&s1.size()==0)// 整数为0时在小数点前添0--没有'-'
  {
   s1 += '0';
  }

  s1 += '.';
 }

 for(i=l-1; i>=0; --i)// 小数部分加入s1
 {
  s1 += st2[i];
 }

 if(s1.empty())
 {
  s1 = "0";
 }

 cout<<s1<<endl;
 return s1;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值