大数除法1

来源:互联网 发布:淘宝代运营被骗案判例 编辑:程序博客网 时间:2024/04/29 04:36

string BigNum :: BigDiv(string s1, string s2)
{
 int b, i, j, k, f, f1, f2, l1, l2, sl1, sl2, t, t1, t2;
 int *n, *n1, *n2;
 char ct;
 string st, st1, st2;

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

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

 for(i=0, b=0, f=0, f1=0, sl1=0; i<l1; ++i)// 转换为不带符号的大整数
 {
  if(s1[i]=='-')// 除符号并进行相应记录
  {
   ++f;
   continue;
  }

  if(s1[i]=='.')// 除小数点并进行相应记录
  {
   f1 = 1;
  }
  else
  {
   if(b==0&&f1==0)// 除整数部分首0
   {
    if(s1[i]!='0')
    {
     st1 += s1[i];
     b = 1;
    }
   }
   else
   {
    st1 += s1[i];
   }

   if(f1==1)// 记录小数位数
   {
    ++sl1;
   }
  }
 }

 for(i=0, b=0, f1=0, sl2=0; i<l2; ++i)// 转换为不带符号的大整数
 {
  if(s2[i]=='-')// 除符号并进行相应记录
  {
   ++f;
   continue;
  }

  if(s2[i]=='.')// 除小数点并进行相应记录
  {
   f1 = 1;
  }
  else
  {
   if(b==0&&f1==0)// 除整数部分首0
   {
    if(s2[i]!='0')
    {
     st2 += s2[i];
     b = 1;
    }
   }
   else
   {
    st2 += s2[i];
   }

   if(f1==1)// 记录小数位数
   {
    ++sl2;
   }
  }
 }

 s1.erase(0, l1);
 s2.erase(0, l2);

 if(f==1)
 {
  s1 += '-';
 }

   // 除处理后的大数的首0--“0.001->001”情况
 st = st1;
 l1 = st.size();
 st1.erase(0, l1);

 for(i=0, b=0; i<l1; ++i)
 {
  if(b==0)// 除大数首0
  {
   if(st[i]!='0')
   {
    st1 += st[i];
    b = 1;
   }
  }
  else
  {
   st1 += st[i];
  }
 }

 st = st2;
 l2 = st.size();
 st2.erase(0, l2);

 for(i=0, b=0; i<l2; ++i)
 {
  if(b==0)// 除大数首0
  {
   if(st[i]!='0')
   {
    st2 += st[i];
    b = 1;
   }
  }
  else
  {
   st2 += st[i];
  }
 }

 st.erase(0, l2);

 l1 = st1.size();
 l2 = st2.size();

 n = new int[l2];
 n1 = new int[l2+1];
 n2 = new int[l2];


 for(i=0, f=0; i<l2; ++i)// 从被除数中取数长度同除数(不够补0)
 {
  if(i<l1)
  {
   t1 = st1[i] - '0';
  }
  else// 补0
  {
   ++f;
   st += '0';// 商上0
   t1 = 0;
  }

  if(f==1)// 添小数点
  {
   st += '.';
  }

  t2 = st2[i] - '0';

  n[i] = t1;
  n2[i] = t2;
 }


 for(i=l2, f2=0; i<l1+l2+T;)// 计算--T为精度
 {
  for(j=0, b=0; j<l2; ++j)// 判断被除数取数是否大于除数
  {
   if(n[j]>n2[j])
   {
    break;
   }

   if(n[j]<n2[j])
   {
    b = 1;
    break;
   }
  }
  
  for(j=0; j<l2; ++j)// 过程赋值
  {
   n1[j] = n[j];
  }
  
  if(b==1)// 增加一位使取得的被除数部分大于除数
  {
   if(i<l1)// 被除数有数
   {
    n1[j] = st1[i] - '0';
   }
   else// 补0
   {
    ++f;
    n1[j] = 0;
   }

   if(f2==0)// 已经正常移位使f2为0
   {
    st += '0';
    f2 = 1;
   }

   if(f==1)
   {
    st += '.';
   }

   ++i;
  }

  f2 = 1;// 防止上次正常移位使f2为0导致这次b为1时需要使商为0

  for(k=9, f1=0; k>0; --k)// 试除并确定商
  {
   if(b==1)// 有增加位情况
   {
    t1 = n1[0];
    t = 1;
   }
   else// 无增加位情况
   {
    t1 = 0;
    t = 0;
   }

   for(j=0; j<l2;)// 对除数乘k值与被除数取数部分比较
   {
    if(f1==0)
    {
     t1 = 10*t1 + n1[t];
    }

    t2 = n2[j];

    if(t1>100)// 已经确定被除数取数部分大于除数乘k值则直接运算
    {
     f1 = 1;
     n[j] = k * t2;
     ++j;
    }
    else
    {
     if(t1>=k*t2)// 每一位除数乘k值与对应被除数位比较
     {
      t1 = t1 - k*t2;
      n[j] = k * t2;
      ++t;
      ++j;
     }
     else
     {
      break;
     }
    }
   }

   if(j==l2)// 整除则不考虑精度
   {
    break;
   }
  }

  itoa(k, &ct, 10);// 整型数字转换为字符型数字
  st += ct;// 商值记录

  for(j=l2-1; j>=0; --j)// 处理除数乘k值结果
  {
   if(n[j]>9&&j>0)
   {
    n[j-1] += n[j] / 10;
    n[j] = n[j] % 10;
   }
  }

  if(b==1)// 有增加位情况
  {
   t = l2;
  }
  else
  {
   t = l2 - 1;
  }

  for(j=l2-1, f1=0; j>=0; --j, --t)// 被除数取数部分减除数乘k的值
  {
   if(j==0&&t==1)// 有增加位情况需对首位特殊处理
   {
    n[j] = 10*n1[j] + n1[t] - n[j] + f1;
   }
   else
   {
    if(n1[t]<n[j])// 借位
    {
     n[j] = 10 + n1[t] + f1 - n[j];
     f1 = -1;
    }
    else
    {
     n[j] = n1[t] - n[j] + f1;
     f1 = 0;
    }
   }
  }

  k = 0;// 整除记录
  t = 0;// 移位补0记录

  while(1)
  {
   if(n[0]!=0)// 不需移位
   {
    break;
   }
   else
   {
    ++t;

    for(j=0; j<l2-1; ++j)// 移位
    {
     n[j] = n[j+1];
    }

    if(i<l1)
    {
     n[j] = st1[i] - '0';
     ++i;
    }
    else
    {
     ++f;
     ++k;
     n[j] = 0;
    }
   
    if(t>1)// 移位超过一次则商上0
    {
     st += '0';
    }

    if(k==l2)// 整除
    {
     break;
    }

    if(f==1)// 商上小数点
    {
     st += '.';
    }
    
    f2 = 0;// 有移位则使f2为以便被除数取数部分小于除数需补数时对商上0
   }
  }

  if(k==l2)// 整除
  {
   break;
  }
 }