diff --git a/ttmath/ttmathbig.h b/ttmath/ttmathbig.h index 26f741b..d65a1eb 100644 --- a/ttmath/ttmathbig.h +++ b/ttmath/ttmathbig.h @@ -1787,25 +1787,19 @@ public: #endif - +private: /*! - a method for converting from 'Int' to this class + an auxiliary method for converting from UInt and Int + + we assume that there'll never be a carry here + (we have an exponent and the value in Big can be bigger than + that one from the UInt) */ template - void FromInt(Int value) + void FromUIntOrInt(const UInt & value, sint compensation) { - info = 0; - bool is_sign = false; - - if( value.IsSign() ) - { - value.ChangeSign(); - is_sign = true; - } - uint minimum_size = (int_size < man)? int_size : man; - sint compensation = (sint)value.CompensationToLeft(); exponent = (sint(int_size)-sint(man)) * sint(TTMATH_BITS_PER_UINT) - compensation; // copying the highest words @@ -1816,10 +1810,42 @@ public: // setting the rest of mantissa.table into zero (if some has left) for( ; i<=man ; ++i) mantissa.table[man-i] = 0; + } - if( is_sign ) + +public: + + + /*! + a method for converting from 'UInt' to this class + */ + template + void FromUInt(UInt value) + { + info = 0; + sint compensation = (sint)value.CompensationToLeft(); + + return FromUIntOrInt(value, compensation); + } + + + /*! + a method for converting from 'Int' to this class + */ + template + void FromInt(Int value) + { + info = 0; + + if( value.IsSign() ) + { + value.ChangeSign(); SetSign(); + } + sint compensation = (sint)value.CompensationToLeft(); + + return FromUIntOrInt(value, compensation); } @@ -1845,6 +1871,28 @@ public: } + /*! + an operator= for converting from 'UInt' to this class + */ + template + Big & operator=(const UInt & value) + { + FromUInt(value); + + return *this; + } + + + /*! + a constructor for converting from 'UInt' to this class + */ + template + Big(const UInt & value) + { + FromUInt(value); + } + + /*! a default constructor @@ -1866,7 +1914,6 @@ public: /*! the default assignment operator */ - Big & operator=(const Big & value) { info = value.info; diff --git a/ttmath/ttmathint.h b/ttmath/ttmathint.h index 0cfd275..3221b99 100644 --- a/ttmath/ttmathint.h +++ b/ttmath/ttmathint.h @@ -475,17 +475,14 @@ public: * convertion methods * */ +private: + /*! - this method convert an UInt type to this class - - this operation has mainly sense if the value from p - can be held in this type - - it returns a carry if the value 'p' is too big + an auxiliary method for converting both from UInt and Int */ template - uint FromInt(const Int & p) + uint FromUIntOrInt(const UInt & p, bool UInt_type) { uint min_size = (value_size < argument_size)? value_size : argument_size; uint i; @@ -496,15 +493,25 @@ public: if( value_size > argument_size ) { - // 'this' is longer than 'p' - uint fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)? TTMATH_UINT_MAX_VALUE : 0; + uint fill; + if( UInt_type ) + fill = 0; + else + fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)? + TTMATH_UINT_MAX_VALUE : 0; + + // 'this' is longer than 'p' for( ; i::table[i] = fill; } else { - uint test = (UInt::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)? TTMATH_UINT_MAX_VALUE : 0; + uint test = (UInt::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)? + TTMATH_UINT_MAX_VALUE : 0; + + if( UInt_type && test!=0 ) + return 1; for( ; i type into this class + + this operation has mainly sense if the value from p + can be held in this type + + it returns a carry if the value 'p' is too big + */ + template + uint FromInt(const Int & p) + { + return FromUIntOrInt(p, false); + } + /*! this method converts the sint type into this class */ - void FromInt(sint value) + uint FromInt(sint value) { uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0; @@ -526,16 +549,46 @@ public: UInt::table[i] = fill; UInt::table[0] = uint(value); + + // there'll never be a carry here + return 0; } /*! - this operator converts an UInt type to this class - - it doesn't return a carry + this method converts UInt into this class */ template - Int & operator=(const Int & p) + uint FromUInt(const UInt & p) + { + return FromUIntOrInt(p, true); + } + + + /*! + this method converts the uint type into this class + */ + uint FromUInt(uint value) + { + for(uint i=1 ; i::table[i] = 0; + + UInt::table[0] = value; + + // there can be a carry here when the size of this value is equal one word + // and the 'value' has the highest bit set + if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 ) + return 1; + + return 0; + } + + // converting from Int + + /*! + the default assignment operator + */ + Int & operator=(const Int & p) { FromInt(p); @@ -544,9 +597,12 @@ public: /*! - the default assignment operator + this operator converts an Int type to this class + + it doesn't return a carry */ - Int & operator=(const Int & p) + template + Int & operator=(const Int & p) { FromInt(p); @@ -575,11 +631,47 @@ public: /*! - this method converts the uint type to this class + the copy constructor + */ + Int(const Int & u) + { + FromInt(u); + } + + + /*! + a constructor for copying from another types + */ + template + Int(const Int & u) + { + // look that 'size' we still set as 'value_size' and not as u.value_size + FromInt(u); + } + + + // converting from UInt + + /*! + this operator converts an UInt type to this class + + it doesn't return a carry + */ + template + Int & operator=(const UInt & p) + { + FromUInt(p); + + return *this; + } + + + /*! + this method converts the Uint type to this class */ Int & operator=(uint i) { - UInt::FromUInt(i); + FromUInt(i); return *this; } @@ -590,10 +682,23 @@ public: */ Int(uint i) { - UInt::FromUInt(i); + FromUInt(i); } + /*! + a constructor for copying from another types + */ + template + Int(const UInt & u) + { + // look that 'size' we still set as 'value_size' and not as u.value_size + FromUInt(u); + } + + // + + #ifdef TTMATH_PLATFORM64 /*! @@ -630,7 +735,7 @@ public: */ Int & operator=(unsigned int i) { - UInt::FromUInt(uint(i)); + FromUInt(uint(i)); return *this; } @@ -644,7 +749,7 @@ public: */ Int(unsigned int i) { - UInt::FromUInt(uint(i)); + FromUInt(uint(i)); } #endif @@ -678,18 +783,6 @@ public: } - /*! - the copy constructor - */ - template - Int(const Int & u) : UInt::size(value_size) - { - // look that 'size' we still set as 'value_size' and not as u.value_size - - operator=(u); - } - - /*! the destructor */