1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | #ifndef STLPLUS_INF #define STLPLUS_INF //////////////////////////////////////////////////////////////////////////////// // Author: Andy Rushton // Copyright: (c) Southampton University 1999-2004 // (c) Andy Rushton 2004 onwards // License: BSD License, see ../docs/license.html // An infinite-precision integer class. This allows calculations on large // integers to be performed without overflow. // this class can throw the following exceptions: // std::out_of_range // std::overflow_error // std::invalid_argument // stlplus::divide_by_zero // why doesn't std have this? // all of these are derivations of the baseclass: // std::logic_error // So you can catch all of them by catching the baseclass // Warning: inf was never intended to be fast, it is just for programs which // need a bit of infinite-precision integer arithmetic. For high-performance // processing, use the Gnu Multi-Precision (GMP) library. The inf type is just // easier to integrate and is already ported to all platforms and compilers // that STLplus is ported to. //////////////////////////////////////////////////////////////////////////////// #include "portability_fixes.hpp" #include "portability_exceptions.hpp" #include <string> #include <iostream> //////////////////////////////////////////////////////////////////////////////// namespace stlplus { //////////////////////////////////////////////////////////////////////////////// class inf { public : ////////////////////////////////////////////////////////////////////////////// // constructors and assignments initialise the inf // the void constructor initialises to zero, the others initialise to the // value of the C integer type or the text value contained in the string inf( void ); explicit inf( short ); explicit inf( unsigned short ); explicit inf( int ); explicit inf( unsigned ); explicit inf( long ); explicit inf( unsigned long ); // exceptions: std::invalid_argument explicit inf( const std:: string &) ; inf( const inf&); ~inf( void ); // assignments with equivalent behaviour to the constructors inf& operator = ( short ); inf& operator = ( unsigned short ); inf& operator = ( int ); inf& operator = ( unsigned ); inf& operator = ( long ); inf& operator = ( unsigned long ); // exceptions: std::invalid_argument inf& operator = ( const std:: string &) ; inf& operator = ( const inf&); ////////////////////////////////////////////////////////////////////////////// // conversions back to the C types // truncate: controls the behaviour when the value is too long for the result // true: truncate the value // false: throw an exception // exceptions: std::overflow_error short to_short( bool truncate = true ) const ; // exceptions: std::overflow_error unsigned short to_unsigned_short( bool truncate = true ) const ; // exceptions: std::overflow_error int to_int( bool truncate = true ) const ; // exceptions: std::overflow_error unsigned to_unsigned( bool truncate = true ) const ; // exceptions: std::overflow_error long to_long( bool truncate = true ) const ; // exceptions: std::overflow_error unsigned long to_unsigned_long( bool truncate = true ) const ; ////////////////////////////////////////////////////////////////////////////// // bitwise manipulation void resize( unsigned bits); void reduce( void ); // the number of significant bits in the value unsigned bits ( void ) const ; unsigned size ( void ) const ; // the number of bits that can be accessed by the bit() method (=bits() rounded up to the next byte) unsigned indexable_bits( void ) const ; // exceptions: std::out_of_range bool bit ( unsigned index) const ; // exceptions: std::out_of_range bool operator [] ( unsigned index) const ; // exceptions: std::out_of_range void set ( unsigned index) ; // exceptions: std::out_of_range void clear ( unsigned index) ; // exceptions: std::out_of_range void preset ( unsigned index, bool value) ; // exceptions: std::out_of_range inf slice( unsigned low, unsigned high) const ; ////////////////////////////////////////////////////////////////////////////// // tests for common values or ranges bool negative ( void ) const ; bool natural ( void ) const ; bool positive ( void ) const ; bool zero ( void ) const ; bool non_zero ( void ) const ; // tests used in if(i) and if(!i) // operator bool (void) const; bool operator ! ( void ) const ; ////////////////////////////////////////////////////////////////////////////// // comparisons bool operator == ( const inf&) const ; bool operator != ( const inf&) const ; bool operator < ( const inf&) const ; bool operator <= ( const inf&) const ; bool operator > ( const inf&) const ; bool operator >= ( const inf&) const ; ////////////////////////////////////////////////////////////////////////////// // bitwise logic operations inf& invert ( void ); inf operator ~ ( void ) const ; inf& operator &= ( const inf&); inf operator & ( const inf&) const ; inf& operator |= ( const inf&); inf operator | ( const inf&) const ; inf& operator ^= ( const inf&); inf operator ^ ( const inf&) const ; inf& operator <<= ( unsigned shift); inf operator << ( unsigned shift) const ; inf& operator >>= ( unsigned shift); inf operator >> ( unsigned shift) const ; ////////////////////////////////////////////////////////////////////////////// // arithmetic operations inf& negate ( void ); inf operator - ( void ) const ; inf& abs ( void ); friend inf abs ( const inf&); inf& operator += ( const inf&); inf operator + ( const inf&) const ; inf& operator -= ( const inf&); inf operator - ( const inf&) const ; inf& operator *= ( const inf&); inf operator * ( const inf&) const ; // exceptions: divide_by_zero inf& operator /= ( const inf&) ; // exceptions: divide_by_zero inf operator / ( const inf&) const ; // exceptions: divide_by_zero inf& operator %= ( const inf&) ; // exceptions: divide_by_zero inf operator % ( const inf&) const ; // combined division operator - returns the result pair(quotient,remainder) in one go // exceptions: divide_by_zero std:: pair <inf,inf> divide( const inf&) const ; ////////////////////////////////////////////////////////////////////////////// // pre- and post- increment and decrement inf& operator ++ ( void ); inf operator ++ ( int ); inf& operator -- ( void ); inf operator -- ( int ); ////////////////////////////////////////////////////////////////////////////// // string representation and I/O std:: string image_debug( void ) const ; // conversion to a string representation // radix must be 10, 2, 8 or 16 // exceptions: std::invalid_argument std:: string to_string( unsigned radix = 10) const ; // conversion from a string // radix == 0 - radix is deduced from the input - assumed 10 unless number is prefixed by 0b, 0 or 0x // however, you can specify the radix to be 10, 2, 8 or 16 to force that interpretation // exceptions: std::invalid_argument inf& from_string( const std:: string &, unsigned radix = 0); ////////////////////////////////////////////////////////////////////////////// private : std:: string m_data; public : const std:: string & get_bytes( void ) const ; void set_bytes( const std:: string &); }; //////////////////////////////////////////////////////////////////////////////// // redefine friends for gcc v4.1 inf abs ( const inf&); //////////////////////////////////////////////////////////////////////////////// std::ostream& operator << (std::ostream&, const inf&); std::istream& operator >> (std::istream&, inf&); //////////////////////////////////////////////////////////////////////////////// } // end namespace stlplus #endif |