Main Page | Modules | Alphabetical List | Compound List | File List | Compound Members | Related Pages

long_int.hpp

00001 #ifndef ross_long_int_header
00002 #define ross_long_int_header
00003 
00004 /*Authored 2002    by  Kyle  Ross,  Undergraduate  Philosophy   Thesis
00005 (Advisor: Professor Bram van Heuveln)
00006 
00007 
00008 This  file is part of the   "Generic Turing Machine Implementation for
00009 Use in the Exploration of the Busy Beaver Problem".
00010 
00011 The "Generic Turing Machine Implementation for  Use in the Exploration
00012 of the Busy Beaver Problem" is free  software; you can redistribute it
00013 and/or modify it under the terms of the  GNU General Public License as
00014 published   by the Free Software Foundation;   either version 2 of the
00015 License, or (at your option) any later version.
00016 
00017 This programme is distributed in the hope that it  will be useful, but
00018 WITHOUT    ANY  WARRANTY;  without   even  the    implied warranty  of
00019 MERCHANTABILITY or FITNESS FOR  A  PARTICULAR  PURPOSE.  See  the  GNU
00020 General Public License for more details.
00021 
00022 You should have received   a copy of  the  GNU General Public  License
00023 along  with  this   programme; if  not,  write   to the Free  Software
00024 Foundation, Inc., 59  Temple Place, Suite  330, Boston, MA  02111-1307
00025 USA (or visit http://www.fsf.org/licenses/licenses.html)
00026 
00027 Created as part of the Busy Beaver Project:
00028 Bram van Heuveln <heuveb@rpi.edu>
00029 Boleshaw Szymanski <szymansk@cs.rpi.edu>
00030 Selmer Bringsjord <selmer@rpi.edu>
00031 Carlos Varela <cvarela@cs.rpi.edu>
00032 Owen Kellett <kelleo@rpi.edu>
00033 Shailesh Kelkar <kelkas@rpi.edu>
00034 Kyle Ross <rossk2@rpi.edu>
00035 Rensselaer Reasoning Group
00036 Department of Cognitive Science
00037 Department of Computer Science
00038 Rensselaer Polytechnic Institute
00039 Troy, New York 12180
00040 U.S.A.
00041 */
00042 
00043 #include <deque>
00044 #include <iostream>
00045 #include <string>
00046 
00047 class long_int
00048 {
00049 public:
00050         long_int()
00051         :zero(true), value(1, 0)
00052         {}
00053         long_int(const long_int &rhs)
00054         :zero(rhs.zero), value(rhs.value)
00055         {}
00056         long_int(unsigned long int new_value)
00057         {
00058                 if(new_value==0)
00059                 {
00060                         zero=true;
00061                         value=std::deque<unsigned short int>(1, 0);
00062                 }
00063                 else
00064                 {
00065                         zero=false;
00066                         while(new_value!=0)
00067                         {
00068                                 value.push_front(new_value%10);
00069                                 new_value/=10;
00070                         }
00071                 }
00072         }
00073 
00074 
00075         const long_int& operator+=(const long_int& rhs)
00076         {
00077                 if(zero && !rhs.zero)
00078                 {
00079                         value=rhs.value;
00080                         zero=false;
00081                 }
00082                 else if(!rhs.zero)
00083                 {
00084                         std::deque<unsigned short int>::const_reverse_iterator i=value.rbegin(), j=rhs.value.rbegin();
00085 
00086                         std::deque<unsigned short int> temp;
00087 
00088                         unsigned short int carry=0, current;
00089                         while(carry || i!=static_cast<std::deque<unsigned short int>::const_reverse_iterator>(value.rend()) || j!=static_cast<std::deque<unsigned short int>::const_reverse_iterator>(rhs.value.rend()))
00090                         {
00091                                 current=carry;
00092                                 if(i!=static_cast<std::deque<unsigned short int>::const_reverse_iterator>(value.rend()))
00093                                 {
00094                                         current+=(*i);
00095                                         ++i;
00096                                 }
00097                                 if(j!=static_cast<std::deque<unsigned short int>::const_reverse_iterator>(rhs.value.rend()))
00098                                 {
00099                                         current+=(*j);
00100                                         ++j;
00101                                 }
00102 
00103                                 carry=current/10;
00104                                 current%=10;
00105 
00106                                 temp.push_front(current);
00107                         }
00108 
00109                         value=temp;
00110                 }
00111 
00112                 return *this;
00113         }
00114 
00115 
00116         const long_int operator+(const long_int& rhs) const
00117         {
00118                 long_int temp=*this;
00119                 temp+=rhs;
00120                 return temp;
00121         }
00122         const long_int multiply_by_digit(unsigned short int digit) const
00123         {
00124                 if(digit==0)
00125                 {
00126                         return long_int(0);
00127                 }
00128 
00129                 if(digit==1 || zero)
00130                 {
00131                         return *this;
00132                 }
00133 
00134                 if(digit>9)
00135                 {
00136                         std::cerr<<"cannot multiply by digit >9"<<std::endl;
00137                         return *this;
00138                 }
00139 
00140                 std::deque<unsigned short int>::const_reverse_iterator i=value.rbegin();
00141 
00142                 long_int temp;
00143                 temp.value.clear();
00144 
00145                 unsigned short int carry=0, current;
00146 
00147                 while(carry || i!=static_cast<std::deque<unsigned short int>::const_reverse_iterator>(value.rend()))
00148                 {
00149                         current=carry;
00150 
00151                         if(i!=static_cast<std::deque<unsigned short int>::const_reverse_iterator>(value.rend()))
00152                         {
00153                                 current+=(*i)*digit;
00154                                 ++i;
00155                         }
00156 
00157                         carry=current/10;
00158                         current%=10;
00159 
00160                         temp.value.push_front(current);
00161                 }
00162 
00163                 temp.zero=false;
00164                 return temp;
00165         }
00166 
00167         const long_int shift_by_power_of_10(unsigned int digit) const
00168         {
00169                 long_int temp=*this;
00170 
00171                 if(!zero && !(digit==0))
00172                 {
00173                         while(digit)
00174                         {
00175                                 temp.value.push_back(0);
00176                                 --digit;
00177                         }
00178                 }
00179 
00180                 return temp;
00181         }
00182         const long_int& operator*=(const long_int& rhs)
00183         {
00184                 if(zero)
00185                 {
00186                         return *this;
00187                 }
00188                 if(rhs.zero)
00189                 {
00190                         return *this=rhs;
00191                 }
00192 
00193                 long_int mult_digits[10];
00194                 for(unsigned short int i=0; i<=9; ++i)
00195                 {
00196                         mult_digits[i]=multiply_by_digit(i);
00197                 }
00198 
00199                 std::deque<unsigned short int>::const_reverse_iterator i=rhs.value.rbegin();
00200 
00201                 unsigned int power_of_10=0;
00202 
00203                 long_int temp(0);
00204 
00205                 while(i!=static_cast<std::deque<unsigned short int>::const_reverse_iterator>(rhs.value.rend()))
00206                 {
00207                         temp+=mult_digits[*i].shift_by_power_of_10(power_of_10);
00208                         ++power_of_10;
00209                         ++i;
00210                 }
00211 
00212                 return *this=temp;
00213         }
00214         const long_int operator*(const long_int& rhs) const
00215         {
00216                 long_int temp=*this;
00217                 temp*=rhs;
00218                 return temp;
00219         }
00220 
00221         const long_int& operator++()
00222         {
00223                 unsigned short int carry=1, current;
00224 
00225                 std::deque<unsigned short int>::reverse_iterator i=value.rbegin();
00226 
00227                 while(carry && i!=static_cast<std::deque<unsigned short int>::reverse_iterator>(value.rend()))
00228                 {
00229                         current=carry+(*i);
00230                         carry=current/10;
00231                         current%=10;
00232                         (*i)=current;
00233                         ++i;
00234                 }
00235 
00236                 if(carry)
00237                 {
00238                         value.push_front(1);
00239                 }
00240                 
00241                 return *this;
00242         }
00243         bool operator==(const long_int& rhs) const
00244         {
00245                 return value==rhs.value;
00246         }
00247         bool operator<(const long_int& rhs) const
00248         {
00249                 if(zero)
00250                 {
00251                         if(rhs.zero)
00252                         {
00253                                 return false;
00254                         }
00255                         else
00256                         {
00257                                 return true;
00258                         }
00259                 }
00260                 else if(rhs.zero)
00261                 {
00262                         return false;
00263                 }
00264 
00265                 if(value.size()<rhs.value.size())
00266                 {
00267                         return true;
00268                 }
00269                 else if(value.size()>rhs.value.size())
00270                 {
00271                         return false;
00272                 }
00273                 else if(value==rhs.value)
00274                 {
00275                         return false;
00276                 }
00277 
00278                 std::deque<unsigned short int>::const_iterator i=value.begin(), j=rhs.value.begin();
00279                 while(true)
00280                 {
00281                         if((*i)<(*j))
00282                         {
00283                                 return true;
00284                         }
00285                         else if((*i)>(*j))
00286                         {
00287                                 return false;
00288                         }
00289                         else
00290                         {
00291                                 ++i;
00292                                 ++j;
00293                         }
00294                 }
00295         }
00296         void print(std::ostream& out) const
00297         {
00298                 if(zero)
00299                 {
00300                         out<<'0';
00301                 }
00302                 else
00303                 {
00304                         for(std::deque<unsigned short int>::const_iterator i=value.begin(); i!=value.end(); ++i)
00305                         {
00306                                 out<<(*i);
00307                         }
00308                 }
00309         }
00310         //begin Owen Kellett modifications
00311         std::string toString() const
00312         {
00313                 std::string result;
00314 
00315                 if(zero)
00316                 {
00317                         result = "0";
00318                 }
00319                 else
00320                 {
00321                         for(std::deque<unsigned short int>::const_iterator i=value.begin(); i!=value.end(); ++i)
00322                         {
00323                                 result+=(char)((*i)+48);
00324                         }
00325                 }
00326                 return result;
00327         }
00328         //end Owen Kellett modifications
00329 
00330 private:
00331         bool zero;
00332         std::deque<unsigned short int> value;
00333 
00334 };
00335 std::ostream& operator<<(std::ostream &out, const long_int &to_print)
00336 {
00337         to_print.print(out);
00338         return out;
00339 }
00340 const long_int pow(const long_int& base, const long_int& exponent)
00341 {
00342         if(exponent==0)
00343         {
00344                 return 1;
00345         }
00346 
00347         long_int counter=0, ret_val=1;
00348         while(!(counter==exponent))
00349         {
00350                 ret_val*=base;
00351                 ++counter;
00352         }
00353 
00354         return ret_val;
00355 }
00356 const long_int permutations(unsigned int n, unsigned int r)
00357 {
00358         if(r<=0)
00359         {
00360                 return long_int(1);
00361         }
00362         if(r>n)
00363         {
00364                 return long_int(0);
00365         }
00366 
00367         long_int result=1;
00368         long_int multiplier=n-r+1;
00369         for(int i=n-r+1; i<=n; ++i)
00370         {
00371                 result*=multiplier;
00372                 ++multiplier;
00373         }
00374         return result;
00375 }
00376 
00377 
00378 #endif

Generated on Thu Nov 20 00:17:31 2003 for BusyBeaver by doxygen 1.3.3