From 83b5ab7170f917549a15b4c8facd0039cbf4f576 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Sun, 12 Mar 2017 17:13:37 +0000 Subject: [PATCH] changed: commentaries to be more doxygen friendly changed: put block characters {...} is some places git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1053 e52654a7-88a9-db11-a3e9-0013d4bc506e --- doxygen.cfg | 6 +- ttmath/ttmath.h | 138 +++++++------ ttmath/ttmathbig.h | 312 +++++++++++++++++------------- ttmath/ttmathint.h | 47 ++--- ttmath/ttmathmisc.h | 22 +-- ttmath/ttmathobjects.h | 7 +- ttmath/ttmaththreads.h | 40 ++-- ttmath/ttmathtypes.h | 31 +-- ttmath/ttmathuint.h | 102 +++++----- ttmath/ttmathuint_noasm.h | 99 ++++++---- ttmath/ttmathuint_x86.h | 50 +++-- ttmath/ttmathuint_x86_64.h | 85 +++++--- ttmath/ttmathuint_x86_64_msvc.asm | 3 + 13 files changed, 549 insertions(+), 393 deletions(-) diff --git a/doxygen.cfg b/doxygen.cfg index f5b9687..3f81c3a 100644 --- a/doxygen.cfg +++ b/doxygen.cfg @@ -827,7 +827,7 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = ttmathdec.h # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -838,7 +838,7 @@ EXCLUDE_PATTERNS = # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* -EXCLUDE_SYMBOLS = auxiliaryfunctions +EXCLUDE_SYMBOLS = auxiliaryfunctions ttmath_adc_x64 ttmath_addindexed_x64 ttmath_addindexed2_x64 ttmath_addvector_x64 ttmath_sbb_x64 ttmath_subindexed_x64 ttmath_subvector_x64 ttmath_rcl_x64 ttmath_rcr_x64 ttmath_div_x64 ttmath_rcl2_x64 ttmath_rcr2_x64 # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include @@ -2018,7 +2018,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = TTMATH_PLATFORM64=1 TTMATH_POSIX_THREADS=1 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/ttmath/ttmath.h b/ttmath/ttmath.h index 3a6218d..94630a7 100644 --- a/ttmath/ttmath.h +++ b/ttmath/ttmath.h @@ -79,10 +79,12 @@ namespace ttmath /*! this function skips the fraction from x - e.g 2.2 = 2 - 2.7 = 2 - -2.2 = 2 - -2.7 = 2 + + samples + - 2.2 = 2 + - 2.7 = 2 + - -2.2 = 2 + - -2.7 = 2 */ template ValueType SkipFraction(const ValueType & x) @@ -96,10 +98,12 @@ namespace ttmath /*! this function rounds to the nearest integer value - e.g 2.2 = 2 - 2.7 = 3 - -2.2 = -2 - -2.7 = -3 + + samples + - 2.2 = 2 + - 2.7 = 3 + - -2.2 = -2 + - -2.7 = -3 */ template ValueType Round(const ValueType & x, ErrorCode * err = 0) @@ -127,12 +131,12 @@ namespace ttmath this function returns a value representing the smallest integer that is greater than or equal to x - Ceil(-3.7) = -3 - Ceil(-3.1) = -3 - Ceil(-3.0) = -3 - Ceil(4.0) = 4 - Ceil(4.2) = 5 - Ceil(4.8) = 5 + - Ceil(-3.7) = -3 + - Ceil(-3.1) = -3 + - Ceil(-3.0) = -3 + - Ceil(4.0) = 4 + - Ceil(4.2) = 5 + - Ceil(4.8) = 5 */ template ValueType Ceil(const ValueType & x, ErrorCode * err = 0) @@ -174,12 +178,12 @@ namespace ttmath this function returns a value representing the largest integer that is less than or equal to x - Floor(-3.6) = -4 - Floor(-3.1) = -4 - Floor(-3) = -3 - Floor(2) = 2 - Floor(2.3) = 2 - Floor(2.8) = 2 + - Floor(-3.6) = -4 + - Floor(-3.1) = -4 + - Floor(-3) = -3 + - Floor(2) = 2 + - Floor(2.3) = 2 + - Floor(2.8) = 2 */ template ValueType Floor(const ValueType & x, ErrorCode * err = 0) @@ -1614,15 +1618,16 @@ namespace ttmath minutes and seconds must be greater than or equal zero result: - if d>=0 : result= d + ((s/60)+m)/60 - if d<0 : result= d - ((s/60)+m)/60 + - if d>=0 : result= d + ((s/60)+m)/60 + - if d<0 : result= d - ((s/60)+m)/60 ((s/60)+m)/60 = (s+60*m)/3600 (second version is faster because there's only one division) - for example: - DegToDeg(10, 30, 0) = 10.5 - DegToDeg(10, 24, 35.6)=10.4098(8) + samples: + + - DegToDeg(10, 30, 0) = 10.5 + - DegToDeg(10, 24, 35.6)=10.4098(8) */ template ValueType DegToDeg( const ValueType & d, const ValueType & m, const ValueType & s, @@ -2053,18 +2058,19 @@ namespace ttmath /*! - indexth Root of x + caltulate the index'th Root of x + index must be integer and not negative <0;1;2;3....) - if index==0 the result is one - if x==0 the result is zero and we assume root(0;0) is not defined + - if index==0 the result is one + - if x==0 the result is zero and we assume root(0;0) is not defined - if index is even (2;4;6...) the result is x^(1/index) and x>0 - if index is odd (1;2;3;...) the result is either - -(abs(x)^(1/index)) if x<0 or - x^(1/index)) if x>0 + - if index is even (2;4;6...) the result is x^(1/index) and x>0 + - if index is odd (1;2;3;...) the result is either + - -(abs(x)^(1/index)) if x<0, or + - x^(1/index)) if x>0 - (for index==1 the result is equal x) + - for index==1 the result is equal x */ template ValueType Root(ValueType x, const ValueType & index, ErrorCode * err = 0) @@ -2122,8 +2128,10 @@ namespace ttmath /*! absolute value of x - e.g. -2 = 2 - 2 = 2 + + samples: + - -2 = 2 + - 2 = 2 */ template ValueType Abs(const ValueType & x) @@ -2137,9 +2145,11 @@ namespace ttmath /*! it returns the sign of the value - e.g. -2 = -1 - 0 = 0 - 10 = 1 + + samples: + - -2 = -1 + - 0 = 0 + - 10 = 1 */ template ValueType Sgn(ValueType x) @@ -2153,11 +2163,11 @@ namespace ttmath /*! the remainder from a division - e.g. - mod( 12.6 ; 3) = 0.6 because 12.6 = 3*4 + 0.6 - mod(-12.6 ; 3) = -0.6 bacause -12.6 = 3*(-4) + (-0.6) - mod( 12.6 ; -3) = 0.6 - mod(-12.6 ; -3) = -0.6 + samples: + - mod( 12.6 ; 3) = 0.6 because 12.6 = 3*4 + 0.6 + - mod(-12.6 ; 3) = -0.6 bacause -12.6 = 3*(-4) + (-0.6) + - mod( 12.6 ; -3) = 0.6 + - mod(-12.6 ; -3) = -0.6 */ template ValueType Mod(ValueType a, const ValueType & b, ErrorCode * err = 0) @@ -2189,7 +2199,8 @@ namespace ttmath this function is used to store factorials in a given container 'more' means how many values should be added at the end - e.g. + sample: + std::vector fact; SetFactorialSequence(fact, 3); // now the container has three values: 1 1 2 @@ -2224,7 +2235,8 @@ namespace ttmath an auxiliary function used to calculate Bernoulli numbers this function returns a sum: - sum(m) = sum_{k=0}^{m-1} {2^k * (m k) * B(k)} k in [0, m-1] (m k) means binomial coefficient = (m! / (k! * (m-k)!)) + + sum(m) = sum_{k=0}^{m-1} {2^k * (m k) * B(k)} k in [0, m-1] (m k) means binomial coefficient = (m! / (k! * (m-k)!)) you should have sufficient factorials in cgamma.fact (cgamma.fact should have at least m items) @@ -2278,9 +2290,10 @@ namespace ttmath an auxiliary function used to calculate Bernoulli numbers start is >= 2 - we use the recurrence formula: - B(m) = 1 / (2*(1 - 2^m)) * sum(m) - where sum(m) is calculated by SetBernoulliNumbersSum() + we use the recurrence formula: + + B(m) = 1 / (2*(1 - 2^m)) * sum(m) + where sum(m) is calculated by SetBernoulliNumbersSum() */ template bool SetBernoulliNumbersMore(CGamma & cgamma, uint start, const volatile StopCalculating * stop = 0) @@ -2333,7 +2346,8 @@ namespace ttmath returns false if there was a stop signal, 'more' means how many values should be added at the end - e.g. + sample: + typedef Big<1,2> MyBig; CGamma cgamma; SetBernoulliNumbers(cgamma, 3); @@ -2380,9 +2394,11 @@ namespace ttmath an auxiliary function used to calculate the Gamma() function we calculate a sum: + sum(n) = sum_{m=2} { B(m) / ( (m^2 - m) * n^(m-1) ) } = 1/(12*n) - 1/(360*n^3) + 1/(1260*n^5) + ... - B(m) means a mth Bernoulli number - the sum starts from m=2, we calculate as long as the value will not change after adding a next part + + B(m) means a mth Bernoulli number + the sum starts from m=2, we calculate as long as the value will not change after adding a next part */ template ValueType GammaFactorialHighSum(const ValueType & n, CGamma & cgamma, ErrorCode & err, @@ -2443,9 +2459,11 @@ namespace ttmath an auxiliary function used to calculate the Gamma() function we calculate a helper function GammaFactorialHigh() by using Stirling's series: - n! = (n/e)^n * sqrt(2*pi*n) * exp( sum(n) ) - where n is a real number (not only an integer) and is sufficient large (greater than TTMATH_GAMMA_BOUNDARY) - and sum(n) is calculated by GammaFactorialHighSum() + + n! = (n/e)^n * sqrt(2*pi*n) * exp( sum(n) ) + + where n is a real number (not only an integer) and is sufficient large (greater than TTMATH_GAMMA_BOUNDARY) + and sum(n) is calculated by GammaFactorialHighSum() */ template ValueType GammaFactorialHigh(const ValueType & n, CGamma & cgamma, ErrorCode & err, @@ -2497,7 +2515,8 @@ namespace ttmath we use this function when n is integer and a small value (from 0 to TTMATH_GAMMA_BOUNDARY] we use the formula: - gamma(n) = (n-1)! = 1 * 2 * 3 * ... * (n-1) + + gamma(n) = (n-1)! = 1 * 2 * 3 * ... * (n-1) */ template ValueType GammaPlusLowIntegerInt(uint n, CGamma & cgamma) @@ -2548,11 +2567,12 @@ namespace ttmath we use this function when n is a small value (from 0 to TTMATH_GAMMA_BOUNDARY] we use a recurrence formula: + gamma(z+1) = z * gamma(z) then: gamma(z) = gamma(z+1) / z - e.g. - gamma(3.89) = gamma(2001.89) / ( 3.89 * 4.89 * 5.89 * ... * 1999.89 * 2000.89 ) + samples: + - gamma(3.89) = gamma(2001.89) / ( 3.89 * 4.89 * 5.89 * ... * 1999.89 * 2000.89 ) */ template ValueType GammaPlusLow(ValueType n, CGamma & cgamma, ErrorCode & err, const volatile StopCalculating * stop) @@ -2643,11 +2663,13 @@ namespace ttmath it's multithread safe, you should create a CGamma<> object and use it whenever you call the Gamma() e.g. + typedef Big<1,2> MyBig; MyBig x=234, y=345.53; CGamma cgamma; std::cout << Gamma(x, cgamma) << std::endl; std::cout << Gamma(y, cgamma) << std::endl; + in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers), and they will be reused in next calls to the function @@ -2771,11 +2793,13 @@ namespace ttmath it's multithread safe, you should create a CGamma<> object and use it whenever you call the Factorial() e.g. + typedef Big<1,2> MyBig; MyBig x=234, y=54345; CGamma cgamma; std::cout << Factorial(x, cgamma) << std::endl; std::cout << Factorial(y, cgamma) << std::endl; + in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers), and they will be reused in next calls to the function diff --git a/ttmath/ttmathbig.h b/ttmath/ttmathbig.h index fceef74..1425c71 100644 --- a/ttmath/ttmathbig.h +++ b/ttmath/ttmathbig.h @@ -66,19 +66,19 @@ class Big /* value = mantissa * 2^exponent - exponent - an integer value with a sign - mantissa - an integer value without a sing + - exponent - an integer value with a sign + - mantissa - an integer value without a sing mantissa must be pushed into the left side that is the highest bit from mantissa must be one (of course if there's another value than zero) -- this job - (pushing bits into the left side) making Standardizing() method + (pushing bits into the left side) is doing by Standardizing() method for example: if we want to store value one (1) into our Big object we must: - set mantissa to 1 - set exponent to 0 - set info to 0 - and call method Standardizing() + - set mantissa to 1 + - set exponent to 0 + - set info to 0 + - and call method Standardizing() */ @@ -135,12 +135,12 @@ public: /*! returning the string represents the currect type of the library we have following types: - asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits) - asm_gcc_32 - with asm code designed for GCC (32 bits) - asm_vc_64 - with asm for VC (64 bit) - asm_gcc_64 - with asm for GCC (64 bit) - no_asm_32 - pure C++ version (32 bit) - without any asm code - no_asm_64 - pure C++ version (64 bit) - without any asm code + - asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits) + - asm_gcc_32 - with asm code designed for GCC (32 bits) + - asm_vc_64 - with asm for VC (64 bit) + - asm_gcc_64 - with asm for GCC (64 bit) + - no_asm_32 - pure C++ version (32 bit) - without any asm code + - no_asm_64 - pure C++ version (64 bit) - without any asm code */ static const char * LibTypeStr() { @@ -675,9 +675,9 @@ public: this method clears the sign (there'll be an absolute value) - e.g. - -1 -> 1 - 2 -> 2 + samples + - -1 -> 1 + - 2 -> 2 */ void Abs() { @@ -687,9 +687,11 @@ public: /*! this method remains the 'sign' of the value - e.g. -2 = -1 - 0 = 0 - 10 = 1 + + samples + - -2 = -1 + - 0 = 0 + - 10 = 1 */ void Sgn() { @@ -714,9 +716,9 @@ public: /*! this method sets the sign - e.g. - -1 -> -1 - 2 -> -2 + samples + - -1 -> -1 + - 2 -> -2 we do not check whether there is a zero or not, if you're using this method you must be sure that the value is (or will be afterwards) different from zero @@ -731,9 +733,9 @@ public: this method changes the sign when there is a value of zero then the sign is not changed - e.g. - -1 -> 1 - 2 -> -2 + samples + - -1 -> 1 + - 2 -> -2 */ void ChangeSign() { @@ -756,8 +758,8 @@ private: this method does the half-to-even rounding (banker's rounding) if is_half is: - true - that means the rest was equal the half (0.5 decimal) - false - that means the rest was greater than a half (greater than 0.5 decimal) + - true - that means the rest was equal the half (0.5 decimal) + - false - that means the rest was greater than a half (greater than 0.5 decimal) if the rest was less than a half then don't call this method (the rounding should does nothing then) @@ -983,10 +985,11 @@ public: bitwise AND this and ss2 must be >= 0 + return values: - 0 - ok - 1 - carry - 2 - this or ss2 was negative + - 0 - ok + - 1 - carry + - 2 - this or ss2 was negative */ uint BitAnd(Big ss2) { @@ -1042,9 +1045,10 @@ public: this and ss2 must be >= 0 return values: - 0 - ok - 1 - carry - 2 - this or ss2 was negative + + - 0 - ok + - 1 - carry + - 2 - this or ss2 was negative */ uint BitOr(Big ss2) { @@ -1097,9 +1101,10 @@ public: this and ss2 must be >= 0 return values: - 0 - ok - 1 - carry - 2 - this or ss2 was negative + + - 0 - ok + - 1 - carry + - 2 - this or ss2 was negative */ uint BitXor(Big ss2) { @@ -1250,8 +1255,8 @@ private: call this method only if the highest bit is set - you have to test it beforehand return: - true - tab was equal the half (0.5 decimal) - false - tab was greater than a half (greater than 0.5 decimal) + - true - tab was equal the half (0.5 decimal) + - false - tab was greater than a half (greater than 0.5 decimal) */ bool CheckGreaterOrEqualHalf(uint * tab, uint len) @@ -1367,9 +1372,9 @@ private: division this = this / ss2 return value: - 0 - ok - 1 - carry (in a division carry can be as well) - 2 - improper argument (ss2 is zero) + - 0 - ok + - 1 - carry (in a division carry can be as well) + - 2 - improper argument (ss2 is zero) */ uint DivRef(const Big & ss2, bool round = true) { @@ -1440,9 +1445,9 @@ public: division this = this / ss2 return value: - 0 - ok - 1 - carry (in a division carry can be as well) - 2 - improper argument (ss2 is zero) + - 0 - ok + - 1 - carry (in a division carry can be as well) + - 2 - improper argument (ss2 is zero) */ uint Div(const Big & ss2, bool round = true) { @@ -1498,21 +1503,20 @@ private: public: /*! - the remainder from a division + caltulate 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 + samples + - 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) + - 0 - ok + - 1 - carry + - 2 - improper argument (ss2 is zero) */ uint Mod(const Big & ss2) { @@ -1554,9 +1558,9 @@ public: binary algorithm (r-to-l) return values: - 0 - ok - 1 - carry - 2 - incorrect arguments (0^0) + - 0 - ok + - 1 - carry + - 2 - incorrect arguments (0^0) */ template uint Pow(UInt pow) @@ -1606,9 +1610,9 @@ public: p can be negative return values: - 0 - ok - 1 - carry - 2 - incorrect arguments 0^0 or 0^(-something) + - 0 - ok + - 1 - carry + - 2 - incorrect arguments 0^0 or 0^(-something) */ template uint Pow(Int pow) @@ -1646,9 +1650,9 @@ public: if pow has a fraction the fraction is skipped (not used in calculation) return values: - 0 - ok - 1 - carry - 2 - incorrect arguments (0^0) + - 0 - ok + - 1 - carry + - 2 - incorrect arguments (0^0) */ uint PowUInt(Big pow) { @@ -1702,9 +1706,9 @@ public: pow can be negative return values: - 0 - ok - 1 - carry - 2 - incorrect arguments 0^0 or 0^(-something) + - 0 - ok + - 1 - carry + - 2 - incorrect arguments 0^0 or 0^(-something) */ uint PowInt(const Big & pow) { @@ -1738,9 +1742,9 @@ public: pow can be negative and with fraction return values: - 0 - ok - 1 - carry - 2 - incorrect argument ('this' <= 0) + - 0 - ok + - 1 - carry + - 2 - incorrect argument ('this' <= 0) */ uint PowFrac(const Big & pow) { @@ -1768,9 +1772,9 @@ public: pow can be negative and with fraction return values: - 0 - ok - 1 - carry - 2 - incorrect argument ('this' or 'pow') + - 0 - ok + - 1 - carry + - 2 - incorrect argument ('this' or 'pow') */ uint Pow(const Big & pow) { @@ -1805,9 +1809,10 @@ public: this function calculates the square root e.g. let this=9 then this.Sqrt() gives 3 - return: 0 - ok - 1 - carry - 2 - improper argument (this<0 or NaN) + return: + - 0 - ok + - 1 - carry + - 2 - improper argument (this<0 or NaN) */ uint Sqrt() { @@ -1930,8 +1935,11 @@ public: Exponent this = exp(x) = e^x we're using the fact that our value is stored in form of: + x = mantissa * 2^exponent + then + e^x = e^(mantissa* 2^exponent) or e^x = (e^mantissa)^(2^exponent) @@ -2100,17 +2108,20 @@ public: (a logarithm with the base equal 'e') we're using the fact that our value is stored in form of: + x = mantissa * 2^exponent + then + ln(x) = ln (mantissa * 2^exponent) = ln (mantissa) + (exponent * ln (2)) the mantissa we'll show as a value from range <1,2) because the logarithm is decreasing too fast when 'x' is going to 0 return values: - 0 - ok - 1 - overflow (carry) - 2 - incorrect argument (x<=0) + - 0 - ok + - 1 - overflow (carry) + - 2 - incorrect argument (x<=0) */ uint Ln(const Big & x) { @@ -2148,13 +2159,14 @@ public: Logarithm from 'x' with a 'base' we're using the formula: + Log(x) with 'base' = ln(x) / ln(base) return values: - 0 - ok - 1 - overflow - 2 - incorrect argument (x<=0) - 3 - incorrect base (a<=0 or a=1) + - 0 - ok + - 1 - overflow + - 2 - incorrect argument (x<=0) + - 3 - incorrect base (a<=0 or a=1) */ uint Log(const Big & x, const Big & base) { @@ -2571,21 +2583,21 @@ public: right. The first bit is the sign bit, S, the next eleven bits are the exponent bits, 'E', and the final 52 bits are the fraction 'F': - S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - 0 1 11 12 63 + S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 0 1 11 12 63 The value V represented by the word may be determined as follows: - * If E=2047 and F is nonzero, then V=NaN ("Not a number") - * If E=2047 and F is zero and S is 1, then V=-Infinity - * If E=2047 and F is zero and S is 0, then V=Infinity - * If 0 sint e = -( exponent.ToInt() ); @@ -4271,9 +4289,9 @@ private: a special method used to calculate the new mantissa and exponent when the 'base' is equal 4, 8 or 16 - when base is 4 then bits is 2 - when base is 8 then bits is 3 - when base is 16 then bits is 4 + - when base is 4 then bits is 2 + - when base is 8 then bits is 3 + - when base is 16 then bits is 4 (and the algorithm can be used with a base greater than 16) */ template @@ -5157,7 +5175,10 @@ private: // we could break the parsing somewhere in the middle of the string, // but the result (value) still can be good // we should set a correct value of 'source' now - for( ; Misc::CharToDigit(*source, conv.base) != -1 ; ++source ); + while( Misc::CharToDigit(*source, conv.base) != -1 ) + { + ++source; + } power_ = power; c += base_.Pow(power_); @@ -5390,8 +5411,10 @@ public: } if( ss2.IsZero() ) + { // this!=0 and ss2==0 return false; + } // we're using the fact that all bits in mantissa are pushed // into the left side -- Standardizing() @@ -5414,16 +5437,22 @@ public: if( IsZero() ) { if( ss2.IsZero() ) + { // we've got two zeroes return false; + } else + { // this==0 and ss2!=0 return false; + } } if( ss2.IsZero() ) + { // this!=0 and ss2==0 return true; + } // we're using the fact that all bits in mantissa are pushed // into the left side -- Standardizing() @@ -5446,16 +5475,22 @@ public: if( IsZero() ) { if( ss2.IsZero() ) + { // we've got two zeroes return true; + } else + { // this==0 and ss2!=0 return false; + } } if( ss2.IsZero() ) + { // this!=0 and ss2==0 return false; + } if( exponent==ss2.exponent && mantissa==ss2.mantissa ) return true; @@ -5467,12 +5502,16 @@ public: bool operator<(const Big & ss2) const { if( IsSign() && !ss2.IsSign() ) + { // this<0 and ss2>=0 return true; + } if( !IsSign() && ss2.IsSign() ) + { // this>=0 and ss2<0 return false; + } // both signs are the same @@ -5495,12 +5534,16 @@ public: bool operator>(const Big & ss2) const { if( IsSign() && !ss2.IsSign() ) + { // this<0 and ss2>=0 return false; + } if( !IsSign() && ss2.IsSign() ) + { // this>=0 and ss2<0 return true; + } // both signs are the same @@ -5736,13 +5779,13 @@ public: /*! this method makes an integer value by skipping any fractions - for example: - 10.7 will be 10 - 12.1 -- 12 - -20.2 -- 20 - -20.9 -- 20 - -0.7 -- 0 - 0.8 -- 0 + samples: + - 10.7 will be 10 + - 12.1 -- 12 + - -20.2 -- 20 + - -20.9 -- 20 + - -0.7 -- 0 + - 0.8 -- 0 */ void SkipFraction() { @@ -5774,9 +5817,9 @@ public: /*! this method remains only a fraction from the value - for example: - 30.56 will be 0.56 - -12.67 -- -0.67 + samples: + - 30.56 will be 0.56 + - -12.67 will be -0.67 */ void RemainFraction() { @@ -5817,7 +5860,7 @@ public: this method returns true if the value is integer (there is no a fraction) - (we don't check nan) + (we don't check NaN) */ bool IsInteger() const { @@ -5859,12 +5902,11 @@ public: this method rounds to the nearest integer value (it returns a carry if it was) - for example: - 2.3 = 2 - 2.8 = 3 - - -2.3 = -2 - -2.8 = 3 + samples: + - 2.3 = 2 + - 2.8 = 3 + - -2.3 = -2 + - -2.8 = 3 */ uint Round() { diff --git a/ttmath/ttmathint.h b/ttmath/ttmathint.h index b2c8d87..7188184 100644 --- a/ttmath/ttmathint.h +++ b/ttmath/ttmathint.h @@ -55,8 +55,8 @@ namespace ttmath \brief Int implements a big integer value with a sign value_size - how many bytes specify our value - on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits - on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits + - on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits + - on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits value_size = 1,2,3,4,5,6.... */ template @@ -131,8 +131,9 @@ public: /*! this method sets the sign - e.g. 1 -> -1 - -2 -> -2 + samples + - 1 -> -1 + - -2 -> -2 from a positive value we make a negative value, if the value is negative we do nothing @@ -290,10 +291,10 @@ public: this = p1(=this) - p2 - when p1>=0 i p2>=0 carry will never be set - when p1<0 i p2<0 carry will never be set - when p1>=0 i p2<0 carry is set when the highest bit of value is set - when p1<0 i p2>=0 carry is set when the highest bit of value is clear + - when p1>=0 i p2>=0 carry will never be set + - when p1<0 i p2<0 carry will never be set + - when p1>=0 i p2<0 carry is set when the highest bit of value is set + - when p1<0 i p2>=0 carry is set when the highest bit of value is clear */ uint Sub(const Int & ss2) { @@ -465,14 +466,14 @@ public: /*! division this = this / ss2 returned values: - 0 - ok - 1 - division by zero + - 0 - ok + - 1 - division by zero for example: (result means 'this') - 20 / 3 --> result: 6 remainder: 2 - -20 / 3 --> result: -6 remainder: -2 - 20 / -3 --> result: -6 remainder: 2 - -20 / -3 --> result: 6 remainder: -2 + - 20 / 3 --> result: 6 remainder: 2 + - -20 / 3 --> result: -6 remainder: -2 + - 20 / -3 --> result: -6 remainder: 2 + - -20 / -3 --> result: 6 remainder: -2 in other words: this(old) = ss2 * this(new)(result) + remainder */ @@ -509,14 +510,14 @@ public: /*! division this = this / ss2 (ss2 is int) returned values: - 0 - ok - 1 - division by zero + - 0 - ok + - 1 - division by zero for example: (result means 'this') - 20 / 3 --> result: 6 remainder: 2 - -20 / 3 --> result: -6 remainder: -2 - 20 / -3 --> result: -6 remainder: 2 - -20 / -3 --> result: 6 remainder: -2 + - 20 / 3 --> result: 6 remainder: 2 + - -20 / 3 --> result: -6 remainder: -2 + - 20 / -3 --> result: -6 remainder: 2 + - -20 / -3 --> result: 6 remainder: -2 in other words: this(old) = ss2 * this(new)(result) + remainder */ @@ -600,9 +601,9 @@ public: power this = this ^ pow return values: - 0 - ok - 1 - carry - 2 - incorrect arguments 0^0 or 0^(-something) + - 0 - ok + - 1 - carry + - 2 - incorrect arguments 0^0 or 0^(-something) */ uint Pow(Int pow) { diff --git a/ttmath/ttmathmisc.h b/ttmath/ttmathmisc.h index fae4255..c9e1560 100644 --- a/ttmath/ttmathmisc.h +++ b/ttmath/ttmathmisc.h @@ -171,10 +171,10 @@ static void SkipWhiteCharacters(const char_type * & c) this static method converts one character into its value for example: - 1 -> 1 - 8 -> 8 - A -> 10 - f -> 15 + - 1 -> 1 + - 8 -> 8 + - A -> 10 + - f -> 15 this method don't check whether c is correct or not */ @@ -195,9 +195,9 @@ return c-'A'+10; (if there can't be a correct value it returns -1) for example: - c=2, base=10 -> function returns 2 - c=A, base=10 -> function returns -1 - c=A, base=16 -> function returns 10 + - c=2, base=10 -> function returns 2 + - c=A, base=10 -> function returns -1 + - c=A, base=16 -> function returns 10 */ static sint CharToDigit(uint c, uint base) { @@ -228,10 +228,10 @@ return sint(c); (we don't have to get a base) for example: - 1 -> 1 - 8 -> 8 - 10 -> A - 15 -> F + - 1 -> 1 + - 8 -> 8 + - 10 -> A + - 15 -> F */ static uint DigitToChar(uint digit) { diff --git a/ttmath/ttmathobjects.h b/ttmath/ttmathobjects.h index 39e9db8..2902c9a 100644 --- a/ttmath/ttmathobjects.h +++ b/ttmath/ttmathobjects.h @@ -81,7 +81,7 @@ public: // (if there's a variable this 'param' is ignored) int param; - Item() {} + Item() { param = 0; } Item(const std::string & v, int p) : value(v), param(p) {} }; @@ -723,14 +723,17 @@ public: in multithreaded environment you can provide an object of this class to the Gamma() or Factorial() function, e.g; + typedef Big<1, 3> MyBig; MyBig x = 123456; CGamma cgamma; std::cout << Gamma(x, cgamma); + each thread should have its own CGamma<> object in a single-thread environment a CGamma<> object is a static variable - in a second version of Gamma() and you don't have to explicitly use it, e.g. + and you don't have to explicitly use it, e.g. + typedef Big<1, 3> MyBig; MyBig x = 123456; std::cout << Gamma(x); diff --git a/ttmath/ttmaththreads.h b/ttmath/ttmaththreads.h index dc2aa4e..57c3650 100644 --- a/ttmath/ttmaththreads.h +++ b/ttmath/ttmaththreads.h @@ -59,24 +59,6 @@ */ -/* - this is a simple skeleton of a program in multithreads environment: - - #define TTMATH_MULTITHREADS - #include - - TTMATH_MULTITHREADS_HELPER - - int main() - { - [...] - } - - make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file) - use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope) -*/ - - namespace ttmath { @@ -186,12 +168,32 @@ namespace ttmath /*! - objects of this class are used to synchronize + \brief objects of this class are used to synchronize + + this is a simple skeleton of a program in multithreads environment: + + #define TTMATH_MULTITHREADS + #include + + TTMATH_MULTITHREADS_HELPER + + int main() + { + [...] + } + + make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file) + use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope) */ class ThreadLock { public: + /*! + lock the current thread + + it uses a global mutex created by TTMATH_MULTITHREADS_HELPER macro + */ bool Lock() { if( pthread_mutex_lock(&ttmath_mutex) != 0 ) diff --git a/ttmath/ttmathtypes.h b/ttmath/ttmathtypes.h index 7880f9a..5511c6f 100644 --- a/ttmath/ttmathtypes.h +++ b/ttmath/ttmathtypes.h @@ -202,15 +202,19 @@ namespace ttmath #else - /*! - on 64bit platforms one word (uint, sint) will be equal 64bits - */ #ifdef _MSC_VER /* in VC 'long' type has 32 bits, __int64 is VC extension */ typedef unsigned __int64 uint; typedef signed __int64 sint; #else + /*! + on 64bit platforms one word (uint, sint) will be equal 64bits + */ typedef unsigned long uint; + + /*! + on 64bit platforms one word (uint, sint) will be equal 64bits + */ typedef signed long sint; #endif @@ -317,12 +321,12 @@ namespace ttmath /*! lib type codes: - asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits) - asm_gcc_32 - with asm code designed for GCC (32 bits) - asm_vc_64 - with asm for VC (64 bit) - asm_gcc_64 - with asm for GCC (64 bit) - no_asm_32 - pure C++ version (32 bit) - without any asm code - no_asm_64 - pure C++ version (64 bit) - without any asm code + - asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits) + - asm_gcc_32 - with asm code designed for GCC (32 bits) + - asm_vc_64 - with asm for VC (64 bit) + - asm_gcc_64 - with asm for GCC (64 bit) + - no_asm_32 - pure C++ version (32 bit) - without any asm code + - no_asm_64 - pure C++ version (64 bit) - without any asm code */ enum LibTypeCode { @@ -407,10 +411,11 @@ namespace ttmath default: true e.g. - Conv c; - c.base_round = false; - Big<1, 1> a = "0.1"; // decimal input - std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999 + + Conv c; + c.base_round = false; + Big<1, 1> a = "0.1"; // decimal input + std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999 */ bool base_round; diff --git a/ttmath/ttmathuint.h b/ttmath/ttmathuint.h index 4cfbeab..9b64745 100644 --- a/ttmath/ttmathuint.h +++ b/ttmath/ttmathuint.h @@ -65,8 +65,8 @@ namespace ttmath \brief UInt implements a big integer value without a sign value_size - how many bytes specify our value - on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits - on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits + - on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits + - on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits value_size = 1,2,3,4,5,6.... */ template @@ -637,13 +637,13 @@ public: this method looks for the highest set bit result: - if 'this' is not zero: - return value - true - 'table_id' - the index of a word <0..value_size-1> + - if 'this' is not zero: + return value - true, + 'table_id' - the index of a word <0..value_size-1>, 'index' - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT) - if 'this' is zero: - return value - false + - if 'this' is zero: + return value - false, both 'table_id' and 'index' are zero */ bool FindLeadingBit(uint & table_id, uint & index) const @@ -669,13 +669,13 @@ public: this method looks for the smallest set bit result: - if 'this' is not zero: - return value - true - 'table_id' - the index of a word <0..value_size-1> + - if 'this' is not zero: + return value - true, + 'table_id' - the index of a word <0..value_size-1>, 'index' - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT) - if 'this' is zero: - return value - false + - if 'this' is zero: + return value - false, both 'table_id' and 'index' are zero */ bool FindLowestBit(uint & table_id, uint & index) const @@ -1187,17 +1187,23 @@ public: Karatsuba multiplication: Assume we have: + this = x = x1*B^m + x0 ss2 = y = y1*B^m + y0 + where x0 and y0 are less than B^m the product from multiplication we can show as: x*y = (x1*B^m + x0)(y1*B^m + y0) = z2*B^(2m) + z1*B^m + z0 where + z2 = x1*y1 z1 = x1*y0 + x0*y1 - z0 = x0*y0 + z0 = x0*y0 + this is standard schoolbook algorithm with O(n^2), Karatsuba observed that z1 can be given in other form: + z1 = (x1 + x0)*(y1 + y0) - z2 - z0 / z1 = (x1*y1 + x1*y0 + x0*y1 + x0*y0) - x1*y1 - x0*y0 = x1*y0 + x0*y1 / + and to calculate the multiplication we need only three multiplications (with some additions and subtractions) Our objects 'this' and 'ss2' we divide into two parts and by using recurrence we calculate the multiplication. @@ -1612,10 +1618,10 @@ public: division this = this / ss2 return values: - 0 - ok - 1 - division by zero - 'this' will be the quotient - 'remainder' - remainder + - 0 - ok + - 1 - division by zero + - 'this' will be the quotient + - 'remainder' - remainder */ uint Div( const UInt & divisor, UInt * remainder = 0, @@ -1646,9 +1652,9 @@ private: /*! return values: - 0 - none has to be done - 1 - division by zero - 2 - division should be made + - 0 - none has to be done + - 1 - division by zero + - 2 - division should be made */ uint Div_StandardTest( const UInt & v, uint & m, uint & n, @@ -1694,13 +1700,13 @@ private: /*! return values: - 0 - ok - 'm' - is the index (from 0) of last non-zero word in table ('this') - 'n' - is the index (from 0) of last non-zero word in v.table - 1 - v is zero - 2 - 'this' is zero - 3 - 'this' is smaller than v - 4 - 'this' is equal v + - 0 - ok + - 'm' - is the index (from 0) of last non-zero word in table ('this') + - 'n' - is the index (from 0) of last non-zero word in v.table + - 1 - v is zero + - 2 - 'this' is zero + - 3 - 'this' is smaller than v + - 4 - 'this' is equal v if the return value is different than zero the 'm' and 'n' are undefined */ @@ -1741,7 +1747,7 @@ public: /*! the first division algorithm - radix 2 + (radix 2) */ uint Div1(const UInt & divisor, UInt * remainder = 0) { @@ -1764,7 +1770,7 @@ public: /*! the first division algorithm - radix 2 + (radix 2) */ uint Div1(const UInt & divisor, UInt & remainder) { @@ -1850,8 +1856,8 @@ public: the second division algorithm return values: - 0 - ok - 1 - division by zero + - 0 - ok + - 1 - division by zero */ uint Div2(const UInt & divisor, UInt * remainder = 0) { @@ -1871,8 +1877,8 @@ public: the second division algorithm return values: - 0 - ok - 1 - division by zero + - 0 - ok + - 1 - division by zero */ uint Div2(const UInt & divisor, UInt & remainder) { @@ -1886,8 +1892,8 @@ private: the second division algorithm return values: - 0 - ok - 1 - division by zero + - 0 - ok + - 1 - division by zero */ uint Div2Ref(const UInt & divisor, UInt * remainder = 0) { @@ -1918,9 +1924,9 @@ private: /*! return values: - 0 - we've calculated the division - 1 - division by zero - 2 - we have to still calculate + - 0 - we've calculated the division + - 1 - division by zero + - 2 - we have to still calculate */ uint Div2_Calculate(const UInt & divisor, UInt * remainder, @@ -1962,9 +1968,9 @@ private: /*! return values: - 0 - we've calculated the division - 1 - division by zero - 2 - we have to still calculate + - 0 - we've calculated the division + - 1 - division by zero + - 2 - we have to still calculate */ uint Div2_FindLeadingBitsAndCheck( const UInt & divisor, UInt * remainder, @@ -2031,7 +2037,7 @@ private: /*! return values: - true if divisor is equal or greater than 'this' + - true if divisor is equal or greater than 'this' */ bool Div2_DivisorGreaterOrEqual( const UInt & divisor, UInt * remainder, @@ -2278,8 +2284,8 @@ private: the bits from 'this' we're moving the same times as 'v') return values: - d - how many times we've moved - return - the next-left value from 'this' (that after table[value_size-1]) + - d - how many times we've moved + - return - the next-left value from 'this' (that after table[value_size-1]) */ uint Div3_Normalize(UInt & v, uint n, uint & d) { @@ -2412,9 +2418,9 @@ public: binary algorithm (r-to-l) return values: - 0 - ok - 1 - carry - 2 - incorrect argument (0^0) + - 0 - ok + - 1 - carry + - 2 - incorrect argument (0^0) */ uint Pow(UInt pow) { @@ -4158,7 +4164,7 @@ public: /*! - this specialization is needed in order to not confused the compiler "error: ISO C++ forbids zero-size array" + this specialization is needed in order to not confuse the compiler "error: ISO C++ forbids zero-size array" when compiling Mul3Big2() method */ template<> diff --git a/ttmath/ttmathuint_noasm.h b/ttmath/ttmathuint_noasm.h index 8ede287..96ab494 100644 --- a/ttmath/ttmathuint_noasm.h +++ b/ttmath/ttmathuint_noasm.h @@ -39,15 +39,16 @@ #define headerfilettmathuint_noasm -#ifdef TTMATH_NOASM - /*! \file ttmathuint_noasm.h - \brief template class UInt with methods without any assembler code + \brief template class UInt with methods without any assembler code (used for no-asm version of ttmath) this file is included at the end of ttmathuint.h */ +#ifdef TTMATH_NOASM + + namespace ttmath { @@ -55,12 +56,12 @@ namespace ttmath /*! returning the string represents the currect type of the library we have following types: - asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits) - asm_gcc_32 - with asm code designed for GCC (32 bits) - asm_vc_64 - with asm for VC (64 bit) - asm_gcc_64 - with asm for GCC (64 bit) - no_asm_32 - pure C++ version (32 bit) - without any asm code - no_asm_64 - pure C++ version (64 bit) - without any asm code + - asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits) + - asm_gcc_32 - with asm code designed for GCC (32 bits) + - asm_vc_64 - with asm for VC (64 bit) + - asm_gcc_64 - with asm for GCC (64 bit) + - no_asm_32 - pure C++ version (32 bit) - without any asm code + - no_asm_64 - pure C++ version (64 bit) - without any asm code */ template const char * UInt::LibTypeStr() @@ -156,12 +157,17 @@ namespace ttmath and returns a carry (if it was) if we've got (value_size=3): + table[0] = 10; table[1] = 30; - table[2] = 5; + table[2] = 5; + and we call: + AddInt(2,1) + then it'll be: + table[0] = 10; table[1] = 30 + 2; table[2] = 5; @@ -199,17 +205,23 @@ namespace ttmath x1 - lower word, x2 - higher word for example if we've got value_size equal 4 and: + table[0] = 3 table[1] = 4 table[2] = 5 table[3] = 6 + then let + x1 = 10 x2 = 20 + and + index = 1 the result of this method will be: + table[0] = 3 table[1] = 4 + x1 = 14 table[2] = 5 + x2 = 25 @@ -245,19 +257,20 @@ namespace ttmath this static method addes one vector to the other 'ss1' is larger in size or equal to 'ss2' - ss1 points to the first (larger) vector - ss2 points to the second vector - ss1_size - size of the ss1 (and size of the result too) - ss2_size - size of the ss2 - result - is the result vector (which has size the same as ss1: ss1_size) + - ss1 points to the first (larger) vector + - ss2 points to the second vector + - ss1_size - size of the ss1 (and size of the result too) + - ss2_size - size of the ss2 + - result - is the result vector (which has size the same as ss1: ss1_size) + + Example: ss1_size is 5, ss2_size is 3 + ss1: ss2: result (output): + 5 1 5+1 + 4 3 4+3 + 2 7 2+7 + 6 6 + 9 9 - Example: ss1_size is 5, ss2_size is 3 - ss1: ss2: result (output): - 5 1 5+1 - 4 3 4+3 - 2 7 2+7 - 6 6 - 9 9 of course the carry is propagated and will be returned from the last item (this method is used by the Karatsuba multiplication algorithm) */ @@ -342,12 +355,17 @@ namespace ttmath and returns a carry (if it was) if we've got (value_size=3): + table[0] = 10; table[1] = 30; table[2] = 5; + and we call: + SubInt(2,1) + then it'll be: + table[0] = 10; table[1] = 30 - 2; table[2] = 5; @@ -377,19 +395,19 @@ namespace ttmath this static method subtractes one vector from the other 'ss1' is larger in size or equal to 'ss2' - ss1 points to the first (larger) vector - ss2 points to the second vector - ss1_size - size of the ss1 (and size of the result too) - ss2_size - size of the ss2 - result - is the result vector (which has size the same as ss1: ss1_size) + - ss1 points to the first (larger) vector + - ss2 points to the second vector + - ss1_size - size of the ss1 (and size of the result too) + - ss2_size - size of the ss2 + - result - is the result vector (which has size the same as ss1: ss1_size) - Example: ss1_size is 5, ss2_size is 3 - ss1: ss2: result (output): - 5 1 5-1 - 4 3 4-3 - 2 7 2-7 - 6 6-1 (the borrow from previous item) - 9 9 + Example: ss1_size is 5, ss2_size is 3 + ss1: ss2: result (output): + 5 1 5-1 + 4 3 4-3 + 2 7 2-7 + 6 6-1 (the borrow from previous item) + 9 9 return (carry): 0 of course the carry (borrow) is propagated and will be returned from the last item (this method is used by the Karatsuba multiplication algorithm) @@ -622,9 +640,11 @@ namespace ttmath bit is from <0,TTMATH_BITS_PER_UINT-1> e.g. - uint x = 100; - uint bit = SetBitInWord(x, 3); - now: x = 108 and bit = 0 + + uint x = 100; + uint bit = SetBitInWord(x, 3); + + now: x = 108 and bit = 0 */ template uint UInt::SetBitInWord(uint & value, uint bit) @@ -657,10 +677,11 @@ namespace ttmath /*! multiplication: result_high:result_low = a * b - result_high - higher word of the result - result_low - lower word of the result + - result_high - higher word of the result + - result_low - lower word of the result this methos never returns a carry + this method is used in the second version of the multiplication algorithms */ template diff --git a/ttmath/ttmathuint_x86.h b/ttmath/ttmathuint_x86.h index da41e3e..811b225 100644 --- a/ttmath/ttmathuint_x86.h +++ b/ttmath/ttmathuint_x86.h @@ -35,16 +35,10 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ - - #ifndef headerfilettmathuint_x86 #define headerfilettmathuint_x86 -#ifndef TTMATH_NOASM -#ifdef TTMATH_PLATFORM32 - - /*! \file ttmathuint_x86.h \brief template class UInt with assembler code for 32bit x86 processors @@ -53,6 +47,12 @@ */ +#ifndef TTMATH_NOASM +#ifdef TTMATH_PLATFORM32 + + + + /*! \brief a namespace for the TTMath library @@ -62,13 +62,14 @@ namespace ttmath /*! returning the string represents the currect type of the library + we have following types: - asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits) - asm_gcc_32 - with asm code designed for GCC (32 bits) - asm_vc_64 - with asm for VC (64 bit) - asm_gcc_64 - with asm for GCC (64 bit) - no_asm_32 - pure C++ version (32 bit) - without any asm code - no_asm_64 - pure C++ version (64 bit) - without any asm code + - asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits) + - asm_gcc_32 - with asm code designed for GCC (32 bits) + - asm_vc_64 - with asm for VC (64 bit) + - asm_gcc_64 - with asm for GCC (64 bit) + - no_asm_32 - pure C++ version (32 bit) - without any asm code + - no_asm_64 - pure C++ version (64 bit) - without any asm code */ template const char * UInt::LibTypeStr() @@ -210,12 +211,17 @@ namespace ttmath e.g. if we've got (value_size=3): + table[0] = 10; table[1] = 30; - table[2] = 5; + table[2] = 5; + and we call: + AddInt(2,1) + then it'll be: + table[0] = 10; table[1] = 30 + 2; table[2] = 5; @@ -314,17 +320,23 @@ namespace ttmath x1 - lower word, x2 - higher word for example if we've got value_size equal 4 and: + table[0] = 3 table[1] = 4 table[2] = 5 table[3] = 6 + then let + x1 = 10 x2 = 20 + and + index = 1 the result of this method will be: + table[0] = 3 table[1] = 4 + x1 = 14 table[2] = 5 + x2 = 25 @@ -653,12 +665,17 @@ namespace ttmath e.g. if we've got (value_size=3): + table[0] = 10; table[1] = 30; table[2] = 5; + and we call: + SubInt(2,1) + then it'll be: + table[0] = 10; table[1] = 30 - 2; table[2] = 5; @@ -1405,9 +1422,10 @@ namespace ttmath bit is from <0,31> e.g. - uint x = 100; - uint bit = SetBitInWord(x, 3); - now: x = 108 and bit = 0 + + uint x = 100; + uint bit = SetBitInWord(x, 3); + now: x = 108 and bit = 0 */ template uint UInt::SetBitInWord(uint & value, uint bit) diff --git a/ttmath/ttmathuint_x86_64.h b/ttmath/ttmathuint_x86_64.h index 2873da8..7ec501d 100644 --- a/ttmath/ttmathuint_x86_64.h +++ b/ttmath/ttmathuint_x86_64.h @@ -51,6 +51,21 @@ this file is included at the end of ttmathuint.h */ + +/*! + \file ttmathuint_x86_64_msvc.asm + \brief some asm routines for x86_64 when using Microsoft compiler + + this file should be first compiled: + - compile with debug info: ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm + - compile without debug info: ml64.exe /c ttmathuint_x86_64_msvc.asm + + this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program + + (you can use win64_assemble.bat file from ttmath subdirectory) +*/ + + #ifndef __GNUC__ #include #endif @@ -195,12 +210,17 @@ namespace ttmath if we've got (value_size=3): + table[0] = 10; table[1] = 30; - table[2] = 5; + table[2] = 5; + and we call: + AddInt(2,1) + then it'll be: + table[0] = 10; table[1] = 30 + 2; table[2] = 5; @@ -265,17 +285,23 @@ namespace ttmath x1 - lower word, x2 - higher word for example if we've got value_size equal 4 and: + table[0] = 3 table[1] = 4 table[2] = 5 table[3] = 6 + then let + x1 = 10 x2 = 20 + and + index = 1 the result of this method will be: + table[0] = 3 table[1] = 4 + x1 = 14 table[2] = 5 + x2 = 25 @@ -341,19 +367,19 @@ namespace ttmath this static method addes one vector to the other 'ss1' is larger in size or equal to 'ss2' - ss1 points to the first (larger) vector - ss2 points to the second vector - ss1_size - size of the ss1 (and size of the result too) - ss2_size - size of the ss2 - result - is the result vector (which has size the same as ss1: ss1_size) + - ss1 points to the first (larger) vector + - ss2 points to the second vector + - ss1_size - size of the ss1 (and size of the result too) + - ss2_size - size of the ss2 + - result - is the result vector (which has size the same as ss1: ss1_size) - Example: ss1_size is 5, ss2_size is 3 - ss1: ss2: result (output): - 5 1 5+1 - 4 3 4+3 - 2 7 2+7 - 6 6 - 9 9 + Example: ss1_size is 5, ss2_size is 3 + ss1: ss2: result (output): + 5 1 5+1 + 4 3 4+3 + 2 7 2+7 + 6 6 + 9 9 of course the carry is propagated and will be returned from the last item (this method is used by the Karatsuba multiplication algorithm) */ @@ -483,12 +509,17 @@ namespace ttmath ***this method is created only on a 64bit platform*** if we've got (value_size=3): + table[0] = 10; table[1] = 30; table[2] = 5; + and we call: + SubInt(2,1) + then it'll be: + table[0] = 10; table[1] = 30 - 2; table[2] = 5; @@ -545,19 +576,19 @@ namespace ttmath this static method subtractes one vector from the other 'ss1' is larger in size or equal to 'ss2' - ss1 points to the first (larger) vector - ss2 points to the second vector - ss1_size - size of the ss1 (and size of the result too) - ss2_size - size of the ss2 - result - is the result vector (which has size the same as ss1: ss1_size) + - ss1 points to the first (larger) vector + - ss2 points to the second vector + - ss1_size - size of the ss1 (and size of the result too) + - ss2_size - size of the ss2 + - result - is the result vector (which has size the same as ss1: ss1_size) - Example: ss1_size is 5, ss2_size is 3 - ss1: ss2: result (output): - 5 1 5-1 - 4 3 4-3 - 2 7 2-7 - 6 6-1 (the borrow from previous item) - 9 9 + Example: ss1_size is 5, ss2_size is 3 + ss1: ss2: result (output): + 5 1 5-1 + 4 3 4-3 + 2 7 2-7 + 6 6-1 (the borrow from previous item) + 9 9 return (carry): 0 of course the carry (borrow) is propagated and will be returned from the last item (this method is used by the Karatsuba multiplication algorithm) @@ -1029,8 +1060,8 @@ namespace ttmath /*! multiplication: result_high:result_low = a * b - result_high - higher word of the result - result_low - lower word of the result + - result_high - higher word of the result + - result_low - lower word of the result this methos never returns a carry this method is used in the second version of the multiplication algorithms diff --git a/ttmath/ttmathuint_x86_64_msvc.asm b/ttmath/ttmathuint_x86_64_msvc.asm index f8f0e14..2f23a63 100644 --- a/ttmath/ttmathuint_x86_64_msvc.asm +++ b/ttmath/ttmathuint_x86_64_msvc.asm @@ -41,6 +41,9 @@ ; this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program ; +; doxygen info is put to ttmathuint_x86_64.h file + + PUBLIC ttmath_adc_x64 PUBLIC ttmath_addindexed_x64 PUBLIC ttmath_addindexed2_x64