fixed: UInt::SetBitInWord(uint & value, uint bit) set 1 if the bit was

equal 1 (should be set 2)
       this affected only no-asm parts - when macro TTMATH_NOASM was defined
fixed: UInt<value_size>::MulInt(uint ss2)
       there was a buffer overflow when value_size was equal 1
fixed: UInt::AddVector() and UInt::SubVector() didn't want to compile
       when macro TTMATH_NOASM was defined
added: macros:
       TTMATH_LOGC(msg, carry)
       TTMATH_VECTOR_LOG(msg, vector, len)
       TTMATH_VECTOR_LOGC(msg, carry, vector, len)
added: UInt::PrintVectorLog() for debugging purposes
changed: UInt<> class uses new log macros



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@203 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2009-10-03 01:10:08 +00:00
parent 31b8c242bd
commit a8eb29e57d
6 changed files with 561 additions and 544 deletions

781
CHANGELOG
View File

@ -1,389 +1,396 @@
Version 0.9.0 prerelease (2009.09.20): Version 0.9.0 prerelease (2009.10.03):
* fixed: Big::operator>>(std::istream&, Big<> &) didn't recognize values * fixed: Big::operator>>(std::istream&, Big<> &) didn't recognize values
in scientific mode (with 'e' character) in scientific mode (with 'e' character)
* added: support for wide characters (wchar_t, std::wstring) * fixed: UInt::SetBitInWord(uint & value, uint bit) set 1 if the bit was
* added: Big::IsInteger() equal 1 (should be set 2)
returns true if the value is integer (without fraction) this affected only no-asm parts - when macro TTMATH_NOASM was defined
(NaN flag is not checked) * fixed: UInt<value_size>::MulInt(uint ss2)
* added: global Gamma() function there was a buffer overflow when value_size was equal 1
* added: gamma() function to the parser * fixed: UInt::AddVector() and UInt::SubVector() didn't want to compile
* added: CGamma<ValueType> class when macro TTMATH_NOASM was defined
is used with Gamma() and Factorial() in multithreaded environment * added: support for wide characters (wchar_t, std::wstring)
* added: multithread support for Big<> class * added: Big::IsInteger()
you should compile with TTMATH_MULTITHREADS returns true if the value is integer (without fraction)
and use TTMATH_MULTITHREADS_HELPER macro somewhere in your *.cpp file (NaN flag is not checked)
* added: Big::AboutEqual(const Big<exp,man> & ss2, int nBitsToIgnore) * added: global Gamma() function
Big::AboutEqualWithoutSign(const Big<exp,man> & ss2, int nBitsToIgnore) * added: gamma() function to the parser
the last nBitsToIgnore bits from mantissas will be skipped when comparing * added: CGamma<ValueType> class
* added: x86_64 asm code for Microsoft Visual compiler is used with Gamma() and Factorial() in multithreaded environment
file: ttmathuint_x86_64_msvc.asm * added: multithread support for Big<> class
(this file should be compiled first because MS VC doesn't support inline assembler in x86_64 mode) you should compile with TTMATH_MULTITHREADS
* added: flag TTMATH_BIG_ZERO to Big<> class and use TTMATH_MULTITHREADS_HELPER macro somewhere in your *.cpp file
if this flag is set then there is a value zero * added: Big::AboutEqual(const Big<exp,man> & ss2, int nBitsToIgnore)
Big::IsZero() is faster now Big::AboutEqualWithoutSign(const Big<exp,man> & ss2, int nBitsToIgnore)
* added: Big::ClearInfoBit(unsigned char) the last nBitsToIgnore bits from mantissas will be skipped when comparing
Big::SetInfoBit(unsigned char) * added: x86_64 asm code for Microsoft Visual compiler
Big::IsInfoBit(unsigned char) file: ttmathuint_x86_64_msvc.asm
some methods for manipulating the info flags (this file should be compiled first because MS VC doesn't support inline assembler in x86_64 mode)
* added: macro: TTMATH_BITS(min_bits) * added: flag TTMATH_BIG_ZERO to Big<> class
if this flag is set then there is a value zero
Big::IsZero() is faster now
* added: Big::ClearInfoBit(unsigned char)
Big::SetInfoBit(unsigned char)
Big::IsInfoBit(unsigned char)
some methods for manipulating the info flags
* added: macro: TTMATH_BITS(min_bits)
which returns the number of machine words which returns the number of machine words
capable to hold min_bits bits capable to hold min_bits bits
* changed: Factorial() is using the Gamma() function now * changed: Factorial() is using the Gamma() function now
* changed: Big::Div(ss2) * changed: Big::Div(ss2)
Big::Mod(ss2) Big::Mod(ss2)
they return 2 when ss2 is zero they return 2 when ss2 is zero
previously returned 1 previously returned 1
* removed: Parser<>::SetFactorialMax() method * removed: Parser<>::SetFactorialMax() method
the factorial() is such a fast now that we don't need the method longer the factorial() is such a fast now that we don't need the method longer
* removed: ErrorCode::err_too_big_factorial * removed: ErrorCode::err_too_big_factorial
Version 0.8.5 (2009.06.16): Version 0.8.5 (2009.06.16):
* fixed: Big::Mod(x) didn't correctly return a carry * fixed: Big::Mod(x) didn't correctly return a carry
and the result was sometimes very big (even greater than x) and the result was sometimes very big (even greater than x)
* fixed: global function Mod(x) didn't set an ErrorCode object * fixed: global function Mod(x) didn't set an ErrorCode object
* fixed: global function Round() didn't test a carry * fixed: global function Round() didn't test a carry
now it sets ErrorCode object now it sets ErrorCode object
* changed: function Sin(x) to Sin(x, ErrorCode * err=0) * changed: function Sin(x) to Sin(x, ErrorCode * err=0)
when x was very big the function returns zero when x was very big the function returns zero
now it sets ErrorCode object to err_overflow now it sets ErrorCode object to err_overflow
and the result has a NaN flag set and the result has a NaN flag set
the same is to Cos() function the same is to Cos() function
* changed: PrepareSin(x) is using Big::Mod() now when reducing 2PI period * changed: PrepareSin(x) is using Big::Mod() now when reducing 2PI period
should be a little accurate especially on a very big 'x' should be a little accurate especially on a very big 'x'
* changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100) * changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100) void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig() those methods by default use MulFastest() and MulFastestBig()
* changed: changed a little Mul2Big() to cooperate with Mul3Big() * changed: changed a little Mul2Big() to cooperate with Mul3Big()
* added: uint UInt::Mul3(const UInt<value_size> & ss2) * added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result) void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication, a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big() zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE) (measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
* added: uint MulFastest(const UInt<value_size> & ss2) * added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result) void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm those methods are trying to select the fastest multiplication algorithm
* added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result) * added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result) uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm those methods are used by the Karatsuba multiplication algorithm
* added: to Big<> class: support for NaN flag (Not a Number) * added: to Big<> class: support for NaN flag (Not a Number)
bool Big::IsNan() - returns true if the NaN flag is set bool Big::IsNan() - returns true if the NaN flag is set
void Big::SetNan() - sets the NaN flag void Big::SetNan() - sets the NaN flag
The NaN flag is set by default after creating an object: The NaN flag is set by default after creating an object:
Big<1, 2> a; // NaN is set (it means the object has not a valid number) Big<1, 2> a; // NaN is set (it means the object has not a valid number)
std::cout << a; // cout gives "NaN" std::cout << a; // cout gives "NaN"
a = 123; // now NaN is not set a = 123; // now NaN is not set
std::cout << a; // cout gives "123" std::cout << a; // cout gives "123"
The NaN is set if there was a carry during calculations The NaN is set if there was a carry during calculations
a.Mul(very_big_value); // a will have a NaN set a.Mul(very_big_value); // a will have a NaN set
The NaN is set if an argument is NaN too The NaN is set if an argument is NaN too
b.SetNan(); b.SetNan();
a.Add(b); // a will have NaN because b has NaN too a.Add(b); // a will have NaN because b has NaN too
If you try to do something on a NaN object, the result is a NaN too If you try to do something on a NaN object, the result is a NaN too
a.SetNan(); a.SetNan();
a.Add(2); // a is still a NaN a.Add(2); // a is still a NaN
The NaN is set if you use incorrect arguments The NaN is set if you use incorrect arguments
a.Ln(-10); // a will have the NaN flag a.Ln(-10); // a will have the NaN flag
The only way to clear the NaN flag is to assign a correct value or other correct object, The only way to clear the NaN flag is to assign a correct value or other correct object,
supposing 'a' has NaN flag, to remove the flag you can either: supposing 'a' has NaN flag, to remove the flag you can either:
a = 10; a = 10;
a.FromInt(30); a.FromInt(30);
a.SetOne(); a.SetOne();
a.FromBig(other_object_without_nan); a.FromBig(other_object_without_nan);
etc. etc.
Version 0.8.4 (2009.05.08): Version 0.8.4 (2009.05.08):
* fixed: UInt::DivInt() didn't check whether the divisor is zero * fixed: UInt::DivInt() didn't check whether the divisor is zero
there was a hardware interruption when the divisor was zero there was a hardware interruption when the divisor was zero
(now the method returns one) (now the method returns one)
* fixed: the problem with GCC optimization on x86_64 * fixed: the problem with GCC optimization on x86_64
sometimes when using -O2 or -O3 GCC doesn't set correctly sometimes when using -O2 or -O3 GCC doesn't set correctly
the stack pointer (actually the stack is used for other things) the stack pointer (actually the stack is used for other things)
and you can't use instructions like push/pop in assembler code. and you can't use instructions like push/pop in assembler code.
All the asm code in x86_64 have been rewritten, now instructions All the asm code in x86_64 have been rewritten, now instructions
push/pop are not used, other thing which have access to stack push/pop are not used, other thing which have access to stack
(like "m" (mask) constraints in Rcl2 and Rcr2) have also gone away, (like "m" (mask) constraints in Rcl2 and Rcr2) have also gone away,
now the library works well with -O2 and -O3 and the asm code now the library works well with -O2 and -O3 and the asm code
is a little faster is a little faster
* added: UInt::PrintLog(const char * msg, std::ostream & output) * added: UInt::PrintLog(const char * msg, std::ostream & output)
used (for debugging purposes) by macro TTMATH_LOG(msg) used (for debugging purposes) by macro TTMATH_LOG(msg)
(it is used in nearly all methods in UInt class) (it is used in nearly all methods in UInt class)
* added: macro TTMATH_DEBUG_LOG: when defined then TTMATH_LOG() * added: macro TTMATH_DEBUG_LOG: when defined then TTMATH_LOG()
put some debug information (to std::cout) put some debug information (to std::cout)
* added: ttmathuint_x86.h, ttmathuint_x86_64.h, ttmathuint_noasm.h, * added: ttmathuint_x86.h, ttmathuint_x86_64.h, ttmathuint_noasm.h,
all the methods which are using assembler code have been all the methods which are using assembler code have been
rewritten to no-asm forms, now we have: rewritten to no-asm forms, now we have:
1. asm for x86 file: ttmathuint_x86.h 1. asm for x86 file: ttmathuint_x86.h
2. asm for x86_64 file: ttmathuint_x86_64.h 2. asm for x86_64 file: ttmathuint_x86_64.h
3. no asm file: ttmathuint_noasm.h 3. no asm file: ttmathuint_noasm.h
(it's used when macro TTMATH_NOASM is defined) (it's used when macro TTMATH_NOASM is defined)
The third form can be used on x86 and x86_64 as well and The third form can be used on x86 and x86_64 as well and
on other platforms with a little effort. on other platforms with a little effort.
Version 0.8.3 (2009.04.06): Version 0.8.3 (2009.04.06):
* fixed: RclMoveAllWords() and RcrMoveAllWords() sometimes didn't return * fixed: RclMoveAllWords() and RcrMoveAllWords() sometimes didn't return
the proper carry, (when 'bits' was greater than or equal to 'value_size') the proper carry, (when 'bits' was greater than or equal to 'value_size')
this had impact on Rcl() and Rcr(), they also returned the wrong carry this had impact on Rcl() and Rcr(), they also returned the wrong carry
* fixed: UInt::Div() didn't return a correct result when the divisor was equal 1 * fixed: UInt::Div() didn't return a correct result when the divisor was equal 1
there was an error in UInt::DivInt() - when the divisor was 1 it returned there was an error in UInt::DivInt() - when the divisor was 1 it returned
zero and the carry was set zero and the carry was set
* fixed: there was a TTMATH_REREFENCE_ASSERT error in Big::PowUInt() caused by: start.Mul(start) * fixed: there was a TTMATH_REREFENCE_ASSERT error in Big::PowUInt() caused by: start.Mul(start)
* fixed: Big::Add incorrectly rounded 'this' when both exponents were equal * fixed: Big::Add incorrectly rounded 'this' when both exponents were equal
it caused that sometimes when adding a zero the result has changed it caused that sometimes when adding a zero the result has changed
this had impact among other things on FromString() method this had impact among other things on FromString() method
"0,8" had different binary representation from "0,80" "0,8" had different binary representation from "0,80"
* fixed: template Big::FromBig(const Big<another_exp, another_man> & another) * fixed: template Big::FromBig(const Big<another_exp, another_man> & another)
didn't correctly set the exponent (when the mantisses had different size - didn't correctly set the exponent (when the mantisses had different size -
when 'man' was different from 'another_man') when 'man' was different from 'another_man')
this had impact on operator= too this had impact on operator= too
sample: sample:
Big<2,3> a = 100; Big<2,3> a = 100;
Big<3,5> b; Big<3,5> b;
b = a; // b had a wrong value b = a; // b had a wrong value
* fixed: Big::Pow(const Big<exp, man> & pow) * fixed: Big::Pow(const Big<exp, man> & pow)
it's using PowInt() only when pow.exponent is in range (-man*TTMATH_BITS_PER_UINT; 0] it's using PowInt() only when pow.exponent is in range (-man*TTMATH_BITS_PER_UINT; 0]
previously the powering 'hung' on an input like this: "(1+ 1e-10000) ^ 10e100000000" previously the powering 'hung' on an input like this: "(1+ 1e-10000) ^ 10e100000000"
(there was 10e100000000 iterations in PowInt()) (there was 10e100000000 iterations in PowInt())
* fixed: in function DegToRad(const ValueType & x, ErrorCode * err = 0) it is better * fixed: in function DegToRad(const ValueType & x, ErrorCode * err = 0) it is better
to make division first and then mutliplication -- the result is more to make division first and then mutliplication -- the result is more
accurate especially when x is: 90,180,270 or 360 accurate especially when x is: 90,180,270 or 360
* fixed: the parser didn't correctly treat operators for changing the base * fixed: the parser didn't correctly treat operators for changing the base
(radix) -- operators '#' and '&', e.g.: (radix) -- operators '#' and '&', e.g.:
'#sin(1)' was equal '0' -- there was a zero from '#' and then '#sin(1)' was equal '0' -- there was a zero from '#' and then
it was multipied by 'sin(1)' it was multipied by 'sin(1)'
the parser didn't check whether Big::FromString() has actually the parser didn't check whether Big::FromString() has actually
read a proper value -- the method Big::FromString() didn't have read a proper value -- the method Big::FromString() didn't have
something to report such a situation something to report such a situation
* fixed: Big::FromString() when the base is 10, the method reads the scientific * fixed: Big::FromString() when the base is 10, the method reads the scientific
part only if such a part it correctly supplied, e.g: part only if such a part it correctly supplied, e.g:
'1234e10', '1234e+10', '1234e-5' '1234e10', '1234e+10', '1234e-5'
previous '1234e' was treated as: '1234e0' (now parsing stops on 'e' and previous '1234e' was treated as: '1234e0' (now parsing stops on 'e' and
the 'e' can be parsed by other parsers, e.g. the mathematical the 'e' can be parsed by other parsers, e.g. the mathematical
parser -- now in the parser would be: '1234e' = '1234 * e' = '3354,3597...' ) parser -- now in the parser would be: '1234e' = '1234 * e' = '3354,3597...' )
* changed: renamed: Big::PowUInt(UInt<pow_size> pow) -> Big::Pow(UInt<pow_size> pow) * changed: renamed: Big::PowUInt(UInt<pow_size> pow) -> Big::Pow(UInt<pow_size> pow)
it returns 2 when there is: 0^0 it returns 2 when there is: 0^0
* changed: renamed: Big::PowInt(Int<pow_size> pow) -> Big::Pow(Int<pow_size> pow) * changed: renamed: Big::PowInt(Int<pow_size> pow) -> Big::Pow(Int<pow_size> pow)
it returns 2 when there is: 0^0 or 0^(-something) it returns 2 when there is: 0^0 or 0^(-something)
* changed: renamed: Big::PowBUInt() -> PowUInt(), Big::PowBInt() -> Big::PowInt() * changed: renamed: Big::PowBUInt() -> PowUInt(), Big::PowBInt() -> Big::PowInt()
they return 2 when the arguments are incorrect (like above) they return 2 when the arguments are incorrect (like above)
* changed: UInt::SetBitInWord(uint & value, uint bit) is taking the first argument by a reference now, * changed: UInt::SetBitInWord(uint & value, uint bit) is taking the first argument by a reference now,
the specific bit is set in the 'value' and the method returns the last state of the bit (zero or one) the specific bit is set in the 'value' and the method returns the last state of the bit (zero or one)
* changed: UInt::SetBit(uint bit_index) - it's using TTMATH_ASSERT now * changed: UInt::SetBit(uint bit_index) - it's using TTMATH_ASSERT now
* changed: the size of built-in variables (constants) in ttmathbig.h * changed: the size of built-in variables (constants) in ttmathbig.h
now they consist of 256 32bit words now they consist of 256 32bit words
macro TTMATH_BUILTIN_VARIABLES_SIZE is equal: 256u on a 32bit platform and 128ul on a 64bit platform macro TTMATH_BUILTIN_VARIABLES_SIZE is equal: 256u on a 32bit platform and 128ul on a 64bit platform
* changed: the asm code in ttmathuint.h and ttmathuint64.h has been completely rewritten * changed: the asm code in ttmathuint.h and ttmathuint64.h has been completely rewritten
now UInt<> is faster about 15-30% than UInt<> from 0.8.2 now UInt<> is faster about 15-30% than UInt<> from 0.8.2
this has impact on Big<> too - it's faster about 10% now this has impact on Big<> too - it's faster about 10% now
* changed: in the parser: the form with operators '#' and '&' is as follows: * changed: in the parser: the form with operators '#' and '&' is as follows:
[-|+][#|&]numeric_value [-|+][#|&]numeric_value
previous was: [-|+][#|&][-|+]numeric_value previous was: [-|+][#|&][-|+]numeric_value
* changed: in the parser: the short form of multiplication has the same * changed: in the parser: the short form of multiplication has the same
priority as the normal multiplication, e.g.: priority as the normal multiplication, e.g.:
'2x^3' = 2 * (x^3) '2x^3' = 2 * (x^3)
previous the priority was greater than powering priority previous the priority was greater than powering priority
previous: '2x^3' = (2*x) ^ 3 previous: '2x^3' = (2*x) ^ 3
* added: UInt::GetBit(uint bit_index) - returning the state of the specific bit * added: UInt::GetBit(uint bit_index) - returning the state of the specific bit
* added: Big::operator=(double) and Big::Big(double) * added: Big::operator=(double) and Big::Big(double)
* added: UInt::Pow(UInt<value_size> pow) and Int::Pow(Int<value_size> pow) * added: UInt::Pow(UInt<value_size> pow) and Int::Pow(Int<value_size> pow)
* added: global template functions in ttmath.h: * added: global template functions in ttmath.h:
ValueType GradToRad(const ValueType & x, ErrorCode * err = 0) ValueType GradToRad(const ValueType & x, ErrorCode * err = 0)
ValueType RadToGrad(const ValueType & x, ErrorCode * err = 0) ValueType RadToGrad(const ValueType & x, ErrorCode * err = 0)
ValueType DegToGrad(const ValueType & x, ErrorCode * err = 0) ValueType DegToGrad(const ValueType & x, ErrorCode * err = 0)
ValueType DegToGrad(const ValueType & d, const ValueType & m, ValueType DegToGrad(const ValueType & d, const ValueType & m,
const ValueType & s, ErrorCode * err = 0) const ValueType & s, ErrorCode * err = 0)
ValueType GradToDeg(const ValueType & x, ErrorCode * err = 0) ValueType GradToDeg(const ValueType & x, ErrorCode * err = 0)
* added: Parser::SetDegRadGrad(int angle) - 0 deg, 1 rad (default), 2 grad * added: Parser::SetDegRadGrad(int angle) - 0 deg, 1 rad (default), 2 grad
this affects following functions (in the parser only): sin, cos, tan, cot, this affects following functions (in the parser only): sin, cos, tan, cot,
asin, acos, atan, acot asin, acos, atan, acot
* added: functions to the parser: gradtorad(grad), radtograd(rad), degtograd(deg), * added: functions to the parser: gradtorad(grad), radtograd(rad), degtograd(deg),
degtograd(d,m,s), gradtodeg(grad) degtograd(d,m,s), gradtodeg(grad)
* added: UInt::FromString, added a parametr 'after_source' * added: UInt::FromString, added a parametr 'after_source'
which is pointing at the end of the parsed string which is pointing at the end of the parsed string
* added: Int::FromString(): parameter 'const char ** after_source = 0' * added: Int::FromString(): parameter 'const char ** after_source = 0'
if exists it's pointing at the end of the parsed string if exists it's pointing at the end of the parsed string
* added: to UInt::FromString(), Int::FromString(), Big::FromString(): * added: to UInt::FromString(), Int::FromString(), Big::FromString():
parameter 'bool * value_read = 0' - (if exists) tells parameter 'bool * value_read = 0' - (if exists) tells
whether something has actually been read (at least one digit) whether something has actually been read (at least one digit)
* added: Objects::IsDefined(const std::string & name) * added: Objects::IsDefined(const std::string & name)
returning true if such an object is defined returning true if such an object is defined
* removed: Big::FromString() this method doesn't longer recognize operators * removed: Big::FromString() this method doesn't longer recognize operators
for changing the base ('#' and '&') for changing the base ('#' and '&')
Version 0.8.2 (2008.06.18): Version 0.8.2 (2008.06.18):
* added: UInt::BitNot2() this method has been proposed by * added: UInt::BitNot2() this method has been proposed by
Arek <kmicicc AnTispam users.sourceforge.net> Arek <kmicicc AnTispam users.sourceforge.net>
* changed: Int::FromInt(const Int<argument_size> & p), * changed: Int::FromInt(const Int<argument_size> & p),
Int::FromInt(sint value) (it returns zero now) Int::FromInt(sint value) (it returns zero now)
Int::operator=(uint i) Int::operator=(uint i)
Int::Int(uint i) Int::Int(uint i)
* added: Int::FromUInt(const UInt<argument_size> & p), * added: Int::FromUInt(const UInt<argument_size> & p),
Int::FromUInt(uint value) Int::FromUInt(uint value)
and appropriate constructors and assignment and appropriate constructors and assignment
operators as well operators as well
* changed: Big::FromInt(Int<int_size> value), * changed: Big::FromInt(Int<int_size> value),
* added: Big::FromUInt(UInt<int_size> value), * added: Big::FromUInt(UInt<int_size> value),
Big::operator=(const UInt<int_size> & value) Big::operator=(const UInt<int_size> & value)
Big::Big(const UInt<int_size> & value) Big::Big(const UInt<int_size> & value)
* changed: the parser is allowed to recognize values which * changed: the parser is allowed to recognize values which
begin with a dot, e.g '.5' is treated as '0.5' begin with a dot, e.g '.5' is treated as '0.5'
* added: a method Big::FromDouble(double) which converts from * added: a method Big::FromDouble(double) which converts from
standard double into a Big standard double into a Big
* added: uint Big::ToDouble(double&) - converting into double * added: uint Big::ToDouble(double&) - converting into double
* added: Big::FromBig() and an operator= and a contructor * added: Big::FromBig() and an operator= and a contructor
for converting from another kind of a Big class for converting from another kind of a Big class
* added: to the parser: avg(), sum() * added: to the parser: avg(), sum()
* added: 'decimal_point' parameter into Big::ToString(...) * added: 'decimal_point' parameter into Big::ToString(...)
* fixed: Big::operator>> didn't use TTMATH_COMMA_CHARACTER_2 macro * fixed: Big::operator>> didn't use TTMATH_COMMA_CHARACTER_2 macro
* added: a short form of multiplication (without the '*' character) * added: a short form of multiplication (without the '*' character)
e.g. '5y', (it's used only if the second parameter e.g. '5y', (it's used only if the second parameter
is a variable or function) is a variable or function)
* changed: variables and functions are case-sensitive now * changed: variables and functions are case-sensitive now
* added: variables and functions can have underline characters * added: variables and functions can have underline characters
in their names in their names
* changed: 'max_digit_after_comma' in Big::ToString() * changed: 'max_digit_after_comma' in Big::ToString()
remove the -2 state remove the -2 state
* added: 'remove_trailing_zeroes' in Big::ToString() * added: 'remove_trailing_zeroes' in Big::ToString()
it's either true or false it's either true or false
* fixed/changed: the way of using Big::SetSign() * fixed/changed: the way of using Big::SetSign()
the method do not check whether there is a zero or not now the method do not check whether there is a zero or not now
(even if there's a zero the method can set a sign bit) (even if there's a zero the method can set a sign bit)
I changed this due to some prior errors I changed this due to some prior errors
(errors corrected in revision 17, 49 and 58) (errors corrected in revision 17, 49 and 58)
Version 0.8.1 (2007.04.17): Version 0.8.1 (2007.04.17):
* fixed: Big::PowFrac(..) didn't return a correct error code * fixed: Big::PowFrac(..) didn't return a correct error code
(when 'this' was negative) (when 'this' was negative)
* added: Root(x; index) (and to the parser as well) * added: Root(x; index) (and to the parser as well)
* added: macro: TTMATH_PRERELEASE_VER (can be either zero or one) * added: macro: TTMATH_PRERELEASE_VER (can be either zero or one)
* added: UInt::MulInt(int, UInt<int another_size>::&) * added: UInt::MulInt(int, UInt<int another_size>::&)
* added: Big::MulUInt(uint) * added: Big::MulUInt(uint)
* changed: Big::MulInt(sint) * changed: Big::MulInt(sint)
* added: Big::ToUInt(uint &) * added: Big::ToUInt(uint &)
* changed: Big::ToInt(sint&) * changed: Big::ToInt(sint&)
* changed: Factorial() it uses Big::MulUInt() at the beginning * changed: Factorial() it uses Big::MulUInt() at the beginning
(faster now especially more on a 32bit platform) (faster now especially more on a 32bit platform)
* added: doxygen.cfg for generating a documentation from the doxygen * added: doxygen.cfg for generating a documentation from the doxygen
* changed: UInt::Rcl(uint c=0) and UInt::Rcr(uint c=0) into * changed: UInt::Rcl(uint c=0) and UInt::Rcr(uint c=0) into
UInt::Rcl2(uint bits, uint c) and UInt::Rcr2(uint bits, uint c) UInt::Rcl2(uint bits, uint c) and UInt::Rcr2(uint bits, uint c)
now they can move more than one bit and they are only private now they can move more than one bit and they are only private
* fixed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c) * fixed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c)
didn't correctly return a carry if the 'bits' were equal didn't correctly return a carry if the 'bits' were equal
to 'value_size*TTMATH_BITS_PER_UINT' to 'value_size*TTMATH_BITS_PER_UINT'
* changed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c) * changed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c)
into UInt::Rcl(uint bits, uint c=0) and into UInt::Rcl(uint bits, uint c=0) and
UInt::Rcr(uint bits, uint c=0) UInt::Rcr(uint bits, uint c=0)
they are faster now when the bits is greater than a half of they are faster now when the bits is greater than a half of
the TTMATH_BITS_PER_UINT the TTMATH_BITS_PER_UINT
* changed: UInt::CompensationToLeft() it's faster now * changed: UInt::CompensationToLeft() it's faster now
* changed: more small changes where there were UInt::Rcl(uint c=0) and * changed: more small changes where there were UInt::Rcl(uint c=0) and
UInt::Rcr(uint c=0) used UInt::Rcr(uint c=0) used
* changed: as the Big type uses UInt::Rcl() and UInt::Rcr() a lot then * changed: as the Big type uses UInt::Rcl() and UInt::Rcr() a lot then
it is much faster now (about 5-25%) it is much faster now (about 5-25%)
* added: ASinh(), ACosh(), ATanh() /ATgh()/, ACoth() /ACtgh()/ * added: ASinh(), ACosh(), ATanh() /ATgh()/, ACoth() /ACtgh()/
and to the parser as well and to the parser as well
* added: UInt::BitAnd(), UInt::BitOr(), UInt::BitXor(), UInt::BitNot(), * added: UInt::BitAnd(), UInt::BitOr(), UInt::BitXor(), UInt::BitNot(),
Big::BitAnd(), Big::BitOr(), Big::BitXor() Big::BitAnd(), Big::BitOr(), Big::BitXor()
* added: to the parser: bitand(), bitor(), bitxor() * added: to the parser: bitand(), bitor(), bitxor()
/band(), bor(), bxor()/ /band(), bor(), bxor()/
* changed: the way of parsing operators in the mathematical parser * changed: the way of parsing operators in the mathematical parser
(the parser is not too much greedy now) (the parser is not too much greedy now)
Version 0.8.0 (2007.03.28): Version 0.8.0 (2007.03.28):
* added: into the parser: SetFactorialMax() * added: into the parser: SetFactorialMax()
* added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec), * added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x), RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/ Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
* changed: class Objects in ttmathobjects.h has been completely rewritten, * changed: class Objects in ttmathobjects.h has been completely rewritten,
we can change the names of user-defined variables or functions, we can change the names of user-defined variables or functions,
and the names are case-sensitive now and the names are case-sensitive now
* added: class History which is used in functions which take a lot of time * added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x) during calculating e.g. Factorial(x)
* added: Tg(x) a wrapper for Tan(x) * added: Tg(x) a wrapper for Tan(x)
* changed: CTan(x) is Cot(x) now * changed: CTan(x) is Cot(x) now
* added: Ctg(x) a wrapper for Cot(x) * added: Ctg(x) a wrapper for Cot(x)
* added: ATg(x) a wrapper for ATan(x) * added: ATg(x) a wrapper for ATan(x)
* changed: ACTan(x) is ACot(x) now * changed: ACTan(x) is ACot(x) now
* added: ACtg(x) a wrapper for ACot(x) * added: ACtg(x) a wrapper for ACot(x)
* added: UInt::PrintTable() (for debugging etc.) * added: UInt::PrintTable() (for debugging etc.)
* changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have * changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have
been rewritten, now they have 128 32bit words (it's about been rewritten, now they have 128 32bit words (it's about
1232 valid decimal digits) 1232 valid decimal digits)
* fixed: previous values from Big::SetPi() Big::SetE() and * fixed: previous values from Big::SetPi() Big::SetE() and
Big::SetLn2() were not too much accurate (last 2-3 words were wrong) Big::SetLn2() were not too much accurate (last 2-3 words were wrong)
* added: Big::SetLn10() (128 32bit words as well) * added: Big::SetLn10() (128 32bit words as well)
* added: macro TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on * added: macro TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on
32bit platforms and 64ul on 64bit platforms (128/2=64) 32bit platforms and 64ul on 64bit platforms (128/2=64)
* added: macros TTMATH_PLATFORM32 and TTMATH_PLATFORM64 * added: macros TTMATH_PLATFORM32 and TTMATH_PLATFORM64
* changed: a small optimisation in UInt::Mul2Big() * changed: a small optimisation in UInt::Mul2Big()
* added: at the end of ttmath.h: #include "ttmathparser.h" * added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser with ttmath.h even if he uses the parser
* added: to samples: big.cpp, parser.cpp * added: to samples: big.cpp, parser.cpp
* added/changes/fixed: in copy-constructors and operators= in Int, * added/changes/fixed: in copy-constructors and operators= in Int,
Uint and Big (more info in the commit log) Uint and Big (more info in the commit log)
* renamed: Big::SetDotOne() into Big::Set05() * renamed: Big::SetDotOne() into Big::Set05()
* changes: a few small optimisations in Big * changes: a few small optimisations in Big
* deleted: the word 'virtual' from destructors: UInt, Int, Big * deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for (types in this library are not projected to be base-classes for
another ones derived from them) another ones derived from them)
* and more small changes (look at the commit log) * and more small changes (look at the commit log)
Version 0.7.2 (2007.03.09): Version 0.7.2 (2007.03.09):
* added: Big::Mod - the remainder from a division * added: Big::Mod - the remainder from a division
* added: Big::Sgn - the 'sign' from the value (-1,0,1) * added: Big::Sgn - the 'sign' from the value (-1,0,1)
* added: global functions Mod and Sgn too * added: global functions Mod and Sgn too
* added: checking whether a user gives a correct value of a variable or function * added: checking whether a user gives a correct value of a variable or function
(user-defined variables/functions in the mathematical parser) (user-defined variables/functions in the mathematical parser)
* added: into the parser: logical operators: > < >= <= == != && || * added: into the parser: logical operators: > < >= <= == != && ||
* added: into the parser: logical functions: and() or() not() if() * added: into the parser: logical functions: and() or() not() if()
* added: ErrorCode::err_unknown_operator when the parser couldn't read an operator * added: ErrorCode::err_unknown_operator when the parser couldn't read an operator
Version 0.7.1 (2007.02.27): Version 0.7.1 (2007.02.27):
* fixed: the error 'overflow during printing' which was caused * fixed: the error 'overflow during printing' which was caused
by Big::FromInt(Int<int_size> value) (the sign has to be set at the end) by Big::FromInt(Int<int_size> value) (the sign has to be set at the end)
* fixed: many small errors * fixed: many small errors
* added: ATan (arctan), ACTan (arc ctan) functions * added: ATan (arctan), ACTan (arc ctan) functions
Version 0.7.0 (2007.02.24): Version 0.7.0 (2007.02.24):
* finished: support for 64bit platforms * finished: support for 64bit platforms
* added: ASin (arcsin), ACos (arccos) functions * added: ASin (arcsin), ACos (arccos) functions
Version 0.6.4 (2007.01.29): Version 0.6.4 (2007.01.29):
* fixed: the problem with a sign in the mathematical parser /-(1) was 1/ * fixed: the problem with a sign in the mathematical parser /-(1) was 1/
* added: UInt::AddInt and UInt::SubInt * added: UInt::AddInt and UInt::SubInt
* changed: UInt::AddOne and UInt::SubOne (much faster now) * changed: UInt::AddOne and UInt::SubOne (much faster now)
* added: UInt::SetBitInWord * added: UInt::SetBitInWord
* changed: UInt::SetBit (much faster now) * changed: UInt::SetBit (much faster now)
UInt::AddTwoUints renamed to UInt::AddTwoInts UInt::AddTwoUints renamed to UInt::AddTwoInts
UInt::FindLeadingBit32 renamed to UInt::FindLeadingBitInWord UInt::FindLeadingBit32 renamed to UInt::FindLeadingBitInWord
UInt::Mul64 renamed to UInt::MulTwoWords UInt::Mul64 renamed to UInt::MulTwoWords
UInt::Div64 renamed to UInt::DivTwoWords UInt::Div64 renamed to UInt::DivTwoWords
* added: UInt::SetBitInWord * added: UInt::SetBitInWord
* and more small changes in UInt type * and more small changes in UInt type
* start adding support for Amd64 (not finished yet) (added ttmathuint64.h) * start adding support for Amd64 (not finished yet) (added ttmathuint64.h)
Version 0.6.3 (2007.01.22): Version 0.6.3 (2007.01.22):
* changed: position of arguments (x and base) in logarithm functions are swapped * changed: position of arguments (x and base) in logarithm functions are swapped
* changed: it's possible to use any multiplication algorithms in the same time * changed: it's possible to use any multiplication algorithms in the same time
(macros UINT_MUL_VERSION_'X' have gone) (macros UINT_MUL_VERSION_'X' have gone)
* added: ExceptionInfo, ReferenceError and RuntimeError classes * added: ExceptionInfo, ReferenceError and RuntimeError classes
* changed: the mess in macros has been cleaned up * changed: the mess in macros has been cleaned up
* added: TTMATH_RELEASE macro * added: TTMATH_RELEASE macro
Version 0.6.2 (2007.01.10): Version 0.6.2 (2007.01.10):
* added: New division algorithm (radix b) where b is 2^32 * added: New division algorithm (radix b) where b is 2^32

View File

@ -491,9 +491,15 @@ namespace ttmath
#ifdef TTMATH_DEBUG_LOG #ifdef TTMATH_DEBUG_LOG
#define TTMATH_LOG(msg) PrintLog(msg, std::cout); #define TTMATH_LOG(msg) PrintLog(msg, std::cout);
#define TTMATH_LOGC(msg, carry) PrintLog(msg, carry, std::cout);
#define TTMATH_VECTOR_LOG(msg, vector, len) PrintVectorLog(msg, std::cout, vector, len);
#define TTMATH_VECTOR_LOGC(msg, carry, vector, len) PrintVectorLog(msg, carry, std::cout, vector, len);
#else #else
#define TTMATH_LOG(msg) #define TTMATH_LOG(msg)
#define TTMATH_LOGC(msg, carry)
#define TTMATH_VECTOR_LOG(msg, vector, len)
#define TTMATH_VECTOR_LOGC(msg, carry, vector, len)
#endif #endif

View File

@ -81,6 +81,12 @@ public:
uint table[value_size]; uint table[value_size];
/*!
some methods used for debugging purposes
*/
/*! /*!
this method is only for debugging purposes or when we want to make this method is only for debugging purposes or when we want to make
a table of a variable (constant) in ttmathbig.h a table of a variable (constant) in ttmathbig.h
@ -122,13 +128,48 @@ public:
} }
/*!
this method is used when macro TTMATH_DEBUG_LOG is defined
*/
template<class char_type, class ostream_type> template<class char_type, class ostream_type>
void PrintLog(const char_type * msg, ostream_type & output) const static void PrintVectorLog(const char_type * msg, ostream_type & output, const uint * vector, uint vector_len)
{ {
output << msg << std::endl; output << msg << std::endl;
for(uint i=0 ; i<value_size ; ++i) for(uint i=0 ; i<vector_len ; ++i)
output << " table[" << i << "]: " << table[i] << std::endl; output << " table[" << i << "]: " << vector[i] << std::endl;
}
/*!
this method is used when macro TTMATH_DEBUG_LOG is defined
*/
template<class char_type, class ostream_type>
static void PrintVectorLog(const char_type * msg, uint carry, ostream_type & output, const uint * vector, uint vector_len)
{
PrintVectorLog(msg, output, vector, vector_len);
output << " carry: " << carry << std::endl;
}
/*!
this method is used when macro TTMATH_DEBUG_LOG is defined
*/
template<class char_type, class ostream_type>
void PrintLog(const char_type * msg, ostream_type & output) const
{
PrintVectorLog(msg, output, table, value_size);
}
/*!
this method is used when macro TTMATH_DEBUG_LOG is defined
*/
template<class char_type, class ostream_type>
void PrintLog(const char_type * msg, uint carry, ostream_type & output) const
{
PrintVectorLog(msg, output, table, value_size);
output << " carry: " << carry << std::endl;
} }
@ -243,7 +284,7 @@ public:
table[i] = 0; table[i] = 0;
TTMATH_LOG("UInt32::SetFromTable") TTMATH_LOG("UInt::SetFromTable")
} }
#endif #endif
@ -308,7 +349,7 @@ public:
for( ; i >= 0 ; --i) for( ; i >= 0 ; --i)
table[i] = 0; table[i] = 0;
TTMATH_LOG("UInt64::SetFromTable") TTMATH_LOG("UInt::SetFromTable")
} }
#endif #endif
@ -436,7 +477,7 @@ public:
last_c = Rcl2(rest_bits, c); last_c = Rcl2(rest_bits, c);
} }
TTMATH_LOG("UInt::Rcl") TTMATH_LOGC("UInt::Rcl", last_c)
return last_c; return last_c;
} }
@ -531,7 +572,7 @@ public:
last_c = Rcr2(rest_bits, c); last_c = Rcr2(rest_bits, c);
} }
TTMATH_LOG("UInt::Rcr") TTMATH_LOGC("UInt::Rcr", last_c)
return last_c; return last_c;
} }
@ -550,11 +591,7 @@ public:
for(a=value_size-1 ; a>=0 && table[a]==0 ; --a); for(a=value_size-1 ; a>=0 && table[a]==0 ; --a);
if( a < 0 ) if( a < 0 )
{ return moving; // all words in table have zero
// there's a value zero
TTMATH_LOG("UInt::CompensationToLeft")
return moving;
}
if( a != value_size-1 ) if( a != value_size-1 )
{ {
@ -583,8 +620,6 @@ public:
} }
/*! /*!
this method looks for the highest set bit this method looks for the highest set bit
@ -607,21 +642,14 @@ public:
// is zero // is zero
index = 0; index = 0;
TTMATH_LOG("UInt::FindLeadingBit")
return false; return false;
} }
// table[table_id] != 0 // table[table_id] != 0
index = FindLeadingBitInWord( table[table_id] ); index = FindLeadingBitInWord( table[table_id] );
TTMATH_LOG("UInt::FindLeadingBit")
return true; return true;
} }
/*! /*!
@ -639,8 +667,6 @@ public:
uint temp = table[index]; uint temp = table[index];
uint res = SetBitInWord(temp, bit); uint res = SetBitInWord(temp, bit);
TTMATH_LOG("UInt::GetBit")
return res; return res;
} }
@ -758,43 +784,39 @@ public:
/*! /*!
multiplication: this = this * ss2 multiplication: this = this * ss2
it returns a carry if it has been it can return a carry
*/ */
uint MulInt(uint ss2) uint MulInt(uint ss2)
{ {
uint r2,r1; uint r1, r2, x1;
uint c = 0;
UInt<value_size> u( *this ); UInt<value_size> u(*this);
SetZero(); SetZero();
for(uint x1=0 ; x1<value_size ; ++x1) if( ss2 == 0 )
{ {
MulTwoWords(u.table[x1], ss2, &r2, &r1 ); TTMATH_LOGC("UInt::MulInt(uint)", 0)
return 0;
if( x1 <= value_size - 2 )
{
if( AddTwoInts(r2,r1,x1) )
return 1;
}
else
{
// last iteration:
// x1 = value_size - 1;
if( r2 )
return 1;
if( AddInt(r1, x1) )
return 1;
}
} }
TTMATH_LOG("UInt::MulInt(uint)") for(x1=0 ; x1<value_size-1 ; ++x1)
{
MulTwoWords(u.table[x1], ss2, &r2, &r1);
c += AddTwoInts(r2,r1,x1);
}
return 0; // x1 = value_size-1 (last word)
MulTwoWords(u.table[x1], ss2, &r2, &r1);
c += (r2!=0) ? 1 : 0;
c += AddInt(r1, x1);
TTMATH_LOGC("UInt::MulInt(uint)", c)
return (c==0)? 0 : 1;
} }
/*! /*!
multiplication: result = this * ss2 multiplication: result = this * ss2
@ -802,17 +824,22 @@ public:
if so there will not be a carry if so there will not be a carry
*/ */
template<uint result_size> template<uint result_size>
uint MulInt(uint ss2, UInt<result_size> & result) void MulInt(uint ss2, UInt<result_size> & result) const
{ {
TTMATH_ASSERT( result_size > value_size )
uint r2,r1; uint r2,r1;
uint x1size=value_size; uint x1size=value_size;
uint x1start=0; uint x1start=0;
if( value_size >= result_size )
return 1;
result.SetZero(); result.SetZero();
if( ss2 == 0 )
{
TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size)
return;
}
if( value_size > 2 ) if( value_size > 2 )
{ {
// if the value_size is smaller than or equal to 2 // if the value_size is smaller than or equal to 2
@ -820,10 +847,10 @@ public:
for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size); for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size);
if( x1size==0 ) if( x1size == 0 )
{ {
TTMATH_LOG("UInt::MulInt(uint, UInt<>)") TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size)
return 0; return;
} }
for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start); for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start);
@ -835,10 +862,9 @@ public:
result.AddTwoInts(r2,r1,x1); result.AddTwoInts(r2,r1,x1);
} }
TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size)
TTMATH_LOG("UInt::MulInt(uint, UInt<>)") return;
return 0;
} }
@ -919,19 +945,19 @@ public:
{ {
if( Add(*this) ) if( Add(*this) )
{ {
TTMATH_LOG("UInt::Mul1") TTMATH_LOGC("UInt::Mul1", 1)
return 1; return 1;
} }
if( ss1.Rcl(1) ) if( ss1.Rcl(1) )
if( Add(ss2) ) if( Add(ss2) )
{ {
TTMATH_LOG("UInt::Mul1") TTMATH_LOGC("UInt::Mul1", 1)
return 1; return 1;
} }
} }
TTMATH_LOG("UInt::Mul1") TTMATH_LOGC("UInt::Mul1", 0)
return 0; return 0;
} }
@ -1001,7 +1027,7 @@ public:
break; break;
} }
TTMATH_LOG("UInt::Mul2") TTMATH_LOGC("UInt::Mul2", c)
return c; return c;
} }
@ -1125,7 +1151,7 @@ public:
break; break;
} }
TTMATH_LOG("UInt::Mul3") TTMATH_LOGC("UInt::Mul3", c)
return c; return c;
} }
@ -1347,7 +1373,7 @@ public:
break; break;
} }
TTMATH_LOG("UInt::MulFastest") TTMATH_LOGC("UInt::MulFastest", c)
return c; return c;
} }
@ -1384,7 +1410,7 @@ public:
uint distancex2 = x2size - x2start; uint distancex2 = x2size - x2start;
if( distancex1 < 3 || distancex2 < 3 ) if( distancex1 < 3 || distancex2 < 3 )
// either 'this' or 'ss2' have only 2 (or 1) item different from zero (side by side) // either 'this' or 'ss2' have only 2 (or 1) items different from zero (side by side)
// (this condition in the future can be improved) // (this condition in the future can be improved)
return Mul2Big3<value_size>(table, ss2.table, result, x1start, x1size, x2start, x2size); return Mul2Big3<value_size>(table, ss2.table, result, x1start, x1size, x2start, x2size);
@ -1592,7 +1618,7 @@ private:
public: public:
/*! /*!
the first division's algorithm the first division algorithm
radix 2 radix 2
*/ */
uint Div1(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0) uint Div1(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
@ -2190,7 +2216,7 @@ public:
return values: return values:
0 - ok 0 - ok
1 - carry or 1 - carry
2 - incorrect argument (0^0) 2 - incorrect argument (0^0)
*/ */
uint Pow(UInt<value_size> pow) uint Pow(UInt<value_size> pow)
@ -2208,7 +2234,7 @@ public:
if( pow.table[0] & 1 ) if( pow.table[0] & 1 )
if( result.Mul(start) ) if( result.Mul(start) )
{ {
TTMATH_LOG("UInt::Pow(UInt<>)") TTMATH_LOGC("UInt::Pow(UInt<>)", 1)
return 1; return 1;
} }
@ -2216,7 +2242,7 @@ public:
// in the second Mul algorithm we can use start.Mul(start) directly (there is no TTMATH_ASSERT_REFERENCE there) // in the second Mul algorithm we can use start.Mul(start) directly (there is no TTMATH_ASSERT_REFERENCE there)
if( start.Mul(start_temp) ) if( start.Mul(start_temp) )
{ {
TTMATH_LOG("UInt::Pow(UInt<>)") TTMATH_LOGC("UInt::Pow(UInt<>)", 1)
return 1; return 1;
} }
@ -2225,7 +2251,7 @@ public:
*this = result; *this = result;
TTMATH_LOG("UInt::Pow(UInt<>)") TTMATH_LOGC("UInt::Pow(UInt<>)", 0)
return 0; return 0;
} }
@ -2311,7 +2337,7 @@ public:
/*! /*!
* *
* conversion method * conversion methods
* *
*/ */
@ -2347,12 +2373,12 @@ public:
for( ; i<argument_size ; ++i) for( ; i<argument_size ; ++i)
if( p.table[i] != 0 ) if( p.table[i] != 0 )
{ {
TTMATH_LOG("UInt::FromUInt(UInt<>)") TTMATH_LOGC("UInt::FromUInt(UInt<>)", 1)
return 1; return 1;
} }
} }
TTMATH_LOG("UInt::FromUInt(UInt<>)") TTMATH_LOGC("UInt::FromUInt(UInt<>)", 0)
return 0; return 0;
} }
@ -2382,9 +2408,7 @@ public:
{ {
FromUInt(p); FromUInt(p);
TTMATH_LOG("UInt::operator=(UInt<argument_size>)") return *this;
return *this;
} }
@ -2393,7 +2417,8 @@ public:
*/ */
UInt<value_size> & operator=(const UInt<value_size> & p) UInt<value_size> & operator=(const UInt<value_size> & p)
{ {
FromUInt(p); for(uint i=0 ; i<value_size ; ++i)
table[i] = p.table[i];
TTMATH_LOG("UInt::operator=(UInt<>)") TTMATH_LOG("UInt::operator=(UInt<>)")
@ -2408,8 +2433,6 @@ public:
{ {
FromUInt(i); FromUInt(i);
TTMATH_LOG("UInt::operator=(uint)")
return *this; return *this;
} }
@ -2420,8 +2443,6 @@ public:
UInt(uint i) UInt(uint i)
{ {
FromUInt(i); FromUInt(i);
TTMATH_LOG("UInt::UInt(uint)")
} }
@ -2441,8 +2462,6 @@ public:
{ {
FromUInt(uint(i)); FromUInt(uint(i));
TTMATH_LOG("UInt::operator=(sint)")
return *this; return *this;
} }
@ -2455,8 +2474,6 @@ public:
UInt(sint i) UInt(sint i)
{ {
FromUInt(uint(i)); FromUInt(uint(i));
TTMATH_LOG("UInt::UInt(sint)")
} }
@ -2487,8 +2504,6 @@ public:
{ {
FromUInt(uint(i)); FromUInt(uint(i));
TTMATH_LOG("UInt64::operator=(unsigned int)")
return *this; return *this;
} }
@ -2502,8 +2517,6 @@ public:
UInt(unsigned int i) UInt(unsigned int i)
{ {
FromUInt(uint(i)); FromUInt(uint(i));
TTMATH_LOG("UInt64::UInt(unsigned int)")
} }
@ -2519,8 +2532,6 @@ public:
{ {
FromUInt(uint(i)); FromUInt(uint(i));
TTMATH_LOG("UInt64::operator=(signed int)")
return *this; return *this;
} }
@ -2536,8 +2547,6 @@ public:
UInt(signed int i) UInt(signed int i)
{ {
FromUInt(uint(i)); FromUInt(uint(i));
TTMATH_LOG("UInt64::UInt(signed int)")
} }
@ -2553,8 +2562,6 @@ public:
UInt(const char * s) UInt(const char * s)
{ {
FromString(s); FromString(s);
TTMATH_LOG("UInt::UInt(const char *)")
} }
@ -2564,8 +2571,6 @@ public:
UInt(const wchar_t * s) UInt(const wchar_t * s)
{ {
FromString(s); FromString(s);
TTMATH_LOG("UInt::UInt(const wchar_t *)")
} }
@ -2590,13 +2595,14 @@ public:
/*! /*!
a default constructor a default constructor
we don't clear table etc. we don't clear the table
*/ */
UInt() UInt()
{ {
// when macro TTMATH_DEBUG_LOG is defined // when macro TTMATH_DEBUG_LOG is defined
// we set special values to the table // we set special values to the table
// in order to be everywhere the same value of the UInt object // in order to be everywhere the same value of the UInt object
// without this it would be difficult to analyse the log file
#ifdef TTMATH_DEBUG_LOG #ifdef TTMATH_DEBUG_LOG
#ifdef TTMATH_PLATFORM32 #ifdef TTMATH_PLATFORM32
for(uint i=0 ; i<value_size ; ++i) for(uint i=0 ; i<value_size ; ++i)
@ -2614,7 +2620,8 @@ public:
*/ */
UInt(const UInt<value_size> & u) UInt(const UInt<value_size> & u)
{ {
FromUInt(u); for(uint i=0 ; i<value_size ; ++i)
table[i] = u.table[i];
TTMATH_LOG("UInt::UInt(UInt<>)") TTMATH_LOG("UInt::UInt(UInt<>)")
} }
@ -2629,8 +2636,6 @@ public:
{ {
// look that 'size' we still set as 'value_size' and not as u.value_size // look that 'size' we still set as 'value_size' and not as u.value_size
FromUInt(u); FromUInt(u);
TTMATH_LOG("UInt::UInt(UInt<argument_size>)")
} }
@ -2717,7 +2722,7 @@ private:
SetZero(); SetZero();
temp.SetZero(); temp.SetZero();
SkipWhiteCharacters(s); Misc::SkipWhiteCharacters(s);
if( after_source ) if( after_source )
*after_source = s; *after_source = s;
@ -2746,7 +2751,7 @@ private:
if( after_source ) if( after_source )
*after_source = s; *after_source = s;
TTMATH_LOG("UInt::FromString") TTMATH_LOGC("UInt::FromString", c)
return (c==0)? 0 : 1; return (c==0)? 0 : 1;
} }
@ -3061,8 +3066,6 @@ public:
{ {
Sub(p2); Sub(p2);
TTMATH_LOG("UInt::operator-=")
return *this; return *this;
} }
@ -3079,8 +3082,6 @@ public:
{ {
Add(p2); Add(p2);
TTMATH_LOG("UInt::operator+=")
return *this; return *this;
} }
@ -3099,8 +3100,6 @@ public:
{ {
Mul(p2); Mul(p2);
TTMATH_LOG("UInt::operator*=")
return *this; return *this;
} }
@ -3119,8 +3118,6 @@ public:
{ {
Div(p2); Div(p2);
TTMATH_LOG("UInt::operator/=")
return *this; return *this;
} }
@ -3145,8 +3142,6 @@ public:
operator=(remainder); operator=(remainder);
TTMATH_LOG("UInt::operator%=")
return *this; return *this;
} }
@ -3158,11 +3153,10 @@ public:
{ {
AddOne(); AddOne();
TTMATH_LOG("UInt::operator++")
return *this; return *this;
} }
/*! /*!
Postfix operator e.g variable++ Postfix operator e.g variable++
*/ */
@ -3172,8 +3166,6 @@ public:
AddOne(); AddOne();
TTMATH_LOG("UInt::operator++(int)")
return temp; return temp;
} }
@ -3182,8 +3174,6 @@ public:
{ {
SubOne(); SubOne();
TTMATH_LOG("UInt::operator--")
return *this; return *this;
} }
@ -3194,8 +3184,6 @@ public:
SubOne(); SubOne();
TTMATH_LOG("UInt::operator--(int)")
return temp; return temp;
} }

View File

@ -51,6 +51,13 @@
namespace ttmath namespace ttmath
{ {
/*!
this method adds two words together
returns carry
this method is created only when TTMATH_NOASM macro is defined
*/
template<uint value_size> template<uint value_size>
uint UInt<value_size>::AddTwoWords(uint a, uint b, uint carry, uint * result) uint UInt<value_size>::AddTwoWords(uint a, uint b, uint carry, uint * result)
{ {
@ -95,7 +102,7 @@ namespace ttmath
for(i=0 ; i<value_size ; ++i) for(i=0 ; i<value_size ; ++i)
c = AddTwoWords(table[i], ss2.table[i], c, &table[i]); c = AddTwoWords(table[i], ss2.table[i], c, &table[i]);
TTMATH_LOG("UInt::Add") TTMATH_LOGC("UInt::Add", c)
return c; return c;
} }
@ -131,7 +138,7 @@ namespace ttmath
for(i=index+1 ; i<value_size && c ; ++i) for(i=index+1 ; i<value_size && c ; ++i)
c = AddTwoWords(table[i], 0, c, &table[i]); c = AddTwoWords(table[i], 0, c, &table[i]);
TTMATH_LOG("UInt::AddInt") TTMATH_LOGC("UInt::AddInt", c)
return c; return c;
} }
@ -184,7 +191,7 @@ namespace ttmath
for(i=index+2 ; i<value_size && c ; ++i) for(i=index+2 ; i<value_size && c ; ++i)
c = AddTwoWords(table[i], 0, c, &table[i]); c = AddTwoWords(table[i], 0, c, &table[i]);
TTMATH_LOG("UInt::AddTwoInts") TTMATH_LOGC("UInt::AddTwoInts", c)
return c; return c;
} }
@ -224,7 +231,7 @@ namespace ttmath
for( ; i<ss1_size ; ++i) for( ; i<ss1_size ; ++i)
c = AddTwoWords(ss1[i], 0, c, &result[i]); c = AddTwoWords(ss1[i], 0, c, &result[i]);
TTMATH_LOG("UInt::AddVector") TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
return c; return c;
} }
@ -232,6 +239,12 @@ namespace ttmath
/*!
this method subtractes one word from the other
returns carry
this method is created only when TTMATH_NOASM macro is defined
*/
template<uint value_size> template<uint value_size>
uint UInt<value_size>::SubTwoWords(uint a, uint b, uint carry, uint * result) uint UInt<value_size>::SubTwoWords(uint a, uint b, uint carry, uint * result)
{ {
@ -273,7 +286,7 @@ namespace ttmath
for(i=0 ; i<value_size ; ++i) for(i=0 ; i<value_size ; ++i)
c = SubTwoWords(table[i], ss2.table[i], c, &table[i]); c = SubTwoWords(table[i], ss2.table[i], c, &table[i]);
TTMATH_LOG("UInt::Sub") TTMATH_LOGC("UInt::Sub", c)
return c; return c;
} }
@ -311,7 +324,7 @@ namespace ttmath
for(i=index+1 ; i<value_size && c ; ++i) for(i=index+1 ; i<value_size && c ; ++i)
c = SubTwoWords(table[i], 0, c, &table[i]); c = SubTwoWords(table[i], 0, c, &table[i]);
TTMATH_LOG("UInt::SubInt") TTMATH_LOGC("UInt::SubInt", c)
return c; return c;
} }
@ -351,7 +364,7 @@ namespace ttmath
for( ; i<ss1_size ; ++i) for( ; i<ss1_size ; ++i)
c = SubTwoWords(ss1[i], 0, c, &result[i]); c = SubTwoWords(ss1[i], 0, c, &result[i]);
TTMATH_LOG("UInt::SubVector") TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
return c; return c;
} }
@ -385,7 +398,7 @@ namespace ttmath
c = new_c; c = new_c;
} }
TTMATH_LOG("UInt::Rcl2_one") TTMATH_LOGC("UInt::Rcl2_one", c)
return c; return c;
} }
@ -424,7 +437,7 @@ namespace ttmath
c = new_c; c = new_c;
} }
TTMATH_LOG("UInt::Rcr2_one") TTMATH_LOGC("UInt::Rcr2_one", c)
return c; return c;
} }
@ -462,7 +475,7 @@ namespace ttmath
c = new_c; c = new_c;
} }
TTMATH_LOG("UInt::Rcl2") TTMATH_LOGC("UInt::Rcl2", c)
return (c & 1); return (c & 1);
} }
@ -501,7 +514,7 @@ namespace ttmath
c = new_c; c = new_c;
} }
TTMATH_LOG("UInt::Rcr2") TTMATH_LOGC("UInt::Rcr2", c)
return (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0; return (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
} }
@ -509,10 +522,9 @@ namespace ttmath
/* /*!
this method returns the number of the highest set bit in x this method returns the number of the highest set bit in x
if the 'x' is zero this method returns '-1' if the 'x' is zero this method returns '-1'
*/ */
template<uint value_size> template<uint value_size>
sint UInt<value_size>::FindLeadingBitInWord(uint x) sint UInt<value_size>::FindLeadingBitInWord(uint x)
@ -539,7 +551,7 @@ namespace ttmath
this method sets a special bit in the 'value' this method sets a special bit in the 'value'
and returns the last state of the bit (zero or one) and returns the last state of the bit (zero or one)
bit is from <0,63> bit is from <0,TTMATH_BITS_PER_UINT-1>
e.g. e.g.
uint x = 100; uint x = 100;
@ -553,7 +565,7 @@ namespace ttmath
uint mask = 1; uint mask = 1;
if( bit > 1 ) if( bit > 0 )
mask = mask << bit; mask = mask << bit;
uint last = value & mask; uint last = value & mask;

View File

@ -152,7 +152,7 @@ namespace ttmath
: "cc", "memory" ); : "cc", "memory" );
#endif #endif
TTMATH_LOG("UInt::Add") TTMATH_LOGC("UInt::Add", c)
return c; return c;
} }
@ -253,7 +253,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::AddInt") TTMATH_LOGC("UInt::AddInt", c)
return c; return c;
} }
@ -374,7 +374,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::AddTwoInts") TTMATH_LOGC("UInt::AddTwoInts", c)
return c; return c;
} }
@ -506,6 +506,8 @@ namespace ttmath
#endif #endif
TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
return c; return c;
} }
@ -592,7 +594,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::Sub") TTMATH_LOGC("UInt::Sub", c)
return c; return c;
} }
@ -694,7 +696,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::SubInt") TTMATH_LOGC("UInt::SubInt", c)
return c; return c;
} }
@ -832,6 +834,8 @@ namespace ttmath
#endif #endif
TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
return c; return c;
} }
@ -908,7 +912,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::Rcl2_one") TTMATH_LOGC("UInt::Rcl2_one", c)
return c; return c;
} }
@ -980,7 +984,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::Rcr2_one") TTMATH_LOGC("UInt::Rcr2_one", c)
return c; return c;
} }
@ -1114,7 +1118,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::Rcl2") TTMATH_LOGC("UInt::Rcl2", c)
return c; return c;
} }
@ -1248,7 +1252,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::Rcr2") TTMATH_LOGC("UInt::Rcr2", c)
return c; return c;
} }

View File

@ -142,7 +142,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::Add") TTMATH_LOGC("UInt::Add", c)
return c; return c;
} }
@ -214,7 +214,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::AddInt") TTMATH_LOGC("UInt::AddInt", c)
return c; return c;
} }
@ -302,7 +302,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::AddTwoInts") TTMATH_LOGC("UInt::AddTwoInts", c)
return c; return c;
} }
@ -390,7 +390,7 @@ namespace ttmath
#endif #endif
// TTMATH_LOG("UInt::AddVector") TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
return c; return c;
} }
@ -452,7 +452,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::Sub") TTMATH_LOGC("UInt::Sub", c)
return c; return c;
} }
@ -523,7 +523,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::SubInt") TTMATH_LOGC("UInt::SubInt", c)
return c; return c;
} }
@ -613,7 +613,7 @@ namespace ttmath
#endif #endif
// TTMATH_LOG("UInt::SubVector") TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
return c; return c;
} }
@ -673,7 +673,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::Rcl2_one") TTMATH_LOGC("UInt::Rcl2_one", c)
return c; return c;
} }
@ -731,7 +731,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::Rcr2_one") TTMATH_LOGC("UInt::Rcr2_one", c)
return c; return c;
} }
@ -810,7 +810,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::Rcl2") TTMATH_LOGC("UInt::Rcl2", c)
return c; return c;
} }
@ -890,7 +890,7 @@ namespace ttmath
#endif #endif
TTMATH_LOG("UInt::Rcr2") TTMATH_LOGC("UInt::Rcr2", c)
return c; return c;
} }