fixed: powering algorithm in:

UInt::Pow(UInt<value_size> pow)
       Big::Pow(UInt<pow_size> pow)
       Big::PowUInt(Big<exp, man> pow)
       when 'pow' was sufficient large the algorithm returned carry
       but the result could have been calculated correctly



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@213 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2009-10-16 16:56:49 +00:00
parent 462ff7cc65
commit af4fbf3098
4 changed files with 426 additions and 419 deletions

800
CHANGELOG
View File

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

View File

@ -1258,15 +1258,18 @@ public:
result.SetOne(); result.SetOne();
uint c = 0; uint c = 0;
while( !c && !pow.IsZero() ) while( !c )
{ {
if( pow.table[0] & 1 ) if( pow.table[0] & 1 )
c += result.Mul(start); c += result.Mul(start);
pow.Rcr(1);
if( pow.IsZero() )
break;
start_temp = start; start_temp = start;
c += start.Mul(start_temp); c += start.Mul(start_temp);
pow.Rcr(1);
} }
*this = result; *this = result;
@ -1374,15 +1377,18 @@ public:
one.SetOne(); one.SetOne();
result = one; result = one;
while( !c && pow >= one ) while( !c )
{ {
if( pow.Mod2() ) if( pow.Mod2() )
c += result.Mul(start); c += result.Mul(start);
c += pow.exponent.Sub( e_one );
if( pow < one )
break;
start_temp = start; start_temp = start;
c += start.Mul(start_temp); c += start.Mul(start_temp);
c += pow.exponent.Sub( e_one );
} }
*this = result; *this = result;

View File

@ -514,7 +514,7 @@ public:
return Pow2(pow); return Pow2(pow);
if( UInt<value_size>::IsZero() ) if( UInt<value_size>::IsZero() )
// if 'p' is negative then // if 'pow' is negative then
// 'this' must be different from zero // 'this' must be different from zero
return 2; return 2;

View File

@ -2228,32 +2228,27 @@ public:
UInt<value_size> start(*this), start_temp; UInt<value_size> start(*this), start_temp;
UInt<value_size> result; UInt<value_size> result;
result.SetOne(); result.SetOne();
uint c = 0;
while( !pow.IsZero() ) while( !c )
{ {
if( pow.table[0] & 1 ) if( pow.table[0] & 1 )
if( result.Mul(start) ) c += result.Mul(start);
{
TTMATH_LOGC("UInt::Pow(UInt<>)", 1) pow.Rcr2_one(0);
return 1; if( pow.IsZero() )
} break;
start_temp = start; start_temp = start;
// 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) ) c += start.Mul(start_temp);
{
TTMATH_LOGC("UInt::Pow(UInt<>)", 1)
return 1;
}
pow.Rcr2_one(0);
} }
*this = result; *this = result;
TTMATH_LOGC("UInt::Pow(UInt<>)", 0) TTMATH_LOGC("UInt::Pow(UInt<>)", c)
return 0; return (c==0)? 0 : 1;
} }