Advertisement
Guest User

clb79a

a guest
Jan 3rd, 2011
478
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 44.33 KB | None | 0 0
  1. #ifndef BIGINT_H
  2. #define BIGINT_H
  3.  
  4. #include <iostream>
  5. #include <sstream>
  6. #include <string>
  7. #include <cstdio>
  8. #include <algorithm>
  9. #include <boost/dynamic_bitset.hpp>
  10. #include <stdexcept>
  11.  
  12. /*
  13. The BigInt class provides an extension of the built-in integral types to integers
  14. of arbitrary size.  Constructors are implemented from the built-in integral
  15. types together with a string constructor.  The format for a valid string is
  16.  
  17.     "[ base identifier ][ sign ] number "
  18.  
  19.     base identifiers can be:
  20.  
  21.         'b' or 'B' for binary
  22.         'x' or 'X' for hex
  23.         'd' or 'D' for decimal
  24.  
  25.     sign can be '+' or '-'
  26.  
  27. A string with no base identifier defaults to decimal and no sign defaults
  28. to positive.  The internal storage mode is binary using Boost dynamic_bitset.
  29.  
  30. A fairly full set of assignment, compound assignment and comparison operators
  31. has been implemented together with overloads of the output and input operators.
  32. The following maniputlators have been defined for the output operator:
  33.  
  34.     bigintbin
  35.     bigintdec
  36.     biginthex
  37.     bigintupper
  38.     bigintlower
  39.     bigintshowbase
  40.     bigintnoshowbase
  41.     bigintdefault
  42.  
  43. The default is bigintnoshowbase bigintdecimal.
  44.  
  45.  
  46. Manipulators for the input operator are:
  47.  
  48.     bigintbin
  49.     bigintdec
  50.     biginthex
  51.     bigintdefault
  52.  
  53. The default is decimal.  The input manipulators only affect the treatment of
  54. a string with no base identifier.  Formatted strings  that include a base
  55. identifier can be correctly input without regard to any maniputlators set.
  56.  
  57. Exceptions:
  58.  
  59. The string constructor will throw std::invalid_argument if passed an invalid
  60. string.  The offending string is incorporated into the what() message.  
  61. Strings can be tested by calling the function isValidBigIntString().
  62. The assignment operator which takes a string for lhs may also throw because
  63. it call the BigInt string constructor implicitly.
  64.  
  65. An attempted to divide by zero will throw std::domain_error.
  66. */
  67.  
  68.  
  69. class BigInt
  70. {
  71. public:
  72.     BigInt();
  73.     BigInt( unsigned long n );
  74.     BigInt( signed long n );
  75.     BigInt( int n );
  76.     BigInt( const std::string& s );
  77.  
  78.     // assignment operators
  79.     BigInt&   operator= ( const unsigned long& rhs );
  80.     BigInt&   operator= ( const signed long& rhs );
  81.     BigInt&   operator= ( const int& rhs );
  82.     BigInt&   operator= ( const std::string& rhs );
  83.     BigInt&   operator= ( const char*& rhs );
  84.  
  85.     // unary operators
  86.     BigInt  operator+ () const;
  87.     BigInt  operator- () const;
  88.  
  89.     // compound assignment operators
  90.     const BigInt& operator+= ( const BigInt& rhs );
  91.     const BigInt& operator-= ( const BigInt& rhs );
  92.     const BigInt& operator*= ( const BigInt& rhs );
  93.     const BigInt& operator/= ( const BigInt& rhs );
  94.     const BigInt& operator%= ( const BigInt& rhs );
  95.  
  96.     void divisionAndRemainder( const BigInt& divisor, BigInt& quotient, BigInt& remainder ) const;
  97.  
  98.     // increment and decrement operators
  99.     BigInt& operator++ ();
  100.     BigInt  operator++ ( int );
  101.     BigInt& operator-- ();
  102.     BigInt  operator-- ( int );
  103.  
  104.     void swap( BigInt& bi );
  105.  
  106.     // conversion functions
  107.     // These conversion functions strip leading but not a terminal zero.  They
  108.     // operate on strings not BigInts.  They should not contain a '+' or '-'.
  109.     static std::string decToHex( const std::string& s );
  110.     static std::string hexToDec( const std::string& s );
  111.  
  112.     static std::string decToBin( const std::string& s );
  113.     static std::string binToDec( const std::string& s );
  114.  
  115.     static std::string hexToBin( const std::string& s );
  116.     static std::string binToHex( const std::string& s );
  117.  
  118.     static void stripLeadingZeroesFromString( std::string& s );
  119.  
  120.     static bool isValidBigIntString( const std::string& s );
  121.  
  122.     static const long int getOutputWordIndex();
  123.     static const long int getInputWordIndex();
  124.  
  125.  
  126. private:
  127.     boost::dynamic_bitset<> x_;
  128.     bool negative_;
  129.  
  130.     // flags for manipulating input and output streams
  131.     enum BigIntBase { def = 0, dec = 1, bin = 2, hex = 4, uppercase = 8, showbase = 15,
  132.         nodec = 30, nobin = 29, nohex = 27, lowercase = 23, noshowbase = 16 };
  133.  
  134.         //  noshowbase uppercase  hex  bin  dec
  135.         //      0          0       0    0    1     dec = 1
  136.         //      0          0       0    1    0     bin = 2
  137.         //      0          0       1    0    0     hex = 4            OR with outputWordIndex_
  138.         //      0          1       0    0    0     uppercase = 8      or inputWordIndex_ to set
  139.         //      1          0       0    0    0     noshowbase  = 16
  140.  
  141.         //      1          1       1    1    0     nodec = 30
  142.         //      1          1       1    0    1     nobin = 29
  143.         //      1          1       0    1    1     nohex = 27         AND with outputWordIndex_
  144.         //      1          0       1    1    1     lowercase = 23     or inputWordIndex_ to clear
  145.         //      0          1       1    1    1     showbase = 15
  146.  
  147.         //      0          0       0    0    0     def = 0 the default, interpreted as decimal and noshowbase
  148.         //      0          0       0    0    1     equivalent to the default
  149.  
  150.  
  151.     void stripLeadingZeroes( boost::dynamic_bitset<>& db );
  152.     void compoundAddAssignIgnoreSign( const BigInt& rhs, boost::dynamic_bitset<>::size_type startIndex = 0 );
  153.  
  154.     static const long int outputWordIndex_;
  155.     static const long int inputWordIndex_;
  156.  
  157.  
  158.     // friends
  159.     friend bool operator<  ( const BigInt& lhs, const BigInt& rhs );
  160.     friend bool operator<= ( const BigInt& lhs, const BigInt& rhs );
  161.     friend bool operator== ( const BigInt& lhs, const BigInt& rhs );
  162.     friend bool operator!= ( const BigInt& lhs, const BigInt& rhs );
  163.     friend bool operator>= ( const BigInt& lhs, const BigInt& rhs );
  164.     friend bool operator>  ( const BigInt& lhs, const BigInt& rhs );
  165.  
  166.     friend std::ostream& operator<< ( std::ostream& os, const BigInt& bi );
  167.     friend std::istream& operator>> ( std::istream& is, BigInt& bi );
  168.  
  169.     // output stream manipulators
  170.     friend std::ostream& bigintbin( std::ostream& os );
  171.     friend std::ostream& bigintdec( std::ostream& os );
  172.     friend std::ostream& biginthex( std::ostream& os );
  173.     friend std::ostream& bigintupper( std::ostream& os );
  174.     friend std::ostream& bigintlower( std::ostream& os );
  175.     friend std::ostream& bigintshowbase( std::ostream& os );
  176.     friend std::ostream& bigintnoshowbase( std::ostream& os );
  177.     friend std::ostream& bigintdefault( std::ostream& os );
  178.  
  179.     // input stream manipulators
  180.     friend std::istream& bigintbin( std::istream& is );
  181.     friend std::istream& bigintdec( std::istream& is );
  182.     friend std::istream& biginthex( std::istream& is );
  183.     friend std::istream& bigintdefault( std::istream& is );
  184.  
  185. };
  186.  
  187. // comparison operators
  188. bool operator<  ( const BigInt& lhs, const BigInt& rhs );
  189. bool operator<= ( const BigInt& lhs, const BigInt& rhs );
  190. bool operator== ( const BigInt& lhs, const BigInt& rhs );
  191. bool operator!= ( const BigInt& lhs, const BigInt& rhs );
  192. bool operator>= ( const BigInt& lhs, const BigInt& rhs );
  193. bool operator>  ( const BigInt& lhs, const BigInt& rhs );
  194.  
  195.  
  196. // binary arithmetic operators
  197. BigInt operator+ ( const BigInt& lhs, const BigInt& rhs );
  198. BigInt operator- ( const BigInt& lhs, const BigInt& rhs );
  199. BigInt operator* ( const BigInt& lhs, const BigInt& rhs );
  200. BigInt operator/ ( const BigInt& lhs, const BigInt& rhs );
  201. BigInt operator% ( const BigInt& lhs, const BigInt& rhs );
  202.  
  203.  
  204. std::ostream& operator<< ( std::ostream& os, const BigInt& bi );
  205. std::istream& operator>> ( std::istream& is, BigInt& bi );
  206.  
  207. // output stream manipulators
  208. std::ostream& bigintbin( std::ostream& os );
  209. std::ostream& bigintdec( std::ostream& os );
  210. std::ostream& biginthex( std::ostream& os );
  211. std::ostream& bigintupper( std::ostream& os );
  212. std::ostream& bigintlower( std::ostream& os );
  213. std::ostream& bigintdefault( std::ostream& os );
  214.  
  215. // input stream manipulators
  216. std::istream& bigintbin( std::istream& is );
  217. std::istream& bigintdec( std::istream& is );
  218. std::istream& biginthex( std::istream& is );
  219. std::istream& bigintdefault( std::istream& is );
  220.  
  221.  
  222. // BigInt Math functions
  223. BigInt factorial( const BigInt& n );
  224.  
  225. #endif
  226.  
  227.  
  228. // ******************  Begin BigInt.hpp  **************************
  229.  
  230. #include "BigInt.h"
  231.  
  232. const long int BigInt::outputWordIndex_ = std::ios::xalloc();
  233. const long int BigInt::inputWordIndex_  = std::ios::xalloc();
  234.  
  235. const long int BigInt::getOutputWordIndex()
  236. {
  237.     return outputWordIndex_;
  238. }
  239.  
  240. const long int BigInt::getInputWordIndex()
  241. {
  242.     return inputWordIndex_;
  243. }
  244.  
  245.  
  246.  
  247. BigInt::BigInt() : x_( std::string( "0" ) ), negative_( false )
  248. {
  249. }
  250.  
  251.  
  252. BigInt::BigInt( unsigned long n ) : x_( sizeof( unsigned long ) * 8, n ), negative_( false )
  253. {
  254.     stripLeadingZeroes( x_ );
  255. }
  256.  
  257.  
  258. BigInt::BigInt( signed long n ) : x_( sizeof( unsigned long ) * 8, ( n < 0 ? static_cast< unsigned long >( -( n + 1 )  ) + 1 : static_cast< unsigned long >( n ) ) ),
  259.     negative_( n < 0 ? true : false )
  260. {
  261.     stripLeadingZeroes( x_ );
  262. }
  263.  
  264.  
  265. BigInt::BigInt( int n ) : x_( sizeof( int ) * 8, ( n < 0 ? static_cast< unsigned int >( -( n + 1 ) ) + 1  : static_cast< unsigned int >( n ) ) ),
  266.     negative_( n < 0 ? true : false )
  267. {
  268.     stripLeadingZeroes( x_ );
  269. }
  270.  
  271.  
  272. BigInt::BigInt( const std::string& s ) : x_( std::string( "0" ) ), negative_( false )
  273. {
  274.     if ( ! BigInt::isValidBigIntString( s ) )
  275.     {
  276.         throw std::invalid_argument( "Invalid BigInt string=" + s );
  277.     }
  278.  
  279.     if ( s.size() == 1 )
  280.     {
  281.         x_[ 0 ] = ( s[ 0 ] == '1' ? true : false );
  282.         negative_ = false;
  283.     }
  284.  
  285.     switch ( s[ 0 ] )
  286.     {
  287.     case 'b' :
  288.     case 'B' :
  289.         if ( s[ 1 ] == '+' || s[ 1 ] == '-' )
  290.         {
  291.             negative_ = ( s[ 1 ] == '-' ? true : false );
  292.             x_ = boost::dynamic_bitset<>( s.substr( 2 ) );
  293.         }
  294.         else
  295.         {
  296.             negative_ = false;
  297.             x_ = boost::dynamic_bitset<>( s.substr( 1 ) );
  298.         }
  299.         break;
  300.  
  301.     case 'd' :
  302.     case 'D' :
  303.         if ( s[ 1 ] == '+' || s[ 1 ] == '-' )
  304.         {
  305.             negative_ = ( s[ 1 ] == '-' ? true : false );
  306.             x_ = boost::dynamic_bitset<>( decToBin( s.substr( 2 ) ) );
  307.         }
  308.         else
  309.         {
  310.             negative_ = false;
  311.             x_ = boost::dynamic_bitset<>( decToBin( s.substr( 1 ) ) );
  312.         }
  313.         break;
  314.  
  315.     case 'x' :
  316.     case 'X' :
  317.         if ( s[ 1 ] == '+' || s[ 1 ] == '-' )
  318.         {
  319.             negative_ = ( s[ 1 ] == '-' ? true : false );
  320.             x_ = boost::dynamic_bitset<>( hexToBin( s.substr( 2 ) ) );
  321.         }
  322.         else
  323.         {
  324.             negative_ = false;
  325.             x_ = boost::dynamic_bitset<>( hexToBin( s.substr( 1 ) ) );
  326.         }
  327.         break;
  328.  
  329.     case '+' :
  330.         negative_ = false;
  331.         x_ = boost::dynamic_bitset<>( decToBin( s.substr( 1 ) ) );
  332.         break;
  333.  
  334.     case '-' :
  335.         negative_ = true;
  336.         x_ = boost::dynamic_bitset<>( decToBin( s.substr( 1 ) ) );
  337.         break;
  338.  
  339.     default :
  340.  
  341.         // no radix identifier or sign so this is a positive decimal
  342.         negative_ = false;
  343.         x_ = boost::dynamic_bitset<>( decToBin( s ) );
  344.     }
  345.     stripLeadingZeroes( x_ );
  346.     if ( x_.size() == 1 && x_[ 0 ] == 0 )
  347.     {
  348.         // this number is zero so...
  349.         negative_ = false;
  350.     }
  351. }
  352.  
  353.  
  354.  
  355.  
  356.  
  357. // assignment operators
  358.  
  359. BigInt&   BigInt::operator= ( const unsigned long& rhs )
  360. {
  361.     BigInt bi( rhs );
  362.     x_        = bi.x_;
  363.     negative_ = bi.negative_;
  364.     return *this;
  365. }
  366.  
  367.  
  368. BigInt&   BigInt::operator= ( const signed long& rhs )
  369. {
  370.     BigInt bi( rhs );
  371.     x_        = bi.x_;
  372.     negative_ = bi.negative_;
  373.     return *this;
  374. }
  375.  
  376.  
  377. BigInt&   BigInt::operator= ( const int& rhs )
  378. {
  379.     BigInt bi( rhs );
  380.     x_        = bi.x_;
  381.     negative_ = bi.negative_;
  382.     return *this;
  383. }
  384.  
  385.  
  386. BigInt&   BigInt::operator= ( const std::string& rhs )
  387. {
  388.     BigInt bi( rhs );
  389.     x_        = bi.x_;
  390.     negative_ = bi.negative_;
  391.     return *this;
  392. }
  393.  
  394.  
  395. BigInt&   BigInt::operator= ( const char*& rhs )
  396. {
  397.     BigInt bi( rhs );
  398.     x_        = bi.x_;
  399.     negative_ = bi.negative_;
  400.     return *this;
  401. }
  402.  
  403.  
  404.  
  405.  
  406. // unary operators
  407. BigInt BigInt::operator+ () const
  408. {
  409.     BigInt bi;
  410.     bi = *this;
  411.     return bi;
  412. }
  413.  
  414. BigInt  BigInt::operator- () const
  415. {
  416.     BigInt bi;
  417.     bi = *this;
  418.     if ( x_.size() == 1 && x_[ 0 ] == 0 )
  419.     {
  420.         // this number is zero so do nothing
  421.     }
  422.     else
  423.     {
  424.         bi.negative_ = !negative_;
  425.     }
  426.     return bi;
  427. }
  428.  
  429.  
  430. // compound assignment operators
  431. const BigInt& BigInt::operator+= ( const BigInt& rhs )
  432. {
  433.     unsigned long newSize =( x_.size() < rhs.x_.size()  ? rhs.x_.size() + 1 : x_.size() + 1 );
  434.     if ( negative_ && rhs.negative_ || !negative_ && !rhs.negative_ )
  435.     {
  436.         // same sign for both numbers
  437.         // resize *this to make sure that it is the largest with an extra bit in case of a final carry
  438.         x_.resize( newSize );
  439.         compoundAddAssignIgnoreSign( rhs );
  440.     }
  441.     else
  442.     {
  443.         // opposite signs
  444.         // We would like to switch the negative number to two's complement
  445.         // before performing the addition, however since rhs is const we
  446.         // will treat *this  as the negative number and then change the sign
  447.         // if necessary at the end.
  448.  
  449.         bool isResultSignNegative = false;
  450.         // switch *this temporarily to the same sign as rhs so we can compare the
  451.         // magnitude of the number.
  452.         negative_ = rhs.negative_;
  453.         if ( *this < rhs )
  454.         {
  455.             isResultSignNegative = false;
  456.         }
  457.         else
  458.         {
  459.             if ( rhs < *this )
  460.             {
  461.                 isResultSignNegative = true;
  462.             }
  463.             else
  464.             {
  465.                 // *this and rhs are same magnitude so the sum is zero
  466.                 negative_ = false;
  467.                 return ( *this = 0 );
  468.             }
  469.         }
  470.         x_.resize( newSize );
  471.         x_.flip();
  472.  
  473.         // note that high order bit of x_ is now 1 ( it's the sign bit for two's complement )
  474.  
  475.         // need to add one to *this
  476.         BigInt one( 1 );
  477.         compoundAddAssignIgnoreSign( one );
  478.         compoundAddAssignIgnoreSign( rhs );
  479.  
  480.         // Check for a negative two's complement number and convert it back
  481.         if ( x_[ x_.size() - 1 ] == 1 )
  482.         {
  483.             x_.flip();
  484.             compoundAddAssignIgnoreSign( one );
  485.         }
  486.         x_.resize( newSize - 1 );
  487.         negative_ = isResultSignNegative;
  488.     }
  489.     stripLeadingZeroes( x_ );
  490.     return *this;
  491. }
  492.  
  493.  
  494. const BigInt& BigInt::operator-= ( const BigInt& rhs )
  495. {
  496.     *this += -rhs;
  497.     return *this;
  498. }
  499.  
  500.  
  501.  
  502. const BigInt& BigInt::operator*= ( const BigInt& rhs )
  503. {
  504.     if ( *this == 0 || rhs == 0 )
  505.     {
  506.         return ( *this = 0 );
  507.     }
  508.  
  509.     BigInt thisCopy( *this );
  510.     x_.reset();
  511.     x_.resize( rhs.x_.size() + x_.size() );
  512.     const BigInt& multiplicand = ( x_.size() < rhs.x_.size() ? rhs : thisCopy);
  513.     const BigInt& multiplier   = ( x_.size() >= rhs.x_.size() ? rhs : thisCopy );
  514.  
  515.     boost::dynamic_bitset<>::size_type multiplierSize = multiplier.x_.size();
  516.     boost::dynamic_bitset<>::size_type startIndex     = 0;
  517.  
  518.     for ( boost::dynamic_bitset<>::size_type i = 0; i < multiplierSize; ++i, ++startIndex )
  519.     {
  520.         if ( multiplier.x_[ i ] == 1 )
  521.         {
  522.             compoundAddAssignIgnoreSign( multiplicand, startIndex );
  523.         }
  524.     }
  525.  
  526.     if ( negative_ == rhs.negative_ )
  527.     {
  528.         negative_ = false;
  529.     }
  530.     else
  531.     {
  532.         negative_ = true;
  533.     }
  534.     stripLeadingZeroes( x_ );
  535.     return *this;
  536. }
  537.  
  538.  
  539. const BigInt& BigInt::operator/= ( const BigInt& rhs )
  540. {
  541.     BigInt quotient;
  542.     BigInt remainder;
  543.     divisionAndRemainder( rhs, quotient, remainder );
  544.     *this = quotient;
  545.     return *this;
  546. }
  547.  
  548.  
  549. const BigInt& BigInt::operator%= ( const BigInt& rhs )
  550. {
  551.     BigInt quotient;
  552.     BigInt remainder;
  553.     divisionAndRemainder( rhs, quotient, remainder );
  554.     *this = remainder;
  555.     return *this;
  556. }
  557.  
  558.  
  559. void BigInt::divisionAndRemainder( const BigInt& divisor, BigInt& quotient, BigInt& remainder ) const
  560. {
  561.  
  562.     /*
  563.     This routine divides *this by divisor, calculating both the quotient and remainder.  We
  564.     will use an algorithm based on the normal way humans calculate division.
  565.  
  566.     Size of quotient:  Consider multiplying a three bit number by a five bit number.  The
  567.     minimum resulting size would be 100 * 10000 = 1000000 (a seven bit number).  The maximum
  568.     resulting size would be 111 * 11111 = 10100001 (an eight bit number).  The resulting size
  569.     will always be the sum of the two sizes or possibly one less.  Hence for division the
  570.     size of the quotient will always be the difference between the two sizes or possibly
  571.     one more ( assuming divisor's size is less than or equal to quotient ).  Thus setting
  572.     the size of quotient to be the difference plus one will guarantee that it will be large
  573.     enough to hold the result.
  574.    
  575.     The rationale for doing it this way is that in division the quotient bits are generated
  576.     starting with the high order bit and ending with the low order bit.  By setting the
  577.     size of quotient before we begin we can store the bits as they are generated from
  578.     index quotient.size() - 1 down to zero.  If we stored   the bits in some container
  579.     as generated we would later have the problem of reversing the bits which doing it
  580.     this way avoids.
  581.    
  582.     We will also find it convenient to pad dividend with two leading zeroes and
  583.     divisor with one leading zero.  Consider the example below of dividing
  584.     10001101 by 111.  The first successful division will be 111 into 1000 or a four
  585.     bit number divided by a three bit number.  But suppose we were dividing 111000 by
  586.     111. Then the first successful division would be 111 into 111 or a 3 bit number
  587.     into a three bit number, thus the first time through the loop would have to be
  588.     handled differently.  By padding both dividend and divisor with a leading zero we
  589.     can always divide a four bit number into a four bit number, thus simplifying the
  590.     loop.  This may result in leading zeroes in quotient, but they  can be stripped
  591.     later if necessary.  We also retain leading zeroes in remainder through out the
  592.     loop so that divisor will always have the same number of bits.  This facilitates
  593.     the lexical comparision of divisor and dividend to see which is bigger.  The
  594.     second zero added to the left of dividend is to make sure dividend is big enough
  595.     to handle any carry coming out of the call to compoundAddAssignIgnoreCase().
  596.     (This may not be necessary, but it is benign and if not necessary will be
  597.     stripped later.  We need to do a detailed analysis of all possible outcomes from
  598.     calls to compoundAddAssignIgnoreCase() before eliminating this second added zero.)
  599.    
  600.  
  601.     Algorithm:  Consider the following example:
  602.  
  603.         10001101 / 111 = 10100 + remainder of 1    ( 141 / 7 = 20 with remainder of 1 )
  604.  
  605.                 start     end
  606.  
  607.                     ^     ^
  608.                     |     |
  609.                           0 0 0 0 0 0          quotient is initialized to all zeroes
  610.                 _____________________
  611.         0 1 1 1 | 0 0 1 0 0 0 1 1 0 1          start and end are indexes into the dividend, initially set
  612.                                                 to define a range the same size as the divisor.
  613.  
  614.         Compare lexically 0111 and 0100  [start, end].   If 0111 were <= 0100 we could put a one in quotient at index end
  615.                                                             and continue with the algorithm, but since 0111 > 0100 we put a
  616.                                                             zero at index end and decrement start and end and try again.
  617.  
  618.  
  619.                   start     end
  620.  
  621.                       ^     ^
  622.                       |     |
  623.                           0 1 0 0 0 0          quotient is 0 1 ? ? ? ?
  624.                 _____________________
  625.         0 1 1 1 | 0 0 1 0 0 0 1 1 0 1        Compare 0111 and 1000 [start, end].  Since 0111 < 1000 we put a one
  626.                       0 1 1 1                in quotient at index end and substract the divisor 0111 from 1000
  627.                       -------                [start, end] in dividend.
  628.                       0 0 0 1
  629.                                             Since we no longer need the first four bits of dividend, but do need
  630.                                             remainder for use in the next division we can safely overwrite the
  631.                                             range [start, end] in dividend with remainder and decrement start and
  632.                                             end.  Our new dividend is now the new start end.
  633.  
  634.  
  635.                   start     end
  636.  
  637.                       ^     ^
  638.                       |     |
  639.                         0 1 0 0 0 0          quotient is 0 1 0 ? ? ?
  640.               _____________________
  641.         1 1 1 | 0 0 0 0 0 1 1 1 0 1          Compare 0111 and 0011 [start, end].  Since 0111 > 0011 we put a zero
  642.                       0 1 1 1                in quotient at index end and decrement start and end.
  643.                       -------                  
  644.                  
  645.  
  646.  
  647.                       start     end
  648.  
  649.                           ^     ^
  650.                           |     |
  651.                           0 1 0 1 0 0        quotient is 0 1 0 1 ? ?
  652.                 _____________________
  653.         0 1 1 1 | 0 0 0 0 0 1 1 1 0 1        Compare 0111 and 0111 [start, end].  Since 0111 <= 0111 we put a one
  654.                           0 1 1 1            in quotient at index end and substract the divisor 0111 from 1000
  655.                           -------            [start, end] in dividend.  The remainder 0000 is then written back
  656.                           0 0 0 0            replacing the range [start, end] in dividend.
  657.                                              Decrement start and end.
  658.  
  659.  
  660.                         start     end
  661.  
  662.                             ^     ^
  663.                             |     |
  664.                           0 1 0 1 0 0        quotient is 0 1 0 1 0 ?
  665.                 ___________________
  666.         0 1 1 1 | 0 0 0 0 0 0 0 0 0 1        Compare 0111 and 0000 [start, end].  Since 0111 > 0000 we put a zero
  667.                             0 1 1 1          in quotient at index end and decrement start and end.
  668.                             -------
  669.                          
  670.  
  671.  
  672.                           start     end
  673.  
  674.                               ^     ^
  675.                               |     |
  676.                           0 1 0 1 0 0        quotient is 0 1 0 1 0 0
  677.                 _____________________
  678.         0 1 1 1 | 0 0 0 0 0 0 0 0 0 1        Compare 0111 and 0000 [start, end].  Since 0111 > 0001 we put a zero
  679.                               0 1 1 1        in quotient at index end and since end is at the zero index we
  680.                               -------        are done. remainder is [start, end] of dividend which is 0001 or one.
  681.  
  682.         Note:  The process of overwriting dividend with remainder is done automatically by
  683.         compoundAddAssignIgnoreSign() when performing the subtraction.
  684.     */
  685.  
  686.     if ( divisor == 0 )
  687.     {
  688.         throw std::domain_error( "Division by zero" );
  689.     }
  690.  
  691.     if ( divisor > *this )
  692.     {
  693.         quotient  = 0;
  694.         remainder = *this;
  695.         return;
  696.     }
  697.     else
  698.     {
  699.         if ( divisor == *this )
  700.         {
  701.             quotient  = 1;
  702.             remainder = 0;
  703.             return;
  704.         }
  705.     }
  706.  
  707.     // We know that divisor < *this so ...
  708.  
  709.     quotient.x_.reset();
  710.     quotient.x_.resize( x_.size() - divisor.x_.size() + 1 );
  711.  
  712.     BigInt dividendPadded( *this );
  713.     dividendPadded.x_.resize( dividendPadded.x_.size() + 2 );
  714.     BigInt divisorPadded( divisor );
  715.     divisorPadded.x_.resize( divisorPadded.x_.size() + 1 );
  716.  
  717.     BigInt twosCompDivisor( divisorPadded );
  718.     twosCompDivisor.x_.resize( divisorPadded.x_.size() + 1 );
  719.     twosCompDivisor.x_.flip();
  720.     twosCompDivisor += 1;
  721.  
  722.     boost::dynamic_bitset<>::size_type divisorPaddedSize = divisorPadded.x_.size();
  723.  
  724.     boost::dynamic_bitset<>::size_type start = dividendPadded.x_.size() - 2;
  725.     boost::dynamic_bitset<>::size_type end   = start - divisorPadded.x_.size() + 1;
  726.  
  727.     boost::dynamic_bitset<>::size_type quotientIndex = quotient.x_.size() - 1;
  728.  
  729.     // Note that we cannot test end >= 0 since end is an unsigned type and
  730.     // decrementing past zero will roll over to a positive value, so
  731.     // end >= 0 will never be false, so...
  732.     unsigned long k = end + 1;
  733.     while ( k > 0 )
  734.     {
  735.         // compare divisorPadded lexically with [start, end]
  736.         bool isDivisorGreaterThanDividend = false;
  737.         boost::dynamic_bitset<>::size_type j = start;
  738.         for ( boost::dynamic_bitset<>::size_type i = divisorPaddedSize; i > 0; --i, --j )
  739.         {
  740.             if ( divisorPadded.x_[ i - 1 ] == dividendPadded.x_[ j ] )
  741.             {
  742.                 continue;
  743.             }
  744.             else
  745.             {
  746.                 if ( divisorPadded.x_[ i - 1 ] > dividendPadded.x_[ j ] )
  747.                 {
  748.                     isDivisorGreaterThanDividend = true;
  749.                     break;
  750.                 }
  751.                 else
  752.                 {
  753.                     break;
  754.                 }
  755.            
  756.             }
  757.         }
  758.         if ( isDivisorGreaterThanDividend )
  759.         {
  760.             quotient.x_[ quotientIndex ] = 0;
  761.             --quotientIndex;
  762.             --start;
  763.             --end;
  764.             --k;
  765.             continue;
  766.         }
  767.  
  768.         // if we reach this far divisor is <= dividend
  769.         quotient.x_[ quotientIndex ] = 1;
  770.         dividendPadded.compoundAddAssignIgnoreSign( twosCompDivisor, end );
  771.         --quotientIndex;
  772.         --start;
  773.         --end;
  774.         --k;
  775.     }
  776.     quotient.stripLeadingZeroes( quotient.x_ );
  777.     dividendPadded.x_.resize( divisorPaddedSize );
  778.     dividendPadded.stripLeadingZeroes( dividendPadded.x_ );
  779.     remainder = dividendPadded;
  780.  
  781. }
  782.  
  783.  
  784. // increment and decrement operators
  785. BigInt& BigInt::operator++ ()
  786. {
  787.     *this += 1;
  788.     return *this;
  789. }
  790.  
  791.  
  792. BigInt BigInt::operator++ ( int )
  793. {
  794.     BigInt bi( *this );
  795.     ++*this;
  796.     return bi;
  797. }
  798.  
  799.  
  800. BigInt& BigInt::operator-- ()
  801. {
  802.     *this -= 1;
  803.     return *this;
  804. }
  805.  
  806. BigInt BigInt::operator-- ( int )
  807. {
  808.     BigInt bi( *this );
  809.     --*this;
  810.     return bi;
  811. }
  812.  
  813.  
  814. void BigInt::swap( BigInt& bi )
  815. {
  816.     x_.swap( bi.x_ );
  817.     bool temp( negative_ );
  818.     negative_ = bi.negative_;
  819.     bi.negative_ = temp;
  820. }
  821.  
  822.  
  823. // conversion functions
  824. std::string BigInt::decToHex( const std::string& s )
  825. {
  826.     /*
  827.     Algorithm:
  828.  
  829.     Consider the example of converting 370 decimal to hex.
  830.  
  831.         First divide 370 by 16
  832.  
  833.                  2                   23
  834.                 ____                ____
  835.             16 |370      -->    16 |370
  836.                 32                  32
  837.                 --                  ----
  838.                  5                   50
  839.                                      48
  840.                                      --
  841.                                       2
  842.  
  843.         The remainder of two is the least significant hex digit, i.e.,
  844.  
  845.                 370d = 23 * 16^1 + 2 * 16^0
  846.  
  847.         We now take the new decimal value 23 and divide by 16 and look at the
  848.         remainder to get the 16^1 hex digit.
  849.  
  850.                  1
  851.                 ___
  852.             16 |23
  853.                 16
  854.                 --
  855.                  7
  856.  
  857.         The remainer of 7 is the hex digit in the 16^1 column, i.e.,
  858.  
  859.                 370d = 1 * 16^2 + 7 * 16^1 + 2 * 16^0
  860.  
  861.  
  862.         Continuing, we take the new decimal value 1 and divide by 16 again.
  863.  
  864.                 0
  865.                 __
  866.             16 |1
  867.                 0
  868.                 -
  869.                 1
  870.  
  871.         The new decimal value of 0 tells us we are done and the remainder
  872.         is the final hex digit.
  873.  
  874.                 370d = 0 * 16^3 + 1 * 16^2 + 7 * 16^1 + 2 * 16^0
  875.  
  876.         Hence 370d = 172x
  877.  
  878.         We note that once the new decimal value is a single digit that digit will
  879.         be the last hex digit since dividing a single digit by sixteen will always
  880.         yield a quotient of zero and a remainder equal to that digit.
  881.  
  882.         Note also that the hex digits are generated in reverse order so after
  883.         storing them in a string as we go we will need to reverse the string.
  884.         The algorithm may also generate an extra trailing zero which will turn
  885.         into a leading zero when reversed so we will need to strip trailing
  886.         zeroes before reversing.
  887.  
  888.     */
  889.  
  890.     // Since 16^5 = 1048576 > 999999, five hex digits are always sufficient
  891.     // to hold six decimals so we divide the decimal string length by six,
  892.     // round up and multiply by five to reserve enough space in the new string.
  893.  
  894.     const char intToChar[ 16 ] = { '0', '1', '2', '3', '4', '5', '6', '7',
  895.         '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
  896.  
  897.     const signed char charToIntShift = -48;
  898.    
  899.     unsigned int base      = 16;
  900.     unsigned int dividend  = 0;
  901.     unsigned int remainder = 0;
  902.     unsigned int decDigit  = 0;
  903.  
  904.     std::string::size_type index = 0;
  905.  
  906.     std::string hexString;
  907.     hexString.reserve( ( ( s.size() / 6 ) + 1 ) * 5 );
  908.  
  909.     if ( s.size() == 0 )
  910.     {
  911.         // What???  How do you convert an empty string to hex?
  912.         return "";
  913.     }
  914.  
  915.     if ( s.size() == 1 )
  916.     {
  917.         hexString.push_back( s[ 0 ] );
  918.         return hexString;
  919.     }
  920.  
  921.     std::string decStr( s );
  922.     std::string newDecStr;
  923.  
  924.     while ( decStr.size() > 1 )
  925.     {
  926.         index = 0;
  927.         remainder = decStr[ 0 ] + charToIntShift;
  928.         newDecStr = "";
  929.         while ( ( index + 1 ) < decStr.size() )
  930.         {
  931.             dividend  = remainder * 10 + decStr[ index + 1 ] + charToIntShift;
  932.             decDigit  = dividend / base;
  933.             remainder = dividend % base;
  934.  
  935.             newDecStr.push_back( intToChar[ decDigit ] );
  936.  
  937.             ++index;
  938.         }
  939.         hexString.push_back( intToChar[ remainder ] );
  940.         decStr = newDecStr;
  941.     }
  942.     hexString.push_back( intToChar[ decDigit ] );
  943.  
  944.     // hexString needs to be reversed, but first we will strip trailing zeroes
  945.     // so they don't turn into leading zeroes.
  946.     if ( hexString.size() <= 1 )
  947.     {
  948.         // We are done since the string and its reversal are the same.
  949.         // ( We also don't want to strip a single zero if present. )
  950.         return hexString;
  951.     }
  952.  
  953.     std::string::iterator iter = hexString.end();
  954.     std::string::iterator startPlusOne = ( hexString.begin() )++;
  955.     --iter;
  956.     while ( iter != startPlusOne && *iter == '0' )
  957.     {
  958.         --iter;
  959.     }
  960.     ++iter;
  961.     // iter now points to the first trailing zero ( possibly end() )
  962.  
  963.     hexString.erase( iter, hexString.end() );
  964.  
  965.     hexString = std::string ( hexString.rbegin(), hexString.rend() );
  966.     return hexString;
  967. }
  968.  
  969.  
  970. std::string BigInt::hexToDec( const std::string& s )
  971. {
  972.     return binToDec( hexToBin( s ) );
  973. }
  974.  
  975.  
  976.  
  977. std::string BigInt::decToBin( const std::string& s )
  978. {
  979.     return hexToBin( decToHex( s ) );
  980. }
  981.  
  982.  
  983. std::string BigInt::binToDec( const std::string& s )
  984. {
  985.     if ( s.empty() )
  986.     {
  987.         return s;
  988.     }
  989.  
  990.     const char binToDecChar[ 10 ] = { '0', '1', '2', '3', '4', '5', '6', '7',
  991.         '8', '9' };
  992.  
  993.     std::string decStr;
  994.     BigInt ten( 10 );
  995.     BigInt dividend;
  996.     dividend.x_ = boost::dynamic_bitset<>( s );
  997.     dividend.stripLeadingZeroes( dividend.x_ );
  998.     BigInt quotient( 0 );
  999.     BigInt remainder( 0 );
  1000.  
  1001.     while ( dividend > 9 )
  1002.     {
  1003.         dividend.divisionAndRemainder( ten, quotient, remainder );
  1004.         decStr.push_back( binToDecChar[ remainder.x_.to_ulong() ] );
  1005.         dividend = quotient;
  1006.     }
  1007.     decStr.push_back( binToDecChar[ quotient.x_.to_ulong() ] );
  1008.     decStr = std::string( decStr.rbegin(), decStr.rend() );
  1009.     return decStr;
  1010. }
  1011.  
  1012.  
  1013.  
  1014. std::string BigInt::hexToBin( const std::string& s )
  1015. {
  1016.     std::string binString( s.size() * 4, '0' );
  1017.     std::string::size_type i = 0;
  1018.     while ( i  != s.size() )
  1019.     {
  1020.         switch ( s[ i ] )
  1021.         {
  1022.         case '0' :
  1023.             binString.replace( i * 4, 4, "0000" );
  1024.             break;
  1025.         case '1' :
  1026.             binString.replace( i * 4, 4, "0001" );
  1027.             break;
  1028.         case '2' :
  1029.             binString.replace( i * 4, 4, "0010" );
  1030.             break;
  1031.         case '3' :
  1032.             binString.replace( i * 4, 4, "0011" );
  1033.             break;
  1034.         case '4' :
  1035.             binString.replace( i * 4, 4, "0100" );
  1036.             break;
  1037.         case '5' :
  1038.             binString.replace( i * 4, 4, "0101" );
  1039.             break;
  1040.         case '6' :
  1041.             binString.replace( i * 4, 4, "0110" );
  1042.             break;
  1043.         case '7' :
  1044.             binString.replace( i * 4, 4, "0111" );
  1045.             break;
  1046.         case '8' :
  1047.             binString.replace( i * 4, 4, "1000" );
  1048.             break;
  1049.         case '9' :
  1050.             binString.replace( i * 4, 4, "1001" );
  1051.             break;
  1052.         case 'a' :
  1053.         case 'A' :
  1054.             binString.replace( i * 4, 4, "1010" );
  1055.             break;
  1056.         case 'b' :
  1057.         case 'B' :
  1058.             binString.replace( i * 4, 4, "1011" );
  1059.             break;
  1060.         case 'c' :
  1061.         case 'C' :
  1062.             binString.replace( i * 4, 4, "1100" );
  1063.             break;
  1064.         case 'd' :
  1065.         case 'D' :
  1066.             binString.replace( i * 4, 4, "1101" );
  1067.             break;
  1068.         case 'e' :
  1069.         case 'E' :
  1070.             binString.replace( i * 4, 4, "1110" );
  1071.             break;
  1072.         case 'f' :
  1073.         case 'F' :
  1074.             binString.replace( i * 4, 4, "1111" );
  1075.             break;
  1076.         default :
  1077.             ;
  1078.         }
  1079.         ++i;
  1080.     }
  1081.     // strip any leading zeroes but not a final zero.
  1082.     stripLeadingZeroesFromString( binString );
  1083.     return binString;
  1084. }
  1085.  
  1086.  
  1087. std::string BigInt::binToHex( const std::string& s )
  1088. {
  1089.     if ( s.empty() )
  1090.     {
  1091.         return s;
  1092.     }
  1093.  
  1094.     const char binToHexChar[ 16 ] = { '0', '1', '2', '3', '4', '5', '6', '7',
  1095.         '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
  1096.  
  1097.     boost::dynamic_bitset<> b( s );
  1098.  
  1099.     // we will pad b with leading zeroes to make sure size of b is a multiple of 4
  1100.     if ( b.size() % 4 != 0 )
  1101.     {
  1102.         b.resize( ( ( b.size() / 4 ) + 1 ) * 4 );
  1103.     }
  1104.     boost::dynamic_bitset<> currentFourBits( 4 );
  1105.  
  1106.     std::string hexString;
  1107.     hexString.reserve( b.size() / 4 );
  1108.    
  1109.     for ( boost::dynamic_bitset<>::size_type index = b.size(); index > 0; index -= 4 )
  1110.     {
  1111.         currentFourBits[ 0 ] = b[ index - 4 ];
  1112.         currentFourBits[ 1 ] = b[ index - 3 ];
  1113.         currentFourBits[ 2 ] = b[ index - 2 ];
  1114.         currentFourBits[ 3 ] = b[ index - 1 ];
  1115.         hexString.push_back( binToHexChar[ currentFourBits.to_ulong() ] );
  1116.     }
  1117.  
  1118.     // strip any leading zeroes but not a final zero.
  1119.     stripLeadingZeroesFromString( hexString );
  1120.     return hexString;
  1121. }
  1122.  
  1123.  
  1124.  
  1125.  
  1126. void BigInt::stripLeadingZeroes( boost::dynamic_bitset<>& db )
  1127. {
  1128.     // We will start at the high bit and reduce the new size by one for
  1129.     // each zero encountered unitl we find a one or reach the low bit,
  1130.     // then resize.  Note that we are careful not to resize to an
  1131.     // empty bitset if all the bits are zero.  The minimum size for
  1132.     // a non-empty bitset after processing is one.
  1133.  
  1134.     boost::dynamic_bitset<>::size_type s = db.size();
  1135.  
  1136.     // convert size which is one based to serve as an index which is zero based
  1137.     s -= 1;
  1138.     // Short circuit evaluation dependency
  1139.     while ( s != 0 && db[ s ] == 0 )
  1140.     {
  1141.         --s;
  1142.     }
  1143.  
  1144.     if ( s + 1 != db.size() )
  1145.     {
  1146.         db.resize( s + 1 );
  1147.     }
  1148. }
  1149.  
  1150.  
  1151.  
  1152. void BigInt::stripLeadingZeroesFromString( std::string& s )
  1153. {
  1154.     // This function strips any leading zeroes but not a final zero.
  1155.     std::string::size_type pos = s.find_first_not_of( '0' );
  1156.     s.erase( 0, ( pos != std::string::npos ? pos : s.size() - 1 ) );
  1157.     return;
  1158. }
  1159.  
  1160.  
  1161. bool BigInt::isValidBigIntString( const std::string& s )
  1162. {
  1163.     using std::string;
  1164.     switch ( s.size() )
  1165.     {
  1166.     case 0 :
  1167.         return false;
  1168.         break;
  1169.  
  1170.     case 1 :
  1171.         // single value must be 0-9
  1172.         return ( string::npos == s.find_first_not_of( "0123456789" ) ? true : false );
  1173.         break;
  1174.  
  1175.     case 2 :
  1176.         switch ( s[ 0 ] )
  1177.         {
  1178.         case 'b' :
  1179.         case 'B' :
  1180.             return ( string::npos == s.substr( 1 ).find_first_not_of( "01" ) ? true : false );
  1181.             break;
  1182.  
  1183.         case 'x' :
  1184.         case 'X' :
  1185.             return ( string::npos == s.substr( 1 ).find_first_not_of( "0123456789ABCDEFabcdef" ) ? true : false );
  1186.             break;
  1187.  
  1188.         case '+' :
  1189.         case '-' :
  1190.         case 'd' :
  1191.         case 'D' :
  1192.             return ( string::npos == s.substr( 1 ).find_first_not_of( "0123456789" ) ? true : false );
  1193.             break;
  1194.  
  1195.         default :
  1196.             // must be base ten with no sign
  1197.             return ( string::npos == s.find_first_not_of( "0123456789" ) ? true : false );
  1198.             break;
  1199.         }
  1200.  
  1201.     default :
  1202.         break;
  1203.     }
  1204.  
  1205.     // s.size() >= 3;
  1206.  
  1207.     switch ( s[ 0 ] )
  1208.     {
  1209.     case 'b' :
  1210.     case 'B' :
  1211.         if ( s[ 1 ] == '+' || s[ 1 ] == '-' )
  1212.         {
  1213.             return ( string::npos == s.substr( 2 ).find_first_not_of( "01" ) ? true : false );
  1214.         }
  1215.         else
  1216.         {
  1217.             return ( string::npos == s.substr( 1 ).find_first_not_of( "01" ) ? true : false );
  1218.         }
  1219.         break;
  1220.  
  1221.     case 'x' :
  1222.     case 'X' :
  1223.         if ( s[ 1 ] == '+' || s[ 1 ] == '-' )
  1224.         {
  1225.             return ( string::npos == s.substr( 2 ).find_first_not_of( "0123456789ABCDEFabcdef" ) ? true : false );
  1226.         }
  1227.         else
  1228.         {
  1229.             return ( string::npos == s.substr( 1 ).find_first_not_of( "0123456789ABCDEFabcdef" ) ? true : false );
  1230.         }
  1231.         break;
  1232.  
  1233.     case 'd' :
  1234.     case 'D' :
  1235.         if ( s[ 1 ] == '+' || s[ 1 ] == '-' )
  1236.         {
  1237.             return ( string::npos == s.substr( 2 ).find_first_not_of( "0123456789" ) ? true : false );
  1238.         }
  1239.         else
  1240.         {
  1241.             return ( string::npos == s.substr( 1 ).find_first_not_of( "0123456789" ) ? true : false );
  1242.         }
  1243.         break;
  1244.  
  1245.     case '+' :
  1246.     case '-' :
  1247.         return ( string::npos == s.substr( 1 ).find_first_not_of( "0123456789" ) ? true : false );
  1248.         break;
  1249.  
  1250.     default :
  1251.         // must be base ten without a sign
  1252.         return ( string::npos == s.find_first_not_of( "0123456789" ) ? true : false );
  1253.         break;
  1254.     }
  1255. }
  1256.  
  1257.  
  1258.  
  1259. void BigInt::compoundAddAssignIgnoreSign( const BigInt& rhs, boost::dynamic_bitset<>::size_type startIndex )
  1260. {
  1261.     /*
  1262.     This function adds with compound assignment rhs to *this, beginning at
  1263.     startIndex for *this, using an ordinary addition algorithm, as though
  1264.     they are the same sign even if they are not. That is, sign is ignored.
  1265.     (*this may have been switched to 2's complement before calling this function)
  1266.  
  1267.     startIndex is a default parameter with default value zero.
  1268.  
  1269.     Example:
  1270.        
  1271.         *this =    101100111      startIndex = 0
  1272.          rhs  =           11
  1273.                    ----------
  1274.                    101101010
  1275.  
  1276.  
  1277.                    101100111      startIndex = 3
  1278.                        11
  1279.                    ----------
  1280.                    101111111
  1281.  
  1282.  
  1283.     We will add rhs to this, changing *this as we go.  It is the responsibility of
  1284.     the calling routine to make sure that *this is large enought to hold the result.
  1285.    
  1286.  
  1287.     Algorithm:
  1288.         Note:  We show result separately as an aid to understanding, but *this
  1289.                will actually be overwritten with result as we go.
  1290.  
  1291.                  --- --- --- ---
  1292.         carry   |   | 1 | 1 | 0 |      ( *this && rhs ) || ( *this && carry ) || { rhs && carry )
  1293.                 |---|---|---|---|
  1294.         *this   | 0 | 1 | 0 | 1 |
  1295.                 |---|---|---|---|
  1296.         rhs     |   |   | 1 | 1 |
  1297.                  --- --- --- ---
  1298.  
  1299.                  --- --- --- ---
  1300.                 | 1 | 0 | 0  | 0 |       ( *this ^ rhs ) ^ carry
  1301.         result  |---|---|---|---|
  1302.  
  1303.  
  1304.         We will add the two bits of *this and rhs and then add the result to the
  1305.         carry bit to get result.  Adding two bits can be done by XORing the bits'
  1306.         The carry bit is set if any two of *this, rhs or carry are set.
  1307.  
  1308.         *this  rhs  Addition  XOR
  1309.           0     0     0        0
  1310.           0     1     1        1
  1311.           1     0     1        1
  1312.           1     1     0        0
  1313.     */
  1314.  
  1315.     unsigned long minSize = rhs.x_.size();
  1316.     bool carryBit         = false;
  1317.     bool newCarryBit      = false;
  1318.  
  1319.     boost::dynamic_bitset<>::size_type thisBitIndex = startIndex;
  1320.     boost::dynamic_bitset<>::size_type rhsBitIndex  = 0;
  1321.     while ( rhsBitIndex < minSize )
  1322.     {
  1323.         // if any two of carry *this or rhs are one we will have a carry
  1324.         newCarryBit        = x_[ thisBitIndex ] && rhs.x_[ rhsBitIndex ] || x_[ thisBitIndex ] && carryBit || rhs.x_[ rhsBitIndex ] && carryBit;
  1325.         x_[ thisBitIndex ] = ( x_[ thisBitIndex ] ^ rhs.x_[ rhsBitIndex ] ) ^ carryBit;
  1326.         carryBit           = newCarryBit;
  1327.         ++rhsBitIndex;
  1328.         ++thisBitIndex;
  1329.     }
  1330.  
  1331.     // We have finished with rhs so we only need to continue if the carryBit is one.
  1332.     while ( thisBitIndex < x_.size() && carryBit )
  1333.     {
  1334.         newCarryBit = x_[ thisBitIndex ] & carryBit;
  1335.         x_[ thisBitIndex ] = x_[ thisBitIndex ] ^ carryBit;
  1336.         carryBit = newCarryBit;
  1337.         ++thisBitIndex;
  1338.     }
  1339. }
  1340.  
  1341.  
  1342.  
  1343. // *****************  Non-member functions  ****************************
  1344.  
  1345.  
  1346. // comparison operators
  1347. bool operator< ( const BigInt& lhs, const BigInt& rhs )
  1348. {
  1349.     // Note that <, <=, >, >= cannot be used on dynamic bitsets unless the
  1350.     // sizes are equal
  1351.     if ( lhs.negative_ && ! rhs.negative_ )
  1352.     {
  1353.         return true;
  1354.     }
  1355.     if ( ! lhs.negative_ && rhs.negative_ )
  1356.     {
  1357.         return false;
  1358.     }
  1359.     if ( ! lhs.negative_ && ! rhs.negative_ )
  1360.     {
  1361.         if ( lhs.x_.size() < rhs.x_.size() )
  1362.         {
  1363.             return true;
  1364.         }
  1365.         else
  1366.         {
  1367.             if ( lhs.x_.size() == rhs.x_.size() )
  1368.             {
  1369.                 return lhs.x_ < rhs.x_;
  1370.             }
  1371.             else
  1372.             {
  1373.                 return false;
  1374.             }
  1375.         }
  1376.     }
  1377.     if ( lhs.negative_ && rhs.negative_ )
  1378.     {
  1379.         if ( lhs.x_.size() < rhs.x_.size() )
  1380.         {
  1381.             return false;
  1382.         }
  1383.         else
  1384.         {
  1385.             if ( lhs.x_.size() == rhs.x_.size() )
  1386.             {
  1387.                 return lhs.x_ > rhs.x_;
  1388.             }
  1389.             else
  1390.             {
  1391.                 return true;
  1392.             }
  1393.         }
  1394.     }
  1395.  
  1396.     // to make the compiler happy about warning that not all control paths
  1397.     // return a value
  1398.     return true;
  1399. }
  1400.  
  1401.  
  1402. bool operator<= ( const BigInt& lhs, const BigInt& rhs )
  1403. {
  1404.     return ( lhs == rhs || lhs < rhs );
  1405. }
  1406.  
  1407.  
  1408. bool operator== ( const BigInt& lhs, const BigInt& rhs )
  1409. {
  1410.     return ( lhs.x_ == rhs.x_ && lhs.negative_ == rhs.negative_ );
  1411. }
  1412.  
  1413.  
  1414. bool operator!= ( const BigInt& lhs, const BigInt& rhs )
  1415. {
  1416.     return !( lhs == rhs );
  1417. }
  1418.  
  1419.  
  1420. bool operator>= ( const BigInt& lhs, const BigInt& rhs )
  1421. {
  1422.     return !( lhs < rhs );
  1423. }
  1424.  
  1425.  
  1426. bool operator> ( const BigInt& lhs, const BigInt& rhs )
  1427. {
  1428.     return !( lhs <= rhs );
  1429. }
  1430.  
  1431.  
  1432.  
  1433. // binary arithmetic operators
  1434. BigInt operator+ ( const BigInt& lhs, const BigInt& rhs )
  1435. {
  1436.     return BigInt( lhs ) += rhs;
  1437. }
  1438.  
  1439.  
  1440. BigInt operator- ( const BigInt& lhs, const BigInt& rhs )
  1441. {
  1442.     return BigInt( lhs ) -= rhs;
  1443. }
  1444.  
  1445.  
  1446. BigInt operator* ( const BigInt& lhs, const BigInt& rhs )
  1447. {
  1448.     return BigInt( lhs ) *= rhs;
  1449. }
  1450.  
  1451.  
  1452. BigInt operator/ ( const BigInt& lhs, const BigInt& rhs )
  1453. {
  1454.     return BigInt( lhs ) /= rhs;
  1455. }
  1456.  
  1457.  
  1458. BigInt operator% ( const BigInt& lhs, const BigInt& rhs )
  1459. {
  1460.     return BigInt( lhs ) %= rhs;
  1461. }
  1462.  
  1463.  
  1464. std::ostream& operator<< ( std::ostream& os, const BigInt& bi )
  1465. {
  1466.     const long int idx( BigInt::getOutputWordIndex() );
  1467.     std::string sign = ( bi.negative_ ? "-" : "" );
  1468.     std::ostringstream oss;
  1469.     oss << bi.x_;
  1470.     long int base      = os.iword( idx ) & 7L;
  1471.     long int alphaCase = os.iword( idx ) & 8L;
  1472.     bool useUpperCase  = ( alphaCase == 8 ? true : false );
  1473.     long int noShowBase  = os.iword( idx ) & 16L;
  1474.     bool useShowBase   = ( noShowBase == 16 ? false : true );
  1475.     switch ( base )
  1476.     {
  1477.     case BigInt::bin :
  1478.         if ( useUpperCase )
  1479.         {
  1480.             os << ( useShowBase ? "B" : "" );
  1481.         }
  1482.         else
  1483.         {
  1484.             os << ( useShowBase ? "b" : "" );
  1485.         }
  1486.         os << sign << oss.str();
  1487.         break;
  1488.  
  1489.     case BigInt::hex :
  1490.         {
  1491.         std::string s( BigInt::binToHex( oss.str() ) );
  1492.         if ( useUpperCase )
  1493.         {
  1494.             // Convert to uppercase.
  1495.             transform( s.begin(), s.end(), s.begin(), toupper );
  1496.             os << ( useShowBase ? "X" : "" ) << sign << s;
  1497.         }
  1498.         else
  1499.         {
  1500.             os << ( useShowBase ? "x" : "" ) << sign << s;
  1501.         }
  1502.         }
  1503.         break;
  1504.  
  1505.     case BigInt::dec :
  1506.     case BigInt::def :
  1507.     default :
  1508.         os << sign << BigInt::binToDec( oss.str() );
  1509.         break;
  1510.     }
  1511.     return os;
  1512. }
  1513.  
  1514.  
  1515. std::istream& operator>> ( std::istream& is, BigInt& bi )
  1516. {
  1517.     /*
  1518.     The input operator skips whitespace and then reads all characters
  1519.     up to the next whitespace ( a space, tab or newline ).  If the string
  1520.     read in is a valid BigInt string with a base identifier as the first
  1521.     character then all flags are ignored and a BigInt is constructed
  1522.     based on that string.  Only if there is no base identifier are the flags
  1523.     consulted as to the type of number, bin, hex or dec with dec being the
  1524.     default.  The only flags implemented for the input operator are:
  1525.  
  1526.         bin
  1527.         nobin
  1528.         hex
  1529.         nohex
  1530.         dec
  1531.         nodec
  1532.         def
  1533.  
  1534.     The flags uppercase, lowercase, showbase, noshowbase have no meaning and cannot
  1535.     be used.
  1536.    
  1537.     Examples:
  1538.  
  1539.         def or dec flag set:
  1540.  
  1541.             "b1010"    binary 1010 = decimal 10
  1542.             "x1010"    hex 1010    = decimal 4112
  1543.             "1010"     dec 1010    = decimal 1010
  1544.  
  1545.         bin flag set
  1546.  
  1547.             "1010"     binary 1010 = decimal 10
  1548.  
  1549.         hex flag set:
  1550.  
  1551.             "1010"     hex 1010 = decimal 4112
  1552.  
  1553.     */
  1554.     BigInt tempBi;
  1555.  
  1556.     std::string s;
  1557.     is >> s;
  1558.     if ( ! BigInt::isValidBigIntString( s ) )
  1559.     {
  1560.         is.setstate( std::ios_base::failbit );
  1561.         return is;
  1562.     }
  1563.     // if we reach this point s has at least one digit
  1564.     std::string::size_type digitStartPos = 0;
  1565.  
  1566.     switch ( s[ 0 ] )
  1567.     {
  1568.     case 'b' :
  1569.     case 'B' :
  1570.     case 'x' :
  1571.     case 'X' :
  1572.     case 'd' :
  1573.     case 'D' :
  1574.         tempBi =  s;
  1575.         bi.swap( tempBi );
  1576.         return is;
  1577.         break;
  1578.  
  1579.     case '+' :
  1580.     case '-' :
  1581.         digitStartPos = 1;
  1582.         break;
  1583.  
  1584.     default :
  1585.         digitStartPos = 0;
  1586.         break;
  1587.     }
  1588.  
  1589.     // no base identifier so consult the base flags
  1590.     const long int idx( BigInt::getInputWordIndex() );
  1591.     long int base = is.iword( idx ) & 7L;
  1592.  
  1593.     switch ( base )
  1594.     {
  1595.     case BigInt::bin :
  1596.         if ( std::string::npos != s.substr( digitStartPos ).find_first_not_of( "01" ) )
  1597.         {
  1598.             is.setstate( std::ios_base::failbit );
  1599.             return is;
  1600.         }
  1601.         tempBi = "b" + s;
  1602.         break;
  1603.     case BigInt::hex :
  1604.         if ( std::string::npos != s.substr( digitStartPos ).find_first_not_of( "0123456789ABCDEFabcdef" ) )
  1605.         {
  1606.             is.setstate( std::ios_base::failbit );
  1607.             return is;
  1608.         }
  1609.         tempBi = "x" + s;
  1610.         break;
  1611.     case BigInt::dec :
  1612.     case BigInt::def :
  1613.         if ( std::string::npos != s.substr( digitStartPos ).find_first_not_of( "0123456789" ) )
  1614.         {
  1615.             is.setstate( std::ios_base::failbit );
  1616.             return is;
  1617.         }
  1618.         tempBi = s;
  1619.         break;
  1620.     default :
  1621.         break;
  1622.     }
  1623.  
  1624.     bi.swap( tempBi );
  1625.     return is;
  1626. }
  1627.  
  1628.  
  1629.  
  1630. std::ostream& bigintbin( std::ostream& os )
  1631. {
  1632.     const long int idx( BigInt::getOutputWordIndex() );
  1633.     os.iword( idx ) = ( os.iword( idx ) & BigInt::nodec & BigInt::nohex ) | BigInt::bin;
  1634.     return os;
  1635. }
  1636.  
  1637.  
  1638. std::ostream& bigintdec( std::ostream& os )
  1639. {
  1640.     const long int idx( BigInt::getOutputWordIndex() );
  1641.     os.iword( idx ) = ( os.iword( idx ) & BigInt::nobin & BigInt::nohex ) | BigInt::dec;
  1642.     return os;
  1643. }
  1644.  
  1645.  
  1646. std::ostream& biginthex( std::ostream& os )
  1647. {
  1648.     const long int idx( BigInt::getOutputWordIndex() );
  1649.     os.iword( idx ) = ( os.iword( idx ) & BigInt::nodec & BigInt::nobin ) | BigInt::hex;
  1650.     return os;
  1651. }
  1652.  
  1653.  
  1654. std::ostream& bigintupper( std::ostream& os )
  1655. {
  1656.     const long int idx( BigInt::getOutputWordIndex() );
  1657.     os.iword( idx ) = ( os.iword( idx ) | BigInt::uppercase );
  1658.     return os;
  1659. }
  1660.  
  1661.  
  1662. std::ostream& bigintlower( std::ostream& os )
  1663. {
  1664.     const long int idx( BigInt::getOutputWordIndex() );
  1665.     os.iword( idx ) = ( os.iword( idx ) & BigInt::lowercase );
  1666.     return os;
  1667. }
  1668.  
  1669.  
  1670. std::ostream& bigintshowbase( std::ostream& os )
  1671. {
  1672.     const long int idx( BigInt::getOutputWordIndex() );
  1673.     os.iword( idx ) = ( os.iword( idx ) & BigInt::showbase );
  1674.     return os;
  1675. }
  1676.  
  1677.  
  1678. std::ostream& bigintnoshowbase( std::ostream& os )
  1679. {
  1680.     const long int idx( BigInt::getOutputWordIndex() );
  1681.     os.iword( idx ) = ( os.iword( idx ) | BigInt::noshowbase );
  1682.     return os;
  1683. }
  1684.  
  1685.  
  1686.  
  1687. std::ostream& bigintdefault( std::ostream& os )
  1688. {
  1689.     const long int idx( BigInt::getOutputWordIndex() );
  1690.     os.iword( idx ) = ( os.iword( idx ) & BigInt::def ) | BigInt::dec;
  1691.     return os;
  1692. }
  1693.  
  1694.  
  1695. // input stream manipulators
  1696. std::istream& bigintbin( std::istream& is )
  1697. {
  1698.     const long int idx( BigInt::getInputWordIndex() );
  1699.     is.iword( idx ) = ( is.iword( idx ) & BigInt::nodec & BigInt::nohex ) | BigInt::bin;
  1700.     return is;
  1701. }
  1702.  
  1703.  
  1704. std::istream& bigintdec( std::istream& is )
  1705. {
  1706.     const long int idx( BigInt::getInputWordIndex() );
  1707.     is.iword( idx ) = ( is.iword( idx ) & BigInt::nobin & BigInt::nohex ) | BigInt::dec;
  1708.     return is;
  1709. }
  1710.  
  1711.  
  1712. std::istream& biginthex( std::istream& is )
  1713. {
  1714.     const long int idx( BigInt::getInputWordIndex() );
  1715.     is.iword( idx ) = ( is.iword( idx ) & BigInt::nodec & BigInt::nobin ) | BigInt::hex;
  1716.     return is;
  1717. }
  1718.  
  1719.  
  1720. std::istream& bigintdefault( std::istream& is )
  1721. {
  1722.     const long int idx( BigInt::getInputWordIndex() );
  1723.     is.iword( idx ) = ( is.iword( idx ) & BigInt::def ) | BigInt::dec;
  1724.     return is;
  1725. }
  1726.  
  1727.  
  1728.  
  1729. // BigInt Math functions
  1730. BigInt factorial( const BigInt& n )
  1731. {
  1732.     BigInt result = 1;
  1733.     BigInt i = 2;
  1734.     while ( i <= n )
  1735.     {
  1736.         result *= i;
  1737.         ++i;
  1738.     }
  1739.     return result;
  1740. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement