高精度开方

  X的二分之一次方怎么求?二分!

  首先求整数部分,从1到X二分答案,选择最接近的那个

  然后是求第一位小数部分,用高精度乘法模拟平方,看看得出的数是否比X大,或者比X小,从0到9不断二分即可

  然后是第二位小数......

 

 

View Code
  1 #include<iostream>
  2 #include<string>
  3 #include<algorithm>
  4 using namespace std;
  5 
  6 int n,nlen;
  7 char str[22];
  8 int c[1000];
  9 int a[1000],b[1000],d[1000];
 10 
 11 int isok(int len)
 12 {
 13     memset(a,0,sizeof(a));
 14     memset(b,0,sizeof(b));
 15     int i,j,t;
 16     t=2*(len-1); //t 是小数的位数
 17     for(j=0,i=len-1;i>=0;i--)
 18     {
 19         a[j++]=c[i];
 20     }
 21     for(i=0;i<len;i++)
 22     {
 23         for(j=0;j<len;j++)
 24         {
 25             b[i+j]+=a[i]*a[j];
 26         }
 27     }
 28     len=2*len-1;
 29     for(i=0;i<len;i++)
 30     {
 31         b[i+1]+=b[i]/10;
 32         b[i]%=10;
 33     }
 34     while(b[len])
 35     {
 36         b[len+1]+=b[len]/10;
 37         b[len]%=10;
 38         len++;
 39     }
 40     if(len-t<nlen) //整数位数小于给定的N的长度,则返回小于
 41         return -1;
 42     if(len-t>nlen) //返回大于
 43         return 1;
 44     for(i=len-1,j=nlen-1;i>=0 && j>=0;i--,j--)
 45     {
 46         if(d[j]>b[i])
 47             return -1;
 48         if(d[j]<b[i])
 49             return 1;
 50     }
 51     while(i>=0)
 52     {
 53         if(b[i]) //整数部分相等,小数部分有值的话,返回大于
 54             return 1;
 55         i--;
 56     }
 57     return 0; //等于
 58 }
 59 
 60 int main()
 61 {
 62     int cas,i;
 63     freopen("in.txt","r",stdin);
 64     scanf("%d",&cas);
 65     while(cas--)
 66     {
 67         scanf("%d",&n);
 68         memset(c,0,sizeof(c));
 69         nlen=0;
 70         int l,r,t,mid,tt;
 71         t=n;
 72         while(t) //将输入的n转化成串的形式,便于比较大小
 73         {
 74             d[nlen]=t%10;
 75             nlen++;
 76             t/=10;
 77         }
 78         l=1;r=n;
 79         int flag=0; //标记是否相等
 80         while(l<=r) //求整数部分
 81         {
 82             mid=(l+r)/2;
 83             c[0]=mid;
 84             tt=isok(1);
 85             if(tt>0)
 86             {
 87                 r=mid-1;
 88             }
 89             else if(tt<0)
 90             {
 91                 
 92                 t=mid;
 93                 l=mid+1;
 94             }
 95             else if(tt==0) 
 96             {
 97                 t=mid;
 98                 flag=1;
 99                 break;
100             }
101         }
102         c[0]=t;
103         for(i=1;i<120;i++) //模拟开方的前119位小数
104         {
105             if(flag) //相等的话,就不用继续求了
106                 continue;
107             l=0;r=9;
108             while(l<=r)
109             {
110                 mid=(l+r)/2;
111                 c[i]=mid;
112                 tt=isok(i+1);
113                 if(tt>0)
114                 {
115                     r=mid-1;
116                 }
117                 else if(tt<0)
118                 {
119                     
120                     t=mid;
121                     l=mid+1;
122                 }
123                 else if(tt==0)
124                 {
125                     t=mid;
126                     flag=1;
127                     break;
128                 }
129             }
130             c[i]=t;
131         }
132         printf("%d.",c[0]);
133         for(i=1;i<120;i++)
134             printf("%d",c[i]);
135         printf("\n");
136     }
137     return 0;
138 }
posted @ 2012-10-17 16:07  Accept  阅读(1130)  评论(0编辑  收藏  举报