1/*==============================================================================
  2|
  3|  NAME
  4|
  5|      ppBigInt.hpp
  6|
  7|  DESCRIPTION
  8|
  9|      Header for non-negative multiple precision integer arithmetic classes.
 10|
 11|      User manual and technical documentation are described in detail in my web page at
 12|      http://seanerikoconnor.freeservers.com/Mathematics/AbstractAlgebra/PrimitivePolynomials/overview.html
 13|
 14|  LEGAL
 15|
 16|     Primpoly Version 16.3 - A Program for Computing Primitive Polynomials.
 17|     Copyright (C) 1999-2024 by Sean Erik O'Connor.  All Rights Reserved.
 18|
 19|     This program is free software: you can redistribute it and/or modify
 20|     it under the terms of the GNU General Public License as published by
 21|     the Free Software Foundation, either version 3 of the License, or
 22|     (at your option) any later version.
 23|
 24|     This program is distributed in the hope that it will be useful,
 25|     but WITHOUT ANY WARRANTY; without even the implied warranty of
 26|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 27|     GNU General Public License for more details.
 28|
 29|     You should have received a copy of the GNU General Public License
 30|     along with this program.  If not, see http://www.gnu.org/licenses/.
 31|     
 32|     The author's address is seanerikoconnor!AT!gmail!DOT!com
 33|     with the !DOT! replaced by . and the !AT! replaced by @
 34|
 35==============================================================================*/
 36
 37// Wrap this header file to prevent duplication if it is included
 38// accidentally more than once.
 39#ifndef __PP_BIGINT_H__
 40#define __PP_BIGINT_H__
 41
 42
 43/*=============================================================================
 44|
 45| NAME
 46|
 47|     BigIntMathError       General math error, including internal memory errors.
 48|     BigIntUnderflow       Underflow.
 49|     BigIntOverflow        Overflow.
 50|     BigIntZeroDivide      Zero divide.
 51|     BigIntRangeError      Input range error.
 52|     BigIntDomainError     Input domain error, i.e. log(-1).
 53|
 54| DESCRIPTION
 55|
 56|     Exception classes for the BigInt class
 57|     derived from the STL exception class runtime_error.
 58|
 59+============================================================================*/
 60
 61class BigIntMathError : public runtime_error
 62{
 63    public:
 64        // Throw with error message, file name and line number.
 65        BigIntMathError( const string & description, const string & file, const int & line )
 66        : runtime_error( description + " in file " + file + " at line " + to_string(line) )
 67        {
 68        } ;
 69
 70        // Throw with an error message.
 71        BigIntMathError( const string & description )
 72			: runtime_error( description )
 73        {
 74        } ;
 75
 76        // Default throw with no error message.
 77        BigIntMathError()
 78			: runtime_error( "BigInt math error:  " )
 79        {
 80        } ;
 81
 82} ; // end class BigIntMathError
 83
 84
 85class BigIntRangeError : public BigIntMathError
 86{
 87    public:
 88        // Throw with error message, file name and line number.
 89        BigIntRangeError( const string & description, const string & file, const int & line )
 90        : BigIntMathError( description + " in file " + file + " at line " + to_string(line) )
 91        {
 92        } ;
 93
 94        // Throw with an error message.
 95        BigIntRangeError( const string & description )
 96			: BigIntMathError( description )
 97        {
 98        } ;
 99
100        // Default throw with no error message.
101        BigIntRangeError()
102			: BigIntMathError( "BigInt range error:  " )
103        {
104        } ;
105
106} ; // end class BigIntRangeError
107
108
109class BigIntDomainError : public BigIntMathError
110{
111    public:
112        // Throw with an error message.
113        BigIntDomainError( const string & description )
114			: BigIntMathError( description )
115        {
116        } ;
117
118        // Default throw with no error message.
119        BigIntDomainError()
120			: BigIntMathError( "BigInt domain error:  " )
121        {
122        } ;
123
124} ; // end class BigIntDomainError
125
126
127class BigIntOverflow : public BigIntMathError
128{
129      public:
130         // Throw with error message, file name and line number.
131         BigIntOverflow( const string & description, const string & file, const int & line )
132         : BigIntMathError( description + " in file " + file + " at line " + to_string(line) )
133         {
134         } ;
135
136          BigIntOverflow( const string & description )
137              : BigIntMathError( description )
138          {
139          } ;
140
141          BigIntOverflow()
142              : BigIntMathError( "BigInt overflow. " )
143          {
144          }
145} ;
146
147
148class BigIntUnderflow : public BigIntMathError
149{
150      public:
151         // Throw with error message, file name and line number.
152         BigIntUnderflow( const string & description, const string & file, const int & line )
153         : BigIntMathError( description + " in file " + file + " at line " + to_string(line) )
154         {
155         } ;
156
157          BigIntUnderflow( const string & description )
158              : BigIntMathError( description )
159          {
160          } ;
161
162          BigIntUnderflow()
163              : BigIntMathError( "BigInt underflow. " )
164          {
165          }
166} ;
167
168
169class BigIntZeroDivide : public BigIntMathError
170{
171      public:
172        // Throw with error message, file name and line number.
173        BigIntZeroDivide( const string & description, const string & file, const int & line )
174        : BigIntMathError( description + " in file " + file + " at line " + to_string(line) )
175        {
176        } ;
177
178          BigIntZeroDivide( const string & description )
179              : BigIntMathError( description )
180          {
181          } ;
182
183          BigIntZeroDivide()
184              : BigIntMathError( "BigInt zero divide. " )
185          {
186          }
187} ;
188
189
190/*=============================================================================
191|
192| NAME
193|
194|     BigInt
195|
196| DESCRIPTION
197|
198|     Class for arbitrary precision non-negative integer arithmetic using any base.
199|
200|     We support the basic operations               + - * /
201|     Also the C-like operators                     += -= *= /= ++ --       where some have mixed BigInt and integer
202|     Comparisions                                  < > <= >= == !=         where some have mixed BigInt and integer
203|     I/O operations                                << >>
204|     Conversion from ordinary integers, to ordinary integers (can throw an overflow exception)
205|     Conversions to and from strings
206|     Bit masking & shifting << bit test and num bits
207|     power (not in BigInt class)
208|     ceil( lg() )
209|
210|     We throw one of the following exceptions,
211|
212|     BigIntMathError       General math error.
213|     BigIntRangeError      Range error on input.
214|     BigIntUnderflow       Underflow.
215|     BigIntOverflow        Overflow.
216|     BigIntZeroDivide      Zero divide.
217|
218| NOTES
219|
220|     The member functions and friends are documented in detail ppBigInt.cpp
221|
222+============================================================================*/
223
224class BigInt
225{
226    public:
227        //-----------------< Basic mathematical operations >------------------
228
229        // *** Constructors.
230
231		// Default constructor.  
232        // e.g. BigInt u ;
233        BigInt() ;
234
235        // Destructor.
236        ~BigInt() ;
237
238        // Constructor from unsigned integers.
239        // Use explicit on these one argument constructors to prevent the compiler doing any
240        // implicit conversions from integers to BigInts.  This should have been the C++ language default.
241        explicit BigInt( const ppuint d ) ;
242        explicit BigInt( const ppuint32 d ) ;
243
244        // Constructor from decimal number string.
245        // e.g. string s = "314159" ;  BigInt w( s ) ;
246        explicit BigInt( const string & s ) ;
247
248        // Copy constructor.
249        // e.g. BigInt u ;  BigInt v( u ) ; 
250        BigInt( const BigInt & u ) ;
251
252        // Assignment.
253        // e.g. BigInt u( "123" ) ;  BigInt v ;  v = u ;
254        BigInt & operator=( const BigInt & n ) ;
255
256		// Conversion to int.
257        // e.g. BigInt( w ) = "123" ;  ppuint u = static_cast<int>( w ) ;
258        operator ppuint() const ;
259
260
261        // *** Input and output operators.
262        
263        // e.g. ostringstream os ;  os << u ;
264        friend ostream & operator<<( ostream & out, const BigInt & u ) ;
265
266        // e.g. istringstream is ;  is >> u ;
267        friend istream & operator>>( istream & in,        BigInt & u ) ;
268
269        // u + v and other additions.
270        friend const BigInt operator+( const BigInt & u, const BigInt & v ) ;
271
272        friend const BigInt operator+( const BigInt & u, const ppuint d ) ;
273
274        BigInt & operator+=( const BigInt & u ) ;
275
276        BigInt & operator+=( const ppuint d ) ;
277
278        // ++u and other increments.
279        BigInt & operator++() ;
280
281        const BigInt operator++( int ) ;
282
283        // u - v and other subtractions.
284        friend const BigInt operator-( const BigInt & u, const BigInt & v ) ;
285
286        friend const BigInt operator-( const BigInt & u, const ppuint d ) ;
287
288        BigInt & operator-=( const BigInt & u ) ;
289
290        BigInt & operator-=( const ppuint d ) ;
291
292        // --u and other decrements
293        BigInt & operator--() ;
294
295        BigInt operator--( int ) ;
296
297        // u * v, and other multiplies.
298        friend const BigInt operator*( const BigInt & u, const BigInt & v ) ;
299
300        friend const BigInt operator*( const BigInt & u, const ppuint d ) ;
301
302        BigInt & operator*=( const BigInt & u ) ;
303
304        BigInt & operator*=( ppuint d ) ;
305
306        // | u / v |, and other integer divides.
307        // --     --
308        friend const BigInt operator/( const BigInt & u, const BigInt & v ) ;
309
310        friend const BigInt operator/( const BigInt & u, const ppuint d ) ;
311
312        BigInt & operator/=( const BigInt & u ) ;
313
314        BigInt & operator/=( ppuint d ) ;
315
316        // u % v, and other integer moduli.
317        friend BigInt operator%( const BigInt & u, const BigInt & v ) ;
318
319        friend ppuint   operator%( const BigInt & u, const ppuint d ) ;
320
321        // --    --
322        // | lg() |
323        int ceilLg() ;
324
325        // Comparisions including
326        // ==, == d, !=, != d, >, > d,
327        // <, < d, >=, >= d, <=, <= d,
328        friend bool operator==( const BigInt & u, const BigInt & v ) ;
329        friend bool operator==( const BigInt & u, const ppuint d     ) ;
330        friend bool operator!=( const BigInt & u, const BigInt & v ) ;
331        friend bool operator!=( const BigInt & u, const ppuint d     ) ;
332        friend bool operator> ( const BigInt & u, const BigInt & v ) ;
333        friend bool operator> ( const BigInt & u, const ppuint d     ) ;
334        friend bool operator< ( const BigInt & u, const BigInt & v ) ;
335        friend bool operator< ( const BigInt & u, const ppuint d     ) ;
336        friend bool operator>=( const BigInt & u, const BigInt & v ) ;
337        friend bool operator>=( const BigInt & u, const ppuint d     ) ;
338        friend bool operator<=( const BigInt & u, const BigInt & v ) ;
339        friend bool operator<=( const BigInt & u, const ppuint d     ) ;
340
341        // Bit masking, testing and setting.
342        friend BigInt operator& ( const BigInt & u, const BigInt & v ) ;
343
344        friend BigInt operator<<( const BigInt & u, ppuint n ) ;
345
346        const bool testBit( const int bitNum ) const ;
347 
348        //-----------------< Helper functions >-------------------------------
349
350        // Conversion to decimal number string.
351        // e.g. BigInt u( "123" ) ; string s = u.toString() ;
352        string toString() const ;
353    
354        // Helper functions for division and mod.
355        friend void divMod( const BigInt & u, const BigInt & v,
356                            BigInt &       q, BigInt &       r ) ;
357
358        friend void divMod( const BigInt & u, const ppuint d,
359                            BigInt &       q, ppuint & r ) ;
360
361        // Highest bit number in a BigInt, 0 is smallest bit.
362        int maxBitNumber() const ;
363
364        // Used by the PolyParser and main for input range checking, so we use a class function
365        // not requiring us to instantiate a BigInt object.
366        static const ppuint getBase() ;
367
368        //-----------------< Unit Test Functions >----------------------------
369
370        friend const ppuint getDigit( const BigInt & u, const int n ) ;
371
372        friend const int getNumDigits( const BigInt & u ) ;
373
374        friend void setBase( const BigInt & u, const ppuint base ) ;
375
376        friend void printNumber( const BigInt & u, ostream & out ) ;
377    
378        friend void printNumber( const BigInt & u ) ;
379
380    // Class variables shared among all classes.
381    // We use static functions instead of static variables to work 
382    // around the C++ static member initialization order problem.
383    private:
384        // Base of the number system (a power of 2) and
385        // corresponding number of bits per digit.
386        static ppuint & base_() ;
387
388        // Pointer to number system base.  Used for unit testing only.
389        static ppuint * pbase ;
390
391        static int & numBitsPerDigit_() ;
392
393    // Private data for member functions only.
394    private:
395		//  Numbers are n-place quantities with base b digits,
396        //         2
397        //  where b  is guaranteed to fit into a digit and
398        //  b is a power of 2.
399        //
400    	//         (u     . . . u )
401		//           n-1         0
402		//
403		//  For programming ease, digits are stored in a vector of
404        //  length n with the least significant digit at digit[ 0 ],
405		//
406		//  +----+----+----+------+------+
407		//  | u  | u  | u  |      | u    |
408		//  |  0 |  1 |  2 | ...  |  n-1 |
409		//  +----+----+----+------+------+
410	   	//
411    	vector<ppuint> digit_ ;
412} ;
413
414
415/*=============================================================================
416|
417| NAME
418|
419|     power
420|
421| DESCRIPTION
422|
423|           n
424|     Does p  for low precision p and n and high precision result.
425|
426+============================================================================*/
427
428//  Don't quite fit into BigInt class.
429BigInt power( ppuint p, ppuint n ) ;
430    
431    
432/*=============================================================================
433|
434| NAME
435|
436|     testBit
437|
438| DESCRIPTION
439|
440|     Bit test for low precision integers.
441|
442+============================================================================*/
443    
444const bool testBit( const ppuint n, const int bitNum ) ;
445
446#endif // __PP_BIGINT_H__ --- End of wrapper for header file.