求一数的N次方的最后几位数(待续)

来源:互联网 发布:齐次矩阵性质 编辑:程序博客网 时间:2024/05/17 03:27

  我曾遇到过一个求解一个数的N次方的末尾几位数字的问题。我首先想到的是先求出它的N次方,然后

再分解这个结果。可是后来又考虑到数据溢出问题,因此这个方法有很大的局限性。
  然后我列出几个算式。发现要求最后几位数,跟本没必要把最后的结果求出来。如求X的Y次方末尾M位

数,只需在每部计算时保留中间结果的后M位数就可以了,然后用这M个数依次去乘X,最后再移位相加即

可。
  如:(M=3)  123*123*123=1860867
         123
       * 123
     ---------
         369
        246
       123
     ---------
       15129  
  此时,只需保留15429的最后三位:4,2,9,然后再计算
        129
      * 123
     --------
        387
       258
      129
     --------
        867 


  于是我写下了如下的代码:(DEV C++编译通过) 
 #include<stdio.h>
 #define MAX 5
 int sub_digits[4],//存放中间结果,如上例中的387,258,129等
 rear[MAX];//存放末尾数
 int depart(int m,int digits[],int n)
 {
 //分解数m的最后n位,并返回实际分解出的位数
     int i;
         for(i=0;i<n;i++)
          {
                digits[i]=m%10;
               m/=10;
              if(!m)
                   break;
          }
         if(i!=n)
         return i+1;
            return i;
 }
 long ntimes(int m,int n)
 {
     long result,x=(long)m;
     result=1L;
     while(n--)
     {
         result*=x;
     }
     return result;
 }
 int main()
 {
     int m,n,i,N,j;
     int n_rear;
     int extra;
     long sum;
      printf("底数m,指数n,取最后N位数: ");
      scanf("%d,%d,%d",&m,&n,&N);
      n_rear=depart(m,rear,N);
      for(j=1;j<n;j++)
      {
               for(i=0;i<n_rear;i++) 
                     sub_digits[i]=rear[i]*m;
               extra=1;
        sum=0L;
               for(i=0;i<n_rear;i++)
               {
                     sum+=sub_digits[i]*extra;
                     extra*=10;
               }
               n_rear=depart(sum,rear,N);
        }
       for(i=0;i<N;i++)
         printf("%d ",rear[i]);
          printf("/n/n%d的%d次方结果为:%d",m,n,ntimes(m,n));
     getch();
     return 0;
 }
  以上代码只是大致实现了那个思路,但它还是不完善,它的局限性在于sum+=sub_digits[i]*extra;由

于sum变量是long型的,还是会产生数据溢出。要能计算更大的结果,可以用一个数组代替

sum.........(To be continued).

原创粉丝点击