diff --git a/CHANGELOG b/CHANGELOG index 7c72336..ff69082 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -Version 0.9.2 prerelease (2010.09.19): +Version 0.9.2 prerelease (2010.09.21): * fixed: Big::Add() sometimes incorrectly rounded the last bit from its mantissa * fixed: Big::BigAnd() Big::BigOr() Big::BigXor() should have set NaN when the argument was negative (they only returned 2) @@ -59,6 +59,7 @@ Version 0.9.2 prerelease (2010.09.19): * removed: macro TTMATH_RELEASE for debug version define TTMATH_DEBUG macro TTMATH_DEBUG is also automatically defined when DEBUG or _DEBUG is set + * removed: macro TTMATH_REFERENCE_ASSERT from all methods from public interface Version 0.9.1 (2010.02.07): diff --git a/ttmath/ttmathbig.h b/ttmath/ttmathbig.h index 751cefc..0ca6b22 100644 --- a/ttmath/ttmathbig.h +++ b/ttmath/ttmathbig.h @@ -1265,15 +1265,13 @@ private: } - -public: - +private: /*! multiplication this = this * ss2 this method returns a carry */ - uint Mul(const Big & ss2, bool round = true) + uint MulRef(const Big & ss2, bool round = true) { TTMATH_REFERENCE_ASSERT( ss2 ) @@ -1336,6 +1334,29 @@ public: } +public: + + + /*! + multiplication this = this * ss2 + this method returns a carry + */ + uint Mul(const Big & ss2, bool round = true) + { + if( this == &ss2 ) + { + Big copy_ss2(ss2); + return MulRef(copy_ss2, round); + } + else + { + return MulRef(ss2, round); + } + } + + +private: + /*! division this = this / ss2 @@ -1344,7 +1365,7 @@ public: 1 - carry (in a division carry can be as well) 2 - improper argument (ss2 is zero) */ - uint Div(const Big & ss2, bool round = true) + uint DivRef(const Big & ss2, bool round = true) { TTMATH_REFERENCE_ASSERT( ss2 ) @@ -1407,24 +1428,36 @@ public: } +public: + /*! - the remainder from a division - - e.g. - 12.6 mod 3 = 0.6 because 12.6 = 3*4 + 0.6 - -12.6 mod 3 = -0.6 bacause -12.6 = 3*(-4) + (-0.6) - 12.6 mod -3 = 0.6 - -12.6 mod -3 = -0.6 - - it means: - in other words: this(old) = ss2 * q + this(new) + division this = this / ss2 return value: 0 - ok - 1 - carry + 1 - carry (in a division carry can be as well) 2 - improper argument (ss2 is zero) */ - uint Mod(const Big & ss2) + uint Div(const Big & ss2, bool round = true) + { + if( this == &ss2 ) + { + Big copy_ss2(ss2); + return DivRef(copy_ss2, round); + } + else + { + return DivRef(ss2, round); + } + } + + +private: + + /*! + the remainder from a division + */ + uint ModRef(const Big & ss2) { TTMATH_REFERENCE_ASSERT( ss2 ) @@ -1456,6 +1489,58 @@ public: } +public: + + /*! + the remainder from a division + + e.g. + 12.6 mod 3 = 0.6 because 12.6 = 3*4 + 0.6 + -12.6 mod 3 = -0.6 bacause -12.6 = 3*(-4) + (-0.6) + 12.6 mod -3 = 0.6 + -12.6 mod -3 = -0.6 + + it means: + in other words: this(old) = ss2 * q + this(new) + + return value: + 0 - ok + 1 - carry + 2 - improper argument (ss2 is zero) + */ + uint Mod(const Big & ss2) + { + if( this == &ss2 ) + { + Big copy_ss2(ss2); + return ModRef(copy_ss2); + } + else + { + return ModRef(ss2); + } + } + + + /*! + this method returns: 'this' mod 2 + (either zero or one) + + this method is much faster than using Mod( object_with_value_two ) + */ + uint Mod2() const + { + if( exponent>sint(0) || exponent<=-sint(man*TTMATH_BITS_PER_UINT) ) + return 0; + + sint exp_int = exponent.ToInt(); + // 'exp_int' is negative (or zero), we set it as positive + exp_int = -exp_int; + + return mantissa.GetBit(exp_int); + } + + /*! power this = this ^ pow (pow without a sign) @@ -1549,26 +1634,6 @@ public: } - /*! - this method returns: 'this' mod 2 - (either zero or one) - - this method is much faster than using Mod( object_with_value_two ) - */ - uint Mod2() const - { - if( exponent>sint(0) || exponent<=-sint(man*TTMATH_BITS_PER_UINT) ) - return 0; - - sint exp_int = exponent.ToInt(); - // 'exp_int' is negative (or zero), we set it as positive - exp_int = -exp_int; - - return mantissa.GetBit(exp_int); - } - - - /*! power this = this ^ abs([pow]) pow is treated as a value without a sign and without a fraction @@ -1642,8 +1707,6 @@ public: */ uint PowInt(const Big & pow) { - TTMATH_REFERENCE_ASSERT( pow ) - if( IsNan() || pow.IsNan() ) return CheckCarry(1); @@ -1680,8 +1743,6 @@ public: */ uint PowFrac(const Big & pow) { - TTMATH_REFERENCE_ASSERT( pow ) - if( IsNan() || pow.IsNan() ) return CheckCarry(1); @@ -1701,7 +1762,6 @@ public: } - /*! power this = this ^ pow pow can be negative and with fraction @@ -1713,8 +1773,6 @@ public: */ uint Pow(const Big & pow) { - TTMATH_REFERENCE_ASSERT( pow ) - if( IsNan() || pow.IsNan() ) return CheckCarry(1); @@ -2055,8 +2113,6 @@ public: */ uint Ln(const Big & x) { - TTMATH_REFERENCE_ASSERT( x ) - if( x.IsNan() ) return CheckCarry(1); @@ -2066,18 +2122,18 @@ public: return 2; } + Big exponent_temp; + exponent_temp.FromInt( x.exponent ); + // m will be the value of the mantissa in range <1,2) Big m(x); m.exponent = -sint(man*TTMATH_BITS_PER_UINT - 1); - LnSurrounding1(m); - - Big exponent_temp; - exponent_temp.FromInt( x.exponent ); - // we must add 'man*TTMATH_BITS_PER_UINT-1' because we've taken it from the mantissa uint c = exponent_temp.Add(man*TTMATH_BITS_PER_UINT-1); + LnSurrounding1(m); + Big ln2; ln2.SetLn2(); c += exponent_temp.Mul(ln2); @@ -2087,7 +2143,6 @@ public: } - /*! Logarithm from 'x' with a 'base' @@ -2102,9 +2157,6 @@ public: */ uint Log(const Big & x, const Big & base) { - TTMATH_REFERENCE_ASSERT( base ) - TTMATH_REFERENCE_ASSERT( x ) - if( x.IsNan() || base.IsNan() ) return CheckCarry(1); @@ -3513,19 +3565,19 @@ private: if( conv.base<2 || conv.base>16 ) return 1; - // the speciality for base equal 2 + // special method for base equal 2 if( conv.base == 2 ) return ToString_CreateNewMantissaAndExponent_Base2(new_man, new_exp); - // the speciality for base equal 4 + // special method for base equal 4 if( conv.base == 4 ) return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 2); - // the speciality for base equal 8 + // special method for base equal 8 if( conv.base == 8 ) return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 3); - // the speciality for base equal 16 + // special method for base equal 16 if( conv.base == 16 ) return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 4); diff --git a/ttmath/ttmathuint.h b/ttmath/ttmathuint.h index 892a2cc..0fd3c23 100644 --- a/ttmath/ttmathuint.h +++ b/ttmath/ttmathuint.h @@ -975,12 +975,14 @@ public: the first version of the multiplication algorithm */ +private: + /*! multiplication: this = this * ss2 it returns carry if it has been */ - uint Mul1(const UInt & ss2) + uint Mul1Ref(const UInt & ss2) { TTMATH_REFERENCE_ASSERT( ss2 ) @@ -1008,6 +1010,26 @@ public: return 0; } + +public: + + /*! + multiplication: this = this * ss2 + can return carry + */ + uint Mul1(const UInt & ss2) + { + if( this == &ss2 ) + { + UInt copy_ss2(ss2); + return Mul1Ref(copy_ss2); + } + else + { + return Mul1Ref(ss2); + } + } + /*! multiplication: result = this * ss2 @@ -1688,10 +1710,33 @@ public: } + /*! + the first division algorithm + radix 2 + */ + uint Div1(const UInt & divisor, UInt & remainder) + { + return Div1(divisor, &remainder); + } + + private: - uint Div1_Calculate(const UInt & divisor, UInt & rest) + { + if( this == &divisor ) + { + UInt divisor_copy(divisor); + return Div1_CalculateRef(divisor_copy, rest); + } + else + { + return Div1_CalculateRef(divisor, rest); + } + } + + + uint Div1_CalculateRef(const UInt & divisor, UInt & rest) { TTMATH_REFERENCE_ASSERT( divisor ) @@ -1749,7 +1794,6 @@ private: public: - /*! the second division algorithm @@ -1759,8 +1803,42 @@ public: */ uint Div2(const UInt & divisor, UInt * remainder = 0) { - TTMATH_REFERENCE_ASSERT( divisor ) + if( this == &divisor ) + { + UInt divisor_copy(divisor); + return Div2Ref(divisor_copy, remainder); + } + else + { + return Div2Ref(divisor, remainder); + } + } + + /*! + the second division algorithm + + return values: + 0 - ok + 1 - division by zero + */ + uint Div2(const UInt & divisor, UInt & remainder) + { + return Div2(divisor, &remainder); + } + + +private: + + /*! + the second division algorithm + + return values: + 0 - ok + 1 - division by zero + */ + uint Div2Ref(const UInt & divisor, UInt * remainder = 0) + { uint bits_diff; uint status = Div2_Calculate(divisor, remainder, bits_diff); if( status < 2 ) @@ -1786,14 +1864,6 @@ public: } - uint Div2(const UInt & divisor, UInt & remainder) - { - return Div2(divisor, &remainder); - } - - -private: - /*! return values: 0 - we've calculated the division @@ -1974,6 +2044,34 @@ private: public: + /*! + the third division algorithm + */ + uint Div3(const UInt & ss2, UInt * remainder = 0) + { + if( this == &ss2 ) + { + UInt copy_ss2(ss2); + return Div3Ref(copy_ss2, remainder); + } + else + { + return Div3Ref(ss2, remainder); + } + } + + + /*! + the third division algorithm + */ + uint Div3(const UInt & ss2, UInt & remainder) + { + return Div3(ss2, &remainder); + } + + +private: + /*! the third division algorithm @@ -1982,10 +2080,8 @@ public: Donald E. Knuth !! give the description here (from the book) */ - uint Div3(const UInt & v, UInt * remainder = 0) + uint Div3Ref(const UInt & v, UInt * remainder = 0) { - TTMATH_REFERENCE_ASSERT( v ) - uint m,n, test; test = Div_StandardTest(v, m, n, remainder);