diff --git a/CHANGELOG b/CHANGELOG index 52c68ed..4ef9a11 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -Version 0.8.6 prerelease (2009.10.07): +Version 0.8.6 prerelease (2009.10.16): * fixed: UInt::SetBitInWord(uint & value, uint bit) set 1 if the bit was equal 1 (should be set 2) this affected only no-asm parts - when macro TTMATH_NOASM was defined @@ -10,6 +10,12 @@ Version 0.8.6 prerelease (2009.10.07): * fixed: Int::FromString(const tt_string & s, uint b = 10) didn't use 'b' (always was '10') * fixed: buffer overflow in Big::ToInt(Int & result) + * fixed: powering algorithm in: + UInt::Pow(UInt pow) + Big::Pow(UInt pow) + Big::PowUInt(Big pow) + when 'pow' was sufficient large the algorithm returned carry + but the result could have been calculated correctly Version 0.8.5 (2009.06.16): diff --git a/ttmath/ttmathbig.h b/ttmath/ttmathbig.h index 0a535b6..cecef32 100644 --- a/ttmath/ttmathbig.h +++ b/ttmath/ttmathbig.h @@ -1137,15 +1137,17 @@ public: result.SetOne(); uint c = 0; - while( !c && !pow.IsZero() ) + while( !c ) { if( pow.table[0] & 1 ) c += result.Mul(start); + pow.Rcr(1); + if( pow.IsZero() ) + break; + start_temp = start; c += start.Mul(start_temp); - - pow.Rcr(1); } *this = result; @@ -1247,15 +1249,18 @@ public: one.SetOne(); result = one; - while( !c && pow >= one ) + while( !c ) { if( pow.Mod2() ) c += result.Mul(start); + c += pow.exponent.Sub( e_one ); + + if( pow < one ) + break; + start_temp = start; c += start.Mul(start_temp); - - c += pow.exponent.Sub( e_one ); } *this = result; diff --git a/ttmath/ttmathuint.h b/ttmath/ttmathuint.h index 06a408b..25da593 100644 --- a/ttmath/ttmathuint.h +++ b/ttmath/ttmathuint.h @@ -2196,32 +2196,27 @@ public: UInt start(*this), start_temp; UInt result; result.SetOne(); - - while( !pow.IsZero() ) + uint c = 0; + + while( !c ) { if( pow.table[0] & 1 ) - if( result.Mul(start) ) - { - TTMATH_LOG("UInt::Pow(UInt<>)") - return 1; - } + c += result.Mul(start); + + pow.Rcr2_one(0); + if( pow.IsZero() ) + break; start_temp = start; // in the second Mul algorithm we can use start.Mul(start) directly (there is no TTMATH_ASSERT_REFERENCE there) - if( start.Mul(start_temp) ) - { - TTMATH_LOG("UInt::Pow(UInt<>)") - return 1; - } - - pow.Rcr2_one(0); + c += start.Mul(start_temp); } *this = result; TTMATH_LOG("UInt::Pow(UInt<>)") - return 0; + return (c==0)? 0 : 1; }