00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00031 #include <iostream>
00032 #include <limits>
00033 #include <list>
00034 #include <cstdio>
00035 #include <cstring>
00036 #include <cstdlib>
00037 #include <cmath>
00038
00039 #ifdef DEBUG
00040 #include <cassert>
00041 #endif
00042
00043 #include "casobject.h"
00044 #include "casexception.h"
00045 #include "sum.h"
00046 #include "product.h"
00047 #include "fraction.h"
00048 #include "longint.h"
00049
00056
00057
00058
00067 unsigned long
00068 LongInt::frontpartlength() const {
00069 std::list<unsigned int>::const_reference i = lst.front();
00070
00071
00072
00073 for ( int e = 1; e < part_len; e++ ) {
00074 if ( i < pow ( ( ( double ) 10 ), e ) ) {
00075 return e;
00076 }
00077 }
00078
00079 return part_len;
00080 }
00081
00092 void
00093 LongInt::str2longint ( const char *str_num ) {
00094
00095 lst.clear();
00096
00097
00098
00099 const char *str_end = str_num + ( strlen ( str_num ) - 1 );
00100
00101
00102 char part[part_len+1];
00103
00104 part[part_len] = '\0';
00105
00106
00107 memset ( part, '0', part_len );
00108
00109 SetPositive();
00110
00111 bool part_need_flush = false;
00112 int c = part_len - 1;
00113 for ( ;str_num <= str_end;str_end-- ) {
00114 if ( ( *str_end == '-' ) || ( *str_end == '+' ) ) {
00115 if ( *str_end == '-' ) {
00116 SetNegative();
00117 }
00118 }
00119 else {
00120 part[c] = *str_end;
00121 part_need_flush = true;
00122 }
00123 c--;
00124
00125
00126
00127
00128 if ( c < 0 || ( str_num == str_end && part_need_flush ) ) {
00129 unsigned int tmp = strtol ( part, NULL, 10 );
00130 lst.push_front ( tmp );
00131 part_need_flush = false;
00132 c = part_len - 1;
00133
00134 memset ( part, '0', part_len );
00135 }
00136 }
00137
00138 stripzeros();
00139 if ( IsZero() ) {
00140 SetPositive();
00141 }
00142 }
00143
00151 void
00152 LongInt::num2longint ( const signed long num ) {
00153 if ( num == 0 ) {
00154 setzero();
00155 }
00156 else {
00157
00158
00159 int size = snprintf ( NULL, 0, "%ld", num ) + 1;
00160 char *buf = new char[size];
00161 snprintf ( buf, size, "%li", num );
00162
00163 str2longint ( buf );
00164
00165 delete[] buf;
00166 }
00167 }
00168
00184 void
00185 LongInt::longint2str ( char *s, unsigned long size ) const {
00186 if ( s == 0 ) {
00187 throw EInvArg();
00188 }
00189
00190 if ( size < ( Length() + 1 ) ) {
00191 throw EBufTooSmall();
00192 }
00193
00194 memset ( s, 0x0, size );
00195
00196
00197 char fmt[fmt_len];
00198 snprintf ( fmt, fmt_len, "%%0%du", part_len );
00199
00200 char *mem_pos = s;
00201 if ( IsNegative() ) {
00202 strncpy ( s, "-", 2 );
00203 mem_pos++;
00204 }
00205
00206 std::list<unsigned int>::const_iterator i = lst.begin();
00207 while ( i != lst.end() ) {
00208
00209 if ( i == lst.begin() ) {
00210 unsigned long frontlen = frontpartlength();
00211 snprintf ( mem_pos, frontlen + 1, "%u" , *i );
00212
00213 mem_pos += frontlen;
00214 }
00215 else {
00216 snprintf ( mem_pos, part_len + 1, fmt, *i );
00217
00218 mem_pos += part_len;
00219 }
00220
00221
00222 i++;
00223 }
00224
00225 }
00226
00232 void
00233 LongInt::setzero() {
00234 lst.clear();
00235 lst.push_front ( 0 );
00236 SetPositive();
00237 }
00238
00244 void
00245 LongInt::stripzeros() {
00246
00247
00248 if ( lst.size() < 2 ) {
00249 return;
00250 }
00251
00252 while ( ( *lst.begin() ) == 0 ) {
00253 lst.pop_front();
00254 if ( lst.size() < 2 ) {
00255 break;
00256 }
00257 }
00258 }
00259
00260
00261
00262
00263
00264
00272 LongInt::LongInt ( signed long l ) : CASNumeric(), div_remainder ( 0 ) {
00273 #ifdef SHOWCONSTRUCTOR
00274 std::cerr << "# LongInt::LongInt(signed long l)" << std::endl;
00275 #endif
00276 num2longint ( l );
00277 SetRadix ( ( unsigned long ) pow ( ( ( double ) 10 ), part_len ) );
00278 meta.SetAll();
00279 }
00280
00288 LongInt::LongInt ( const char *s ) : CASNumeric(), div_remainder ( 0 ) {
00289 #ifdef SHOWCONSTRUCTOR
00290 std::cerr << "# LongInt::LongInt(const char *s)" << std::endl;
00291 #endif
00292 str2longint ( s );
00293 SetRadix ( ( unsigned long ) pow ( ( ( double ) 10 ), part_len ) );
00294 meta.SetAll();
00295 }
00296
00304 LongInt::LongInt ( const std::string &s ) : CASNumeric(), div_remainder ( 0 ) {
00305 #ifdef SHOWCONSTRUCTOR
00306 std::cerr << "# LongInt::LongInt(const std::string &s)" << std::endl;
00307 #endif
00308 str2longint ( s.c_str() );
00309 SetRadix ( ( unsigned long ) pow ( ( ( double ) 10 ), part_len ) );
00310 meta.SetAll();
00311 }
00312
00318 LongInt::LongInt ( const LongInt &r ) {
00319 #ifdef SHOWCONSTRUCTOR
00320 std::cerr << "# Copy Constructor LongInt::LongInt()" << std::endl;
00321 #endif
00322
00323 SetSign ( r.GetSign() );
00324 SetDivDepth ( r.GetDivDepth() );
00325 SetRadix ( r.GetRadix() );
00326 lst = r.lst;
00327
00328 if ( r.div_remainder != 0 ) {
00329 div_remainder = new LongInt ( 0L );
00330 div_remainder->lst = r.div_remainder->lst;
00331 div_remainder->SetSign ( r.div_remainder->GetSign() );
00332 } else {
00333 div_remainder = 0;
00334 }
00335 meta = r.meta;
00336 }
00337
00341 LongInt::~LongInt() {
00342 #ifdef SHOWCONSTRUCTOR
00343 std::cerr << "# LongInt::~LongInt()" << std::endl;
00344 #endif
00345 if ( div_remainder != 0 ) {
00346 delete div_remainder;
00347 }
00348 }
00349
00358 CASObject*
00359 LongInt::Clone() const {
00360 LongInt *res = new LongInt;
00361 *res = *this;
00362
00363 return res;
00364 }
00365
00366
00367
00368
00369
00384 void LongInt::Get ( char **s ) const throw ( EInvArg,
00385 EUninitializedPtr ) { if ( s == 0 ) { throw EInvArg(); }
00386
00387 if ( *s != 0 ) {
00388 throw EUninitializedPtr();
00389 }
00390
00391
00392 unsigned long size = Length() + 1;
00393 *s = new char[size];
00394
00395 longint2str ( *s, size );
00396 }
00397
00408 void
00409 LongInt::Get ( char *s, unsigned long size ) const {
00410 longint2str ( s, size );
00411 }
00412
00421 void
00422 LongInt::Get ( std::string &s ) const {
00423 char *tmp = 0;
00424
00425 Get ( &tmp );
00426 s = tmp;
00427
00428 delete []tmp;
00429 }
00430
00438 unsigned long
00439 LongInt::Length() const {
00440 long max_strlen = lst.size() * part_len;
00441
00442
00443
00444 max_strlen += IsNegative() ? 1 : 0;
00445
00446
00447
00448 return max_strlen - ( part_len - frontpartlength() );
00449 }
00450
00456 void
00457 LongInt::Print() const {
00458 char *str = 0;
00459 Get ( &str );
00460
00461 std::cout << str;
00462
00463 delete[] str;
00464 }
00465
00474 CASObject*
00475 LongInt::Invert() const {
00476 LongInt tmp = *this;
00477
00478 tmp.InvertIP();
00479 return tmp.Clone();
00480 }
00481
00490 CASObject*
00491 LongInt::Absolute() const {
00492 LongInt tmp = *this;
00493
00494 tmp.SetPositive();
00495 return tmp.Clone();
00496 }
00497
00503 bool
00504 LongInt::IsZero() const{
00505 return ( lst.size() == 1 && lst.back() == 0 );
00506 }
00507
00513 bool
00514 LongInt::IsOne() const{
00515 return ( lst.size() == 1 && lst.back() == 1 );
00516 }
00517
00530 CASObject*
00531 LongInt::GCD ( const CASObject* i ) const {
00532 if ( GetType() != i->GetType() ) {
00533 LongInt tmp ( 1L );
00534 return tmp.Clone();
00535 }
00536 const LongInt *li = dynamic_cast<const LongInt*> ( i );
00537 #ifdef DEBUG
00538 assert ( li != 0 );
00539 #endif
00540 LongInt c = *this > *li ? *this : *li;
00541 LongInt d = *this > *li ? *li : *this;
00542 LongInt r;
00543
00544 while ( !d.IsZero() ) {
00545 r = c % d;
00546 c = d;
00547 d = r;
00548 }
00549
00550 LongInt *ret_val = new LongInt ( c );
00551
00552 return ret_val;
00553 }
00554
00568 LongInt
00569 LongInt::Pow ( const LongInt &exp ) const {
00570 LongInt tmp ( 1L );
00571
00572 for ( LongInt i ( 0L ); i < exp; i++ ) {
00573 tmp = tmp * ( *this );
00574 }
00575
00576 return tmp;
00577 }
00578
00588 inline LongInt
00589 LongInt::Pow ( unsigned long exp ) const {
00590 LongInt tmp ( exp );
00591 return Pow ( tmp );
00592 }
00593
00609 LongInt
00610 LongInt::FractionalPart ( const LongInt &r ) const {
00611 #ifdef WARNINGS
00612 #warning "LongInt::FractionalPart(): Not fully implemented"
00613 #endif
00614
00615 LongInt d_res = *this / r;
00616
00617
00618 LongInt d_remainder = * ( d_res.div_remainder );
00619
00620
00621 if ( d_remainder.IsZero() ) {
00622 return LongInt ( 0L );
00623 }
00624
00625 LongInt u = d_remainder;
00626 u.AbsoluteIP();
00627 LongInt v = r;
00628 v.AbsoluteIP();
00629
00630
00631 LongInt part_dividend;
00632 part_dividend.lst.clear();
00633
00634 LongInt result;
00635 result.lst.clear();
00636
00637 std::list<unsigned int>::const_iterator dividend = u.lst.begin();
00638
00639 for ( unsigned long i = 0; i < GetDivDepth(); i++ ) {
00640
00641 if ( dividend != u.lst.end() ) {
00642 part_dividend.lst.push_back ( *dividend );
00643 part_dividend.stripzeros();
00644 if ( i == 0 ) {
00645 part_dividend.lst.push_back ( 0 );
00646 }
00647 } else {
00648 part_dividend.lst.push_back ( 0 );
00649 }
00650
00651
00652
00653
00654 LongInt sum ( 0L );
00655
00656 unsigned int t = 0;
00657
00658 while ( sum < part_dividend ) {
00659 sum += v;
00660 t++;
00661 }
00662
00663
00664 if ( sum > part_dividend ) {
00665 t--;
00666 }
00667
00668 #ifdef DEBUG
00669 assert ( t < ( unsigned long ) pow ( ( ( double ) 10 ), part_len ) );
00670 #endif
00671
00672
00673
00674 result.lst.push_back ( t );
00675
00676 part_dividend -= ( v * t );
00677
00678 if ( part_dividend.IsZero() ) {
00679 break;
00680 }
00681
00682 if ( dividend != u.lst.end() ) {
00683 dividend++;
00684 }
00685 }
00686
00687 return result;
00688
00689 }
00690
00704 LongInt
00705 LongInt::FractionalPart ( signed long r ) const {
00706 return FractionalPart ( LongInt ( r ) );
00707 }
00708
00722 CASObject*
00723 LongInt::Add ( const CASObject* addend ) const {
00724 checkptr ( addend );
00725
00726 if ( GetType() == addend->GetType() ) {
00727 const LongInt *li_ptr = dynamic_cast<const LongInt*> ( addend );
00728 #ifdef DEBUG
00729 assert ( li_ptr != 0 );
00730 #endif
00731 LongInt res;
00732
00733 res = ( *this ) + ( *li_ptr );
00734 return res.Clone();
00735 }
00736
00737 Sum tmp;
00738 CASObject* result;
00739
00740 tmp.Append ( this );
00741 result = tmp.Add ( addend );
00742
00743 return result;
00744 }
00745
00760 CASObject*
00761 LongInt::Subtract ( const CASObject* sub ) const {
00762 checkptr ( sub );
00763
00764 if ( GetType() == sub->GetType() ) {
00765 const LongInt *li_ptr = dynamic_cast<const LongInt*> ( sub );
00766 #ifdef DEBUG
00767 assert ( li_ptr != 0 );
00768 #endif
00769 LongInt res;
00770
00771 res = ( *this ) - ( *li_ptr );
00772 return res.Clone();
00773 }
00774
00775 Sum tmp;
00776 CASObject *result;
00777
00778 tmp.Append ( this );
00779 result = tmp.Subtract ( sub );
00780
00781
00782 return result;
00783
00784 }
00785
00801 CASObject*
00802 LongInt::Multiply ( const CASObject* fact ) const {
00803 checkptr ( fact );
00804
00805 if ( GetType() < fact->GetType() ) {
00806 return fact->Multiply ( this );
00807 }
00808
00809 if ( GetType() == fact->GetType() ) {
00810 const LongInt *li_ptr = dynamic_cast<const LongInt*> ( fact );
00811 #ifdef DEBUG
00812 assert ( li_ptr != 0 );
00813 #endif
00814 LongInt res;
00815
00816 res = ( *this ) * ( *li_ptr );
00817 return res.Clone();
00818 }
00819
00820 Product *res = new Product;
00821
00822
00823 CASObject *tmp = this->Clone();
00824 tmp->meta.SetCoefficient();
00825 res->Append ( tmp );
00826 res->Append ( fact );
00827 CASObject::Garbage->Put ( tmp );
00828
00829 return res;
00830 }
00831
00843 CASObject*
00844 LongInt::Divide ( const CASObject* divisor ) const {
00845 checkptr ( divisor );
00846
00847 return new Fraction ( this, divisor );
00848 }
00849
00863 CASObject*
00864 LongInt::Power ( const CASObject* exp ) const {
00865 checkptr ( exp );
00866
00867 if ( GetType() == exp->GetType() ) {
00868 const LongInt *num_exp = dynamic_cast<const LongInt*> ( exp );
00869 #ifdef DEBUG
00870 assert ( num_exp != 0 );
00871 #endif
00872 LongInt res;
00873 res = Pow ( *num_exp );
00874 return res.Clone();
00875 }
00876
00877 #ifdef WARNINGS
00878 #warning __FILE__ " " __LINE__ "Cannot exponentiate numeric value with anything other than numeric value"
00879 #endif
00880 std::cout << "Cannot exponentiate ";
00881 Print();
00882 std::cout << " by ";
00883 exp->Print();
00884 std::cout << std::endl;
00885
00886 throw ENotImplemented();
00887 }
00888
00900 CASObject*
00901 LongInt::Modulo ( const CASObject* divisor ) const {
00902 checkptr ( divisor );
00903
00904 if ( GetType() == divisor->GetType() ) {
00905 const LongInt *li_ptr = dynamic_cast<const LongInt*> ( divisor );
00906 #ifdef DEBUG
00907 assert ( li_ptr != 0 );
00908 #endif
00909 LongInt *result = new LongInt;
00910
00911 *result = ( *this ) % ( *li_ptr );
00912 return result;
00913 }
00914
00915 return new LongInt ( 0L );
00916 }
00917
00926 bool
00927 LongInt::IsEqual ( const CASObject* o ) const {
00928 checkptr ( o );
00929
00930 if ( GetType() != o->GetType() ) {
00931 return false;
00932 }
00933
00934 const LongInt *li_ptr = dynamic_cast<const LongInt*> ( o );
00935 #ifdef DEBUG
00936 assert ( li_ptr != 0 );
00937 #endif
00938 return ( *this ) == ( *li_ptr );
00939
00940 }
00941
00951 bool
00952 LongInt::IsLT ( const CASObject* o ) const {
00953 checkptr ( o );
00954
00955 if ( GetType() < o->GetType() ) {
00956 return true;
00957 }
00958
00959 if ( GetType() > o->GetType() ) {
00960 return false;
00961 }
00962
00963 const LongInt *li = dynamic_cast<const LongInt *> ( o );
00964
00965 #ifdef DEBUG
00966 assert ( li != 0 );
00967 #endif
00968
00969 return ( *this ) < ( *li );
00970 }
00971
00981 bool
00982 LongInt::IsGT ( const CASObject* o ) const {
00983 checkptr ( o );
00984
00985 if ( IsEqual ( o ) ) {
00986 return false;
00987 }
00988
00989 return !IsLT ( o );
00990 }
00991
01003 bool
01004 LongInt::IsSimilar ( const CASObject* o ) const {
01005 checkptr ( o );
01006
01007 if ( GetType() == o->GetType() ) {
01008 return true;
01009 }
01010
01011 return false;
01012 }
01013
01023 CASObject*
01024 LongInt::Evaluate() const {
01025 CASObject *ret_val = Clone();
01026
01027 ret_val->Sort();
01028 ret_val->meta.SetEvaluated();
01029
01030 return ret_val;
01031 }
01032
01033
01034
01035
01036
01037
01045 LongInt&
01046 LongInt::operator= ( const LongInt &r ) {
01047 #ifdef SHOWCONSTRUCTOR
01048 std::cerr << "# LongInt::operator=()" << std::endl;
01049 #endif
01050 if ( this == &r ) {
01051 return *this;
01052 }
01053 SetSign ( r.GetSign() );
01054 SetDivDepth ( r.GetDivDepth() );
01055 SetRadix ( r.GetRadix() );
01056 lst.clear();
01057 lst = r.lst;
01058
01059 if ( r.div_remainder != 0 ) {
01060 CASObject::Garbage->Put ( div_remainder );
01061 div_remainder = 0;
01062 }
01063
01064 #ifdef DEBUG
01065 assert ( div_remainder == 0 );
01066 #endif
01067
01068 if ( r.div_remainder != 0 ) {
01069 div_remainder = new LongInt ( 0L );
01070 div_remainder->lst = r.div_remainder->lst;
01071 div_remainder->SetSign ( r.div_remainder->GetSign() );;
01072 }
01073
01074 meta = r.meta;
01075
01076 return *this;
01077 }
01078
01086 LongInt&
01087 LongInt::operator= ( const signed long &r ) {
01088 if ( r == 0 ) {
01089 setzero();
01090 }
01091 else {
01092 num2longint ( r );
01093 }
01094
01095 SetRadix ( ( unsigned long ) pow ( ( ( double ) 10 ), part_len ) );
01096
01097 if ( div_remainder != 0 ) {
01098 CASObject::Garbage->Put ( div_remainder );
01099 div_remainder = 0;
01100 }
01101
01102 meta.SetAll();
01103
01104 return *this;
01105 }
01106
01114 LongInt&
01115 LongInt::operator+= ( const LongInt &r ) {
01116 return ( *this = *this + r );
01117 }
01118
01126 LongInt&
01127 LongInt::operator+= ( const signed long &r ) {
01128 return operator+= ( LongInt ( r ) );
01129 }
01130
01138 LongInt&
01139 LongInt::operator-= ( const LongInt &r ) {
01140 return ( *this = *this - r );
01141 }
01142
01150 LongInt&
01151 LongInt::operator-= ( const signed long &r ) {
01152 return operator-= ( LongInt ( r ) );
01153 }
01154
01162 LongInt&
01163 LongInt::operator*= ( const LongInt &r ) {
01164 return ( *this = *this * r );
01165 }
01166
01174 LongInt&
01175 LongInt::operator*= ( const signed long &r ) {
01176 return operator*= ( LongInt ( r ) );
01177 }
01178
01186 LongInt&
01187 LongInt::operator/= ( const LongInt &r ) {
01188 return ( *this = *this / r );
01189 }
01190
01198 LongInt&
01199 LongInt::operator/= ( const signed long &r ) {
01200 return operator/= ( LongInt ( r ) );
01201 }
01202
01210 LongInt&
01211 LongInt::operator%= ( const LongInt &r ) {
01212 return ( *this = *this % r );
01213 }
01214
01222 LongInt&
01223 LongInt::operator%= ( const signed long &r ) {
01224 return operator%= ( LongInt ( r ) );
01225 }
01226
01234 const LongInt
01235 LongInt::operator+ ( const LongInt &r ) const {
01236 if ( r.IsZero() ) {
01237 return *this;
01238 }
01239
01240 if ( IsNegative() && r.IsPositive() ) {
01241 LongInt tmp = *this;
01242 tmp.SetPositive();
01243 return r -tmp;
01244 }
01245
01246 if ( IsPositive() && r.IsNegative() ) {
01247 LongInt tmp = r;
01248 tmp.SetPositive();
01249 return ( *this ) - tmp;
01250 }
01251 std::list<unsigned int> sum;
01252
01253 unsigned long max_iter = r.lst.size() > lst.size() ? r.lst.size() : lst.size();
01254 std::list<unsigned int>::const_iterator i_addend1 = lst.end();
01255 i_addend1--;
01256 std::list<unsigned int>::const_iterator i_addend2 = r.lst.end();
01257 i_addend2--;
01258
01259 unsigned int addend1 = *i_addend1;
01260 unsigned int addend2 = *i_addend2;
01261 unsigned int remainder = 0;
01262
01263 for ( unsigned long i = 0; i < max_iter; i++ ) {
01264
01265 unsigned int res = addend1 + addend2 + remainder;
01266 if ( res >= GetRadix() ) {
01267 res -= GetRadix();
01268 remainder = 1;
01269 }
01270 else {
01271 remainder = 0;
01272 }
01273
01274 sum.push_front ( res );
01275
01276 if ( i_addend1 != lst.begin() ) {
01277 i_addend1--;
01278 addend1 = *i_addend1;
01279 }
01280 else {
01281 addend1 = 0;
01282 }
01283
01284 if ( i_addend2 != r.lst.begin() ) {
01285 i_addend2--;
01286 addend2 = *i_addend2;
01287 }
01288 else {
01289 addend2 = 0;
01290 }
01291
01292 }
01293
01294
01295 if ( remainder != 0 ) {
01296 sum.push_front ( remainder );
01297 }
01298
01299 LongInt ret_val;
01300 ret_val.lst = sum;
01301 ret_val.SetSign ( GetSign() );
01302
01303 ret_val.stripzeros();
01304 return ret_val;
01305 }
01306
01314 const LongInt
01315 LongInt::operator+ ( const long &r ) const {
01316 return operator+ ( LongInt ( r ) );
01317 }
01318
01326 const LongInt
01327 LongInt::operator* ( const LongInt &r ) const {
01328
01329 if ( IsZero() || r.IsZero() ) {
01330 return LongInt ( 0L );
01331 }
01332
01333 LongInt result ( 0L );
01334 LongInt tmp ( 0L );
01335 unsigned int prod;
01336 unsigned int modulo;
01337
01338
01339 std::list<unsigned int>::const_iterator fact2 = r.lst.end();
01340 fact2--;
01341
01342 for ( unsigned long outer_l = 0; outer_l < r.lst.size(); outer_l++ ) {
01343
01344 std::list<unsigned int>::const_iterator fact1 = lst.end();
01345 fact1--;
01346
01347 unsigned int carry = 0;
01348 for ( unsigned long inner_l = 0; inner_l < lst.size(); inner_l++ ) {
01349 prod = ( ( *fact1 ) * ( *fact2 ) ) + carry;
01350 carry = ( unsigned int ) prod / GetRadix();
01351 modulo = prod % GetRadix();
01352 tmp = modulo;
01353 tmp = tmp << outer_l;
01354 tmp = tmp << inner_l;
01355 result = result + tmp;
01356 fact1--;
01357 }
01358
01359
01360 if ( carry != 0 ) {
01361 tmp = carry;
01362 tmp = tmp << outer_l;
01363 tmp = tmp << lst.size();
01364
01365 result = result + tmp;
01366 }
01367 fact2--;
01368 }
01369
01370
01371 result.SetSign ( ( r.IsNegative() ^ IsNegative() ? Negative : Positive ) );
01372
01373 result.stripzeros();
01374
01375 return result;
01376 }
01377
01386 const LongInt
01387 LongInt::operator* ( const long &r ) const {
01388 return operator* ( LongInt ( r ) );
01389 }
01390
01398 const LongInt
01399 LongInt::operator- ( const LongInt &r ) const {
01400 if ( r.IsZero() ) {
01401 return *this;
01402 }
01403
01404 if ( IsNegative() && r.IsPositive() ) {
01405 LongInt lh = *this;
01406 lh.SetPositive();
01407 LongInt res = r + lh;
01408 res.SetNegative();
01409 return res;
01410 }
01411
01412 if ( r.IsNegative() ) {
01413 LongInt tmp = r;
01414 tmp.SetPositive();
01415 return ( *this ) + tmp;
01416 }
01417
01418
01419
01420
01421
01422 bool stays_pos;
01423 if ( *this < r ) {
01424 stays_pos = false;
01425 } else {
01426 stays_pos = true;
01427 }
01428
01429 std::list<unsigned int> sum;
01430
01431 unsigned long max_iter = r.lst.size() > lst.size() ? r.lst.size() : lst.size();
01432 std::list<unsigned int>::const_iterator i_minuend =
01433 ( stays_pos ? lst.end() : r.lst.end() );
01434 i_minuend--;
01435 std::list<unsigned int>::const_iterator i_subtrahend =
01436 ( stays_pos ? r.lst.end() : lst.end() );
01437 i_subtrahend--;
01438
01439 unsigned int minuend = *i_minuend;
01440 unsigned int subtrahend = *i_subtrahend;
01441 int remainder = 0;
01442
01443 for ( unsigned long i = 0; i < max_iter; i++ ) {
01444
01445 int res = minuend - ( subtrahend + remainder );
01446 if ( res < 0 ) {
01447 remainder = 1;
01448 res = GetRadix() + res;
01449
01450 }
01451 else {
01452 remainder = 0;
01453 }
01454
01455 sum.push_front ( ( unsigned int ) res );
01456
01457 if ( i_minuend != ( stays_pos ? lst.begin() : r.lst.begin() ) ) {
01458 i_minuend--;
01459 minuend = *i_minuend;
01460 }
01461 else {
01462 minuend = 0;
01463 }
01464
01465 if ( i_subtrahend != ( stays_pos ? r.lst.begin() : lst.begin() ) ) {
01466 i_subtrahend--;
01467 subtrahend = *i_subtrahend;
01468 }
01469 else {
01470 subtrahend = 0;
01471 }
01472
01473 }
01474
01475 LongInt ret_val;
01476 ret_val.lst = sum;
01477 ret_val.SetPositive();
01478 ret_val.stripzeros();
01479 if ( !stays_pos && !ret_val.IsZero() ) {
01480 ret_val.SetNegative();
01481 }
01482 return ret_val;
01483
01484 }
01485
01494 const LongInt
01495 LongInt::operator- ( const long &r ) const {
01496 return operator- ( LongInt ( r ) );
01497 }
01498
01506 const LongInt
01507 LongInt::operator/ ( const LongInt &r ) const {
01508 LongInt u = ( *this );
01509 u.AbsoluteIP();
01510 LongInt v = r;
01511 v.AbsoluteIP();
01512
01513
01514
01515 LongInt result ( 0L );
01516
01517 if ( v.IsZero() ) {
01518 throw EDivByZero();
01519 }
01520
01521 if ( u < v ) {
01522 result.div_remainder = new LongInt;
01523 result.div_remainder->lst = lst;
01524 result.div_remainder->SetSign ( GetSign() );
01525 return result;
01526 }
01527
01528 if ( u == v ) {
01529 result = 1;
01530 result.div_remainder = new LongInt;
01531 return result;
01532 }
01533
01534 if ( v == 1 ) {
01535
01536 result = *this;
01537 result.div_remainder = new LongInt;
01538 return result;
01539 }
01540
01541
01542 result.lst.clear();
01543
01544
01545 LongInt part_dividend;
01546 part_dividend.lst.clear();
01547
01548 std::list<unsigned int>::const_iterator dividend = u.lst.begin();
01549
01550 while ( dividend != u.lst.end() ) {
01551
01552 part_dividend.lst.push_back ( *dividend );
01553 part_dividend.stripzeros();
01554
01555
01556
01557 LongInt sum ( 0L );
01558
01559 unsigned int t = 0;
01560
01561 while ( sum < part_dividend ) {
01562 sum += v;
01563 t++;
01564 }
01565
01566
01567 if ( sum > part_dividend ) {
01568 t--;
01569 }
01570
01571 #ifdef DEBUG
01572 assert ( t < ( unsigned long ) pow ( ( ( double ) 10 ), part_len ) );
01573 #endif
01574
01575 result.lst.push_back ( t );
01576
01577 part_dividend -= ( v * t );
01578 dividend++;
01579 }
01580
01581
01582 result.SetSign ( ( r.IsNegative() ^ IsNegative() ? Negative : Positive ) );
01583 result.stripzeros();
01584
01585 #ifdef DEBUG
01586 assert ( result.div_remainder == 0 );
01587 #endif
01588
01589 result.div_remainder = new LongInt ( 0L );
01590 result.div_remainder->lst = part_dividend.lst;
01591 result.div_remainder->SetSign ( part_dividend.GetSign() );
01592
01593 return result;
01594
01595 }
01596
01605 const LongInt
01606 LongInt::operator/ ( const long &r ) const {
01607 return operator/ ( LongInt ( r ) );
01608 }
01609
01622 const LongInt
01623 LongInt::operator% ( const LongInt &r ) const {
01624 #ifdef WARNINGS
01625 #warning "LongInt::operator%(): Not fully implemented"
01626 #endif
01627 LongInt result = *this / r;
01628 LongInt modulo = * ( result.div_remainder );
01629
01630 if ( r < 0L && *this > 0L ) {
01631 modulo += r;
01632 return modulo;
01633 }
01634
01635 if ( r > 0L && *this < 0L ) {
01636 modulo -= r;
01637 modulo.InvertIP();
01638 return modulo;
01639 }
01640
01641 if ( r < 0L && *this < 0L ) {
01642 modulo.InvertIP();
01643 return modulo;
01644 }
01645
01646 return modulo;
01647 }
01648
01657 const LongInt
01658 LongInt::operator% ( const long &r ) const {
01659 return operator% ( LongInt ( r ) );
01660 }
01661
01670 const bool
01671 LongInt::operator== ( const LongInt &r ) const {
01672 if ( Length() != r.Length() ) {
01673 return false;
01674 }
01675
01676 if ( IsNegative() != r.IsNegative() ) {
01677 return false;
01678 }
01679
01680 if ( lst.size() != r.lst.size() ) {
01681 return false;
01682 }
01683
01684 std::list<unsigned int>::const_iterator it1 = lst.begin();
01685 std::list<unsigned int>::const_iterator it2 = r.lst.begin();
01686
01687 while ( it1 != lst.end() ) {
01688 if ( *it1 != *it2 ) {
01689 return false;
01690 }
01691
01692 it1++;
01693 it2++;
01694 }
01695
01696 return true;
01697 }
01698
01707 const bool
01708 LongInt::operator== ( const long &r ) const {
01709 return operator== ( LongInt ( r ) );
01710 }
01711
01721 const bool
01722 LongInt::operator!= ( const LongInt &r ) const {
01723 return ! ( *this == r );
01724 }
01725
01734 const bool
01735 LongInt::operator!= ( const long &r ) const {
01736 return ! ( *this == LongInt ( r ) );
01737 }
01738
01748 const bool
01749 LongInt::operator< ( const LongInt &r ) const {
01750 if ( *this == r ) {
01751 return false;
01752 }
01753
01754 if ( IsNegative() && r.IsPositive() ) {
01755 return true;
01756 }
01757
01758 if ( IsPositive() && r.IsNegative() ) {
01759 return false;
01760 }
01761
01762 if ( lst.size() < r.lst.size() ) {
01763 return ( IsNegative() ? false : true );
01764 }
01765
01766 if ( lst.size() > r.lst.size() ) {
01767 return ( IsNegative() ? true : false );
01768 }
01769
01770 std::list<unsigned int>::const_iterator it1 = lst.begin();
01771 std::list<unsigned int>::const_iterator it2 = r.lst.begin();
01772
01773 while ( it1 != lst.end() ) {
01774 if ( *it1 != *it2 ) {
01775 if ( *it1 < *it2 ) {
01776 return ( IsNegative() ? false : true );
01777 }
01778 else {
01779 return ( IsNegative() ? true : false );
01780 }
01781 }
01782
01783 it1++;
01784 it2++;
01785 }
01786 throw EInternal();
01787 }
01788
01798 const bool
01799 LongInt::operator< ( const long &r ) const {
01800 return operator< ( LongInt ( r ) );
01801 }
01802
01812 const bool
01813 LongInt::operator> ( const LongInt &r ) const {
01814 if ( *this == r ) {
01815 return false;
01816 }
01817
01818 if ( IsNegative() && r.IsPositive() ) {
01819 return false;
01820 }
01821
01822 if ( IsPositive() && r.IsNegative() ) {
01823 return true;
01824 }
01825
01826 if ( lst.size() > r.lst.size() ) {
01827 return ( IsNegative() ? false : true );
01828 }
01829
01830 if ( lst.size() < r.lst.size() ) {
01831 return ( IsNegative() ? true : false );
01832 }
01833
01834 std::list<unsigned int>::const_iterator it1 = lst.begin();
01835 std::list<unsigned int>::const_iterator it2 = r.lst.begin();
01836
01837 while ( it1 != lst.end() ) {
01838 if ( *it1 != *it2 ) {
01839 if ( *it1 > *it2 ) {
01840 return ( IsNegative() ? false : true );
01841 }
01842 else {
01843 return ( IsNegative() ? true : false );
01844 }
01845 }
01846
01847 it1++;
01848 it2++;
01849 }
01850 throw EInternal();
01851 }
01852
01862 const bool
01863 LongInt::operator> ( const long &r ) const {
01864 return operator> ( LongInt ( r ) );
01865 }
01866
01876 const bool
01877 LongInt::operator>= ( const LongInt &r ) const {
01878 if ( *this == r ) {
01879 return true;
01880 }
01881
01882 if ( *this > r ) {
01883 return true;
01884 }
01885
01886 return false;
01887 }
01888
01898 const bool
01899 LongInt::operator>= ( const long &r ) const {
01900 return operator>= ( LongInt ( r ) );
01901 }
01902
01912 const bool
01913 LongInt::operator<= ( const LongInt &r ) const {
01914 if ( *this == r ) {
01915 return true;
01916 }
01917
01918 if ( *this < r ) {
01919 return true;
01920 }
01921
01922 return false;
01923 }
01924
01934 const bool
01935 LongInt::operator<= ( const long &r ) const {
01936 return operator<= ( LongInt ( r ) );
01937 }
01938
01947 const LongInt
01948 LongInt::operator<< ( const signed long &r ) const {
01949 if ( r < 0 ) {
01950 return *this;
01951 }
01952
01953 LongInt tmp = *this;
01954 for ( signed long l = 0; l < r; l++ ) {
01955 tmp.lst.push_back ( 0 );
01956 }
01957
01958 tmp.stripzeros();
01959 return tmp;
01960 }
01961
01967 const LongInt
01968 LongInt::operator++() {
01969 return ( *this ) = operator+ ( 1 );
01970 }
01971
01977 const LongInt
01978 LongInt::operator++ ( int ) {
01979 LongInt before = *this;
01980 ( *this ) = operator+ ( 1 );
01981
01982 return before;
01983 }
01984
01990 const LongInt
01991 LongInt::operator--() {
01992 return ( *this ) = operator- ( 1 );
01993 }
01994
02000 const LongInt
02001 LongInt::operator-- ( int ) {
02002 LongInt before = *this;
02003 ( *this ) = operator- ( 1 );
02004
02005 return before;
02006 }
02007
02008
02009