diff --git a/ttmath/ttmathbig.h b/ttmath/ttmathbig.h index 0ca6b22..809f6cf 100644 --- a/ttmath/ttmathbig.h +++ b/ttmath/ttmathbig.h @@ -2404,12 +2404,12 @@ public: /*! a method for converting 'uint' to this class */ - void FromUInt(uint value) + uint FromUInt(uint value) { if( value == 0 ) { SetZero(); - return; + return 0; } info = 0; @@ -2422,6 +2422,17 @@ public: // there shouldn't be a carry because 'value' has the 'uint' type Standardizing(); + + return 0; + } + + + /*! + a method for converting 'uint' to this class + */ + uint FromInt(uint value) + { + return FromUInt(value); } @@ -2904,19 +2915,19 @@ public: /*! a method for converting 'ulint' (64bit unsigned integer) to this class */ - void FromUInt(ulint value) + uint FromUInt(ulint value) { if( value == 0 ) { SetZero(); - return; + return 0; } info = 0; if( man == 1 ) { - sint bit = mantissa.FindLeadingBitInWord(uint(value >> 32)); + sint bit = mantissa.FindLeadingBitInWord(uint(value >> TTMATH_BITS_PER_UINT)); if( bit != -1 ) { @@ -2940,7 +2951,7 @@ public: #endif // man >= 2 - mantissa.table[man-1] = uint(value >> 32); + mantissa.table[man-1] = uint(value >> TTMATH_BITS_PER_UINT); mantissa.table[man-2] = uint(value); #ifdef _MSC_VER @@ -2957,15 +2968,24 @@ public: // there shouldn't be a carry because 'value' has the 'ulint' type // (we have sufficient exponent) Standardizing(); + + return 0; } + /*! + a method for converting 'ulint' (64bit unsigned integer) to this class + */ + uint FromInt(ulint value) + { + return FromUInt(value); + } /*! a method for converting 'slint' (64bit signed integer) to this class */ - void FromInt(slint value) + uint FromInt(slint value) { bool is_sign = false; @@ -2979,8 +2999,11 @@ public: if( is_sign ) SetSign(); + + return 0; } + /*! a constructor for converting 'ulint' (64bit unsigned integer) to this class */ @@ -2989,6 +3012,7 @@ public: FromUInt(value); } + /*! an operator for converting 'ulint' (64bit unsigned integer) to this class */ @@ -3008,6 +3032,7 @@ public: FromInt(value); } + /*! an operator for converting 'slint' (64bit signed integer) to this class */ @@ -3024,70 +3049,82 @@ public: #ifdef TTMATH_PLATFORM64 - /*! - in 64bit platforms we must define additional operators and contructors - in order to allow a user initializing the objects in this way: - Big<...> type = 20; - or - Big<...> type; - type = 30; - - decimal constants such as 20, 30 etc. are integer literal of type int, - if the value is greater it can even be long int, - 0 is an octal integer of type int - (ISO 14882 p2.13.1 Integer literals) + /* + this method converts 32 bit unsigned int to this class + ***this method is created only on a 64bit platform*** */ - - /*! - an operator= for converting 'signed int' to this class - ***this operator is created only on a 64bit platform*** - it takes one argument of 32bit - - - */ - Big & operator=(signed int value) + uint FromUInt(unsigned int value) { - FromInt(sint(value)); + return FromUInt(uint(value)); + } - return *this; + + /* + this method converts 32 bit unsigned int to this class + ***this method is created only on a 64bit platform*** + */ + uint FromInt(unsigned int value) + { + return FromUInt(uint(value)); + } + + + /* + this method converts 32 bit signed int to this class + ***this method is created only on a 64bit platform*** + */ + uint FromInt(signed int value) + { + return FromInt(sint(value)); } /*! - an operator= for converting 'unsigned int' to this class + an operator= for converting 32 bit unsigned int to this class ***this operator is created only on a 64bit platform*** - it takes one argument of 32bit */ Big & operator=(unsigned int value) { - FromUInt(uint(value)); + FromUInt(value); return *this; } /*! - a constructor for converting 'signed int' to this class + a constructor for converting 32 bit unsigned int to this class ***this constructor is created only on a 64bit platform*** - it takes one argument of 32bit - */ - Big(signed int value) - { - FromInt(sint(value)); - } - - /*! - a constructor for converting 'unsigned int' to this class - ***this constructor is created only on a 64bit platform*** - it takes one argument of 32bit */ Big(unsigned int value) { - FromUInt(uint(value)); + FromUInt(value); + } + + + /*! + an operator for converting 32 bit signed int to this class + ***this operator is created only on a 64bit platform*** + */ + Big & operator=(signed int value) + { + FromInt(value); + + return *this; + } + + + /*! + a constructor for converting 32 bit signed int to this class + ***this constructor is created only on a 64bit platform*** + */ + Big(signed int value) + { + FromInt(value); } #endif + private: /*! @@ -3098,7 +3135,7 @@ private: that one from the UInt) */ template - void FromUIntOrInt(const UInt & value, sint compensation) + uint FromUIntOrInt(const UInt & value, sint compensation) { uint minimum_size = (int_size < man)? int_size : man; exponent = (sint(int_size)-sint(man)) * sint(TTMATH_BITS_PER_UINT) - compensation; @@ -3115,17 +3152,18 @@ private: // the highest bit is either one or zero (when the whole mantissa is zero) // we can only call CorrectZero() CorrectZero(); + + return 0; } public: - /*! a method for converting from 'UInt' to this class */ template - void FromUInt(UInt value) + uint FromUInt(UInt value) { info = 0; sint compensation = (sint)value.CompensationToLeft(); @@ -3134,11 +3172,21 @@ public: } + /*! + a method for converting from 'UInt' to this class + */ + template + uint FromInt(const UInt & value) + { + return FromUInt(value); + } + + /*! a method for converting from 'Int' to this class */ template - void FromInt(Int value) + uint FromInt(Int value) { info = 0; bool is_sign = false; @@ -3154,6 +3202,8 @@ public: if( is_sign ) SetSign(); + + return 0; } @@ -3339,9 +3389,10 @@ public: a method for converting into a string struct Conv is defined in ttmathtypes.h, look there for more information about parameters */ - std::string ToString() const + std::string ToString(uint base = 10) const { Conv conv; + conv.base = base; return ToString(conv); } @@ -3403,9 +3454,10 @@ public: a method for converting into a string struct Conv is defined in ttmathtypes.h, look there for more information about parameters */ - std::wstring ToWString() const + std::wstring ToWString(uint base = 10) const { Conv conv; + conv.base = base; return ToWString(conv); } diff --git a/ttmath/ttmathint.h b/ttmath/ttmathint.h index dbe14a2..39e5247 100644 --- a/ttmath/ttmathint.h +++ b/ttmath/ttmathint.h @@ -726,6 +726,16 @@ public: } + /*! + this method converts UInt into this class + */ + template + uint FromInt(const UInt & p) + { + return FromUIntOrInt(p, true); + } + + /*! this method converts the uint type into this class */ @@ -745,6 +755,14 @@ public: } + /*! + this method converts the uint type into this class + */ + uint FromInt(uint value) + { + return FromUInt(value); + } + /*! the default assignment operator @@ -861,6 +879,37 @@ public: #ifdef TTMATH_PLATFORM32 + /*! + this method converts unsigned 64 bit int type to this class + ***this method is created only on a 32bit platform*** + */ + uint FromUInt(ulint n) + { + uint c = UInt::FromUInt(n); + + if( c ) + return 1; + + if( value_size == 1 ) + return ((UInt::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1; + + if( value_size == 2 ) + return ((UInt::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1; + + return 0; + } + + + /*! + this method converts unsigned 64 bit int type to this class + ***this method is created only on a 32bit platform*** + */ + uint FromInt(ulint n) + { + return FromUInt(n); + } + + /*! this method converts signed 64 bit int type to this class ***this method is created only on a 32bit platform*** @@ -888,6 +937,28 @@ public: } + /*! + this operator converts unsigned 64 bit int type to this class + ***this operator is created only on a 32bit platform*** + */ + Int & operator=(ulint n) + { + FromUInt(n); + + return *this; + } + + + /*! + a constructor for converting unsigned 64 bit int to this class + ***this constructor is created only on a 32bit platform*** + */ + Int(ulint n) + { + FromUInt(n); + } + + /*! this operator converts signed 64 bit int type to this class ***this operator is created only on a 32bit platform*** @@ -917,59 +988,82 @@ public: #ifdef TTMATH_PLATFORM64 /*! - this method converts the signed int type to this class - + this method converts 32 bit unsigned int type to this class ***this operator is created only on a 64bit platform*** - it takes one argument of 32bit */ - Int & operator=(signed int i) + uint FromUInt(unsigned int i) { - FromInt(sint(i)); - - return *this; + return FromUInt(uint(i)); } /*! - a constructor for converting the signed int to this class - - ***this constructor is created only on a 64bit platform*** - it takes one argument of 32bit + this method converts 32 bit unsigned int type to this class + ***this operator is created only on a 64bit platform*** */ - Int(signed int i) + uint FromInt(unsigned int i) { - FromInt(sint(i)); + return FromUInt(i); } /*! - this method converts the unsigned int type to this class - + this method converts 32 bit signed int type to this class + ***this operator is created only on a 64bit platform*** + */ + uint FromInt(signed int i) + { + return FromInt(sint(i)); + } + + + /*! + this method converts 32 bit unsigned int type to this class ***this operator is created only on a 64bit platform*** - it takes one argument of 32bit */ Int & operator=(unsigned int i) { - FromUInt(uint(i)); + FromUInt(i); return *this; } /*! - a constructor for converting the unsigned int to this class - + a constructor for converting 32 bit unsigned int to this class ***this constructor is created only on a 64bit platform*** - it takes one argument of 32bit */ Int(unsigned int i) { - FromUInt(uint(i)); + FromUInt(i); + } + + + /*! + this operator converts 32 bit signed int type to this class + ***this operator is created only on a 64bit platform*** + */ + Int & operator=(signed int i) + { + FromInt(i); + + return *this; + } + + + /*! + a constructor for converting 32 bit signed int to this class + ***this constructor is created only on a 64bit platform*** + */ + Int(signed int i) + { + FromInt(i); } #endif + /*! a constructor for converting string to this class (with the base=10) */ @@ -1040,6 +1134,96 @@ public: } + + /*! + this method converts the value to sint type + can return a carry if the value is too long to store it in sint type + */ + uint ToInt(sint & result) const + { + result = sint( UInt::table[0] ); + uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0; + + if( (result & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) ) + return 1; + + for(uint i=1 ; i::table[i] != mask ) + return 1; + + return 0; + } + + +#ifdef TTMATH_PLATFORM32 + + /*! + this method converts the value to slint type (64 bit signed integer) + can return a carry if the value is too long to store it in slint type + *** this method is created only on a 32 bit platform *** + */ + uint ToInt(slint & result) const + { + if( value_size == 1 ) + { + result = slint(sint(UInt::table[0])); + } + else + { + uint low = UInt::table[0]; + uint high = UInt::table[1]; + + result = low; + result |= (ulint(high) << TTMATH_BITS_PER_UINT); + + uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0; + + if( (high & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) ) + return 1; + + for(uint i=2 ; i::table[i] != mask ) + return 1; + } + + return 0; + } + +#endif + + + +#ifdef TTMATH_PLATFORM64 + + /*! + this method converts the value to a 32 signed integer + can return a carry if the value is too long to store it in this type + *** this method is created only on a 64 bit platform *** + */ + uint ToInt(int & result) const + { + // !! need testing + + uint first = UInt::table[0]; + + result = int(first); + uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0; + + if( (first >> 31) != (mask >> 31) ) + return 1; + + for(uint i=1 ; i::table[i] != mask ) + return 1; + + return 0; + } + +#endif + + + + private: /*! diff --git a/ttmath/ttmathuint.h b/ttmath/ttmathuint.h index 0fd3c23..4dd7086 100644 --- a/ttmath/ttmathuint.h +++ b/ttmath/ttmathuint.h @@ -2621,10 +2621,25 @@ public: } + /*! + this method converts an UInt type to this class + + this operation has mainly sense if the value from p is + equal or smaller than that one which is returned from UInt::SetMax() + + it returns a carry if the value 'p' is too big + */ + template + uint FromInt(const UInt & p) + { + return FromUInt(p); + } + + /*! this method converts the uint type to this class */ - void FromUInt(uint value) + uint FromUInt(uint value) { for(uint i=1 ; i type = 10; - - above "10" constant has the int type (signed int), if we don't give such - operators and constructors the compiler will not compile the program, - because it has to make a conversion and doesn't know into which type - (the UInt class has operator=(const char*), operator=(uint) etc.) */ UInt & operator=(sint i) { - FromUInt(uint(i)); + FromInt(i); return *this; } @@ -2710,7 +2742,7 @@ public: */ UInt(sint i) { - FromUInt(uint(i)); + FromInt(i); } @@ -2726,9 +2758,9 @@ public: table[0] = (uint)n; if( value_size == 1 ) - return (n <= ulint(TTMATH_UINT_MAX_VALUE)) ? 0 : 1; + return ((n >> TTMATH_BITS_PER_UINT) == 0) ? 0 : 1; - table[1] = (uint)(n >> 32); + table[1] = (uint)(n >> TTMATH_BITS_PER_UINT); for(uint i=2 ; i & operator=(slint n) + { + FromInt(n); + + return *this; + } + + + /*! + a constructor for converting signed 64 bit int to this class + ***this constructor is created only on a 32bit platform*** + */ + UInt(slint n) + { + FromInt(n); + } + #endif #ifdef TTMATH_PLATFORM64 - /*! - in 64bit platforms we must define additional operators and contructors - in order to allow a user initializing the objects in this way: - UInt<...> type = 20; - or - UInt<...> type; - type = 30; - - decimal constants such as 20, 30 etc. are integer literal of type int, - if the value is greater it can even be long int, - 0 is an octal integer of type int - (ISO 14882 p2.13.1 Integer literals) - */ /*! - this operator converts the unsigned int type to this class - + this method converts 32 bit unsigned int type to this class + ***this operator is created only on a 64bit platform*** + */ + uint FromUInt(unsigned int i) + { + // !! need testing + return FromUInt(uint(i)); + } + + /*! + this method converts 32 bit unsigned int type to this class + ***this operator is created only on a 64bit platform*** + */ + uint FromInt(unsigned int i) + { + // !! need testing + return FromUInt(uint(i)); + } + + + /*! + this method converts 32 bit signed int type to this class + ***this operator is created only on a 64bit platform*** + */ + uint FromInt(signed int i) + { + // !! need testing + return FromInt(sint(i)); + } + + + /*! + this operator converts 32 bit unsigned int type to this class ***this operator is created only on a 64bit platform*** - it takes one argument of 32bit */ UInt & operator=(unsigned int i) { - FromUInt(uint(i)); + FromUInt(i); return *this; } /*! - a constructor for converting the unsigned int to this class - + a constructor for converting 32 bit unsigned int to this class ***this constructor is created only on a 64bit platform*** - it takes one argument of 32bit */ UInt(unsigned int i) { - FromUInt(uint(i)); + FromUInt(i); } /*! - an operator for converting the signed int to this class - + an operator for converting 32 bit signed int to this class ***this constructor is created only on a 64bit platform*** - it takes one argument of 32bit - - look at the description of UInt::operator=(sint) */ UInt & operator=(signed int i) { - FromUInt(uint(i)); + FromInt(i); return *this; } /*! - a constructor for converting the signed int to this class - + a constructor for converting 32 bit signed int to this class ***this constructor is created only on a 64bit platform*** - it takes one argument of 32bit - - look at the description of UInt::operator=(sint) */ UInt(signed int i) { - FromUInt(uint(i)); + FromInt(i); } @@ -2849,6 +2935,15 @@ public: } + /*! + a constructor for converting a string to this class (with the base=10) + */ + UInt(const std::string & s) + { + FromString( s.c_str() ); + } + + #ifndef TTMATH_DONT_USE_WCHAR /*! @@ -2871,13 +2966,6 @@ public: #endif - /*! - a constructor for converting a string to this class (with the base=10) - */ - UInt(const std::string & s) - { - FromString( s.c_str() ); - } /*! @@ -2948,8 +3036,177 @@ public: return table[0]; } - // !! add a second version of ToUInt() with an reference (pointer) to the output value - // and with returning carry + + /*! + this method converts the value to uint type + can return a carry if the value is too long to store it in uint type + */ + uint ToUInt(uint & result) const + { + result = table[0]; + + for(uint i=1 ; i> 32) != 0 ) + return 1; + + for(uint i=1 ; i