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
This commit is contained in:
parent
35333b1e32
commit
83b5ab7170
|
@ -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
|
||||
|
|
138
ttmath/ttmath.h
138
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<class ValueType>
|
||||
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<class ValueType>
|
||||
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<class ValueType>
|
||||
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<class ValueType>
|
||||
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<class ValueType>
|
||||
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<class ValueType>
|
||||
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<class ValueType>
|
||||
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<class ValueType>
|
||||
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<class ValueType>
|
||||
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<ValueType> 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<class ValueType>
|
||||
bool SetBernoulliNumbersMore(CGamma<ValueType> & 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<MyBig> 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<class ValueType>
|
||||
ValueType GammaFactorialHighSum(const ValueType & n, CGamma<ValueType> & 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<class ValueType>
|
||||
ValueType GammaFactorialHigh(const ValueType & n, CGamma<ValueType> & 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<class ValueType>
|
||||
ValueType GammaPlusLowIntegerInt(uint n, CGamma<ValueType> & 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<class ValueType>
|
||||
ValueType GammaPlusLow(ValueType n, CGamma<ValueType> & 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<MyBig> 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<MyBig> 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
|
||||
|
||||
|
|
|
@ -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<exp, man> 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<exp, man> 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<exp, man> 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<exp, man> & 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<exp, man> & 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<exp, man> & 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_size>
|
||||
uint Pow(UInt<pow_size> 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_size>
|
||||
uint Pow(Int<pow_size> 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<exp, man> 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<exp, man> & 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<exp, man> & 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<exp, man> & 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<exp,man> & 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<exp,man> & x, const Big<exp,man> & 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<E<2047 then V=(-1)**S * 2 ** (E-1023) * (1.F) where "1.F" is intended
|
||||
- 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<E<2047 then V=(-1)**S * 2 ** (E-1023) * (1.F) where "1.F" is intended
|
||||
to represent the binary number created by prefixing F with an implicit
|
||||
leading 1 and a binary point.
|
||||
* If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-1022) * (0.F) These are
|
||||
- If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-1022) * (0.F) These are
|
||||
"unnormalized" values.
|
||||
* If E=0 and F is zero and S is 1, then V=-0
|
||||
* If E=0 and F is zero and S is 0, then V=0
|
||||
- If E=0 and F is zero and S is 1, then V=-0
|
||||
- If E=0 and F is zero and S is 0, then V=0
|
||||
*/
|
||||
|
||||
#ifdef TTMATH_PLATFORM32
|
||||
|
@ -2811,6 +2823,7 @@ public:
|
|||
|
||||
if the value is too big:
|
||||
'result' will be +/-infinity (depending on the sign)
|
||||
|
||||
if the value is too small:
|
||||
'result' will be 0
|
||||
*/
|
||||
|
@ -2838,22 +2851,23 @@ private:
|
|||
The first bit is the sign bit, S, the next eight bits are the exponent bits, 'E',
|
||||
and the final 23 bits are the fraction 'F':
|
||||
|
||||
S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
|
||||
0 1 8 9 31
|
||||
S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
|
||||
0 1 8 9 31
|
||||
|
||||
The value V represented by the word may be determined as follows:
|
||||
|
||||
* If E=255 and F is nonzero, then V=NaN ("Not a number")
|
||||
* If E=255 and F is zero and S is 1, then V=-Infinity
|
||||
* If E=255 and F is zero and S is 0, then V=Infinity
|
||||
* If 0<E<255 then V=(-1)**S * 2 ** (E-127) * (1.F) where "1.F" is intended to represent
|
||||
the binary number created by prefixing F with an implicit leading 1 and a binary point.
|
||||
* If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-126) * (0.F) These are "unnormalized" values.
|
||||
* If E=0 and F is zero and S is 1, then V=-0
|
||||
* If E=0 and F is zero and S is 0, then V=0
|
||||
- If E=255 and F is nonzero, then V=NaN ("Not a number")
|
||||
- If E=255 and F is zero and S is 1, then V=-Infinity
|
||||
- If E=255 and F is zero and S is 0, then V=Infinity
|
||||
- If 0<E<255 then V=(-1)**S * 2 ** (E-127) * (1.F) where "1.F" is intended to represent
|
||||
the binary number created by prefixing F with an implicit leading 1 and a binary point.
|
||||
- If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-126) * (0.F) These are "unnormalized" values.
|
||||
- If E=0 and F is zero and S is 1, then V=-0
|
||||
- If E=0 and F is zero and S is 0, then V=0
|
||||
*/
|
||||
bool IsInf(float value) const
|
||||
{
|
||||
// CHECK ME
|
||||
// need testing on a 64 bit machine
|
||||
|
||||
union
|
||||
|
@ -2881,6 +2895,7 @@ public:
|
|||
|
||||
if the value is too big:
|
||||
'result' will be +/-infinity (depending on the sign)
|
||||
|
||||
if the value is too small:
|
||||
'result' will be 0
|
||||
*/
|
||||
|
@ -2898,11 +2913,12 @@ public:
|
|||
this method converts from this class into the 'float'
|
||||
|
||||
if the value is too big:
|
||||
'result' will be +/-infinity (depending on the sign)
|
||||
and the method returns 1
|
||||
- 'result' will be +/-infinity (depending on the sign)
|
||||
- and the method returns 1
|
||||
|
||||
if the value is too small:
|
||||
'result' will be 0
|
||||
and the method returns 1
|
||||
- 'result' will be 0
|
||||
- and the method returns 1
|
||||
*/
|
||||
uint ToFloat(float & result) const
|
||||
{
|
||||
|
@ -2935,11 +2951,12 @@ public:
|
|||
this method converts from this class into the 'double'
|
||||
|
||||
if the value is too big:
|
||||
'result' will be +/-infinity (depending on the sign)
|
||||
and the method returns 1
|
||||
- 'result' will be +/-infinity (depending on the sign)
|
||||
- and the method returns 1
|
||||
|
||||
if the value is too small:
|
||||
'result' will be 0
|
||||
and the method returns 1
|
||||
- 'result' will be 0
|
||||
- and the method returns 1
|
||||
*/
|
||||
uint ToDouble(double & result) const
|
||||
{
|
||||
|
@ -3672,11 +3689,10 @@ public:
|
|||
a method for converting into a string
|
||||
struct Conv is defined in ttmathtypes.h, look there for more information about parameters
|
||||
|
||||
output:
|
||||
return value:
|
||||
0 - ok and 'result' will be an object of type std::string (or std::wstring) which holds the value
|
||||
1 - if there is a carry (it shoudn't be in a normal situation - if it is that means there
|
||||
is somewhere an error in the library)
|
||||
return value:
|
||||
- 0 - ok and 'result' will be an object of type std::string (or std::wstring) which holds the value
|
||||
- 1 - if there is a carry (it shoudn't be in a normal situation - if it is that means there
|
||||
is somewhere an error in the library)
|
||||
*/
|
||||
uint ToString( std::string & result,
|
||||
uint base = 10,
|
||||
|
@ -4221,10 +4237,12 @@ private:
|
|||
|
||||
|
||||
if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
|
||||
{
|
||||
// if 'exponent' is <= than '-sint(man*TTMATH_BITS_PER_UINT)'
|
||||
// it means that we must cut the whole mantissa
|
||||
// (there'll not be any of the valid bits)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// e will be from (-man*TTMATH_BITS_PER_UINT, 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<class string_type>
|
||||
|
@ -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<exp,man> & 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<exp,man> & 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()
|
||||
{
|
||||
|
|
|
@ -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<uint value_size>
|
||||
|
@ -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<value_size> & 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<value_size> pow)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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<MyBig> 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);
|
||||
|
|
|
@ -59,24 +59,6 @@
|
|||
*/
|
||||
|
||||
|
||||
/*
|
||||
this is a simple skeleton of a program in multithreads environment:
|
||||
|
||||
#define TTMATH_MULTITHREADS
|
||||
#include<ttmath/ttmath.h>
|
||||
|
||||
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/ttmath.h>
|
||||
|
||||
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 )
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<uint value_size>
|
||||
|
@ -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<value_size> & divisor,
|
||||
UInt<value_size> * 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<value_size> & 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<value_size> & divisor, UInt<value_size> * remainder = 0)
|
||||
{
|
||||
|
@ -1764,7 +1770,7 @@ public:
|
|||
|
||||
/*!
|
||||
the first division algorithm
|
||||
radix 2
|
||||
(radix 2)
|
||||
*/
|
||||
uint Div1(const UInt<value_size> & divisor, UInt<value_size> & 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<value_size> & divisor, UInt<value_size> * 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<value_size> & divisor, UInt<value_size> & 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<value_size> & divisor, UInt<value_size> * 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<value_size> & divisor, UInt<value_size> * 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<value_size> & divisor,
|
||||
UInt<value_size> * 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<value_size> & divisor,
|
||||
UInt<value_size> * 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<value_size> & 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<value_size> 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<>
|
||||
|
|
|
@ -39,15 +39,16 @@
|
|||
#define headerfilettmathuint_noasm
|
||||
|
||||
|
||||
#ifdef TTMATH_NOASM
|
||||
|
||||
/*!
|
||||
\file ttmathuint_noasm.h
|
||||
\brief template class UInt<uint> with methods without any assembler code
|
||||
\brief template class UInt<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<uint value_size>
|
||||
const char * UInt<value_size>::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 value_size>
|
||||
uint UInt<value_size>::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<uint value_size>
|
||||
|
|
|
@ -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<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<uint value_size>
|
||||
const char * UInt<value_size>::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 value_size>
|
||||
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
||||
|
|
|
@ -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 <intrin.h>
|
||||
#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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue