#ifndef BIGINTEGER_HPP
#define BIGINTEGER_HPP
#include
#include
// It can be nice to wrap your material in an appropriate namespace.
namespace vtc {
// This class supports very large *unsigned* integers.
class BigInteger {
// Declaration of a non-method that can access the private section of BigInteger.
friend std::ostream &operator<<( std::ostream &os, const BigInteger &bi );
public:
// Default constructor.
// Won't be generated because there is at least one explicitly declared constructor.
BigInteger( );
// Copy constructor.
// Is generated because there is no other explicitly declared copy constructor.
// BigInteger( const BigInteger & );
// Other constructors of interest.
BigInteger( unsigned long long value );
BigInteger( const std::string &raw_digits ); // What if raw_digits isn't all digits?
// Named method returns the number of digits in the the number (not counting leading
// zeros). The value 0 has zero digits.
int number_of_digits( ) const;
// Operator methods for supporting the usual arithmetic operations.
// Only one operator method is shown for illustration.
//
// This method takes 'right' by reference to avoid copying large object. It is a
// reference to const since += does not attempt to modify its right operand. This method
// returns a reference to 'this' so that += operations can be chained.
BigInteger &operator+=( const BigInteger &right );
// Conversion operator to convert BigInteger to unsigned long long.
operator unsigned long long( ) const; // What if there is overflow in the conversion?
private:
// Static members exist even if you never create any class instances. Static constants
// can be initialized inside the class definition. They are constant expressions known
// to the compiler and can be used as such.
static const int maximum_size = 100;
// Each element of the digits array is a base 10 digit.
// TODO: This is quite memory inefficient since 32 bits are used to hold less than 4
// bits of information. Better representations are possible.
int digits[maximum_size];
};
// This function is inline for performance (and thus defined in the header file). It takes
// its parameters as references (to avoid copying) to const (since neither operand is
// changed. It returns a BigInteger by value (not reference) to avoid returning a reference
// to a local variable that will be deallocated with the function returns. Uses of this
// operator are, in effect, replaced with the temporary object that is returned by it.
inline BigInteger operator+( const BigInteger &left, const BigInteger &right )
{
// Createa temporary BigInteger that is a copy of left. Note the use of the C++ 2011
// uniform initialization syntax.
BigInteger temp { left }; // Uses the generated copy constructor.
temp += right;
return temp;
}
}
#endif