20 Commits
0.8.0 ... 0.8.2

Author SHA1 Message Date
98c2379182 changed: small changes especially cosmetic in documentation (commentaries)
changed: version of the library: now 0.8.2


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@68 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-06-18 00:33:05 +00:00
2933213a02 changed: info about Big::ToString()
the changes which were made in revision 60 and 63
	 (I forgot to change the info there)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@67 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-06-07 16:17:37 +00:00
4d0241c9c9 changed: the way of using Big::SetSign()
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)
         I changed this due to some prior errors
         (errors corrected in revision 17, 49 and 58)
added:   in Big::MulInt() checking whether the values are zeros
         and if so the metdhod returns zero immediately
removed: file TODO (I didn't use it)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@66 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-06-07 14:07:59 +00:00
4f3f05fa9d changed: 'max_digit_after_comma' in Big::ToString()
remove the -2 state
added:   'remove_trailing_zeroes' in Big::ToString()
         it's either true or false


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@63 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-04-12 08:46:09 +00:00
f139e6457c added: a short form of multiplication (without the '*' character)
e.g. '5y', (it's used only if the second parameter
       is a variable or function)
changed: variables and functions are case-sensitive now
added: variables and functions can have underline characters
       in their names


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@61 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-01-23 23:45:42 +00:00
29bb4fb3f7 added: 'decimal_point' parameter into Big::ToString(...)
fixed: Big::operator>> didn't use TTMATH_COMMA_CHARACTER_2 macro


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@60 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-12-09 20:07:45 +00:00
5002f435ae fixed: there was an error in Big::FromInt(Int<int_size> value)
SetSign() was used before the object was initialized


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@58 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-11-09 13:28:36 +00:00
61886fc829 added: Big::FromBig() and an operator= and a contructor
for converting from another kind of a Big class
added:  to the parser: avg(), sum()


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@56 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-11-04 21:56:04 +00:00
25f876762a fixed: Big::FromDouble(double) sometimes sets a wrong value
there was SetSign() used when the value was not
       defined, and also was a small mistake when the mantissa 
       was equal one word (on 32bit platforms)
added: uint Big::ToDouble(double&) - converting into double


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@49 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-07-29 22:42:45 +00:00
692ff5406e added: a method Big::FromDouble(double) for 64bit platforms
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@48 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-07-23 21:29:27 +00:00
669698c6d7 added: method Big::FromDouble(double) which converts from
standard double into a Big<> (only 32bit platforms)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@47 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-07-22 23:20:09 +00:00
93ba8ce17d changed: the parser is allowed to recognize values which
begin with a dot, e.g '.5' is treated as '0.5'


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@46 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-07-22 14:15:44 +00:00
d27cabec93 changed: Int::FromInt(const Int<argument_size> & p),
Int::FromInt(sint value) (it returns zero now)
         Int::operator=(uint i)
         Int::Int(uint i)
added:   Int::FromUInt(const UInt<argument_size> & p),
         Int::FromUInt(uint value)
         and appropriate constructors and assignment 
         operators as well
changed: Big::FromInt(Int<int_size> value),
added:   Big::FromUInt(UInt<int_size> value),
         Big::operator=(const UInt<int_size> & value)
         Big::Big(const UInt<int_size> & value)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@42 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-05-27 23:33:47 +00:00
bc9d528a75 added: Uint::BitNot2() this method has been proposed by
Arek <kmicicc AnTispam users.sourceforge.net>


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@41 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-04-23 21:35:55 +00:00
bb16c871c9 changed: the way of parsing operators in the mathematical parser
(the parser is not too much greedy now)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@38 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-04-17 13:42:19 +00:00
2116418f08 added: UInt::BitAnd(), UInt::BitOr(), UInt::BitXor(), UInt::BitNot(),
Big::BitAnd(), Big::BitOr(), Big::BitXor()
added: to the parser: bitand(), bitor(), bitxor()
       /band(), bor(), bxor()/


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@36 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-04-13 18:14:11 +00:00
062881900a changed: small changes in: Big::SetPi(), Big::Set05Pi(), Big::Set2Pi(),
Big::ChangeSign()
added:   ASinh(), ACosh(), ATanh() /ATgh()/, ACoth() /ACtgh()/
         and to the parser as well


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@35 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-04-12 17:17:22 +00:00
0170572f84 added: doxygen.cfg for generating a documentation from the doxygen
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)
        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)
       didn't correctly return a carry if the 'bits' were equal
       to 'value_size*TTMATH_BITS_PER_UINT'
changed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c)
        into UInt::Rcl(uint bits, uint c=0) and
        UInt::Rcr(uint bits, uint c=0)
        they are faster now when the bits is greater than a half of
        the TTMATH_BITS_PER_UINT
changed: UInt::CompensationToLeft() it's faster now
changed: more small changes where there were UInt::Rcl(uint c=0) and
       UInt::Rcr(uint c=0) used


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@34 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-04-11 22:14:17 +00:00
e40ed603c6 added: UInt::MulInt(int, UInt<int another_size>::&)
added: Big::MulUInt(uint)
changed: Big::MulInt(sint)
added: Big::ToUInt(uint &)
changed: Big::ToInt(sint&)
changed: Factorial() it uses Big::MulUInt() at the beginning
         (faster now especially more on a 32bit platform)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@33 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-04-07 22:21:31 +00:00
c97ebf282f fixed: Big::PowFrac(..) didn't return a correct error code
(when 'this' was negative)
added: Root(x; index) (and to the parser as well)
added: macro: TTMATH_PRERELEASE_VER (can be either zero or one)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@32 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-04-05 19:08:15 +00:00
13 changed files with 3709 additions and 495 deletions

233
CHANGELOG
View File

@@ -1,84 +1,171 @@
Version 0.8.2 (2008.06.18):
* added: UInt::BitNot2() this method has been proposed by
Arek <kmicicc AnTispam users.sourceforge.net>
* changed: Int::FromInt(const Int<argument_size> & p),
Int::FromInt(sint value) (it returns zero now)
Int::operator=(uint i)
Int::Int(uint i)
* added: Int::FromUInt(const UInt<argument_size> & p),
Int::FromUInt(uint value)
and appropriate constructors and assignment
operators as well
* changed: Big::FromInt(Int<int_size> value),
* added: Big::FromUInt(UInt<int_size> value),
Big::operator=(const UInt<int_size> & value)
Big::Big(const UInt<int_size> & value)
* changed: the parser is allowed to recognize values which
begin with a dot, e.g '.5' is treated as '0.5'
* added: a method Big::FromDouble(double) which converts from
standard double into a Big
* added: uint Big::ToDouble(double&) - converting into double
* added: Big::FromBig() and an operator= and a contructor
for converting from another kind of a Big class
* added: to the parser: avg(), sum()
* added: 'decimal_point' parameter into Big::ToString(...)
* fixed: Big::operator>> didn't use TTMATH_COMMA_CHARACTER_2 macro
* added: a short form of multiplication (without the '*' character)
e.g. '5y', (it's used only if the second parameter
is a variable or function)
* changed: variables and functions are case-sensitive now
* added: variables and functions can have underline characters
in their names
* changed: 'max_digit_after_comma' in Big::ToString()
remove the -2 state
* added: 'remove_trailing_zeroes' in Big::ToString()
it's either true or false
* fixed/changed: the way of using Big::SetSign()
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)
I changed this due to some prior errors
(errors corrected in revision 17, 49 and 58)
Version 0.8.1 (2007.04.17):
* fixed: Big::PowFrac(..) didn't return a correct error code
(when 'this' was negative)
* added: Root(x; index) (and to the parser as well)
* added: macro: TTMATH_PRERELEASE_VER (can be either zero or one)
* added: UInt::MulInt(int, UInt<int another_size>::&)
* added: Big::MulUInt(uint)
* changed: Big::MulInt(sint)
* added: Big::ToUInt(uint &)
* changed: Big::ToInt(sint&)
* changed: Factorial() it uses Big::MulUInt() at the beginning
(faster now especially more on a 32bit platform)
* added: doxygen.cfg for generating a documentation from the doxygen
* 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)
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)
didn't correctly return a carry if the 'bits' were equal
to 'value_size*TTMATH_BITS_PER_UINT'
* changed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c)
into UInt::Rcl(uint bits, uint c=0) and
UInt::Rcr(uint bits, uint c=0)
they are faster now when the bits is greater than a half of
the TTMATH_BITS_PER_UINT
* changed: UInt::CompensationToLeft() it's faster now
* changed: more small changes where there were UInt::Rcl(uint c=0) and
UInt::Rcr(uint c=0) used
* changed: as the Big type uses UInt::Rcl() and UInt::Rcr() a lot then
it is much faster now (about 5-25%)
* added: ASinh(), ACosh(), ATanh() /ATgh()/, ACoth() /ACtgh()/
and to the parser as well
* added: UInt::BitAnd(), UInt::BitOr(), UInt::BitXor(), UInt::BitNot(),
Big::BitAnd(), Big::BitOr(), Big::BitXor()
* added: to the parser: bitand(), bitor(), bitxor()
/band(), bor(), bxor()/
* changed: the way of parsing operators in the mathematical parser
(the parser is not too much greedy now)
Version 0.8.0 (2007.03.28):
* added: into the parser: SetFactorialMax()
* added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
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, and the
names are case-sensitive now
* added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
* added: Tg(x) a wrapper for Tan(x)
* changed: CTan(x) is Cot(x) now
* added: Ctg(x) a wrapper for Cot(x)
* added: ATg(x) a wrapper for ATan(x)
* changed: ACTan(x) is ACot(x) now
* added: ACtg(x) a wrapper for ACot(x)
* added: UInt::PrintTable() (for debugging etc.)
* changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have
been rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
* fixed: previous values from Big::SetPi() Big::SetE() and
Big::SetLn2() were not too much accurate (last 2-3 words were wrong)
* added: Big::SetLn10() (128 32bit words as well)
* added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on
32bit platforms and 64ul on 64bit platforms (128/2=64)
* added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
* changed: a small optimisation in UInt::Mul2Big()
* added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
* added: to samples: big.cpp, parser.cpp
* added/changes/fixed: in copy-constructors and operators= in Int,
Uint and Big (more info in the commit log)
* renamed Big::SetDotOne() into Big::Set05()
* changes: a few small optimisations in Big
* deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
* and more small changes (look at the commit log)
* added: into the parser: SetFactorialMax()
* added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
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,
and the names are case-sensitive now
* added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
* added: Tg(x) a wrapper for Tan(x)
* changed: CTan(x) is Cot(x) now
* added: Ctg(x) a wrapper for Cot(x)
* added: ATg(x) a wrapper for ATan(x)
* changed: ACTan(x) is ACot(x) now
* added: ACtg(x) a wrapper for ACot(x)
* added: UInt::PrintTable() (for debugging etc.)
* changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have
been rewritten, now they have 128 32bit words (it's about
1232 valid decimal digits)
* fixed: previous values from Big::SetPi() Big::SetE() and
Big::SetLn2() were not too much accurate (last 2-3 words were wrong)
* added: Big::SetLn10() (128 32bit words as well)
* added: macro TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on
32bit platforms and 64ul on 64bit platforms (128/2=64)
* added: macros TTMATH_PLATFORM32 and TTMATH_PLATFORM64
* changed: a small optimisation in UInt::Mul2Big()
* added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
* added: to samples: big.cpp, parser.cpp
* added/changes/fixed: in copy-constructors and operators= in Int,
Uint and Big (more info in the commit log)
* renamed: Big::SetDotOne() into Big::Set05()
* changes: a few small optimisations in Big
* deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
* and more small changes (look at the commit log)
Version 0.7.2 (2007.03.09):
* added: Big::Mod - the remainder from a division
* 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
(user-defined variables/functions in the mathematical parser)
* added: into the parser: logical operators: > < >= <= == != && ||
* added: into the parser: logical functions: and() or() not() if()
* added: ErrorCode::err_unknown_operator when the parser couldn't read an operator
* added: Big::Mod - the remainder from a division
* 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
(user-defined variables/functions in the mathematical parser)
* added: into the parser: logical operators: > < >= <= == != && ||
* added: into the parser: logical functions: and() or() not() if()
* added: ErrorCode::err_unknown_operator when the parser couldn't read an operator
Version 0.7.1 (2007.02.27):
* 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)
* fixed many small errors
* added ATan (arctan), ACTan (arc ctan) functions
* 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)
* fixed: many small errors
* added: ATan (arctan), ACTan (arc ctan) functions
Version 0.7.0 (2007.02.24):
* finished support for 64bit platforms
* added ASin (arcsin), ACos (arccos) functions
* finished: support for 64bit platforms
* added: ASin (arcsin), ACos (arccos) functions
Version 0.6.4 (2007.01.29):
* fixed the problem with a sign in the mathematical parser /-(1) was 1/
* added UInt::AddInt and UInt::SubInt
* changed UInt::AddOne and UInt::SubOne (much faster now)
* added UInt::SetBitInWord
* changed UInt::SetBit (much faster now)
* UInt::AddTwoUints renamed to UInt::AddTwoInts
* UInt::FindLeadingBit32 renamed to UInt::FindLeadingBitInWord
* added UInt::SetBitInWord
* UInt::Mul64 renamed to UInt::MulTwoWords
* UInt::Div64 renamed to UInt::DivTwoWords
* and more small changes in UInt type
* start adding support for Amd64 (not finished yet) (added ttmathuint64.h)
* fixed: the problem with a sign in the mathematical parser /-(1) was 1/
* added: UInt::AddInt and UInt::SubInt
* changed: UInt::AddOne and UInt::SubOne (much faster now)
* added: UInt::SetBitInWord
* changed: UInt::SetBit (much faster now)
UInt::AddTwoUints renamed to UInt::AddTwoInts
UInt::FindLeadingBit32 renamed to UInt::FindLeadingBitInWord
UInt::Mul64 renamed to UInt::MulTwoWords
UInt::Div64 renamed to UInt::DivTwoWords
* added: UInt::SetBitInWord
* and more small changes in UInt type
* start adding support for Amd64 (not finished yet) (added ttmathuint64.h)
Version 0.6.3 (2007.01.22):
* position of arguments (x and base) in logarithm functions are swapped
* it's possible to use any multiplication algorithms in the same time
(macros UINT_MUL_VERSION_'X' have gone)
* added ExceptionInfo, ReferenceError and RuntimeError classes
* the mess in macros has been cleaned up
* added TTMATH_RELEASE macro
* 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
(macros UINT_MUL_VERSION_'X' have gone)
* 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):
* New division algorithm (radix b) where b is 2^32
* added: New division algorithm (radix b) where b is 2^32

View File

@@ -1,4 +1,4 @@
Copyright (c) 2006-2007, Tomasz Sowa
Copyright (c) 2006-2008, Tomasz Sowa
All rights reserved.
Redistribution and use in source and binary forms, with or without

18
README
View File

@@ -7,18 +7,20 @@ subtracting, multiplying, dividing etc. With the library also goes
a mathematical parser which helps you solving input formulas read directly
from a user.
TTMath is developed under the (new) BSD licence which means that it is free
for both personal and commercial use but the library has some technical
limitations: you can use it only on i386 and Amd64, another platforms are
not supported (Intel 64bit platforms were not tested but should work as
well), and you can use this library only with the C++ programming language.
TTMath is developed under the BSD licence which means that it is free
for both personal and commercial use.
The library has some technical limitations:
* there are only two platforms that are supported: x86 and x86_64,
* you can use this library only with the C++ programming language.
The main goal of the library is to allow one to use big values in the same
way as the standard types like int, float, etc. It does not need to be
compiled first because the whole library is written as the C++ templates.
This means only C++ developers can use this library and one thing they have
to do is to use 'include' directive of the preprocessor. How big the
to do is to use 'include' directive of the preprocessor. How big the
values can be is set directly in the source code by the programmer.
Author: Tomasz Sowa <t.sowa AnTispam slimaczek.pl>
Home page: http://sourceforge.net/projects/ttmath
Author: Tomasz Sowa <t.sowa@slimaczek.pl>
Project pages: http://ttmath.slimaczek.pl
http://sourceforge.net/projects/ttmath

7
TODO
View File

@@ -1,7 +0,0 @@
TODO TTMath Library
===================
* Add bitwise operators (or functions) and, or, xor
* Add functions for generating random values

1257
doxygen.cfg Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2007, Tomasz Sowa
* Copyright (c) 2006-2008, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -275,6 +275,11 @@ namespace ttmath
*
*/
/*
this namespace consists of auxiliary functions
(something like 'private' in a class)
*/
namespace auxiliaryfunctions
{
@@ -1171,6 +1176,173 @@ namespace ttmath
}
/*
*
* inverse hyperbolic functions
*
*
*/
/*!
inverse hyperbolic sine
asinh(x) = ln( x + sqrt(x^2 + 1) )
*/
template<class ValueType>
ValueType ASinh(const ValueType & x, ErrorCode * err = 0)
{
ValueType xx(x), one, result;
uint c = 0;
one.SetOne();
c += xx.Mul(x);
c += xx.Add(one);
one.exponent.SubOne(); // one=0.5
// xx is >= 1
c += xx.PowFrac(one); // xx=sqrt(xx)
c += xx.Add(x);
c += result.Ln(xx); // xx > 0
// here can only be a carry
if( err )
*err = c ? err_overflow : err_ok;
return result;
}
/*!
inverse hyperbolic cosine
acosh(x) = ln( x + sqrt(x^2 - 1) ) x in <1, infinity)
*/
template<class ValueType>
ValueType ACosh(const ValueType & x, ErrorCode * err = 0)
{
ValueType xx(x), one, result;
uint c = 0;
one.SetOne();
if( x < one )
{
if( err )
*err = err_improper_argument;
return result;
}
c += xx.Mul(x);
c += xx.Sub(one);
// xx is >= 0
// we can't call a PowFrac when the 'x' is zero
// if x is 0 the sqrt(0) is 0
if( !xx.IsZero() )
{
one.exponent.SubOne(); // one=0.5
c += xx.PowFrac(one); // xx=sqrt(xx)
}
c += xx.Add(x);
c += result.Ln(xx); // xx >= 1
// here can only be a carry
if( err )
*err = c ? err_overflow : err_ok;
return result;
}
/*!
inverse hyperbolic tangent
atanh(x) = 0.5 * ln( (1+x) / (1-x) ) x in (-1, 1)
*/
template<class ValueType>
ValueType ATanh(const ValueType & x, ErrorCode * err = 0)
{
ValueType nominator(x), denominator, one, result;
uint c = 0;
one.SetOne();
if( !x.SmallerWithoutSignThan(one) )
{
if( err )
*err = err_improper_argument;
return result;
}
c += nominator.Add(one);
denominator = one;
c += denominator.Sub(x);
c += nominator.Div(denominator);
c += result.Ln(nominator);
c += result.exponent.SubOne();
// here can only be a carry
if( err )
*err = c ? err_overflow : err_ok;
return result;
}
/*!
inverse hyperbolic tantent
*/
template<class ValueType>
ValueType ATgh(const ValueType & x, ErrorCode * err = 0)
{
return ATanh(x, err);
}
/*!
inverse hyperbolic cotangent
acoth(x) = 0.5 * ln( (x+1) / (x-1) ) x in (-infinity, -1) or (1, infinity)
*/
template<class ValueType>
ValueType ACoth(const ValueType & x, ErrorCode * err = 0)
{
ValueType nominator(x), denominator(x), one, result;
uint c = 0;
one.SetOne();
if( !x.GreaterWithoutSignThan(one) )
{
if( err )
*err = err_improper_argument;
return result;
}
c += nominator.Add(one);
c += denominator.Sub(one);
c += nominator.Div(denominator);
c += result.Ln(nominator);
c += result.exponent.SubOne();
// here can only be a carry
if( err )
*err = c ? err_overflow : err_ok;
return result;
}
/*!
inverse hyperbolic cotantent
*/
template<class ValueType>
ValueType ACtgh(const ValueType & x, ErrorCode * err = 0)
{
return ACoth(x, err);
}
/*
@@ -1342,6 +1514,273 @@ namespace ttmath
}
namespace auxiliaryfunctions
{
template<class ValueType>
bool RootCheckIndexSign(ValueType & x, const ValueType & index, ErrorCode * err)
{
if( index.IsSign() )
{
// index cannot be negative
if( err )
*err = err_improper_argument;
return true;
}
return false;
}
template<class ValueType>
bool RootCheckIndexZero(ValueType & x, const ValueType & index, ErrorCode * err)
{
if( index.IsZero() )
{
if( x.IsZero() )
{
// there isn't root(0;0) - we assume it's not defined
if( err )
*err = err_improper_argument;
return true;
}
// root(x;0) is 1 (if x!=0)
x.SetOne();
if( err )
*err = err_ok;
return true;
}
return false;
}
template<class ValueType>
bool RootCheckIndexOne(ValueType & x, const ValueType & index, ErrorCode * err)
{
ValueType one;
one.SetOne();
if( index == one )
{
//root(x;1) is x
// we do it because if we used the PowFrac function
// we would lose the precision
if( err )
*err = err_ok;
return true;
}
return false;
}
template<class ValueType>
bool RootCheckIndexFrac(ValueType & x, const ValueType & index, ErrorCode * err)
{
ValueType indexfrac(index);
indexfrac.RemainFraction();
if( !indexfrac.IsZero() )
{
// index must be integer
if( err )
*err = err_improper_argument;
return true;
}
return false;
}
template<class ValueType>
bool RootCheckXZero(ValueType & x, const ValueType & index, ErrorCode * err)
{
if( x.IsZero() )
{
// root(0;index) is zero (if index!=0)
x.SetZero();
if( err )
*err = err_ok;
return true;
}
return false;
}
template<class ValueType>
bool RootCheckIndex(ValueType & x, const ValueType & index, ErrorCode * err, bool * change_sign)
{
*change_sign = false;
if( index.Mod2() )
{
// index is odd (1,3,5...)
if( x.IsSign() )
{
*change_sign = true;
x.Abs();
}
}
else
{
// index is even
// x cannot be negative
if( x.IsSign() )
{
if( err )
*err = err_improper_argument;
return true;
}
}
return false;
}
}
/*!
indexth Root of x
index must be integer and not negative <0;1;2;3....)
if index==0 the result is one
if x==0 the result is zero and we assume root(0;0) is not defined
if index is even (2;4;6...) the result is x^(1/index) and x>0
if index is odd (1;2;3;...) the result is either
-(abs(x)^(1/index)) if x<0 or
x^(1/index)) if x>0
(for index==1 the result is equal x)
*/
template<class ValueType>
ValueType Root(ValueType x, const ValueType & index, ErrorCode * err = 0)
{
using namespace auxiliaryfunctions;
if( RootCheckIndexSign(x, index, err) ) return x;
if( RootCheckIndexZero(x, index, err) ) return x;
if( RootCheckIndexOne (x, index, err) ) return x;
if( RootCheckIndexFrac(x, index, err) ) return x;
if( RootCheckXZero(x, index, err) ) return x;
// index integer and index!=0
// x!=0
uint c = 0;
bool change_sign;
if( RootCheckIndex(x, index, err, &change_sign ) ) return x;
ValueType newindex;
newindex.SetOne();
c += newindex.Div(index);
c += x.PowFrac(newindex); // here can only be a carry
if( change_sign )
{
// the value of x should be different from zero
// (x is actually tested by RootCheckXZero)
TTMATH_ASSERT( x.IsZero() == false )
x.SetSign();
}
if( err )
*err = c ? err_overflow : err_ok;
return x;
}
namespace auxiliaryfunctions
{
template<class ValueType>
uint FactorialInt( const ValueType & x, ErrorCode * err,
const volatile StopCalculating * stop,
ValueType & result)
{
uint maxvalue = TTMATH_UINT_MAX_VALUE;
if( x < TTMATH_UINT_MAX_VALUE )
x.ToUInt(maxvalue);
uint multipler = 1;
uint carry = 0;
while( !carry && multipler<maxvalue )
{
if( stop && stop->WasStopSignal() )
{
if( err )
*err = err_interrupt;
return 2;
}
++multipler;
carry += result.MulUInt(multipler);
}
if( err )
*err = carry ? err_overflow : err_ok;
return carry ? 1 : 0;
}
template<class ValueType>
int FactorialMore( const ValueType & x, ErrorCode * err,
const volatile StopCalculating * stop,
ValueType & result)
{
ValueType multipler(TTMATH_UINT_MAX_VALUE);
ValueType one;
one.SetOne();
uint carry = 0;
while( !carry && multipler < x )
{
if( stop && stop->WasStopSignal() )
{
if( err )
*err = err_interrupt;
return 2;
}
carry += multipler.Add(one);
carry += result.Mul(multipler);
}
if( err )
*err = carry ? err_overflow : err_ok;
return carry ? 1 : 0;
}
} // namespace
/*!
the factorial from given 'x'
e.g.
@@ -1350,6 +1789,8 @@ namespace ttmath
template<class ValueType>
ValueType Factorial(const ValueType & x, ErrorCode * err = 0, const volatile StopCalculating * stop = 0)
{
using namespace auxiliaryfunctions;
static History<ValueType> history;
ValueType result;
@@ -1384,33 +1825,17 @@ namespace ttmath
return result;
}
ValueType multipler;
ValueType one;
uint carry = 0;
one = result; // =1
multipler = result; // =1
while( !carry && multipler < x )
{
if( stop && stop->WasStopSignal() )
{
if( err )
*err = err_interrupt;
uint status = FactorialInt(x, err, stop, result);
if( status == 0 )
status = FactorialMore(x, err, stop, result);
if( status == 2 )
// the calculation has been interrupted
return result;
}
carry += multipler.Add(one);
carry += result.Mul(multipler);
}
err_tmp = carry ? err_overflow : err_ok;
err_tmp = status==1 ? err_overflow : err_ok;
history.Add(x, result, err_tmp);
if( err )
*err = carry ? err_overflow : err_ok;
return result;
}
@@ -1432,7 +1857,7 @@ namespace ttmath
/*!
it returns the sign of the value
e.g. -2 = 1
e.g. -2 = -1
0 = 0
10 = 1
*/

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2007, Tomasz Sowa
* Copyright (c) 2006-2008, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -208,7 +208,7 @@ private:
public:
/*!
this method adds two value with a sign and returns carry
this method adds two value with a sign and returns a carry
we're using methods from the base class because values are stored with U2
we must only make the carry correction
@@ -475,17 +475,14 @@ public:
* convertion methods
*
*/
private:
/*!
this method convert an UInt<another_size> type to this class
this operation has mainly sense if the value from p
can be held in this type
it returns a carry if the value 'p' is too big
an auxiliary method for converting both from UInt and Int
*/
template<uint argument_size>
uint FromInt(const Int<argument_size> & p)
uint FromUIntOrInt(const UInt<argument_size> & p, bool UInt_type)
{
uint min_size = (value_size < argument_size)? value_size : argument_size;
uint i;
@@ -496,15 +493,25 @@ public:
if( value_size > argument_size )
{
// 'this' is longer than 'p'
uint fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)? TTMATH_UINT_MAX_VALUE : 0;
uint fill;
if( UInt_type )
fill = 0;
else
fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)?
TTMATH_UINT_MAX_VALUE : 0;
// 'this' is longer than 'p'
for( ; i<value_size ; ++i)
UInt<value_size>::table[i] = fill;
}
else
{
uint test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)? TTMATH_UINT_MAX_VALUE : 0;
uint test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)?
TTMATH_UINT_MAX_VALUE : 0;
if( UInt_type && test!=0 )
return 1;
for( ; i<argument_size ; ++i)
if( p.table[i] != test )
@@ -514,11 +521,27 @@ public:
return 0;
}
public:
/*!
this method converts an Int<another_size> type into this class
this operation has mainly sense if the value from p
can be held in this type
it returns a carry if the value 'p' is too big
*/
template<uint argument_size>
uint FromInt(const Int<argument_size> & p)
{
return FromUIntOrInt(p, false);
}
/*!
this method converts the sint type into this class
*/
void FromInt(sint value)
uint FromInt(sint value)
{
uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0;
@@ -526,16 +549,46 @@ public:
UInt<value_size>::table[i] = fill;
UInt<value_size>::table[0] = uint(value);
// there'll never be a carry here
return 0;
}
/*!
this operator converts an UInt<another_size> type to this class
it doesn't return a carry
this method converts UInt<another_size> into this class
*/
template<uint argument_size>
Int<value_size> & operator=(const Int<argument_size> & p)
uint FromUInt(const UInt<argument_size> & p)
{
return FromUIntOrInt(p, true);
}
/*!
this method converts the uint type into this class
*/
uint FromUInt(uint value)
{
for(uint i=1 ; i<value_size ; ++i)
UInt<value_size>::table[i] = 0;
UInt<value_size>::table[0] = value;
// there can be a carry here when the size of this value is equal one word
// and the 'value' has the highest bit set
if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 )
return 1;
return 0;
}
// converting from Int
/*!
the default assignment operator
*/
Int<value_size> & operator=(const Int<value_size> & p)
{
FromInt(p);
@@ -544,9 +597,12 @@ public:
/*!
the default assignment operator
this operator converts an Int<another_size> type to this class
it doesn't return a carry
*/
Int<value_size> & operator=(const Int<value_size> & p)
template<uint argument_size>
Int<value_size> & operator=(const Int<argument_size> & p)
{
FromInt(p);
@@ -575,11 +631,47 @@ public:
/*!
this method converts the uint type to this class
a copy constructor
*/
Int(const Int<value_size> & u)
{
FromInt(u);
}
/*!
a constructor for copying from another types
*/
template<uint argument_size>
Int(const Int<argument_size> & u)
{
// look that 'size' we still set as 'value_size' and not as u.value_size
FromInt(u);
}
// converting from UInt
/*!
this operator converts an UInt<another_size> type to this class
it doesn't return a carry
*/
template<uint argument_size>
Int<value_size> & operator=(const UInt<argument_size> & p)
{
FromUInt(p);
return *this;
}
/*!
this method converts the Uint type to this class
*/
Int<value_size> & operator=(uint i)
{
UInt<value_size>::FromUInt(i);
FromUInt(i);
return *this;
}
@@ -590,10 +682,23 @@ public:
*/
Int(uint i)
{
UInt<value_size>::FromUInt(i);
FromUInt(i);
}
/*!
a constructor for copying from another types
*/
template<uint argument_size>
Int(const UInt<argument_size> & u)
{
// look that 'size' we still set as 'value_size' and not as u.value_size
FromUInt(u);
}
//
#ifdef TTMATH_PLATFORM64
/*!
@@ -630,7 +735,7 @@ public:
*/
Int<value_size> & operator=(unsigned int i)
{
UInt<value_size>::FromUInt(uint(i));
FromUInt(uint(i));
return *this;
}
@@ -644,7 +749,7 @@ public:
*/
Int(unsigned int i)
{
UInt<value_size>::FromUInt(uint(i));
FromUInt(uint(i));
}
#endif
@@ -678,18 +783,6 @@ public:
}
/*!
the copy constructor
*/
template<uint argument_size>
Int(const Int<argument_size> & u) : UInt<value_size>::size(value_size)
{
// look that 'size' we still set as 'value_size' and not as u.value_size
operator=(u);
}
/*!
the destructor
*/
@@ -697,6 +790,7 @@ public:
{
}
/*!
this method returns the lowest value from table with a sign

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2007, Tomasz Sowa
* Copyright (c) 2006-2008, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -102,7 +102,7 @@ public:
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
return true;
if( can_be_digit && (c>='0' && c<='9') )
if( can_be_digit && ((c>='0' && c<='9') || c=='_') )
return true;
return false;

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2007, Tomasz Sowa
* Copyright (c) 2006-2008, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,7 @@ namespace ttmath
x = [+|-]Value[operator[+|-]Value][operator[+|-]Value]...
where:
an operator can be:
^ (pow) (the highest priority)
^ (pow) (almost the heighest priority, look below at 'short mul')
* (mul)
/ (div) (* and / have the same priority)
@@ -85,6 +85,12 @@ namespace ttmath
|| (logical or) (the lowest priority)
short mul:
or if the second Value (Var below) is either a variable or function there cannot be
an operator between them, e.g.
[+|-]ValueVar is treated as [+|-]Value * Var and the multiplication
has the greatest priority: 2^3m equals 2^(3*m)
and Value can be:
constant e.g. 100
@@ -106,6 +112,7 @@ namespace ttmath
for separating parameters
"1 < 2" (the result will be: 1)
"4 < 3" (the result will be: 0)
"2+x" (of course if the variable 'x' is defined)
etc.
we can also use a semicolon for separating any 'x' input strings
@@ -122,13 +129,15 @@ class Parser
private:
/*!
there are 5 mathematical operators as follows:
there are 5 mathematical operators as follows (with their standard priorities):
add (+)
sub (-)
mul (*)
div (/)
pow (^)
with their standard priorities
and 'shortmul' used when there is no any operators between
a first parameter and a variable or function
(the 'shortmul' has the greatest priority e.g. '5^3m' equals '5^(3*m)' )
*/
class MatOperator
{
@@ -136,7 +145,7 @@ private:
enum Type
{
none,add,sub,mul,div,pow,lt,gt,let,get,eq,neq,lor,land
none,add,sub,mul,div,pow,lt,gt,let,get,eq,neq,lor,land,shortmul
};
@@ -181,6 +190,10 @@ private:
priority = 14;
break;
case shortmul:
priority = 20;
break;
default:
Error( err_internal_error );
break;
@@ -426,7 +439,7 @@ void SkipWhiteCharacters()
/*!
a auxiliary method for RecurrenceParsingVariablesOrFunction(...)
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/
void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const std::string & name)
{
@@ -444,7 +457,7 @@ void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, cons
/*!
a auxiliary method for RecurrenceParsingVariablesOrFunction(...)
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/
void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::string & name)
{
@@ -455,7 +468,7 @@ void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::stri
}
/*!
a auxiliary method for RecurrenceParsingVariablesOrFunction(...)
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/
void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::string & name)
{
@@ -618,6 +631,7 @@ void Factorial(int sindex, int amount_of_args, ValueType & result)
Error( err );
}
void Abs(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
@@ -1030,6 +1044,162 @@ void Coth(int sindex, int amount_of_args, ValueType & result)
}
void Root(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 2 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::Root(stack[sindex].value, stack[sindex+2].value, &err);
if( err != err_ok )
Error( err );
}
void ASinh(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::ASinh(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void ACosh(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::ACosh(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void ATanh(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::ATanh(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void ACoth(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::ACoth(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void BitAnd(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 2 )
Error( err_improper_amount_of_arguments );
uint err;
result = stack[sindex].value;
err = result.BitAnd(stack[sindex+2].value);
switch(err)
{
case 1:
Error( err_overflow );
break;
case 2:
Error( err_improper_argument );
break;
}
}
void BitOr(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 2 )
Error( err_improper_amount_of_arguments );
uint err;
result = stack[sindex].value;
err = result.BitOr(stack[sindex+2].value);
switch(err)
{
case 1:
Error( err_overflow );
break;
case 2:
Error( err_improper_argument );
break;
}
}
void BitXor(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 2 )
Error( err_improper_amount_of_arguments );
uint err;
result = stack[sindex].value;
err = result.BitXor(stack[sindex+2].value);
switch(err)
{
case 1:
Error( err_overflow );
break;
case 2:
Error( err_improper_argument );
break;
}
}
void Sum(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args == 0 )
Error( err_improper_amount_of_arguments );
result = stack[sindex].value;
for(int i=1 ; i<amount_of_args ; ++i )
if( result.Add( stack[ sindex + i*2 ].value ) )
Error( err_overflow );
}
void Avg(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args == 0 )
Error( err_improper_amount_of_arguments );
result = stack[sindex].value;
for(int i=1 ; i<amount_of_args ; ++i )
if( result.Add( stack[ sindex + i*2 ].value ) )
Error( err_overflow );
if( result.Div( amount_of_args ) )
Error( err_overflow );
}
/*!
this method returns the value from a user-defined function
@@ -1107,7 +1277,7 @@ void CallFunction(const std::string & function_name, int amount_of_args, int sin
/*!
insert a function to the functions' table
inserting a function to the functions' table
function_name - name of the function
pf - pointer to the function (to the wrapper)
@@ -1119,7 +1289,7 @@ void InsertFunctionToTable(const std::string & function_name, pfunction pf)
/*!
insert a function to the variables' table
inserting a function to the variables' table
(this function returns value of variable)
variable_name - name of the function
@@ -1178,11 +1348,26 @@ void CreateFunctionsTable()
InsertFunctionToTable(std::string("tgh"), &Parser<ValueType>::Tanh);
InsertFunctionToTable(std::string("coth"), &Parser<ValueType>::Coth);
InsertFunctionToTable(std::string("ctgh"), &Parser<ValueType>::Coth);
InsertFunctionToTable(std::string("root"), &Parser<ValueType>::Root);
InsertFunctionToTable(std::string("asinh"), &Parser<ValueType>::ASinh);
InsertFunctionToTable(std::string("acosh"), &Parser<ValueType>::ACosh);
InsertFunctionToTable(std::string("atanh"), &Parser<ValueType>::ATanh);
InsertFunctionToTable(std::string("atgh"), &Parser<ValueType>::ATanh);
InsertFunctionToTable(std::string("acoth"), &Parser<ValueType>::ACoth);
InsertFunctionToTable(std::string("actgh"), &Parser<ValueType>::ACoth);
InsertFunctionToTable(std::string("bitand"), &Parser<ValueType>::BitAnd);
InsertFunctionToTable(std::string("bitor"), &Parser<ValueType>::BitOr);
InsertFunctionToTable(std::string("bitxor"), &Parser<ValueType>::BitXor);
InsertFunctionToTable(std::string("band"), &Parser<ValueType>::BitAnd);
InsertFunctionToTable(std::string("bor"), &Parser<ValueType>::BitOr);
InsertFunctionToTable(std::string("bxor"), &Parser<ValueType>::BitXor);
InsertFunctionToTable(std::string("sum"), &Parser<ValueType>::Sum);
InsertFunctionToTable(std::string("avg"), &Parser<ValueType>::Avg);
}
/*!
this method create the table of variables
this method creates the table of variables
*/
void CreateVariablesTable()
{
@@ -1195,7 +1380,7 @@ void CreateVariablesTable()
/*!
convert from a big letter to a small one
converting from a big letter to a small one
*/
int ToLowerCase(int c)
{
@@ -1206,8 +1391,6 @@ return c;
}
/*!
this method read the name of a variable or a function
@@ -1224,29 +1407,31 @@ int character;
result.erase();
character = ToLowerCase(*pstring);
character = *pstring;
/*
the first letter must be from range 'a' - 'z'
the first letter must be from range 'a' - 'z' or 'A' - 'Z'
*/
if( character<'a' || character>'z' )
if( ! (( character>='a' && character<='z' ) || ( character>='A' && character<='Z' )) )
Error( err_unknown_character );
do
{
result += character;
character = ToLowerCase( * ++pstring );
character = * ++pstring;
}
while( (character>='a' && character<='z') ||
(character>='0' && character<='9') );
(character>='A' && character<='Z') ||
(character>='0' && character<='9') ||
character=='_' );
SkipWhiteCharacters();
/*
if there's character '(' that means this name is a name of a function
if there's a character '(' that means this name is a name of a function
*/
if( *pstring == '(' )
{
@@ -1327,7 +1512,6 @@ const char * new_stack_pointer;
}
/*!
this method converts the character ascii c into the value in range <0;base-1>
@@ -1412,12 +1596,15 @@ int character;
return 2;
}
else
if( character=='#' || character=='&' || CharToDigit(character, base)!=-1 )
if( character=='#' || character=='&' ||
character==TTMATH_COMMA_CHARACTER_1 ||
(character==TTMATH_COMMA_CHARACTER_2 && TTMATH_COMMA_CHARACTER_2 != 0) ||
CharToDigit(character, base)!=-1 )
{
/*
warning:
if we're using for example the base equal 16
we can find a first character like 'e' that is there is not e=2.71..
we can find a first character like 'e' that is not e=2.71..
but the value 14, for this case we must use something like var::e for variables
(not implemented yet)
*/
@@ -1457,6 +1644,7 @@ void InsertOperatorToTable(const std::string & name, typename MatOperator::Type
operators_table.insert( std::make_pair(name, type) );
}
/*!
this method creates the table of operators
*/
@@ -1478,13 +1666,22 @@ void CreateMathematicalOperatorsTable()
}
bool CanBeMathematicalOperator(unsigned char c)
{
if( c=='|' || c=='&' || c=='!' || c=='=' || c=='<' || c=='>' ||
c=='*' || c=='/' || c=='+' || c=='-' || c=='^' )
return true;
/*!
returns true if 'str2' is the substring of str1
return false;
e.g.
true when str1="test" and str2="te"
*/
bool IsSubstring(const std::string & str1, const std::string & str2)
{
if( str2.length() > str1.length() )
return false;
for(std::string::size_type i=0 ; i<str2.length() ; ++i)
if( str1[i] != str2[i] )
return false;
return true;
}
@@ -1494,17 +1691,31 @@ return false;
void ReadMathematicalOperator(Item & result)
{
std::string oper;
typename OperatorsTable::iterator iter_old, iter_new;
for( ; CanBeMathematicalOperator(*pstring) ; ++pstring )
iter_old = operators_table.end();
for( ; true ; ++pstring )
{
oper += *pstring;
iter_new = operators_table.lower_bound(oper);
if( iter_new == operators_table.end() || !IsSubstring(iter_new->first, oper) )
{
oper.erase( --oper.end() ); // we've got mininum one element
typename OperatorsTable::iterator iter = operators_table.find(oper);
if( iter == operators_table.end() )
Error( err_unknown_operator );
result.type = Item::mat_operator;
result.moperator.SetType( iter->second );
if( iter_old != operators_table.end() && iter_old->first == oper )
{
result.type = Item::mat_operator;
result.moperator.SetType( iter_old->second );
break;
}
Error( err_unknown_operator );
}
iter_old = iter_new;
}
}
@@ -1535,10 +1746,15 @@ int ReadOperator(Item & result)
++pstring;
}
else
if( CanBeMathematicalOperator(*pstring) )
ReadMathematicalOperator(result);
if( (*pstring>='a' && *pstring<='z') || (*pstring>='A' && *pstring<='Z') )
{
// short mul (without any operators)
result.type = Item::mat_operator;
result.moperator.SetType( MatOperator::shortmul );
}
else
Error( err_unknown_character );
ReadMathematicalOperator(result);
return 0;
}
@@ -1599,6 +1815,7 @@ int res;
break;
case MatOperator::mul:
case MatOperator::shortmul:
if( value1.Mul(value2) ) Error( err_overflow );
break;
@@ -1616,6 +1833,7 @@ int res;
break;
default:
/*
on the stack left an unknown operator but we had to recognize its before
@@ -1718,7 +1936,7 @@ return kod;
/*!
this method calculate how many parameters there are on the stack
and index of the first parameter
and the index of the first parameter
if there aren't any parameters on the stack this method returns
'size' equals zero and 'index' pointing after the first bracket
@@ -2113,7 +2331,6 @@ ErrorCode Parse(const char * str)
stack.resize( default_stack_size );
try
{
Parse();

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2007, Tomasz Sowa
* Copyright (c) 2006-2008, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -58,10 +58,14 @@
/*!
the version of the library
TTMATH_PRERELEASE_VER is either zero or one
if zero that means this is the release version of the library
*/
#define TTMATH_MAJOR_VER 0
#define TTMATH_MINOR_VER 8
#define TTMATH_REVISION_VER 0
#define TTMATH_REVISION_VER 2
#define TTMATH_PRERELEASE_VER 0
/*!
@@ -178,7 +182,7 @@ namespace ttmath
/*!
characters which represent the comma operator
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing (default, can be overwritten in ToString() function)
TTMATH_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character
that means you can input values for example 1.2345 and 1,2345 as well
@@ -193,6 +197,7 @@ namespace ttmath
#define TTMATH_COMMA_CHARACTER_2 ','
/*!
this variable defines how many iterations are performed
during some kind of calculating when we're making any long formulas
@@ -243,7 +248,8 @@ namespace ttmath
err_object_exists,
err_unknown_object,
err_still_calculating,
err_too_big_factorial
err_too_big_factorial,
err_in_short_form_used_function
};

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2007, Tomasz Sowa
* Copyright (c) 2006-2008, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -52,6 +52,9 @@
/*!
\brief a namespace for the TTMath library
*/
namespace ttmath
{
@@ -69,8 +72,8 @@ class UInt
public:
/*!
buffer for this integer value
the first value (index 0) means the lowest word of this value
buffer for the integer value
table[0] - the lowest word of the value
*/
uint table[value_size];
@@ -117,7 +120,7 @@ public:
/*!
it returns the size of the table
this method returns the size of the table
*/
uint Size() const
{
@@ -126,17 +129,19 @@ public:
/*!
this method sets value zero
this method sets zero
*/
void SetZero()
{
// in the future here can be 'memset'
for(uint i=0 ; i<value_size ; ++i)
table[i] = 0;
}
/*!
this method sets value one
this method sets one
*/
void SetOne()
{
@@ -218,6 +223,8 @@ public:
}
/*!
*
* basic mathematic functions
@@ -225,14 +232,12 @@ public:
*/
/*!
this method adding ss2 to the this and adding carry if it's defined
adding ss2 to the this and adding carry if it's defined
(this = this + ss2 + c)
c must be zero or one (might be a bigger value than 1)
function returns carry (1) (if it was)
function returns carry (1) (if it has been)
*/
uint Add(const UInt<value_size> & ss2, uint c=0)
{
@@ -339,8 +344,8 @@ public:
/*!
this method adds one word (at a specific position)
and returns a carry (if it was)
adding one word (at a specific position)
and returning a carry (if it has been)
e.g.
@@ -355,7 +360,7 @@ public:
table[1] = 30 + 2;
table[2] = 5;
of course if there was a carry from table[3] it would be returned
of course if there was a carry from table[2] it would be returned
*/
uint AddInt(uint value, uint index = 0)
{
@@ -462,7 +467,7 @@ public:
/*!
this method adds only two unsigned words to the existing value
adding only two unsigned words to the existing value
and these words begin on the 'index' position
(it's used in the multiplication algorithm 2)
@@ -630,12 +635,12 @@ public:
/*!
this method's subtracting ss2 from the 'this' and subtracting
subtracting ss2 from the 'this' and subtracting
carry if it has been defined
(this = this - ss2 - c)
c must be zero or one (might be a bigger value than 1)
function returns carry (1) (if it was)
function returns carry (1) (if it has been)
*/
uint Sub(const UInt<value_size> & ss2, uint c=0)
{
@@ -819,7 +824,7 @@ public:
"leal (%%ebx,%%edx,4), %%ebx \n"
"movl %%esi, %%edx \n"
"movl %%esi, %%edx \n"
"clc \n"
"1: \n"
@@ -878,18 +883,31 @@ public:
}
private:
#ifdef TTMATH_PLATFORM32
/*!
this method moving once all bits into the left side
return value <- this <- C
this method moves all bits into the left hand side
return value <- this <- c
the lowest bit will hold value of 'c' and
function returns the highest bit
the lowest *bits* will be held the 'c' and
the state of one additional bit (on the left hand side)
will be returned
for example:
let this is 001010000
after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1
*/
uint Rcl(uint c=0)
uint Rcl2(uint bits, uint c)
{
if( bits == 0 )
return 0;
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
register sint b = value_size;
register uint * p1 = table;
@@ -900,12 +918,16 @@ public:
push eax
push ebx
push ecx
push edx
mov ecx,[b]
mov ebx,[p1]
mov edx, [bits]
a:
xor eax, eax
sub eax, [c]
mov eax,0
sub eax,[c]
mov ecx, [b]
mov ebx, [p1]
p:
rcl dword ptr[ebx],1
@@ -917,10 +939,15 @@ public:
loop p
dec edx
jnz a
mov eax,0
adc eax,eax
mov [c],eax
pop edx
pop ecx
pop ebx
pop eax
@@ -931,12 +958,16 @@ public:
#ifdef __GNUC__
__asm__ __volatile__(
"push %%esi \n"
"2: \n"
"xorl %%eax,%%eax \n"
"subl %%edx,%%eax \n"
"push %%ebx \n"
"push %%ecx \n"
"movl $0,%%eax \n"
"subl %%edx,%%eax \n"
"1: \n"
"rcll $1,(%%ebx) \n"
@@ -947,14 +978,20 @@ public:
"loop 1b \n"
"movl $0, %%edx \n"
"adcl %%edx,%%edx \n"
"pop %%ecx \n"
"pop %%ebx \n"
"decl %%esi \n"
"jnz 2b \n"
"movl $0, %%edx \n"
"adcl %%edx, %%edx \n"
"pop %%esi \n"
: "=d" (c)
: "0" (c), "c" (b), "b" (p1)
: "0" (c), "c" (b), "b" (p1), "S" (bits)
: "%eax", "cc", "memory" );
#endif
@@ -965,14 +1002,24 @@ public:
/*!
this method moving once all bits into the right side
C -> *this -> return value
this method moves all bits into the right hand side
C -> this -> return value
the highest bit will be held value of 'c' and
function returns the lowest bit
the highest *bits* will be held the 'c' and
the state of one additional bit (on the right hand side)
will be returned
for example:
let this is 000000010
after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1
*/
uint Rcr(uint c=0)
uint Rcr2(uint bits, uint c)
{
if( bits == 0 )
return 0;
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
register sint b = value_size;
register uint * p1 = table;
@@ -983,15 +1030,19 @@ public:
push eax
push ebx
push ecx
push edx
mov edx,[bits]
a:
xor eax,eax
sub eax,[c]
mov ebx,[p1]
mov ecx,[b]
lea ebx,[ebx+4*ecx]
mov eax,0
sub eax,[c]
p:
dec ebx
dec ebx
@@ -1001,11 +1052,16 @@ public:
rcr dword ptr [ebx],1
loop p
dec edx
jnz a
mov eax,0
adc eax,eax
mov [c],eax
pop edx
pop ecx
pop ebx
pop eax
@@ -1016,12 +1072,17 @@ public:
#ifdef __GNUC__
__asm__ __volatile__(
"push %%esi \n"
"2: \n"
"push %%ebx \n"
"push %%ecx \n"
"leal (%%ebx,%%ecx,4),%%ebx \n"
"movl $0, %%eax \n"
"xorl %%eax, %%eax \n"
"subl %%edx, %%eax \n"
"1: \n"
@@ -1034,14 +1095,20 @@ public:
"loop 1b \n"
"movl $0, %%edx \n"
"adcl %%edx,%%edx \n"
"pop %%ecx \n"
"pop %%ebx \n"
"decl %%esi \n"
"jnz 2b \n"
"movl $0, %%edx \n"
"adcl %%edx, %%edx \n"
"pop %%esi \n"
: "=d" (c)
: "0" (c), "c" (b), "b" (p1)
: "0" (c), "c" (b), "b" (p1), "S" (bits)
: "%eax", "cc", "memory" );
#endif
@@ -1052,8 +1119,49 @@ public:
#endif
/*!
an auxiliary method for moving bits into the left hand side
this method moves only words
*/
void RclMoveAllWords( sint & all_words, uint & rest_bits, uint & last_c,
uint bits, uint c)
{
rest_bits = sint(bits % TTMATH_BITS_PER_UINT);
all_words = sint(bits / TTMATH_BITS_PER_UINT);
if( all_words >= sint(value_size) )
{
if( all_words==value_size && rest_bits==0 )
last_c = table[0] & 1;
all_words = value_size; // not value_size - 1
rest_bits = 0;
}
if( all_words > 0 )
{
sint first;
sint second;
last_c = table[value_size - all_words] & 1; // all_words is greater than 0
// copying the first part of the value
for(first = value_size-1, second=first-all_words ; second>=0 ; --first, --second)
table[first] = table[second];
// sets the rest bits of value into 'c'
uint mask = c ? TTMATH_UINT_MAX_VALUE : 0;
for( ; first>=0 ; --first )
table[first] = mask;
}
}
public:
/*!
this method moving all bits into the left side 'bits' times
moving all bits into the left side 'bits' times
return value <- this <- C
bits is from a range of <0, man * TTMATH_BITS_PER_UINT>
@@ -1062,42 +1170,95 @@ public:
the value c will be set into the lowest bits
and the method returns state of the last moved bit
*/
uint Rcl(uint bits, uint c)
uint Rcl(uint bits, uint c=0)
{
sint first;
sint second;
uint last_c = 0;
if( bits > value_size*TTMATH_BITS_PER_UINT )
bits = value_size*TTMATH_BITS_PER_UINT;
sint all_words = 0;
uint rest_bits = bits;
sint all_words = sint(bits) / sint(TTMATH_BITS_PER_UINT);
if( bits >= TTMATH_BITS_PER_UINT )
RclMoveAllWords(all_words, rest_bits, last_c, bits, c);
if( all_words > 0 )
// rest_bits is from 0 to TTMATH_BITS_PER_UINT-1 now
if( rest_bits > 0 )
{
// copying the first part of the value
for(first = value_size-1, second=first-all_words ; second>=0 ; --first, --second)
// if rest_bits is greater than a half of TTMATH_BITS_PER_UINT
// we're moving bits into the right hand side
// (TTMATH_BITS_PER_UINT-rest_bits) times
// and then we're moving one word into left
if( rest_bits > TTMATH_BITS_PER_UINT/2 + 1 )
{
last_c = table[first] & 1;
table[first] = table[second];
uint temp = table[0];
Rcr2(TTMATH_BITS_PER_UINT-rest_bits,0);
last_c = table[value_size-1] & 1;
for(uint i=value_size-1 ; i>0 ; --i)
table[i] = table[i-1];
table[0] = temp << rest_bits;
if( c )
{
uint mask = TTMATH_UINT_MAX_VALUE << rest_bits;
table[0] |= ~mask;
}
}
else
{
last_c = Rcl2(rest_bits, c);
}
// sets the rest bits of value into 'c'
uint mask = (c!=0)? TTMATH_UINT_MAX_VALUE : 0;
for( ; first>=0 ; --first )
table[first] = mask;
}
sint rest_bits = sint(bits) % sint(TTMATH_BITS_PER_UINT);
for( ; rest_bits > 0 ; --rest_bits )
last_c = Rcl(c);
return last_c;
}
private:
/*!
an auxiliary method for moving bits into the right hand side
this method moves only words
*/
void RcrMoveAllWords( sint & all_words, uint & rest_bits, uint & last_c,
uint bits, uint c)
{
rest_bits = sint(bits % TTMATH_BITS_PER_UINT);
all_words = sint(bits / TTMATH_BITS_PER_UINT);
if( all_words >= sint(value_size) )
{
if( all_words==value_size && rest_bits==0 )
last_c = (table[value_size-1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
all_words = value_size; // not value_size - 1
rest_bits = 0;
}
if( all_words > 0 )
{
uint first;
uint second;
last_c = (table[all_words - 1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0; // all_words is > 0
// copying the first part of the value
for(first=0, second=all_words ; second<value_size ; ++first, ++second)
table[first] = table[second];
// sets the rest bits of value into 'c'
uint mask = c ? TTMATH_UINT_MAX_VALUE : 0;
for( ; first<value_size ; ++first )
table[first] = mask;
}
}
public:
/*!
this method moving all bits into the right side 'bits' times
moving all bits into the right side 'bits' times
c -> this -> return value
bits is from a range of <0, man * TTMATH_BITS_PER_UINT>
@@ -1106,39 +1267,42 @@ public:
the value c will be set into the highest bits
and the method returns state of the last moved bit
*/
uint Rcr(uint bits, uint c)
uint Rcr(uint bits, uint c=0)
{
sint first;
sint second;
sint last_c = 0;
uint last_c = 0;
sint all_words = 0;
uint rest_bits = bits;
if( bits > value_size*TTMATH_BITS_PER_UINT )
bits = value_size*TTMATH_BITS_PER_UINT;
if( bits >= TTMATH_BITS_PER_UINT )
RcrMoveAllWords(all_words, rest_bits, last_c, bits, c);
sint all_words = sint(bits) / sint(TTMATH_BITS_PER_UINT);
if( all_words > 0 )
// rest_bits is from 0 to TTMATH_BITS_PER_UINT-1 now
if( rest_bits > 0 )
{
// copying the first part of the value
for(first=0, second=all_words ; second<sint(value_size) ; ++first, ++second)
if( rest_bits > TTMATH_BITS_PER_UINT/2 + 1 )
{
last_c = table[first] & TTMATH_UINT_HIGHEST_BIT;
table[first] = table[second];
uint temp = table[value_size-1];
Rcl2(TTMATH_BITS_PER_UINT-rest_bits,0);
last_c = (table[0] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
for(uint i=0 ; i<value_size-1 ; ++i)
table[i] = table[i+1];
table[value_size-1] = temp >> rest_bits;
if( c )
{
uint mask = TTMATH_UINT_MAX_VALUE >> rest_bits;
table[value_size-1] |= ~mask;
}
}
else
{
last_c = Rcr2(rest_bits, c);
}
if( last_c )
last_c = 1;
// sets the rest bits of value into 'c'
uint mask = (c!=0)? TTMATH_UINT_MAX_VALUE : 0;
for( ; first<sint(value_size) ; ++first )
table[first] = mask;
}
sint rest_bits = sint(bits) % sint(TTMATH_BITS_PER_UINT);
for( ; rest_bits > 0 ; --rest_bits )
last_c = Rcr(c);
return last_c;
}
@@ -1175,14 +1339,14 @@ public:
table[i] = 0;
}
// moving the rest bits (max TTMATH_BITS_PER_UINT -- only one word)
while( !IsTheHighestBitSet() )
{
Rcl();
++moving;
}
uint moving2 = FindLeadingBitInWord( table[value_size-1] );
// moving2 is different from -1 because the value table[value_size-1]
// is not zero
return moving;
moving2 = TTMATH_BITS_PER_UINT - moving2 - 1;
Rcl(moving2);
return moving + moving2;
}
@@ -1314,7 +1478,7 @@ public:
/*!
it sets the bit bit_index
setting the 'bit_index' bit
bit_index bigger or equal zero
*/
@@ -1330,6 +1494,76 @@ public:
}
/*!
this method performs a bitwise operation AND
*/
void BitAnd(const UInt<value_size> & ss2)
{
for(uint x=0 ; x<value_size ; ++x)
table[x] &= ss2.table[x];
}
/*!
this method performs a bitwise operation OR
*/
void BitOr(const UInt<value_size> & ss2)
{
for(uint x=0 ; x<value_size ; ++x)
table[x] |= ss2.table[x];
}
/*!
this method performs a bitwise operation XOR
*/
void BitXor(const UInt<value_size> & ss2)
{
for(uint x=0 ; x<value_size ; ++x)
table[x] ^= ss2.table[x];
}
/*!
this method performs a bitwise operation NOT
*/
void BitNot()
{
for(uint x=0 ; x<value_size ; ++x)
table[x] = ~table[x];
}
/*!
this method performs a bitwise operation NOT but only
on the range of <0, leading_bit>
for example:
BitNot2(8) = BitNot2( 1000(bin) ) = 111(bin) = 7
*/
void BitNot2()
{
uint table_id, index;
if( FindLeadingBit(table_id, index) )
{
for(uint x=0 ; x<table_id ; ++x)
table[x] = ~table[x];
uint mask = TTMATH_UINT_MAX_VALUE;
uint shift = TTMATH_BITS_PER_UINT - index - 1;
if(shift)
mask >>= shift;
table[table_id] ^= mask;
}
else
table[0] = 1;
}
/*!
*
* Multiplication
@@ -1340,7 +1574,7 @@ public:
public:
#ifdef TTMATH_PLATFORM32
@@ -1442,6 +1676,47 @@ public:
return 0;
}
/*!
multiplication: result = this * ss2
we're using this method only when result_size is greater than value_size
if so there will not be a carry
*/
template<uint result_size>
uint MulInt(uint ss2, UInt<result_size> & result)
{
uint r2,r1;
uint x1size=value_size;
uint x1start=0;
if( value_size >= result_size )
return 1;
result.SetZero();
if( value_size > 2 )
{
// if the value_size is smaller than or equal to 2
// there is no sense to set x1size and x1start to another values
for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size);
if( x1size==0 )
return 0;
for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start);
}
for(uint x1=x1start ; x1<x1size ; ++x1)
{
MulTwoWords(table[x1], ss2, &r2, &r1 );
result.AddTwoInts(r2,r1,x1);
}
return 0;
}
/*!
the multiplication 'this' = 'this' * ss2
@@ -1504,7 +1779,7 @@ public:
if( Add(*this) )
return 1;
if( ss1.Rcl() )
if( ss1.Rcl(1) )
if( Add(ss2) )
return 1;
}
@@ -1893,7 +2168,7 @@ private:
div_a:
c = Rcl(c);
c = Rcl(1, c);
c = rest.Add(rest,c);
c = rest.Sub(divisor,c);
@@ -1908,12 +2183,12 @@ private:
if(loop)
goto div_a;
c = Rcl(c);
c = Rcl(1, c);
return 0;
div_c:
c = Rcl(c);
c = Rcl(1, c);
c = rest.Add(rest,c);
c = rest.Add(divisor);
@@ -1926,7 +2201,7 @@ private:
if(loop)
goto div_c;
c = Rcl(c);
c = Rcl(1, c);
c = rest.Add(divisor);
return 0;
@@ -2007,7 +2282,7 @@ private:
if( CmpSmaller(divisor_copy, table_id) )
{
divisor_copy.Rcr();
divisor_copy.Rcr(1);
--bits_diff;
}
@@ -2283,16 +2558,17 @@ private:
{
uint c = 0;
// !!!!!!!!! change
for( d = 0 ; (v.table[n-1] & TTMATH_UINT_HIGHEST_BIT) == 0 ; ++d )
{
// we can move the bits only to the 'n-1' index but at the moment
// we don't have such method
// maybe it's time to write it now?
v.Rcl(0);
v.Rcl(1, 0);
c <<= 1;
if( Rcl(0) )
if( Rcl(1, 0) )
c += 1;
}
@@ -2388,7 +2664,7 @@ private:
public:
/*!
this method sets n firt bits to value zero
this method sets n first bits to value zero
For example:
let n=2 then if there's a value 111 (bin) there'll be '100' (bin)
@@ -2424,7 +2700,7 @@ public:
/*!
it returns true if the highest bit of the value is set
this method returns true if the highest bit of the value is set
*/
bool IsTheHighestBitSet() const
{
@@ -2433,7 +2709,7 @@ public:
/*!
it returns true if the lowest bit of the value is set
this method returns true if the lowest bit of the value is set
*/
bool IsTheLowestBitSet() const
{
@@ -2442,7 +2718,7 @@ public:
/*!
it returns true if the value is equal zero
this method returns true if the value is equal zero
*/
bool IsZero() const
{
@@ -2475,7 +2751,7 @@ public:
A -> 10
f -> 15
this method don't check whether c 'is' correct or not
this method don't check whether c is correct or not
*/
static uint CharToDigit(uint c)
{
@@ -2845,6 +3121,8 @@ public:
}
/*!
*
* methods for comparing
@@ -2852,6 +3130,14 @@ public:
*/
/*!
this method returns true if 'this' is smaller than 'l'
'index' is an index of the first word from will be the comparison performed
(note: we start the comparison from back - from the last word, when index is -1 /default/
it is automatically set into the last word)
I introduced it for some kind of optimization made in the second division algorithm (Div2)
*/
bool CmpSmaller(const UInt<value_size> & l, sint index = -1) const
{
sint i;
@@ -2874,6 +3160,15 @@ public:
/*!
this method returns true if 'this' is bigger than 'l'
'index' is an index of the first word from will be the comparison performed
(note: we start the comparison from back - from the last word, when index is -1 /default/
it is automatically set into the last word)
I introduced it for some kind of optimization made in the second division algorithm (Div2)
*/
bool CmpBigger(const UInt<value_size> & l, sint index = -1) const
{
sint i;
@@ -2895,6 +3190,13 @@ public:
}
/*!
this method returns true if 'this' is equal 'l'
'index' is an index of the first word from will be the comparison performed
(note: we start the comparison from back - from the last word, when index is -1 /default/
it is automatically set into the last word)
*/
bool CmpEqual(const UInt<value_size> & l, sint index = -1) const
{
sint i;
@@ -2912,6 +3214,15 @@ public:
return true;
}
/*!
this method returns true if 'this' is smaller than or equal 'l'
'index' is an index of the first word from will be the comparison performed
(note: we start the comparison from back - from the last word, when index is -1 /default/
it is automatically set into the last word)
*/
bool CmpSmallerEqual(const UInt<value_size> & l, sint index=-1) const
{
sint i;
@@ -2932,6 +3243,15 @@ public:
return true;
}
/*!
this method returns true if 'this' is bigger than or equal 'l'
'index' is an index of the first word from will be the comparison performed
(note: we start the comparison from back - from the last word, when index is -1 /default/
it is automatically set into the last word)
*/
bool CmpBiggerEqual(const UInt<value_size> & l, sint index=-1) const
{
sint i;
@@ -2953,7 +3273,9 @@ public:
}
//
/*
operators for comparising
*/
bool operator<(const UInt<value_size> & l) const
{
@@ -2961,7 +3283,6 @@ public:
}
bool operator>(const UInt<value_size> & l) const
{
return CmpBigger(l);
@@ -2974,7 +3295,6 @@ public:
}
bool operator!=(const UInt<value_size> & l) const
{
return !operator==(l);
@@ -3090,6 +3410,7 @@ public:
return *this;
}
/*!
Prefix operator e.g ++variable
*/
@@ -3183,6 +3504,11 @@ public:
#ifdef TTMATH_PLATFORM64
private:
uint Rcl2(uint bits, uint c);
uint Rcr2(uint bits, uint c);
public:
// these methods are for 64bit processors and are defined in 'ttmathuint64.h'
UInt<value_size> & operator=(unsigned int i);
UInt(unsigned int i);
@@ -3194,8 +3520,6 @@ public:
uint AddTwoInts(uint x2, uint x1, uint index);
uint Sub(const UInt<value_size> & ss2, uint c=0);
uint SubInt(uint value, uint index = 0);
uint Rcl(uint c=0);
uint Rcr(uint c=0);
static sint FindLeadingBitInWord(uint x);
static uint SetBitInWord(uint value, uint bit);
static void MulTwoWords(uint a, uint b, uint * result2, uint * result1);

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2007, Tomasz Sowa
* Copyright (c) 2006-2008, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -416,7 +416,7 @@ namespace ttmath
"movq $0, %%rdx \n"
"movq (%%rbx), %%rax \n"
"addq %%rsi, %%rax \n"
"addq %%rsi, %%rax \n"
"movq %%rax, (%%rbx) \n"
"inc %%rbx \n"
@@ -429,7 +429,7 @@ namespace ttmath
"inc %%rbx \n"
"movq (%%rbx), %%rax \n"
"adcq %%rdi, %%rax \n"
"adcq %%rdi, %%rax \n"
"movq %%rax, (%%rbx) \n"
"jnc 2f \n"
@@ -638,17 +638,27 @@ namespace ttmath
/*!
this method moving once all bits into the left side
return value <- this <- C
this method moves all bits into the left hand side
return value <- this <- c
the lowest *bits* will be held the 'c' and
the state of one additional bit (on the left hand side)
will be returned
for example:
let this is 001010000
after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1
***this method is created only on a 64bit platform***
the lowest bit will hold value of 'c' and
function returns the highest bit
*/
template<uint value_size>
uint UInt<value_size>::Rcl(uint c)
uint UInt<value_size>::Rcl2(uint bits, uint c)
{
if( bits == 0 )
return 0;
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
register sint b = value_size;
register uint * p1 = table;
@@ -659,12 +669,17 @@ namespace ttmath
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rsi \n"
"2: \n"
"xorq %%rax,%%rax \n"
"subq %%rdx,%%rax \n"
"push %%rbx \n"
"push %%rcx \n"
"movq $0,%%rax \n"
"subq %%rdx,%%rax \n"
"1: \n"
"rclq $1,(%%rbx) \n"
@@ -679,14 +694,20 @@ namespace ttmath
"loop 1b \n"
"movq $0, %%rdx \n"
"adcq %%rdx,%%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
"decq %%rsi \n"
"jnz 2b \n"
"movq $0, %%rdx \n"
"adcq %%rdx, %%rdx \n"
"pop %%rsi \n"
: "=d" (c)
: "0" (c), "c" (b), "b" (p1)
: "0" (c), "c" (b), "b" (p1), "S" (bits)
: "%rax", "cc", "memory" );
#endif
@@ -697,17 +718,27 @@ namespace ttmath
/*!
this method moving once all bits into the right side
C -> *this -> return value
this method moves all bits into the right hand side
C -> this -> return value
the highest *bits* will be held the 'c' and
the state of one additional bit (on the right hand side)
will be returned
for example:
let this is 000000010
after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1
***this method is created only on a 64bit platform***
the highest bit will be held value of 'c' and
function returns the lowest bit
*/
template<uint value_size>
uint UInt<value_size>::Rcr(uint c)
uint UInt<value_size>::Rcr2(uint bits, uint c)
{
if( bits == 0 )
return 0;
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
register sint b = value_size;
register uint * p1 = table;
@@ -720,12 +751,18 @@ namespace ttmath
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rsi \n"
"2: \n"
"push %%rbx \n"
"push %%rcx \n"
"leaq (%%rbx,%%rcx,8),%%rbx \n"
"movq $0, %%rax \n"
"xorq %%rax, %%rax \n"
"subq %%rdx, %%rax \n"
"1: \n"
@@ -742,14 +779,20 @@ namespace ttmath
"loop 1b \n"
"movq $0, %%rdx \n"
"adcq %%rdx,%%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
"decq %%rsi \n"
"jnz 2b \n"
"movq $0, %%rdx \n"
"adcq %%rdx,%%rdx \n"
"pop %%rsi \n"
: "=d" (c)
: "0" (c), "c" (b), "b" (p1)
: "0" (c), "c" (b), "b" (p1), "S" (bits)
: "%rax", "cc", "memory" );
#endif
@@ -940,4 +983,3 @@ namespace ttmath
#endif
} //namespace