• 高精度运算


    为了后面课程准备,先把基础的大数高精度运算先实现一遍。

      1 为了后面课程准备,先把基础的大数高精度运算先实现一遍。
      2 
      3 //BIGN.h
      4 
      5 #ifndef BIGN_H
      6 #define BIGN_H
      7 
      8 #include <iostream>
      9 #include <vector>
     10 #include <string>
     11 using namespace std;
     12 const int MAXN = 3000;
     13 
     14 //三元组gcd(a,b) = ax + by = d
     15 struct gcd
     16 {
     17     int x;
     18     int y;
     19     int d;
     20 };
     21 
     22 
     23 class bign
     24 {
     25 private:
     26     int n;   //参数n
     27     gcd m;   //定义一个三元组,使用欧几里得算法来进行递归求出最大公因子
     28 public:
     29     //阶乘的精确值
     30     string factorial(int n);
     31     
     32     /**
     33      *注:由于我们研究的密码学群Z的范围在{0,1,2,....,n-1}当中
     34      *故下面的大数相加,大数相减,大数相乘并没有考虑出现负数的情况
     35      */
     36 
     37     //大数相加
     38     string add(string a,string b);
     39 
     40     //大数相减
     41     //默认s1>=s2,未处理负数情况
     42     string sub(string a,string b);
     43 
     44     //大数相乘
     45     //未考虑负数相乘的情况
     46     string mul(string a,string b);
     47 
     48     //返回一个十进制数的二进制长度
     49     int BitLength(int x);
     50 
     51     //返回x的二进制表示中从低到高的第i位
     52     int BitAt(int x,int i);
     53 
     54     //返回值:a^b mod n 的值
     55     //通过模重复平方法
     56     int Modular_Expoent(int a,int b,int n);
     57 
     58     //返回一个三元组
     59     gcd extended_Euclid(int a,int b);
     60 
     61     //模逆运算
     62     int inverse(int a,int m);
     63 };
     64 
     65 string bign::factorial(int n)
     66 {
     67     string result;
     68     vector<long long> ff;
     69     ff.resize(MAXN);
     70     ff[0] = 1;
     71     int i,j;
     72     for(i = 2;i <= n;i++)
     73     {
     74         long long c = 0;
     75         for(j = 0;j < MAXN;j++)
     76         {
     77             long long s = ff[j] * i + c;   //模拟乘法的过程
     78             ff[j] = s % 10;
     79             c = s /10;
     80         }
     81     }
     82     for(j = MAXN - 1;j >= 0;j--)
     83     {
     84         if(ff[j])
     85             break;
     86     }
     87     for(i = j;i >= 0;i--)
     88     {
     89         result += (ff[i] + '0');
     90     }
     91     return  result;
     92 }
     93 
     94 
     95 string bign::add(string a,string b)
     96 {
     97     string result;
     98     string rr;
     99     int i;
    100     int l1,l2,len1,len2;
    101     l1 = len1 = a.size();
    102     l2 = len2 = b.size();
    103     int aa,bb,cc,dd;
    104     dd = 0;
    105     while(l1 > 0 && l2 > 0)
    106     {
    107         aa = a[l1-1] - '0';
    108         bb = b[l2-1] - '0';
    109         cc = (aa + bb+dd) % 10;
    110         dd = (aa + bb+dd) / 10;
    111         result += cc+'0';
    112         l1--;
    113         l2--;
    114     }
    115     while(l1 > 0)
    116     {
    117         aa = a[l1-1] - '0';
    118         cc = (aa + dd) % 10;
    119         dd = (aa + dd) / 10;
    120         result += cc + '0';
    121         l1--;
    122     }
    123     while(l2 > 0)
    124     {
    125         bb = b[l2-1] - '0';
    126         cc = (bb + dd) % 10;
    127         dd = (bb + dd) / 10;
    128         result += cc + '0';
    129         l2--;
    130     }
    131     if(dd == 1)
    132         result += '1';
    133     for(i = result.size() - 1;i >= 0 ;i--)
    134         rr += result[i];
    135     return rr;
    136 }
    137 
    138 string bign::sub(string Max,string Min)
    139 {
    140     string result;
    141     int lmax,lmin;
    142     lmax = Max.size();
    143     lmin = Min.size();
    144     int i,j,k;
    145     for(i = 0;i <= lmax;i++)
    146         result += '0';
    147     result[lmax] = '';
    148     lmax--;
    149     j = lmax;
    150     for(i = lmin - 1;i >= 0;i--,j--)
    151     {
    152         if(Max[j] - Min[i] >= 0)
    153         {
    154             result[j] = Max[j] - Min[i] + '0';
    155         }
    156         else
    157         {
    158             result[j] = 10 + Max[j] - Min[i] + '0';
    159             Max[j-1]--;
    160         }
    161     }
    162     while(Max[j] < 0)
    163     {
    164         Max[j] += 10;
    165         Max[j - 1]--;
    166         j--;
    167     }
    168     while(j >= 0)
    169     {
    170         result[j] = Max[j];
    171         j--;
    172     }
    173     return result;
    174 }
    175 
    176 
    177 string bign::mul(string aa,string bb)
    178 {
    179     if(aa == "0" || bb == "0")
    180         return "0";
    181     else
    182     {
    183         string result;
    184         int i,j;
    185         int len1 = aa.size();
    186         int len2 = bb.size();
    187         for(i = 0,j = len1 - 1;i <= j;i++,j--)
    188         {
    189             char temp = aa[i];
    190             aa[i] = aa[j];
    191             aa[j] = temp;
    192         }
    193         for(i = 0,j = len2 - 1;i <= j;i++,j--)
    194         {
    195             char temp = bb[i];
    196             bb[i] = bb[j];
    197             bb[j] = temp;
    198         }
    199         vector<int> c;
    200         c.resize(MAXN);
    201         for(i = 0;i < len1;i++)
    202         {
    203             for(j = 0;j < len2;j++)
    204             {
    205                 c[i+j] += (aa[i] - '0') * (bb[j] - '0');
    206             }
    207         }
    208         int k = len1 + len2;
    209         for(i = 0;i < k;i++)
    210         {
    211             if(c[i] > 9)
    212             {
    213                 c[i+1] += c[i] / 10;
    214                 c[i] %= 10;
    215             }
    216         }
    217         for(i = k - 1;i >= 0;i--)
    218         {
    219             if(c[i])
    220                 break;
    221         }
    222         for(j = i;j >= 0;j--)
    223         {
    224             result += (c[j] + '0');
    225         }
    226         return result;
    227     }
    228 }
    229 
    230 int bign::BitLength(int x)
    231 {
    232     int d = 0;
    233     while(x > 0)
    234     {
    235         x >>= 1;
    236         d++;
    237     }
    238     return d;
    239 }
    240 
    241 int bign::BitAt(int x,int i)
    242 {
    243     return ( x & (1 << (i - 1)) );
    244 }
    245 
    246 int bign::Modular_Expoent(int a,int b,int n)
    247 {
    248     int i,y = 1;
    249     for(i = BitLength(b);i > 0;i--)
    250     {
    251         y = (y * y) % n;
    252         if(BitAt(b,i) > 0)
    253             y = (y * a) % n;
    254     }
    255     return y;
    256 }
    257 
    258 gcd bign::extended_Euclid(int a,int b)
    259 {
    260     gcd aa,bb;
    261     if(b == 0)
    262     {
    263         aa.x = 1;
    264         aa.y = 0;
    265         aa.d = a;
    266         return aa;
    267     }
    268     else
    269     {
    270         bb = extended_Euclid(b,a%b);
    271         aa.x = bb.y;
    272         aa.y = bb.x - (a / b) * bb.y;
    273         aa.d = bb.d;
    274     }
    275     return aa;
    276 }
    277 
    278 int bign::inverse(int a,int m)
    279 {
    280     gcd aa;
    281     aa = extended_Euclid(a,m);
    282     return aa.x;
    283 }
    284 #endif
    285  
     
  • 相关阅读:
    LINQ体验(6)——LINQ语句之Join和Order By
    转 Spring.NET 与 NHibernate 的整合
    项目经理人必须要遵循的14个成功原则
    做成功的项目经理人
    就业模拟试题_Net(答案)
    java中的23中设计模式
    七种武器——.NET工程师求职面试必杀技
    如何识别真正的程序员
    WCF传输大数据的设置
    就业模拟试题_Java(答案)
  • 原文地址:https://www.cnblogs.com/sysu-blackbear/p/3335890.html
Copyright © 2020-2023  润新知