大整数类BIGN的设计与实现 C++高精度模板

转载自郭大侠的博客点击打开链接


首先感谢刘汝佳所著的《算法竞赛入门经典》。


众所周知,C++中储存能力最大的unsigned long long 也是有着一个上限,如果我们想计算非常大的整数时,就不知所措了,所以,我写了一个高精度类,允许大整数的四则运算


这个类利用字符串进行输入输出,并利用数组进行储存与处理,通过模拟四则运算,可以计算很大的整数的加减乘除比大小。


支持负数,前导零,支持字符串、整型赋值,支持流输入输出


贴上我的代码:

[cpp]  view plain  copy
  1. #include<string>  
  2. #include<iostream>  
  3. #include<iosfwd>  
  4. #include<cmath>  
  5. #include<cstring>  
  6. #include<stdlib.h>  
  7. #include<stdio.h>  
  8. #include<cstring>  
  9. #define MAX_L 2005 //最大长度,可以修改  
  10. using namespace std;  
  11.   
  12. class bign  
  13. {  
  14. public:  
  15.     int len, s[MAX_L];//数的长度,记录数组  
  16. //构造函数  
  17.     bign();  
  18.     bign(const char*);  
  19.     bign(int);  
  20.     bool sign;//符号 1正数 0负数  
  21.     string toStr() const;//转化为字符串,主要是便于输出  
  22.     friend istream& operator>>(istream &,bign &);//重载输入流  
  23.     friend ostream& operator<<(ostream &,bign &);//重载输出流  
  24. //重载复制  
  25.     bign operator=(const char*);  
  26.     bign operator=(int);  
  27.     bign operator=(const string);  
  28. //重载各种比较  
  29.     bool operator>(const bign &) const;  
  30.     bool operator>=(const bign &) const;  
  31.     bool operator<(const bign &) const;  
  32.     bool operator<=(const bign &) const;  
  33.     bool operator==(const bign &) const;  
  34.     bool operator!=(const bign &) const;  
  35. //重载四则运算  
  36.     bign operator+(const bign &) const;  
  37.     bign operator++();  
  38.     bign operator++(int);  
  39.     bign operator+=(const bign&);  
  40.     bign operator-(const bign &) const;  
  41.     bign operator--();  
  42.     bign operator--(int);  
  43.     bign operator-=(const bign&);  
  44.     bign operator*(const bign &)const;  
  45.     bign operator*(const int num)const;  
  46.     bign operator*=(const bign&);  
  47.     bign operator/(const bign&)const;  
  48.     bign operator/=(const bign&);  
  49. //四则运算的衍生运算  
  50.     bign operator%(const bign&)const;//取模(余数)  
  51.     bign factorial()const;//阶乘  
  52.     bign Sqrt()const;//整数开根(向下取整)  
  53.     bign pow(const bign&)const;//次方  
  54. //一些乱乱的函数  
  55.     void clean();  
  56.     ~bign();  
  57. };  
  58. #define max(a,b) a>b ? a : b  
  59. #define min(a,b) a<b ? a : b  
  60.   
  61. bign::bign()  
  62. {  
  63.     memset(s, 0, sizeof(s));  
  64.     len = 1;  
  65.     sign = 1;  
  66. }  
  67.   
  68. bign::bign(const char *num)  
  69. {  
  70.     *this = num;  
  71. }  
  72.   
  73. bign::bign(int num)  
  74. {  
  75.     *this = num;  
  76. }  
  77.   
  78. string bign::toStr() const  
  79. {  
  80.     string res;  
  81.     res = "";  
  82.     for (int i = 0; i < len; i++)  
  83.         res = (char)(s[i] + '0') + res;  
  84.     if (res == "")  
  85.         res = "0";  
  86.     if (!sign&&res != "0")  
  87.         res = "-" + res;  
  88.     return res;  
  89. }  
  90.   
  91. istream &operator>>(istream &in, bign &num)  
  92. {  
  93.     string str;  
  94.     in>>str;  
  95.     num=str;  
  96.     return in;  
  97. }  
  98.   
  99. ostream &operator<<(ostream &out, bign &num)  
  100. {  
  101.     out<<num.toStr();  
  102.     return out;  
  103. }  
  104.   
  105. bign bign::operator=(const char *num)  
  106. {  
  107.     memset(s, 0, sizeof(s));  
  108.     char a[MAX_L] = "";  
  109.     if (num[0] != '-')  
  110.         strcpy(a, num);  
  111.     else  
  112.         for (int i = 1; i < strlen(num); i++)  
  113.             a[i - 1] = num[i];  
  114.     sign = !(num[0] == '-');  
  115.     len = strlen(a);  
  116.     for (int i = 0; i < strlen(a); i++)  
  117.         s[i] = a[len - i - 1] - 48;  
  118.     return *this;  
  119. }  
  120.   
  121. bign bign::operator=(int num)  
  122. {  
  123.     if (num < 0)  
  124.         sign = 0, num = -num;  
  125.     else  
  126.         sign = 1;  
  127.     char temp[MAX_L];  
  128.     sprintf(temp, "%d", num);  
  129.     *this = temp;  
  130.     return *this;  
  131. }  
  132.   
  133. bign bign::operator=(const string num)  
  134. {  
  135.     const char *tmp;  
  136.     tmp = num.c_str();  
  137.     *this = tmp;  
  138.     return *this;  
  139. }  
  140.   
  141. bool bign::operator<(const bign &num) const  
  142. {  
  143.     if (sign^num.sign)  
  144.         return num.sign;  
  145.     if (len != num.len)  
  146.         return len < num.len;  
  147.     for (int i = len - 1; i >= 0; i--)  
  148.         if (s[i] != num.s[i])  
  149.             return sign ? (s[i] < num.s[i]) : (!(s[i] < num.s[i]));  
  150.     return !sign;  
  151. }  
  152.   
  153. bool bign::operator>(const bign&num)const  
  154. {  
  155.     return num < *this;  
  156. }  
  157.   
  158. bool bign::operator<=(const bign&num)const  
  159. {  
  160.     return !(*this>num);  
  161. }  
  162.   
  163. bool bign::operator>=(const bign&num)const  
  164. {  
  165.     return !(*this<num);  
  166. }  
  167.   
  168. bool bign::operator!=(const bign&num)const  
  169. {  
  170.     return *this > num || *this < num;  
  171. }  
  172.   
  173. bool bign::operator==(const bign&num)const  
  174. {  
  175.     return !(num != *this);  
  176. }  
  177.   
  178. bign bign::operator+(const bign &num) const  
  179. {  
  180.     if (sign^num.sign)  
  181.     {  
  182.         bign tmp = sign ? num : *this;  
  183.         tmp.sign = 1;  
  184.         return sign ? *this - tmp : num - tmp;  
  185.     }  
  186.     bign result;  
  187.     result.len = 0;  
  188.     int temp = 0;  
  189.     for (int i = 0; temp || i < (max(len, num.len)); i++)  
  190.     {  
  191.         int t = s[i] + num.s[i] + temp;  
  192.         result.s[result.len++] = t % 10;  
  193.         temp = t / 10;  
  194.     }  
  195.     result.sign = sign;  
  196.     return result;  
  197. }  
  198.   
  199. bign bign::operator++()  
  200. {  
  201.     *this = *this + 1;  
  202.     return *this;  
  203. }  
  204.   
  205. bign bign::operator++(int)  
  206. {  
  207.     bign old = *this;  
  208.     ++(*this);  
  209.     return old;  
  210. }  
  211.   
  212. bign bign::operator+=(const bign &num)  
  213. {  
  214.     *this = *this + num;  
  215.     return *this;  
  216. }  
  217.   
  218. bign bign::operator-(const bign &num) const  
  219. {  
  220.     bign b=num,a=*this;  
  221.     if (!num.sign && !sign)  
  222.     {  
  223.         b.sign=1;  
  224.         a.sign=1;  
  225.         return b-a;  
  226.     }  
  227.     if (!b.sign)  
  228.     {  
  229.         b.sign=1;  
  230.         return a+b;  
  231.     }  
  232.     if (!a.sign)  
  233.     {  
  234.         a.sign=1;  
  235.         b=bign(0)-(a+b);  
  236.         return b;  
  237.     }  
  238.     if (a<b)  
  239.     {  
  240.         bign c=(b-a);  
  241.         c.sign=false;  
  242.         return c;  
  243.     }  
  244.     bign result;  
  245.     result.len = 0;  
  246.     for (int i = 0, g = 0; i < a.len; i++)  
  247.     {  
  248.         int x = a.s[i] - g;  
  249.         if (i < b.len) x -= b.s[i];  
  250.         if (x >= 0) g = 0;  
  251.         else  
  252.         {  
  253.             g = 1;  
  254.             x += 10;  
  255.         }  
  256.         result.s[result.len++] = x;  
  257.     }  
  258.     result.clean();  
  259.     return result;  
  260. }  
  261.   
  262. bign bign::operator * (const bign &num)const  
  263. {  
  264.     bign result;  
  265.     result.len = len + num.len;  
  266.   
  267.     for (int i = 0; i < len; i++)  
  268.         for (int j = 0; j < num.len; j++)  
  269.             result.s[i + j] += s[i] * num.s[j];  
  270.   
  271.     for (int i = 0; i < result.len; i++)  
  272.     {  
  273.         result.s[i + 1] += result.s[i] / 10;  
  274.         result.s[i] %= 10;  
  275.     }  
  276.     result.clean();  
  277.     result.sign = !(sign^num.sign);  
  278.     return result;  
  279. }  
  280.   
  281. bign bign::operator*(const int num)const  
  282. {  
  283.     bign x = num;  
  284.     bign z = *this;  
  285.     return x*z;  
  286. }  
  287. bign bign::operator*=(const bign&num)  
  288. {  
  289.     *this = *this * num;  
  290.     return *this;  
  291. }  
  292.   
  293. bign bign::operator /(const bign&num)const  
  294. {  
  295.     bign ans;  
  296.     ans.len = len - num.len + 1;  
  297.     if (ans.len < 0)  
  298.     {  
  299.         ans.len = 1;  
  300.         return ans;  
  301.     }  
  302.   
  303.     bign divisor = *this, divid = num;  
  304.     divisor.sign = divid.sign = 1;  
  305.     int k = ans.len - 1;  
  306.     int j = len - 1;  
  307.     while (k >= 0)  
  308.     {  
  309.         while (divisor.s[j] == 0) j--;  
  310.         if (k > j) k = j;  
  311.         char z[MAX_L];  
  312.         memset(z, 0, sizeof(z));  
  313.         for (int i = j; i >= k; i--)  
  314.             z[j - i] = divisor.s[i] + '0';  
  315.         bign dividend = z;  
  316.         if (dividend < divid) { k--; continue; }  
  317.         int key = 0;  
  318.         while (divid*key <= dividend) key++;  
  319.         key--;  
  320.         ans.s[k] = key;  
  321.         bign temp = divid*key;  
  322.         for (int i = 0; i < k; i++)  
  323.             temp = temp * 10;  
  324.         divisor = divisor - temp;  
  325.         k--;  
  326.     }  
  327.     ans.clean();  
  328.     ans.sign = !(sign^num.sign);  
  329.     return ans;  
  330. }  
  331.   
  332. bign bign::operator/=(const bign&num)  
  333. {  
  334.     *this = *this / num;  
  335.     return *this;  
  336. }  
  337.   
  338. bign bign::operator%(const bign& num)const  
  339. {  
  340.     bign a = *this, b = num;  
  341.     a.sign = b.sign = 1;  
  342.     bign result, temp = a / b*b;  
  343.     result = a - temp;  
  344.     result.sign = sign;  
  345.     return result;  
  346. }  
  347.   
  348. bign bign::pow(const bign& num)const  
  349. {  
  350.     bign result = 1;  
  351.     for (bign i = 0; i < num; i++)  
  352.         result = result*(*this);  
  353.     return result;  
  354. }  
  355.   
  356. bign bign::factorial()const  
  357. {  
  358.     bign result = 1;  
  359.     for (bign i = 1; i <= *this; i++)  
  360.         result *= i;  
  361.     return result;  
  362. }  
  363.   
  364. void bign::clean()  
  365. {  
  366.     if (len == 0) len++;  
  367.     while (len > 1 && s[len - 1] == '\0')  
  368.         len--;  
  369. }  
  370.   
  371. bign bign::Sqrt()const  
  372. {  
  373.     if(*this<0)return -1;  
  374.     if(*this<=1)return *this;  
  375.     bign l=0,r=*this,mid;  
  376.     while(r-l>1)  
  377.     {  
  378.         mid=(l+r)/2;  
  379.         if(mid*mid>*this)  
  380.             r=mid;  
  381.         else   
  382.             l=mid;  
  383.     }  
  384.     return l;  
  385. }  
  386.   
  387. bign::~bign()  
  388. {  
  389. }  
  390.   
  391. bign num0,num1,res;  
  392.   
  393. int main()  
  394. {  
  395.     cin>>num0>>num1;  
  396.     res=num0+num1;  
  397.     cout<<res<<endl;  
  398.   
  399.     num0=5;  
  400.     num1="71";  
  401.     res=num0-num1;  
  402.     cout<<res<<endl;  
  403.   
  404.     res=num0.Sqrt();  
  405.     cout<<res<<endl;  
  406.   
  407.     res=num0.pow(5);  
  408.     cout<<res<<endl;  
  409.     return 0;  
  410. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值