• 高精度模板


    高精度模板,留个备份:

      1 #include <cstdio>
      2 #include <cstring>
      3 
      4 struct BigNumber
      5 {
      6     static const long long BASE = 1000000000;
      7     static const int BASEDIGS = 9;
      8     
      9     int ndigs;
     10     long long *digs;
     11     
     12     void init(int n, const long long *d)
     13     {
     14         while (n > 0 && d[n - 1] == 0)
     15             --n;
     16         ndigs = n;
     17         digs = new long long[n];
     18         for (int i = 0; i < n; ++i)
     19             digs[i] = d[i];
     20     }
     21     
     22     BigNumber(int n, const long long *d)
     23     {
     24         init(n, d);
     25     }
     26     
     27     BigNumber operator <<(int sh) const
     28     {
     29         int n = sh + ndigs;
     30         long long d[n];
     31         for (int i = 0; i < sh; ++i)
     32             d[i] = 0;
     33         for (int i = 0; i < ndigs; ++i)
     34             d[i + sh] = digs[i];
     35         return BigNumber(n, d);
     36     }
     37     
     38     BigNumber(long long x = 0)
     39     {
     40         long long d[2];
     41         d[0] = x % BASE;
     42         d[1] = x / BASE;
     43         init(2, d);
     44     }
     45     
     46     BigNumber(const BigNumber&a)
     47     {
     48         init(a.ndigs, a.digs);
     49     }
     50     
     51     BigNumber(const char *s)
     52     {
     53         int n = strlen(s), nd = n / BASEDIGS + 1;
     54         long long d[nd];
     55         for (int i = 0; i < nd; i++)
     56         {
     57             d[i] = 0;
     58             for (int j = BASEDIGS - 1; j >= 0; j--)
     59             {
     60                 long long poz = i * BASEDIGS + j;
     61                 if (poz < n) d[i] = 10 * d[i] + s[n - 1 - poz] - '0';
     62             }
     63         }
     64         init(nd, d);
     65     }
     66     
     67     ~BigNumber()
     68     {
     69         delete[] digs;
     70     }
     71     
     72     BigNumber &operator =(const BigNumber &a)
     73     {
     74         delete[] digs;
     75         init(a.ndigs, a.digs);
     76         return *this;
     77     }
     78 
     79     BigNumber operator +(const BigNumber &a) const
     80     {
     81         int n = (ndigs > a.ndigs ? ndigs : a.ndigs) + 1;
     82         long long d[n];
     83         for (int i = 0; i < n; i++)
     84             d[i] = 0;
     85         for (int i = 0; i < n; i++)
     86         {
     87             if (i < ndigs) d[i] += digs[i];
     88             if (i < a.ndigs) d[i] += a.digs[i];
     89             if (d[i] >= BASE)
     90             {
     91                 d[i] -= BASE;
     92                 ++d[i + 1];
     93             }
     94         }
     95         return BigNumber(n, d);
     96     }
     97     
     98     BigNumber &operator +=(const BigNumber &a)
     99     {
    100         return *this = *this + a;
    101     }
    102 
    103     BigNumber operator -(const BigNumber &a) const
    104     {
    105         long long d[ndigs];
    106         for (int i = 0; i < ndigs; i++)
    107             d[i] = digs[i];
    108         for (int i = 0; i < ndigs; i++)
    109         {
    110             if (i < a.ndigs) d[i] -= a.digs[i];
    111             if (d[i] < 0)
    112             {
    113                 d[i] += BASE;
    114                 --d[i + 1];
    115             }
    116         }
    117         return BigNumber(ndigs, d);
    118     }
    119     
    120     BigNumber &operator -=(const BigNumber &a)
    121     {
    122         return *this = *this - a;
    123     }
    124     
    125     BigNumber operator *(const BigNumber &a) const
    126     {
    127         int n = ndigs + a.ndigs;
    128         long long d[n];
    129         for (int i = 0; i < n; i++)
    130             d[i] = 0;
    131         for (int i = 0; i < ndigs; i++)
    132         {
    133             long long p = 0;
    134             for (int j = 0; j < a.ndigs; j++)
    135             {
    136                 long long v = (long long) (digs[i]) * a.digs[j];
    137                 long long v1 = v / BASE, v0 = v % BASE;
    138                 d[i + j] += v0 + p;
    139                 p = v1 + d[i + j] / BASE;
    140                 d[i + j] %= BASE;
    141             }
    142             for(int j = i + a.ndigs; p > 0; ++j)
    143             {
    144                 d[j] += p;
    145                 p = d[j] / BASE;
    146                 d[j] %= BASE;
    147             }
    148         }
    149         return BigNumber(n, d);
    150     }
    151     
    152     BigNumber &operator *=(const BigNumber &a)
    153     {
    154         return *this = *this * a;
    155     }
    156     
    157     BigNumber operator /(const BigNumber &a) const
    158     {
    159         int n = (ndigs - a.ndigs + 1 > 0 ? ndigs - a.ndigs + 1 : 0);
    160         long long d[n];
    161         BigNumber prod;
    162         for(int i = n - 1; i >= 0; i--)
    163         {
    164             long long l = 0, r = BASE - 1;
    165             while(l < r)
    166             {
    167                 long long m = (l + r + 1) / 2;
    168                 if (*this < prod + (a * m << i))
    169                     r = m - 1;
    170                 else l = m;
    171             }
    172             prod += a * l << i;
    173             d[i] = l;
    174         }
    175         return BigNumber(n, d);
    176     }
    177     
    178     BigNumber &operator /=(const BigNumber &a)
    179     {
    180         return *this = *this / a;
    181     }
    182     
    183     BigNumber operator %(const BigNumber &a) const 
    184     {
    185         return *this - *this / a * a;
    186     }
    187     
    188     BigNumber &operator%=(const BigNumber&a) {
    189         return *this = *this % a;
    190     }
    191     
    192     BigNumber sqrt() const
    193     {
    194         int n = (ndigs + 1) / 2;
    195         long long d[n];
    196         for (int i = 0; i < n; i++)
    197             d[i] = 0;
    198         BigNumber sq;
    199         for (int i = n - 1; i >= 0; i--)
    200         {
    201             BigNumber a(n, d);
    202             long long l = 0, r = BASE - 1;
    203             while (l < r) {
    204                 long long m = (l + r + 1) / 2;
    205                 if (*this < sq + (a * 2 * m << i) + (BigNumber(m) * m << 2 * i))
    206                     r = m - 1;
    207                 else l = m;
    208             }
    209             sq += (a * 2 * l << i) + (BigNumber(l) * l << 2 * i);
    210             d[i] = l;
    211         }
    212         return BigNumber(n, d);
    213     }
    214 
    215     BigNumber operator *(long long x) const
    216     {
    217         int n = ndigs + 1;
    218         long long d[n];
    219         long long a = 0;
    220         for (int i = 0; i < ndigs; i++)
    221         {
    222             a += digs[i] * x;
    223             d[i] = a % BASE;
    224             a /= BASE;
    225         }
    226         d[ndigs] = a;
    227         return BigNumber(n, d);
    228     }
    229     
    230     BigNumber &operator *=(long long x)
    231     {
    232         return *this = *this * x;
    233     }
    234 
    235     BigNumber operator /(long long x) const
    236     {
    237         long long d[ndigs];
    238         long long a = 0;
    239         for (int i = ndigs - 1; i >= 0; i--)
    240         {
    241             a = BASE * a + digs[i];
    242             d[i] = a / x;
    243             a %= x;
    244         }
    245         return BigNumber(ndigs, d);
    246     }
    247     
    248     BigNumber &operator /=(long long x)
    249     {
    250         return *this = *this / x;
    251     }
    252     
    253     long long operator %(long long x) const
    254     {
    255         long long a = 0;
    256         for (int i = ndigs - 1; i >= 0; i--)
    257         {
    258             a = BASE * a + digs[i];
    259             a %= x;
    260         }
    261         return a;
    262     }
    263     
    264     bool operator <(const BigNumber &a) const
    265     {
    266         if (ndigs < a.ndigs) return true;
    267         if (ndigs > a.ndigs) return false;
    268         for(int i = ndigs - 1; i >= 0; i--)
    269         {
    270             if (digs[i] < a.digs[i]) return true;
    271             if (digs[i] > a.digs[i]) return false;
    272         }
    273         return false;
    274     }
    275     
    276     bool operator ==(const BigNumber &a) const
    277     {
    278         if (ndigs != a.ndigs) return false;
    279         for (int i = 0; i < ndigs; i++)
    280         {
    281             if (digs[i] != a.digs[i])
    282                 return false;
    283         }
    284         return true;
    285     }
    286     
    287     bool operator >(const BigNumber &a) const
    288     {
    289         return a < *this;
    290     }
    291     
    292     bool operator <=(const BigNumber &a) const
    293     {
    294         return !(a < *this);
    295     }
    296     
    297     bool operator >=(const BigNumber &a) const
    298     {
    299         return !(*this < a);
    300     }
    301     
    302     bool operator !=(const BigNumber &a) const
    303     {
    304         return !(*this == a);
    305     }
    306 
    307     void write() const
    308     {
    309         if (ndigs == 0) printf("0");
    310         else
    311         {
    312             printf("%lld", digs[ndigs - 1]);
    313             for (int i = ndigs - 2; i >= 0; i--)
    314                 printf("%0*lld", BASEDIGS, digs[i]);
    315         }
    316     }
    317     
    318     void write(char *buf) const
    319     {
    320         if(ndigs == 0) sprintf(buf, "0");
    321         else
    322         {
    323             long long pos = 0;
    324             pos += sprintf(buf, "%lld", digs[ndigs - 1]);
    325             for (int i = ndigs - 2; i >= 0; i--)
    326                 pos += sprintf(buf + pos, "%0*lld", BASEDIGS, digs[i]);
    327         }
    328     }
    329 };
  • 相关阅读:
    C#中Split用法
    ASP.NET Get和Post两种提交的区别:
    BAT常用命令
    SQL语句:在两个数据库间复制表结构和数据数据库
    C#中Array与ArrayList用法及转换
    找出输入区间内的回文质数
    (转)加藤嘉一:中国大学生,你没资格抱怨政府
    最长公共子序列(LCS)
    shell(希尔)排序
    关于Ubuntu中google chrome浏览器字体的设置
  • 原文地址:https://www.cnblogs.com/lightning34/p/4610087.html
Copyright © 2020-2023  润新知