高精度求整数的幂

Posted by Harid十月 - 27 - 2010 Leave comments   166 views 

这是我设计的一个求整数的高精度幂的一个算法,可以计算一个整数的 n 幂次的高精度结果。因为底数与指数圴为 int 型,所以理论上只要不超出 int 型的最大数,则可以求出0至32767以内的任一数的0至32767以内的任次幂的精确值,不过前提是程序要求你定的用来保存结果的数组的长度够长(没那么长,当然后面的值就掉了),这个值如果你输入了 1000 ,则程序能精确到一个4000位的结果。另外因为这里没有考虑多少算法效率,只为实现,所以还牵扯到计算时间。如果底数与指数同时很大,可能要很长的时间才能计算出来。例如2的1000次方是一个302位的数,所以只要400位长度的数组就能保存。程序里默认为2000单元的数组,即可以保存一个8000位长度的数。程序里默认底数是2,指数要求输入。

算法简要描述

算法是以万进制作为基础,通过使用数组来保存结果以达到保证计算结果精度的要求。

每个元素保存0至9999间的一个数,当乘以Base(底数)后该元素值大于9999后,则向上进一位,并将该值减去10000(while循环,确保进位正确)后的值(即小于等于9999的一个数)存入当前元素里,并注意补齐(如剩下34时,补为0034,输出时注意即可)。

最后输出。

2的1000次方的结果:

2的1000次方

10的79次方(每行为80个字符,所以刚好一行):

10的79次

32000的1000次方的结果(结果相当长,有三屏才能输出完全):

第一屏:

32000-1000-1

第三屏:

32000-1000-2

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
const int Base = 2;   /*the base number.Here is 2.*/
const long ArrSize = 4000; /*arrSize is 2000 meaning that the array can store a number which is 8000 bit.*/
unsigned long * getArray(long); /*Getting a array.*/
int main()
{
    using namespace std;
    int power = 1;   /*Initialize the exponent to 1.*/
    cout <<"\tPlease enter the exponent:\n\t";
    while (!(cin>>power) || power<0 || cin.get()!='\n')
    {
        cerr <<"Error! Eenter again: ";
        cin.clear();
        while (cin.get()!='\n')
            continue;
    }
    unsigned long * pt_arr;   /*point to the array.*/
    pt_arr = getArray(ArrSize);  /*Create a array and initialize it to zero.*/
    *pt_arr = Base;
    /*Start a calculation*/
    for(int i=1; i<power; i++)  /*Out shell is used to calculate an involution*/
    {
        for(int k=0; k<ArrSize; k++) /*Let array element multiply the Base firstly.*/
            if(*(pt_arr+k) != 0)     /*Then judge every element whether it is larger than 9999.*/
                *(pt_arr+k) *= Base;
        for(int j=0; j<ArrSize; j++)  /*Inner shell is used to make sure that every element won't overflow.*/
        {
            while(*(pt_arr+j) > 9999)
            {
                *(pt_arr+j) -= 10000; /*Make sure every element won't overflow.*/
                *(pt_arr+j+1) += 1;   /*a carry*/
            }
        }
    }
    /*End calculation*/
    /*Show result.*/
    short sign_first = 0;
    for(int m=ArrSize; m>=0; m--)
    {
        if(sign_first == 0 && (*(pt_arr+m)) != 0)
        {
            sign_first = 1;
            cout <<(*(pt_arr+m));
        }
        else if((*(pt_arr+m)) >999)
            cout <<*(pt_arr+m);
        else if((*(pt_arr+m)) <=9 && (*(pt_arr+m)) != 0)
            cout <<"000"<<*(pt_arr+m);
        else if((*(pt_arr+m)) >9 && (*(pt_arr+m)) <=99)
            cout <<"00"<<*(pt_arr+m);
        else if((*(pt_arr+m)) >99 && (*(pt_arr+m)) <=999)
            cout <<"0"<<*(pt_arr+m);
        if(sign_first == 1 && (*(pt_arr+m)) == 0)
            cout <<"0000";
    }
    cout <<endl;
    delete [] pt_arr;
    return 0;
}
unsigned long * getArray(long n)
{
    unsigned long * pt;
    pt = new unsigned long[n+1];
    for(int i=0; i<n; i++)
        *(pt+i) = 0;  /*Initialize every element to zero.*/
    return pt;
}

   声明:本文采用 BY-NC-SA 协议进行授权 | 星期九
   原创文章转载请注明:转自《高精度求整数的幂

分享本文: 腾讯微博 QQ空间 人人网 百度空间 开心网 新浪微博 Google Reader 豆瓣
Comments(44) Leave comments
  1. Gravatar
    Tanky Woo SouGou Browser SouGou Browser 2.X Windows Windows XP

    再次遇到高精度,可以把这个当成一个模板了。以后会经常用的。

    • Gravatar Harid  @  十二月 1st, 2010 at 23:48 replied.

      @Tanky Woo, 可以在这个基础上改一下,让它可以计算浮点数的乘方。

评论分页
2 + 8 =  (required)
 疑问 鼓掌 难过 呲牙 强 微笑 快哭了 坏笑 汗 奋斗 撇嘴 OK 偷笑 委屈 尴尬 傲慢 握手 玫瑰 胜利 大哭 抱拳
启用云输入法:      

NOTICE1: You should type some Chinese word (like “你好”) in your comment to pass the spam-check, thanks for your patience!

NOTICE2: 请申请gravatar头像(http://en.gravatar.com),木有头像的会显示为“小怪物”头像,将难以通过审核!

NOTICE3: 如果您能消除一下评论框旁边的邻居的寂寞的话,Harid将不胜感激,你懂的!^_^