Advertisement
thecplusplusguy

Bignum library in C++ - bignum.cpp

Jul 6th, 2012
555
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.75 KB | None | 0 0
  1. //a bignum library written in C++, it can (in theory) calculate with 4 billion digit long numbers
  2. //this is mostly for demonstration purposes, if you need performance, use something like GNU arbitrary precision library
  3. //Implemented by: http://www.youtube.com/user/thecplusplusguy
  4. #include "bignum.h"
  5. bignum::bignum()
  6. {
  7.     size=10;
  8.     num=new int[size];
  9.     for(int i=0;i<size;i++)
  10.         num[i]=0;
  11.     minus=false;
  12. }
  13.  
  14. bignum::bignum(int a)
  15. {
  16.     size=20;
  17.     if(a<0)
  18.     {
  19.         a*=-1;
  20.         minus=true;
  21.     }else
  22.         minus=false;
  23.     num=new int[size];
  24.     for(int i=0;i<size;i++)
  25.         num[i]=0;
  26.     num[size-1]=a;
  27.     remainder();
  28. }
  29.  
  30. bignum::bignum(const char* c)
  31. {
  32.     size=strlen(c);
  33.     num=new int[size];
  34.     for(int i=0;i<size;i++)
  35.         num[i]=c[i]-48;
  36.     remainder();
  37.     minus=false;
  38. }
  39.  
  40. bignum::bignum(const bignum& bn)
  41. {
  42.     if(this==&bn)
  43.         return;
  44.     size=bn.getSize();
  45.     num=new int[size];
  46.     for(int i=0;i<size;i++)
  47.         num[i]=bn.getNum()[i];
  48. //  remainder();    //MAYBE?
  49.     minus=false;
  50. }
  51.  
  52.  
  53. bignum::~bignum()
  54. {
  55.     delete[] num;
  56. }
  57.  
  58. void bignum::remainder()
  59. {
  60.     int m=0;
  61.     for(int i=size-1;i>0;i--)
  62.     {
  63.         if(num[i]>=0)
  64.         {
  65.             num[i-1]+=num[i]/10;
  66.             num[i]=num[i]%10;
  67.         }else
  68.         {
  69.             num[i]*=-1;
  70.             num[i-1]-=num[i]/10+1;
  71.             if(num[i]%10!=0)
  72.                 num[i]=10-num[i]%10;
  73.             else
  74.             {
  75.                 num[i-1]++;
  76.                 num[i]=0;
  77.             }
  78.         }
  79.     }
  80.     /*
  81.     int i=0;
  82.     while(i<size && num[i]==0)
  83.         i++;
  84.     if(num[i]<0)
  85.     {
  86.         minus=true;
  87.         num[i]*=-1;
  88.     }*/
  89. }
  90.  
  91. void bignum::allocate(int s)
  92. {
  93.         int* num2=new int[s];
  94.         int j=size-1;
  95.         for(int i=0;i<s;i++)
  96.             num2[i]=0;
  97.         for(int i=s-1;i>=0 && j>=0;i--)
  98.             num2[i]=num[j--];
  99.         delete num;
  100.         num=num2;
  101.         size=s;
  102. }
  103.  
  104. int bignum::getSize() const
  105. {
  106.     return size;
  107. }
  108.  
  109. int* bignum::getNum() const
  110. {
  111.     return num;
  112. }
  113.  
  114. int bignum::getNumSize() const
  115. {
  116.     for(int i=0;i<size;i++)
  117.         if(num[i]!=0)
  118.             return size-i;
  119.     return 0;
  120. }
  121.  
  122. int bignum::numLength(int a)
  123. {
  124.     int i=1;
  125.     while((a/=10)!=0)
  126.         i++;
  127.     return i;
  128. }
  129.  
  130. bignum bignum::operator+(const bignum& bn)
  131. {
  132.     bignum tmpnum(bn);
  133.     tmpnum+=(*this);
  134.     return tmpnum;
  135. }
  136.  
  137. bignum bignum::operator+(int a)
  138. {
  139.     bignum tmpnum(a);
  140.     tmpnum+=(*this);
  141.     return tmpnum;
  142. }
  143.  
  144. bignum bignum::operator+(const char* a)
  145. {
  146.     bignum tmpnum(a);
  147.     tmpnum+=(*this);
  148.     return tmpnum;
  149. }
  150.  
  151.  
  152. bignum bignum::operator-(const bignum& bn)
  153. {
  154.     bignum tmpnum(*this);
  155.     tmpnum-=bn;
  156.     return tmpnum;
  157. }
  158.  
  159. bignum bignum::operator-(int a)
  160. {
  161.     bignum tmpnum(*this);
  162.     tmpnum-=a;
  163.     return tmpnum;
  164. }
  165.  
  166. bignum bignum::operator-(const char* a)
  167. {
  168.     bignum tmpnum(*this);
  169.     tmpnum-=a;
  170.     return tmpnum;
  171. }
  172.  
  173. bignum& bignum::operator+=(const bignum& bn)
  174. {
  175.     int s=bn.getSize();
  176.     int m=size>s ? size : s;
  177. //  if(size>s || (num[0]!=0 && bn.getNum()[0]!=0))
  178.         allocate(m+1);
  179.     int j=size-1;
  180.     for(int i=s-1;i>=0;i--)
  181.     {
  182.         num[j]+=bn.getNum()[i];
  183.         j--;
  184.     }
  185.     remainder();
  186.     return (*this);
  187. }
  188.  
  189. bignum& bignum::operator+=(int a)
  190. {
  191.     num[size-1]+=a;
  192.     remainder();
  193.     return (*this);
  194. }
  195.  
  196. bignum& bignum::operator+=(const char* a)
  197. {
  198.     bignum bn(a);
  199.     (*this)+=bn;
  200.     return (*this);
  201. }
  202.  
  203. bignum& bignum::operator-=(const bignum& bn)
  204. {
  205.     int s=bn.getSize();
  206.     int m=size>s ? size : s;
  207.     if(size>s || (num[0]!=0 && bn.getNum()[0]!=0))
  208.         allocate(m+1);
  209.     int j=size-1;
  210.     for(int i=s-1;i>=0;i--)
  211.     {
  212.         num[j]-=bn.getNum()[i];
  213.         j--;
  214.     }
  215.     remainder();
  216.     return (*this);
  217. }
  218.  
  219.  
  220. bignum& bignum::operator-=(int a)
  221. {
  222.     num[size-1]-=a;
  223.     remainder();
  224.     return (*this);
  225. }
  226.  
  227. bignum& bignum::operator-=(const char* a)
  228. {
  229.     bignum bn(a);
  230.     (*this)-=bn;
  231.     return (*this);
  232. }
  233.  
  234. bignum& bignum::operator=(const bignum& bn)
  235. {
  236.     size=bn.getSize();
  237.     delete[] num;
  238.     num=new int[size];
  239.     for(int i=0;i<size;i++)
  240.         num[i]=bn.getNum()[i];
  241. //  remainder();    //maybe?
  242.     return (*this);
  243. }
  244.  
  245. bignum& bignum::operator=(int i)
  246. {
  247.     size=20;
  248.     delete[] num;
  249.     num=new int[size];
  250.     for(int j=0;j<size;j++)
  251.         num[j]=0;
  252.     num[size-1]=i;
  253.     remainder();
  254. }
  255.  
  256. bignum& bignum::operator=(const char* a)
  257. {
  258.     delete[] num;
  259.     size=strlen(a);
  260.     num=new int[size];
  261.     for(int i=0;i<size;i++)
  262.         num[i]=a[i]-'0';
  263. }
  264.  
  265.  
  266. bignum bignum::operator*(const bignum& bn)
  267. {
  268.     bignum tmpnum(bn);
  269.     tmpnum*=(*this);
  270.     return tmpnum; 
  271. }
  272.  
  273. bignum bignum::operator*(int a)
  274. {
  275.     bignum tmpnum(*this);
  276.     tmpnum*=a;
  277.     return tmpnum; 
  278. }
  279.  
  280.  
  281. bignum bignum::operator*(const char* a)
  282. {
  283.     bignum tmpnum(*this);
  284.     tmpnum*=a;
  285.     return tmpnum; 
  286. }
  287.  
  288. bignum& bignum::operator*=(const bignum& bn)
  289. {
  290.     int s=bn.getNumSize()+getNumSize();
  291.     if(size<s)
  292.         allocate(bn.getSize()+size);
  293.     int* tmp=new int[bn.getSize()+size];
  294.     for(int i=0;i<bn.getSize()+size;i++)
  295.         tmp[i]=0;
  296.     for(int i=bn.getSize()-1;i>=0;i--)
  297.         for(int j=0;j<size;j++)
  298.         {
  299.             tmp[i+j+1]+=bn.getNum()[i]*num[j];
  300.         }
  301.     int j=size-1;
  302.     for(int i=bn.getSize()+size-1;i>=0 && j>=0;i--)
  303.         num[j--]=tmp[i];
  304.     delete[] tmp;
  305.     remainder();
  306.     return (*this);
  307. }
  308.  
  309. bignum& bignum::operator*=(int a)
  310. {
  311.     int n=numLength(a);
  312.     int s=n+getNumSize();
  313.     if(size<s)
  314.         allocate(n+size);
  315.     int* tmp=new int[n+size];
  316.     for(int i=0;i<n+size;i++)
  317.         tmp[i]=0;
  318.     int cur;
  319.     for(int i=n-1;i>=0;i--)
  320.     {
  321.         cur=a%10;
  322.         for(int j=0;j<size;j++)
  323.         {
  324.             tmp[i+j+1]+=cur*num[j];
  325.         }
  326.         a/=10;
  327.     }
  328.     int j=size-1;
  329.     for(int i=n+size-1;i>=0 && j>=0;i--)
  330.         num[j--]=tmp[i];
  331.     delete[] tmp;
  332.     remainder();
  333.     return (*this);
  334. }
  335.  
  336. bignum& bignum::operator*=(const char* a)
  337. {
  338.     bignum bn(a);
  339.     (*this)*=bn;
  340.     return (*this);
  341. }
  342.  
  343.  
  344. bignum bignum::operator/(const bignum& bn)
  345. {
  346.     bignum tmpnum(*this);
  347.     tmpnum/=bn;
  348.     return tmpnum; 
  349. }
  350.  
  351.  
  352.  
  353. bignum bignum::operator/(int a)
  354. {
  355.     bignum tmpnum((*this));
  356.     tmpnum/=a;
  357.     return tmpnum; 
  358. }
  359.  
  360.  
  361. bignum bignum::operator/(const char* a)
  362. {
  363.    
  364.     bignum tmpnum((*this));
  365.     tmpnum/=a;
  366.     return tmpnum; 
  367. }
  368.  
  369.  
  370.  
  371.  
  372. bignum bignum::operator%(const bignum& bn)
  373. {
  374.     bignum tmpnum(*this);
  375.     tmpnum%=bn;
  376.     return tmpnum; 
  377. }
  378.  
  379.  
  380.  
  381. bignum bignum::operator%(int a)
  382. {
  383.     bignum tmpnum((*this));
  384.     tmpnum%=a;
  385.     return tmpnum; 
  386. }
  387.  
  388.  
  389. bignum bignum::operator%(const char* a)
  390. {
  391.    
  392.     bignum tmpnum((*this));
  393.     tmpnum%=a;
  394.     return tmpnum; 
  395. }
  396.  
  397.  
  398.  
  399.  
  400.  
  401. bignum& bignum::operator/=(int a)
  402. {
  403.     if(a==0)
  404.         return (*this);
  405.     int maradek=0;
  406.     int* tmp=new int[size];
  407.     for(int i=0;i<size;i++)
  408.         tmp[i]=0;
  409.     int i=0;
  410.     int j=0;
  411.     while((maradek/a)==0 && i<size)
  412.     {
  413.         maradek*=10;
  414.         maradek+=num[i];
  415.         i++;
  416.     }
  417.     while(i<=size)
  418.     {
  419.         tmp[j++]=maradek/a;
  420.         maradek=maradek%a;
  421.         maradek*=10;
  422.         maradek+=num[i];
  423.         i++;
  424.     }
  425.     int k=size-1;
  426.     for(i=0;i<size;i++)
  427.         num[i]=0;
  428.     for(i=j-1;i>=0;i--)
  429.         num[k--]=tmp[i];
  430.     remainder();
  431.     delete[] tmp;
  432.     return (*this);
  433. }
  434.  
  435.  
  436. bignum& bignum::operator/=(const bignum& bn)
  437. {
  438.     bignum r(*this);
  439.     bignum dd(bn);
  440.     bignum q(0);
  441.     while(dd<=r)
  442.         dd*=2;
  443.     while(dd!=bn)
  444.     {
  445.         dd/=2;
  446.         q*=2;
  447.         if(dd<=r)
  448.         {
  449.             r-=dd;
  450.             q+=1;
  451.         }
  452.     }
  453.     int j=size-1;
  454.     for(int i=0;i<size;i++)
  455.         num[i]=0;
  456.     for(int i=q.getSize()-1;i>=0 && j>=0;i--)
  457.         num[j--]=q.getNum()[i];
  458.     return (*this);
  459.  
  460. }
  461.  
  462. bignum& bignum::operator/=(const char* c)
  463. {
  464.     bignum bn(c);
  465.     (*this)/=bn;
  466.     return (*this);
  467. }
  468.  
  469.  
  470. bignum& bignum::operator%=(const bignum& bn)
  471. {
  472.     bignum r(*this);
  473.     bignum dd(bn);
  474. //  bignum q(0);
  475.     while(dd<=r)
  476.         dd*=2;
  477.     while(dd!=bn)
  478.     {
  479.         dd/=2;
  480.     //  q*=2;
  481.         if(dd<=r)
  482.         {
  483.             r-=dd;
  484.     //      q+=1;
  485.         }
  486.     }
  487.     int j=size-1;
  488.     for(int i=0;i<size;i++)
  489.         num[i]=0;
  490.     for(int i=r.getSize()-1;i>=0 && j>=0;i--)
  491.         num[j--]=r.getNum()[i];
  492.     return (*this);
  493.  
  494. }
  495.  
  496. bignum& bignum::operator%=(const char* c)
  497. {
  498.     bignum bn(c);
  499.     (*this)%=bn;
  500.     return (*this);
  501. }
  502.  
  503. bignum& bignum::operator%=(int a)
  504. {
  505.     bignum bn(a);
  506.     (*this)%=bn;
  507.     return (*this);
  508. }
  509.  
  510.  
  511.  
  512. bool bignum::operator==(const bignum& bn) const
  513. {
  514.     if(bn.getNumSize()!=getNumSize())
  515.         return false;
  516.     int j=bn.getSize()-1;
  517.     for(int i=size-1;i>=0 && j>=0;i--)
  518.     {
  519.         if(bn.getNum()[j--]!=num[i])
  520.             return false;
  521.     }
  522.     return true;
  523. }
  524. bool bignum::operator==(int n) const
  525. {
  526.     bignum bn(n);
  527.     return (*this)==bn;
  528. }
  529.  
  530. bool bignum::operator==(const char* c)  const
  531. {
  532.     bignum bn(c);
  533.     return (*this)==bn;
  534. }
  535.  
  536.  
  537. bool bignum::operator>(const bignum& bn) const
  538. {
  539.     if(bn.getNumSize()>getNumSize())
  540.         return false;
  541.     if(bn.getNumSize()<getNumSize())
  542.         return true;
  543.     int j=bn.getSize()-bn.getNumSize();
  544.     for(int i=size-getNumSize();i<size;i++)
  545.     {
  546.         if(num[i]!=bn.getNum()[j])
  547.             return num[i]>bn.getNum()[j];
  548.         j++;           
  549.     }
  550.     return false;
  551. }
  552.  
  553. bool bignum::operator>(int n)  const
  554. {
  555.     bignum bn(n);
  556.     return (*this)>bn;
  557. }
  558.  
  559. bool bignum::operator>(const char* c)    const
  560. {
  561.     bignum bn(c);
  562.     return (*this)>bn;
  563. }
  564.  
  565.  
  566. bool bignum::operator<(const bignum& bn) const
  567. {
  568.     return !((*this)>bn) && bn!=(*this);
  569. }
  570.  
  571. bool bignum::operator<(int n) const
  572. {
  573.     bignum bn(n);
  574.     return (*this)<bn;
  575. }
  576.  
  577. bool bignum::operator<(const char* c)    const
  578. {
  579.     bignum bn(c);
  580.     return (*this)<bn;
  581. }
  582.  
  583.  
  584.  
  585. bool bignum::operator<=(const bignum& bn)  const
  586. {
  587.     return !((*this)>bn);
  588. }
  589.  
  590. bool bignum::operator<=(int n)  const
  591. {
  592.     bignum bn(n);
  593.     return (*this)<=bn;
  594. }
  595.  
  596. bool bignum::operator<=(const char* c)   const
  597. {
  598.     bignum bn(c);
  599.     return (*this)<=bn;
  600. }
  601.  
  602.  
  603.  
  604. bool bignum::operator>=(const bignum& bn)  const
  605. {
  606.     return !((*this)<bn);
  607. }
  608.  
  609. bool bignum::operator>=(int n)  const
  610. {
  611.     bignum bn(n);
  612.     return (*this)>=bn;
  613. }
  614.  
  615. bool bignum::operator>=(const char* c)   const
  616. {
  617.     bignum bn(c);
  618.     return (*this)>=bn;
  619. }
  620.  
  621.  
  622. bool bignum::operator!=(const bignum& b)  const
  623. {
  624.     return !(*this==b);
  625. }
  626. bool bignum::operator!=(int n)  const
  627. {
  628.     return !(*this==n);
  629. }
  630.  
  631. bool bignum::operator!=(const char* c)  const
  632. {
  633.     return !(*this==c);
  634. }
  635.  
  636.  
  637.  
  638. bignum& bignum::operator++()
  639. {
  640.     num[size-1]++;
  641.     remainder();
  642.     return (*this);
  643. }
  644.  
  645. bignum& bignum::operator--()
  646. {
  647.     num[size-1]--;
  648.     remainder();
  649.     return (*this);
  650. }
  651.  
  652.  
  653.  
  654. std::ostream& operator<<(std::ostream& in,const bignum& num)
  655. {
  656.     bool b=false;
  657.     for(int i=0;i<num.getSize();i++)
  658.     {
  659.         if(!b && num.getNum()[i]!=0)
  660.             b=true;
  661.         if(b)
  662.             in << num.getNum()[i];
  663.     }
  664.     if(!b)
  665.         in << 0;
  666.     return in;
  667. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement