26 Commits
0.8.2 ... 0.8.3

Author SHA1 Message Date
d8b829f4c5 changed: version of the library: 0.8.3 now
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@120 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-04-06 16:34:19 +00:00
fca1bc1a33 added: Objects::IsDefined(const std::string & name)
returning true if such an object is defined


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@117 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-04-02 05:21:49 +00:00
c65857297b fixed: the parser didn't correctly treat operators for changing the base
(radix) -- operators '#' and '&', e.g.:
       '#sin(1)' was equal '0' -- there was a zero from '#' and then
       it was multipied by 'sin(1)'
       the parser didn't check whether Big::FromString() has actually
       read a proper value -- the method Big::FromString() didn't have
       something to report such a situation
fixed: Big::FromString() when the base is 10, the method reads the scientific
       part only if such a part it correctly supplied, e.g:
       '1234e10', '1234e+10', '1234e-5'
       previous '1234e' was treated as: '1234e0' (now parsing stops on 'e' and
       the 'e' can be parsed by other parsers, e.g. the mathematical
       parser -- now in the parser would be: '1234e' = '1234 * e' = '3354,3597...' )
added: to Int::FromString(): parameter 'const char ** after_source = 0'
       if exists it's pointing at the end of the parsed string
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)
added: the parser checks itself for the operators for changing the base
       (operators '#' and '&')
changed: in the parser: the form with operators '#' and '&' is as follows:
       [-|+][#|&]numeric_value
       previous was: [-|+][#|&][-|+]numeric_value
removed: Big::FromString() this method doesn't longer recognize operators
       for changing the base ('#' and '&')
changed: in the parser: the short form of multiplication has the same
       priority as the normal multiplication, e.g.:
       '2x^3' = 2 * (x^3)
       previous the priority was greater than powering priority
       previous: '2x^3' = (2*x) ^ 3



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@113 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-28 17:40:36 +00:00
f530635262 changed: doxygen.cfg changed lines ends: dos mode to unix mode (\r\n to \n)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@112 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-27 22:35:41 +00:00
9327b4ebd4 changed: updated CHANGELOG to previous commit
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@111 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-27 22:31:54 +00:00
d695785cbb fixed: in function DegToRad(const ValueType & x, ErrorCode * err = 0) it is better
to make division first and then mutliplication -- the result is more
       accurate especially when x is: 90,180,270 or 360
added: global template functions in ttmath.h:
       ValueType GradToRad(const ValueType & x, ErrorCode * err = 0)
       ValueType RadToGrad(const ValueType & x, ErrorCode * err = 0)
       ValueType DegToGrad(const ValueType & x, ErrorCode * err = 0)
       ValueType DegToGrad(const ValueType & d, const ValueType & m,
                           const ValueType & s, ErrorCode * err = 0)
       ValueType GradToDeg(const ValueType & x, ErrorCode * err = 0)
added: Parser::SetDegRadGrad(int angle) - 0 deg, 1 rad (default), 2 grad
       this affects following functions (in the parser only): sin, cos, tan, cot,
       asin, acos, atan, acot
added: functions to the parser: gradtorad(grad), radtograd(rad), degtograd(deg),
       degtograd(d,m,s), gradtodeg(grad)
removed: Big::Ln() and Big::Log() some old info was removed


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@110 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-27 22:26:51 +00:00
85d1b87ac0 added: '#ifndef __GNUC__' to Big::Pow() where is using '#pragma warning'
in order to not confuse GCC


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@109 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-25 02:01:42 +00:00
bfdc6d3df3 fixed: Big::Pow(const Big<exp, man> & pow)
it's using PowInt() only when pow.exponent is in range (-man*TTMATH_BITS_PER_UINT; 0]
       previously the powering 'hung' on an input like this: "(1+ 1e-10000) ^ 10e100000000"
       (the was 10e100000000 iterations in PowInt())


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@108 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-25 01:12:00 +00:00
5668fbecf5 changed: current info in CHANGELOG
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@107 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-24 21:10:17 +00:00
3899b8631c fixed: template Big::FromBig(const Big<another_exp, another_man> & another)
didn't correctly set the exponent (when the mantisses had different size -
       when 'man' was different from 'another_man')
       this had impact on operator= too
       sample:
       Big<2,3> a = 100;
       Big<3,5> b;
       b = a; // b had a wrong value


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@106 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-24 20:34:33 +00:00
460608859c added: 'constgen' directory -- there is a program there to generate some constants used in ttmathbig.h
changed: the size of built-in variables (constants) in ttmathbig.h
         now they consist of 256 32bit words
         macro TTMATH_BUILTIN_VARIABLES_SIZE is equal: 256u on a 32bit platform and 128ul on a 64bit platform
added:   macro CONSTANTSGENERATOR which is useful for generating constants
         (it's used by 'gen' program in 'constgen' directory)
         after declaring this macro the methods: ExpSurrounding0() and LnSurrounding1() will be public visible
         and the inner loop can do more iterations than TTMATH_ARITHMETIC_MAX_LOOP
changed: in methods: ExpSurrounding0() and LnSurrounding1() - the way of comparising with the last word
         (now we're comparing not with the last state but with a state from a few words back)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@105 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-12 20:54:46 +00:00
978815f12d fixed: there was a TTMATH_REREFENCE_ASSERT error in Big::PowUInt() caused by: start.Mul(start)
fixed:   Big::Add incorrectly rounded 'this' when both exponents were equal
         it caused that sometimes when adding a zero the result has changed
         this had impact among other things on FromString() method
         "0,8" had different binary representation from "0,80"
changed: renamed: Big::PowUInt(UInt<pow_size> pow) -> Big::Pow(UInt<pow_size> pow)
         it returns 2 when there is: 0^0
changed: renamed: Big::PowInt(Int<pow_size> pow) -> Big::Pow(Int<pow_size> pow)
         it returns 2 when there is: 0^0 or 0^(-something)
changed: renamed: Big::PowBUInt() -> PowUInt(), Big::PowBInt() -> Big::PowInt()
         they return 2 when the arguments are incorrect (like above)
changed: UInt::SetBitInWord(uint & value, uint bit) is taking the first argument by a reference now,
         the specific bit is set in the 'value' and the method returns the last state of the bit (zero or one)
added:   UInt::GetBit(uint bit_index) - returning the state of the specific bit
changed: UInt::SetBit(uint bit_index) - it's using TTMATH_ASSERT now
changed: Big::Mod2() - it's using mantissa.GetBit() now
added:   Big::operator=(double) and Big::Big(double)
added:   TTMATH_ASSERT somewhere in ttmathuint64.h
added:   UInt::Pow(UInt<value_size> pow) and Int::Pow(Int<value_size> pow)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@104 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-11 19:05:13 +00:00
404727f3de changed: small changes in: UInt:: RclMoveAllWords, UInt::RcrMoveAllWords, UInt::SetBitInWord(),
UInt::FindLeadingBitInWord, UInt::SetBitInWord
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
         this error was from the beginning of the TTMath library


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@103 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-07 22:54:42 +00:00
4aebe9aa18 fixed: UInt::Rcr2_one used edx but there was not a push/pop instruction
(it was in the intel syntax, edx changed to ecx)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@102 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-04 22:04:36 +00:00
e18201ba35 changed: UInt::Div3_Normalize - faster now
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@101 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-03 20:41:00 +00:00
5b24101a83 added: macros TTMATH_ASSERT to: UInt::AddInt UInt::AddTwoInts UInt::SubInt UInt::SetBitInWord
fixed:   UInt::FindLeadingBitInWord(x) didn't correctly return result -1 when the x was 0
         the mistake made by Thomas Braby, it was not in the 0.8.2 release
changed: tests: we do not test for lahf/sahf instructions now (in 64bit code)
         we don't use these instructions



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@97 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-02-17 11:37:12 +00:00
6da0386a2d added: tests: addtwoints for 64bits
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@96 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-02-16 18:11:38 +00:00
c7c859fc76 changed: UInt::FromString(...) skips the input digits when the value is too big
added: tests: addtwoints (only 32bit)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@95 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-02-16 17:57:34 +00:00
1d81dc75ff fixed: RclMoveAllWords() and RcrMoveAllWords() sometimes didn't return
the proper carry, (when 'bits' was greater than or equal to 'value_size')
        this had impact on Rcl() and Rcr(), they also returned the wrong carry


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@85 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-10-31 20:43:08 +00:00
712bfc9c3b added: UInt::Rcl2_one(c) and UInt::Rcr2_one(c)
they are much faster than UInt::Rcl2(1,c) and Rcr2(1,c)
changed: UInt::Rcl() and UInt::Rcr()
       we don't longer make the things with moving a half in the left and a half in the right
       we simply use Rcl2_one() and Rcl2() /Rcr2_one() and Rcr2()/


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@84 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-10-30 23:38:24 +00:00
91e7badb62 changed: asm code in: UInt::Sub, UInt::SubInt (32 and 64bit)
(much faster now)
changed: asm code in: UInt::Rcl2, UInt::Rcr2 (32 and 64bit)
         previous versions of Rcl2 and Rcr2 had O(n2) complexity,
         now they have O(n) and are much faster
changed: now we do not use LAHF and SAHF instructions (both in 32 and 64 bit code)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@83 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-10-29 21:54:27 +00:00
cfd719cca2 changed: asm code in UInt::Add, UInt::AddInt, AddTwoInts
32 and 64 bits, much faster now
added:   tests for UInt::AddInt
fixed:   tests: test_lahf() returned incorrect value for 32bit platform


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@82 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-10-25 20:05:51 +00:00
f1115a2ce9 added: test of the LAHF and SAHF instructions
(on a 64bit platform)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@81 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-10-23 20:17:40 +00:00
ca51020fe6 changed: 64bit asm code didn't want to compile
there were used 'lahf' and 'sahf' instructions
         probably they are supported in a new version of GCC
         with '-msahf' option but GCC 4.2.1 has no such option
         at the moment I'm using opcodes:
            lahf -> 9f
            sahf -> 9e
         Warning! these instructions are not on all 64bit processors
         from: http://gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html
         "Early Intel CPUs with Intel 64 lacked LAHF and SAHF instructions supported
          by AMD64 until introduction of Pentium 4 G1 step in December 2005."
changed: UInt::Add on 64bit platform
changed: UInt::Add on 32bit platform (a little)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@80 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-10-22 18:56:04 +00:00
f8f324f98f changed: UInt::FromString, added a parametr 'after_source'
which is pointing at the end of the parsing string
added:   initial import of tests: testing UInt::Add method
         (not finished)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@79 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-10-21 17:42:41 +00:00
cdd95f602c some optimisations made in assembler code by thomasbraby at zoom.co.uk
(not verified yet)
modified files: ttmathuint.h ttmathuint64.h
I've changed a little the intel syntax (it didn't want to compile)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@78 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-10-17 09:57:36 +00:00
19 changed files with 3045 additions and 1344 deletions

433
CHANGELOG
View File

@@ -1,171 +1,262 @@
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)
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
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
Version 0.7.0 (2007.02.24):
* 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
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):
* 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):
* added: New division algorithm (radix b) where b is 2^32
Version 0.8.3 (2009.04.06):
* fixed: RclMoveAllWords() and RcrMoveAllWords() sometimes didn't return
the proper carry, (when 'bits' was greater than or equal to 'value_size')
this had impact on Rcl() and Rcr(), they also returned the wrong carry
* 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
* fixed: there was a TTMATH_REREFENCE_ASSERT error in Big::PowUInt() caused by: start.Mul(start)
* fixed: Big::Add incorrectly rounded 'this' when both exponents were equal
it caused that sometimes when adding a zero the result has changed
this had impact among other things on FromString() method
"0,8" had different binary representation from "0,80"
* fixed: template Big::FromBig(const Big<another_exp, another_man> & another)
didn't correctly set the exponent (when the mantisses had different size -
when 'man' was different from 'another_man')
this had impact on operator= too
sample:
Big<2,3> a = 100;
Big<3,5> b;
b = a; // b had a wrong value
* fixed: Big::Pow(const Big<exp, man> & pow)
it's using PowInt() only when pow.exponent is in range (-man*TTMATH_BITS_PER_UINT; 0]
previously the powering 'hung' on an input like this: "(1+ 1e-10000) ^ 10e100000000"
(there was 10e100000000 iterations in PowInt())
* fixed: in function DegToRad(const ValueType & x, ErrorCode * err = 0) it is better
to make division first and then mutliplication -- the result is more
accurate especially when x is: 90,180,270 or 360
* fixed: the parser didn't correctly treat operators for changing the base
(radix) -- operators '#' and '&', e.g.:
'#sin(1)' was equal '0' -- there was a zero from '#' and then
it was multipied by 'sin(1)'
the parser didn't check whether Big::FromString() has actually
read a proper value -- the method Big::FromString() didn't have
something to report such a situation
* fixed: Big::FromString() when the base is 10, the method reads the scientific
part only if such a part it correctly supplied, e.g:
'1234e10', '1234e+10', '1234e-5'
previous '1234e' was treated as: '1234e0' (now parsing stops on 'e' and
the 'e' can be parsed by other parsers, e.g. the mathematical
parser -- now in the parser would be: '1234e' = '1234 * e' = '3354,3597...' )
* changed: renamed: Big::PowUInt(UInt<pow_size> pow) -> Big::Pow(UInt<pow_size> pow)
it returns 2 when there is: 0^0
* changed: renamed: Big::PowInt(Int<pow_size> pow) -> Big::Pow(Int<pow_size> pow)
it returns 2 when there is: 0^0 or 0^(-something)
* changed: renamed: Big::PowBUInt() -> PowUInt(), Big::PowBInt() -> Big::PowInt()
they return 2 when the arguments are incorrect (like above)
* changed: UInt::SetBitInWord(uint & value, uint bit) is taking the first argument by a reference now,
the specific bit is set in the 'value' and the method returns the last state of the bit (zero or one)
* changed: UInt::SetBit(uint bit_index) - it's using TTMATH_ASSERT now
* changed: the size of built-in variables (constants) in ttmathbig.h
now they consist of 256 32bit words
macro TTMATH_BUILTIN_VARIABLES_SIZE is equal: 256u on a 32bit platform and 128ul on a 64bit platform
* changed: the asm code in ttmathuint.h and ttmathuint64.h has been completely rewritten
now UInt<> is faster about 15-30% than UInt<> from 0.8.2
this has impact on Big<> too - it's faster about 10% now
* changed: in the parser: the form with operators '#' and '&' is as follows:
[-|+][#|&]numeric_value
previous was: [-|+][#|&][-|+]numeric_value
* changed: in the parser: the short form of multiplication has the same
priority as the normal multiplication, e.g.:
'2x^3' = 2 * (x^3)
previous the priority was greater than powering priority
previous: '2x^3' = (2*x) ^ 3
* added: UInt::GetBit(uint bit_index) - returning the state of the specific bit
* added: Big::operator=(double) and Big::Big(double)
* added: UInt::Pow(UInt<value_size> pow) and Int::Pow(Int<value_size> pow)
* added: global template functions in ttmath.h:
ValueType GradToRad(const ValueType & x, ErrorCode * err = 0)
ValueType RadToGrad(const ValueType & x, ErrorCode * err = 0)
ValueType DegToGrad(const ValueType & x, ErrorCode * err = 0)
ValueType DegToGrad(const ValueType & d, const ValueType & m,
const ValueType & s, ErrorCode * err = 0)
ValueType GradToDeg(const ValueType & x, ErrorCode * err = 0)
* added: Parser::SetDegRadGrad(int angle) - 0 deg, 1 rad (default), 2 grad
this affects following functions (in the parser only): sin, cos, tan, cot,
asin, acos, atan, acot
* added: functions to the parser: gradtorad(grad), radtograd(rad), degtograd(deg),
degtograd(d,m,s), gradtodeg(grad)
* added: UInt::FromString, added a parametr 'after_source'
which is pointing at the end of the parsed string
* added: Int::FromString(): parameter 'const char ** after_source = 0'
if exists it's pointing at the end of the parsed string
* 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)
* added: Objects::IsDefined(const std::string & name)
returning true if such an object is defined
* removed: Big::FromString() this method doesn't longer recognize operators
for changing the base ('#' and '&')
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)
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
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
Version 0.7.0 (2007.02.24):
* 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
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):
* 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):
* added: New division algorithm (radix b) where b is 2^32

View File

@@ -1,28 +1,28 @@
Copyright (c) 2006-2008, Tomasz Sowa
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name Tomasz Sowa nor the names of contributors to this
project may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
Copyright (c) 2006-2009, Tomasz Sowa
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name Tomasz Sowa nor the names of contributors to this
project may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.

52
README
View File

@@ -1,26 +1,26 @@
TTMath - a bignum library for C++
TTMath is a small library which allows one to perform arithmetic operations
with big unsigned integer, big signed integer and big floating point
numbers. It provides standard mathematical operations like adding,
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 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
values can be is set directly in the source code by the programmer.
Author: Tomasz Sowa <t.sowa@slimaczek.pl>
Project pages: http://ttmath.slimaczek.pl
http://sourceforge.net/projects/ttmath
TTMath - a bignum library for C++
TTMath is a small library which allows one to perform arithmetic operations
with big unsigned integer, big signed integer and big floating point
numbers. It provides standard mathematical operations like adding,
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 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
values can be is set directly in the source code by the programmer.
Author: Tomasz Sowa <t.sowa@slimaczek.pl>
Project pages: http://ttmath.slimaczek.pl
http://sourceforge.net/projects/ttmath

27
constgen/Makefile Normal file
View File

@@ -0,0 +1,27 @@
o = main.o
CC = g++
CFLAGS = -s -O2 -DCONSTANTSGENERATOR
name = gen
.SUFFIXES: .cpp .o
.cpp.o:
$(CC) -c $(CFLAGS) $<
all: $(name)
$(name): $(o)
$(CC) -o $(name) $(CFLAGS) $(o)
main.o: main.cpp
clean:
rm -f *.o
rm -f *.s
rm -f $(name)
rm -f $(name).exe

126
constgen/main.cpp Normal file
View File

@@ -0,0 +1,126 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name Tomasz Sowa nor the names of contributors to this
* project may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
this simple program is used to make constants which then are put into ttmathbig.h
*/
#include "../ttmath/ttmath.h"
#include <iostream>
void CalcPi()
{
ttmath::Big<1,400> pi;
// 3100 digits after commna, taken from: http://zenwerx.com/pi.php
pi = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
"8214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196"
"4428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273"
"7245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094"
"3305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912"
"9833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132"
"0005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235"
"4201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859"
"5024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303"
"5982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989"
"3809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151"
"5574857242454150695950829533116861727855889075098381754637464939319255060400927701671139009848824012"
"8583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912"
"9331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279"
"6782354781636009341721641219924586315030286182974555706749838505494588586926995690927210797509302955"
"3211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000"
"8164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333"
"4547762416862518983569485562099219222184272550254256887671790494601653466804988627232791786085784383"
"8279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863"
"0674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759009"
"9465764078951269468398352595709825822620522489407726719478268482601476990902640136394437455305068203"
"4962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382"
"6868386894277415599185592524595395943104997252468084598727364469584865383673622262609912460805124388"
"4390451244136549762780797715691435997700129616089441694868555848406353422072225828488648158456028506"
"0168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125"
"1507606947945109659609402522887971089314566913686722874894056010150330861792868092087476091782493858"
"9009714909675985261365549781893129784821682998948722658804857564014270477555132379641451523746234364"
"5428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344"
"0374200731057853906219838744780847848968332144571386875194350643021845319104848100537061468067491927"
"8191197939952061419663428754440643745123718192179998391015919561814675142691239748940907186494231961"
"5679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215";
std::cout << "---------------- PI ----------------" << std::endl;
pi.mantissa.PrintTable(std::cout);
}
void CalcE()
{
ttmath::Big<1,400> e;
ttmath::uint steps;
// macro CONSTANTSGENERATOR has to be defined
e.ExpSurrounding0(1, &steps);
std::cout << "---------------- e ----------------" << std::endl;
e.mantissa.PrintTable(std::cout);
std::cout << "ExpSurrounding0(1): " << steps << " iterations" << std::endl;
}
void CalcLn(int x)
{
ttmath::Big<1,400> ln;
ttmath::uint steps;
// macro CONSTANTSGENERATOR has to be defined
ln.LnSurrounding1(x, &steps);
std::cout << "---------------- ln(" << x << ") ----------------" << std::endl;
ln.mantissa.PrintTable(std::cout);
std::cout << "LnSurrounding1(" << x << "): " << steps << " iterations" << std::endl;
}
int main()
{
CalcPi();
CalcE();
CalcLn(2);
CalcLn(10);
return 0;
}

View File

@@ -32,20 +32,21 @@ MyBig atemp;
if( !atemp.Add(b) )
std::cout << "a + b = " << atemp << std::endl;
else
std::cout << "a + b = (carry) " << atemp << std::endl;
std::cout << "a + b = (carry)" << std::endl;
// it have no sense to print 'atemp' (it's undefined)
atemp = a;
if( !atemp.Sub(b) )
std::cout << "a - b = " << atemp << std::endl;
else
std::cout << "a - b = (carry) " << atemp << std::endl;
std::cout << "a - b = (carry)" << std::endl;
atemp = a;
if( !atemp.Mul(b) )
std::cout << "a * b = " << atemp << std::endl;
else
std::cout << "a * b = (carry: the result is too big) " << std::endl;
// it have no sense to print 'atemp' (it's undefined)
std::cout << "a * b = (carry)" << std::endl;
atemp = a;
if( !atemp.Div(b) )
@@ -68,9 +69,8 @@ MyBig a,b;
// 'a' will have the max value which can be held in this type
a.SetMax();
// at the moment conversions from double (or float etc.) are not supported
// you cannot do that: b = 456.32f
b = "456.32";
// conversion from double
b = 456.32;
// Look at the value 'a' and the product from a+b and a-b
// Don't worry this is the nature of floating point numbers
@@ -89,9 +89,9 @@ a * b = 12193540837712.2708
a / b = 0.0012499665458095765
Calculating with a carry
a = 1.624801256070839555e+646457012
b = 456.32
b = 456.31999999999999
a + b = 1.624801256070839555e+646457012
a - b = 1.624801256070839555e+646457012
a * b = (carry: the result is too big)
a / b = 3.56066193914542329e+646457009
a * b = (carry)
a / b = 3.56066193914542334e+646457009
*/

31
tests/Makefile Normal file
View File

@@ -0,0 +1,31 @@
CC = g++
o = main.o uinttest.o
CFLAGS = -Wall -O2 -s
ttmath = ..
name = tests
.SUFFIXES: .cpp .o
.cpp.o:
$(CC) -c $(CFLAGS) -I$(ttmath) $<
all: $(name)
$(name): $(o)
$(CC) -o $(name) $(CFLAGS) -I$(ttmath) $(o)
main.o: main.cpp uinttest.h
uinttest.o: uinttest.cpp uinttest.h
clean:
rm -f *.o
rm -f $(name)
rm -f $(name).exe

68
tests/main.cpp Normal file
View File

@@ -0,0 +1,68 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name Tomasz Sowa nor the names of contributors to this
* project may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <iostream>
#include <ttmath/ttmath.h>
#include "uinttest.h"
const char uint_tests_file[] = "tests.uint32";
void test_uint()
{
UIntTest test;
test.set_file_name(uint_tests_file);
test.go();
}
int main()
{
using namespace ttmath;
test_uint();
return 0;
}

92
tests/tests.uint32 Normal file
View File

@@ -0,0 +1,92 @@
# Add
# min_bits max_bits a b result carry
add 32 0 0 0 0 0
add 32 0 1 1 2 0
add 32 0 2342234 3563456 5905690 0
add 32 0 254455 3453435 3707890 0
add 32 0 4294967295 0 4294967295 0
add 32 32 4294967295 1 0 1
add 32 32 4294967295 0 4294967295 0
add 64 64 18446744073709551615 1 0 1
add 64 64 18446744073709551615 0 18446744073709551615 0
add 96 96 79228162514264337593543950335 1 0 1
add 96 96 79228162514264337593543950335 0 79228162514264337593543950335 0
add 128 128 340282366920938463463374607431768211455 1 0 1
add 128 128 340282366920938463463374607431768211455 0 340282366920938463463374607431768211455 0
add 160 160 1461501637330902918203684832716283019655932542975 1 0 1
add 160 160 1461501637330902918203684832716283019655932542975 0 1461501637330902918203684832716283019655932542975 0
add 192 192 6277101735386680763835789423207666416102355444464034512895 1 0 1
add 192 192 6277101735386680763835789423207666416102355444464034512895 0 6277101735386680763835789423207666416102355444464034512895 0
# AddInt
# min_bits max_bits bits_per_int a b(int) index result carry
addint 32 0 32 0 0 0 0 0
addint 32 0 32 1000 2000 0 3000 0
addint 64 0 32 562342345 1423445 1 6113650284997065 0
addint 64 0 32 5342342455 3423553423 0 8765895878 0
addint 96 0 32 478895734 46756734 2 862509505820513898647477878 0
addint 128 0 32 27370506140054471803784984408165997441 24543 3 27372450636847059393422542757339093889 0
addint 128 128 32 340282366841711102552375003685868034945 2234543 3 177038656721750864719686733515479937 1
addint 160 160 32 1461501637330902918124457471805283415910032366465 3 3 158457126631793409034731674497 1
addint 192 0 32 6277101735386680763835789423128439055191355840718134336385 3354 1 6277101735386680763835789423128439055191355855123454647169 0
addint 192 192 32 6277101735386680763835789423128439055191355840718134336385 3354 5 4901876491607848387655079701569502248322251848964993 1
addint 64 0 64 0 0 0 0 0
addint 64 0 64 5342342 345534234 0 350876576 0
addint 64 0 64 5342342455 34235534234 0 39577876689 0
addint 64 64 64 18446744073709550615 2000 0 999 1
addint 128 0 64 42895062544824211012058135 3453234 0 42895062544824211015511369 0
addint 128 0 64 42895062544824211012058135 456234234 1 8458931214807741031021280279 0
addint 128 128 64 340282366920938426569886460012664978455 45623 1 804702316727431770143767 1
addint 192 192 64 6277101735386680763835789423207666379208867297044931279895 45623234 1 841563227924816702308613143 1
addint 192 192 64 6277101735386679588840776445207152040176347835149297122327 45623234 2 15523607057094857017675614218510090830281178135 1
addint 192 192 64 6277101735386680763835789423207666416102355444464034512895 1 0 0 1
# AddTwoInts
# a the value
# c lower word
# b higher word
# index - index of the lower (c) word
# if there is a carry the result is skipped
# min_bits max_bits bits_per_int a b(int) c(int) index result carry
addtwoints 64 0 32 0 0 0 0 0 0
addtwoints 64 0 32 23542345 3453245 2356252356 0 14831576719870221 0
addtwoints 64 64 32 4563456879824345332 3453245255 3673623543 0 0 1
addtwoints 96 0 32 345345634564352344231 1231354534 345324551 1 22714482299528678798871855271 0
addtwoints 96 96 32 33333336690445123453645645123 4241542514 145235414 1 0 1
addtwoints 128 0 32 921345787234870984751756 2356245656 3423623455 2 186681013820253010515426931265335245452 0
addtwoints 128 128 32 259817508127340892734075234234345345346 3452345324 452354345 2 0 1
addtwoints 160 0 32 458674036702857083457018457034 435236456 1451234242 1 466702732224470435083940719562 0
addtwoints 160 0 32 258672084570198475012875019876674534523452543562 935245345 736765636 3 576919584276960743542382023227664277469907669578 0
addtwoints 192 0 32 2398670187501982374012837086745045 3253453245 234567536 4 4754927244626858434362642830810490464530603685767816794581 0
addtwoints 192 192 32 1734564564356435667546738087098769876387468736123143453646 3456345245 3256347435 4 0 1
addtwoints 128 0 64 0 0 0 0 0 0
addtwoints 128 0 64 14513452345 234512412345 8473567534 0 4325990452636459442359440119399 0
addtwoints 128 128 64 325434534534536347567567356714513452345 4324546234512412345 8473567534 0 0 1
addtwoints 192 0 64 8786356223462562562561234 4356879827345 34745638455 1 1482569380039046311960318103044992688410168990618834 0
addtwoints 192 0 64 875687458745872039847234234048572306857602 12341234356 3472568734534 1 4199505313073142510985676024483326499863441546882 0
addtwoints 192 192 64 6234554767823878635622346242564564564564564564562562561234 457644356879827345 34844576655 1 0 1

424
tests/uinttest.cpp Normal file
View File

@@ -0,0 +1,424 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name Tomasz Sowa nor the names of contributors to this
* project may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "uinttest.h"
void UIntTest::set_file_name(const std::string & f)
{
file_name = f;
}
bool UIntTest::read_uint(uuint & result)
{
UInt<1> temp;
int c = temp.FromString(pline, 10, &pline);
result = temp.ToUInt();
if( c )
{
std::cerr << " carry from reading uint" << std::endl;
return false;
}
return true;
}
template<uuint type_size>
bool UIntTest::read_uint(UInt<type_size> & result)
{
int c = result.FromString(pline, 10, &pline);
if( c )
{
std::cerr << " carry from UInt<>::FromString()" << std::endl;
return false;
}
return true;
}
bool UIntTest::check_minmax_bits(int type_size)
{
uuint min_bits;
uuint max_bits;
read_uint(min_bits);
read_uint(max_bits);
if( min_bits != 0 && type_size * TTMATH_BITS_PER_UINT < (unsigned int)min_bits )
return false;
if( max_bits != 0 && type_size * TTMATH_BITS_PER_UINT > (unsigned int)max_bits )
return false;
return true;
}
bool UIntTest::check_minmax_bits_bitperint(int type_size)
{
if( !check_minmax_bits(type_size) )
return false;
uuint bits;
read_uint(bits);
if( TTMATH_BITS_PER_UINT != bits )
return false;
return true;
}
bool UIntTest::check_end()
{
skip_white_characters();
if( *pline!='#' && *pline!= 0 )
{
std::cerr << "syntax error" << std::endl;
return false;
}
return true;
}
template<uuint type_size>
bool UIntTest::check_result_carry(const ttmath::UInt<type_size> & result, const ttmath::UInt<type_size> & new_result,
int carry, int new_carry)
{
bool ok = true;
if( new_carry != carry )
{
std::cerr << "Incorrect carry: " << new_carry << " (expected: " << carry << ")" << std::endl;
ok = false;
}
if( new_result != result )
{
std::cerr << "Incorrect result: " << new_result << " (expected: " << result << ")" << std::endl;
ok = false;
}
return ok;
}
template<uuint type_size>
bool UIntTest::check_result_or_carry(const ttmath::UInt<type_size> & result, const ttmath::UInt<type_size> & new_result,
int carry, int new_carry)
{
if( new_carry != carry )
{
std::cerr << "Incorrect carry: " << new_carry << " (expected: " << carry << ")" << std::endl;
return false;
}
if( new_carry == 1 )
return true;
if( new_result != result )
{
std::cerr << "Incorrect result: " << new_result << " (expected: " << result << ")" << std::endl;
return false;
}
return true;
}
template<uuint type_size>
void UIntTest::test_add()
{
UInt<type_size> a,b,result, new_result;
if( !check_minmax_bits(type_size) )
return;
read_uint(a);
read_uint(b);
read_uint(result);
uuint carry;
read_uint(carry);
std::cerr << '[' << row << "] Add<" << type_size << ">: ";
if( !check_end() )
return;
new_result = a;
int new_carry = new_result.Add(b);
if( check_result_carry(result, new_result, carry, new_carry) )
std::cerr << "ok" << std::endl;
}
template<uuint type_size>
void UIntTest::test_addint()
{
UInt<type_size> a, result, new_result;
if( !check_minmax_bits_bitperint(type_size) )
return;
uuint b, index, carry;
read_uint(a);
read_uint(b);
read_uint(index);
read_uint(result);
read_uint(carry);
std::cerr << '[' << row << "] AddInt<" << type_size << ">: ";
if( !check_end() )
return;
new_result = a;
int new_carry = new_result.AddInt(b, index);
if( check_result_carry(result, new_result, carry, new_carry) )
std::cerr << "ok" << std::endl;
}
template<uuint type_size>
void UIntTest::test_addtwoints()
{
UInt<type_size> a, result, new_result;
if( !check_minmax_bits_bitperint(type_size) )
return;
std::cerr << '[' << row << "] AddTwoInts<" << type_size << ">: ";
uuint b, c, index, carry;
read_uint(a);
read_uint(b);
read_uint(c);
read_uint(index);
read_uint(result);
read_uint(carry);
if( !check_end() )
return;
if( index >= type_size - 1 )
{
std::cerr << "index too large" << std::endl;
return;
}
new_result = a;
int new_carry = new_result.AddTwoInts(b, c, index);
if( check_result_or_carry(result, new_result, carry, new_carry) )
std::cerr << "ok" << std::endl;
}
int UIntTest::upper_char(int c)
{
if( c>='a' && c<='z' )
return c - 'a' + 'A';
return c;
}
bool UIntTest::is_white(int c)
{
if( c==' ' || c=='\t' || c==13 )
return true;
return false;
}
void UIntTest::skip_white_characters()
{
while( is_white(*pline) )
++pline;
}
bool UIntTest::read_method()
{
skip_white_characters();
if( *pline == '#' )
return false;
method.clear();
for(int c = upper_char(*pline) ; c>='A'&& c<='Z' ; c = upper_char(*pline) )
{
method += c;
++pline;
}
if( method.empty() )
{
skip_white_characters();
if( *pline == 0 )
return false;
else
{
std::cerr << '[' << row << "] ";
std::cerr << "syntax error" << std::endl;
return false;
}
}
return true;
}
void UIntTest::test_method()
{
const char * p = pline;
if( method == "ADD" )
{
pline = p; test_add<1>();
pline = p; test_add<2>();
pline = p; test_add<3>();
pline = p; test_add<4>();
pline = p; test_add<5>();
pline = p; test_add<6>();
pline = p; test_add<7>();
pline = p; test_add<8>();
pline = p; test_add<9>();
}
else
if( method == "ADDINT" )
{
pline = p; test_addint<1>();
pline = p; test_addint<2>();
pline = p; test_addint<3>();
pline = p; test_addint<4>();
pline = p; test_addint<5>();
pline = p; test_addint<6>();
pline = p; test_addint<7>();
pline = p; test_addint<8>();
pline = p; test_addint<9>();
}
else
if( method == "ADDTWOINTS" )
{
pline = p; test_addtwoints<1>();
pline = p; test_addtwoints<2>();
pline = p; test_addtwoints<3>();
pline = p; test_addtwoints<4>();
pline = p; test_addtwoints<5>();
pline = p; test_addtwoints<6>();
pline = p; test_addtwoints<7>();
pline = p; test_addtwoints<8>();
pline = p; test_addtwoints<9>();
}
else
{
std::cerr << '[' << row << "] ";
std::cerr << "method " << method << " is not supported" << std::endl;
}
}
bool UIntTest::check_line()
{
std::getline(file, line);
pline = line.c_str();
if( read_method() )
test_method();
if( file.eof() )
return false;
return true;
}
void UIntTest::go()
{
file.open(file_name.c_str());
if( !file )
{
std::cerr << "I can't open the input file" << std::endl;
return;
}
row = 1;
while( check_line() )
++row;
}

105
tests/uinttest.h Normal file
View File

@@ -0,0 +1,105 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name Tomasz Sowa nor the names of contributors to this
* project may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef headerfileuinttest
#define headerfileuinttest
#include <string>
#include <fstream>
#include <iostream>
#include <ttmath/ttmath.h>
using namespace ttmath;
typedef ttmath::uint uuint;
class UIntTest
{
std::string file_name;
// current line from the file
std::string line;
const char * pline;
std::ifstream file;
std::string method;
int row;
public:
void set_file_name(const std::string & f);
void go();
bool read_uint(uuint & result);
template<uuint type_size>
bool read_uint(UInt<type_size> & result);
template<uuint type_size> void test_add();
template<uuint type_size> void test_addint();
template<uuint type_size> void test_addtwoints();
template<uuint type_size> bool check_result_carry(const ttmath::UInt<type_size> & result, const ttmath::UInt<type_size> & new_result,
int carry, int new_carry);
template<uuint type_size> bool check_result_or_carry(const ttmath::UInt<type_size> & result, const ttmath::UInt<type_size> & new_result,
int carry, int new_carry);
int upper_char(int c);
bool is_white(int c);
void skip_white_characters();
bool read_method();
void test_method();
bool check_line();
bool check_minmax_bits(int type_size);
bool check_minmax_bits_bitperint(int type_size);
bool check_end();
};
#endif

View File

@@ -1,11 +1,11 @@
/*
* This file is a part of TTMath Mathematical Library
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* Copyright (c) 2006-2008, Tomasz Sowa
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -1347,7 +1347,7 @@ namespace ttmath
/*
*
* functions for converting between degrees and radians
* functions for converting between degrees, radians and gradians
*
*
*/
@@ -1361,14 +1361,18 @@ namespace ttmath
template<class ValueType>
ValueType DegToRad(const ValueType & x, ErrorCode * err = 0)
{
ValueType result, delimiter;
ValueType result, temp;
uint c = 0;
result.SetPi();
c += result.Mul(x);
result = x;
delimiter = 180;
c += result.Div(delimiter);
// it is better to make division first and then multiplication
// the result is more accurate especially when x is: 90,180,270 or 360
temp = 180;
c += result.Div(temp);
temp.SetPi();
c += result.Mul(temp);
if( err )
*err = c ? err_overflow : err_ok;
@@ -1468,6 +1472,128 @@ namespace ttmath
}
/*!
this function converts gradians to radians
it returns: x * pi / 200
*/
template<class ValueType>
ValueType GradToRad(const ValueType & x, ErrorCode * err = 0)
{
ValueType result, temp;
uint c = 0;
result = x;
// it is better to make division first and then multiplication
// the result is more accurate especially when x is: 100,200,300 or 400
temp = 200;
c += result.Div(temp);
temp.SetPi();
c += result.Mul(temp);
if( err )
*err = c ? err_overflow : err_ok;
return result;
}
/*!
this function converts radians to gradians
it returns: x * 200 / pi
*/
template<class ValueType>
ValueType RadToGrad(const ValueType & x, ErrorCode * err = 0)
{
ValueType result, delimiter;
uint c = 0;
result = 200;
c += result.Mul(x);
delimiter.SetPi();
c += result.Div(delimiter);
if( err )
*err = c ? err_overflow : err_ok;
return result;
}
/*!
this function converts degrees to gradians
it returns: x * 200 / 180
*/
template<class ValueType>
ValueType DegToGrad(const ValueType & x, ErrorCode * err = 0)
{
ValueType result, temp;
uint c = 0;
result = x;
temp = 200;
c += result.Mul(temp);
temp = 180;
c += result.Div(temp);
if( err )
*err = c ? err_overflow : err_ok;
return result;
}
/*!
this function converts degrees in the long format to gradians
*/
template<class ValueType>
ValueType DegToGrad( const ValueType & d, const ValueType & m, const ValueType & s,
ErrorCode * err = 0)
{
ValueType temp_deg = DegToDeg(d,m,s,err);
if( err && *err!=err_ok )
return temp_deg;
return DegToGrad(temp_deg, err);
}
/*!
this function converts degrees to gradians
it returns: x * 180 / 200
*/
template<class ValueType>
ValueType GradToDeg(const ValueType & x, ErrorCode * err = 0)
{
ValueType result, temp;
uint c = 0;
result = x;
temp = 180;
c += result.Mul(temp);
temp = 200;
c += result.Div(temp);
if( err )
*err = c ? err_overflow : err_ok;
return result;
}
/*
*
* another functions

View File

@@ -1,11 +1,11 @@
/*
* This file is a part of TTMath Mathematical Library
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* Copyright (c) 2006-2008, Tomasz Sowa
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -212,20 +212,35 @@ private:
0x99c32718, 0x6af4e23c, 0x1a946834, 0xb6150bda, 0x2583e9ca, 0x2ad44ce8, 0xdbbbc2db, 0x04de8ef9,
0x2e8efc14, 0x1fbecaa6, 0x287c5947, 0x4e6bc05d, 0x99b2964f, 0xa090c3a2, 0x233ba186, 0x515be7ed,
0x1f612970, 0xcee2d7af, 0xb81bdd76, 0x2170481c, 0xd0069127, 0xd5b05aa9, 0x93b4ea98, 0x8d8fddc1,
0x86ffb7dc, 0x90a6c08f, 0x4df435c9, 0x34028492, 0x36c3fab4, 0xd27c7026, 0xc1d4dcb2, 0x602646df // (last one was: 0x602646de)
// 0xc9751e76, ...
// (the last word was rounded up because the next one is 0xc9751e76 -- first bit is one 0xc..)
// 128 32bit words for the mantissa -- about 1232 valid digits (decimal)
0x86ffb7dc, 0x90a6c08f, 0x4df435c9, 0x34028492, 0x36c3fab4, 0xd27c7026, 0xc1d4dcb2, 0x602646de,
0xc9751e76, 0x3dba37bd, 0xf8ff9406, 0xad9e530e, 0xe5db382f, 0x413001ae, 0xb06a53ed, 0x9027d831,
0x179727b0, 0x865a8918, 0xda3edbeb, 0xcf9b14ed, 0x44ce6cba, 0xced4bb1b, 0xdb7f1447, 0xe6cc254b,
0x33205151, 0x2bd7af42, 0x6fb8f401, 0x378cd2bf, 0x5983ca01, 0xc64b92ec, 0xf032ea15, 0xd1721d03,
0xf482d7ce, 0x6e74fef6, 0xd55e702f, 0x46980c82, 0xb5a84031, 0x900b1c9e, 0x59e7c97f, 0xbec7e8f3,
0x23a97a7e, 0x36cc88be, 0x0f1d45b7, 0xff585ac5, 0x4bd407b2, 0x2b4154aa, 0xcc8f6d7e, 0xbf48e1d8,
0x14cc5ed2, 0x0f8037e0, 0xa79715ee, 0xf29be328, 0x06a1d58b, 0xb7c5da76, 0xf550aa3d, 0x8a1fbff0,
0xeb19ccb1, 0xa313d55c, 0xda56c9ec, 0x2ef29632, 0x387fe8d7, 0x6e3c0468, 0x043e8f66, 0x3f4860ee,
0x12bf2d5b, 0x0b7474d6, 0xe694f91e, 0x6dbe1159, 0x74a3926f, 0x12fee5e4, 0x38777cb6, 0xa932df8c,
0xd8bec4d0, 0x73b931ba, 0x3bc832b6, 0x8d9dd300, 0x741fa7bf, 0x8afc47ed, 0x2576f693, 0x6ba42466,
0x3aab639c, 0x5ae4f568, 0x3423b474, 0x2bf1c978, 0x238f16cb, 0xe39d652d, 0xe3fdb8be, 0xfc848ad9,
0x22222e04, 0xa4037c07, 0x13eb57a8, 0x1a23f0c7, 0x3473fc64, 0x6cea306b, 0x4bcbc886, 0x2f8385dd,
0xfa9d4b7f, 0xa2c087e8, 0x79683303, 0xed5bdd3a, 0x062b3cf5, 0xb3a278a6, 0x6d2a13f8, 0x3f44f82d,
0xdf310ee0, 0x74ab6a36, 0x4597e899, 0xa0255dc1, 0x64f31cc5, 0x0846851d, 0xf9ab4819, 0x5ded7ea1,
0xb1d510bd, 0x7ee74d73, 0xfaf36bc3, 0x1ecfa268, 0x359046f4, 0xeb879f92, 0x4009438b, 0x481c6cd7,
0x889a002e, 0xd5ee382b, 0xc9190da6, 0xfc026e47, 0x9558e447, 0x5677e9aa, 0x9e3050e2, 0x765694df,
0xc81f56e8, 0x80b96e71, 0x60c980dd, 0x98a573ea, 0x4472065a, 0x139cd290, 0x6cd1cb72, 0x9ec52a53 // last one was: 0x9ec52a52
//0x86d44014, ...
// (the last word 0x9ec52a52 was rounded up because the next one is 0x86d44014 -- first bit is one 0x8..)
// 256 32bit words for the mantissa -- about 2464 valid decimal digits
};
// the value of PI is comming from the website "Paul's 8192 Digits of Pi"
// http://www.escape.com/~paulg53/math/pi/8192.html
// 2999 digits were taken from this website
// (later they were compared with http://zenwerx.com/pi.php)
// and they were set into Big<1,300> type (using operator=(const char*) on 32bit platform)
// and then the first 128 words were taken into this table
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 128,
// and on 64bit platform value 64 (128/2=64))
// the value of PI is comming from the website http://zenwerx.com/pi.php
// 3101 digits were taken from this website
// (later the digits were compared with:
// http://www.eveandersson.com/pi/digits/1000000 and http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html )
// and they were set into Big<1,400> type (using operator=(const char*) on a 32bit platform)
// and then the first 256 words were taken into this table
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
// and on 64bit platform value 128 (256/2=128))
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
}
@@ -288,17 +303,34 @@ public:
0xac7d5f42, 0xd69f6d18, 0x7763cf1d, 0x55034004, 0x87f55ba5, 0x7e31cc7a, 0x7135c886, 0xefb4318a,
0xed6a1e01, 0x2d9e6832, 0xa907600a, 0x918130c4, 0x6dc778f9, 0x71ad0038, 0x092999a3, 0x33cb8b7a,
0x1a1db93d, 0x7140003c, 0x2a4ecea9, 0xf98d0acc, 0x0a8291cd, 0xcec97dcf, 0x8ec9b55a, 0x7f88a46b,
0x4db5a851, 0xf44182e1, 0xc68a007e, 0x5e0dd902, 0x0bfd64b6, 0x45036c7a, 0x4e677d2c, 0x38532a3a
//0x23ba4442,...
// 128 32bit words for the mantissa -- about 1232 valid digits (decimal)
0x4db5a851, 0xf44182e1, 0xc68a007e, 0x5e0dd902, 0x0bfd64b6, 0x45036c7a, 0x4e677d2c, 0x38532a3a,
0x23ba4442, 0xcaf53ea6, 0x3bb45432, 0x9b7624c8, 0x917bdd64, 0xb1c0fd4c, 0xb38e8c33, 0x4c701c3a,
0xcdad0657, 0xfccfec71, 0x9b1f5c3e, 0x4e46041f, 0x388147fb, 0x4cfdb477, 0xa52471f7, 0xa9a96910,
0xb855322e, 0xdb6340d8, 0xa00ef092, 0x350511e3, 0x0abec1ff, 0xf9e3a26e, 0x7fb29f8c, 0x183023c3,
0x587e38da, 0x0077d9b4, 0x763e4e4b, 0x94b2bbc1, 0x94c6651e, 0x77caf992, 0xeeaac023, 0x2a281bf6,
0xb3a739c1, 0x22611682, 0x0ae8db58, 0x47a67cbe, 0xf9c9091b, 0x462d538c, 0xd72b0374, 0x6ae77f5e,
0x62292c31, 0x1562a846, 0x505dc82d, 0xb854338a, 0xe49f5235, 0xc95b9117, 0x8ccf2dd5, 0xcacef403,
0xec9d1810, 0xc6272b04, 0x5b3b71f9, 0xdc6b80d6, 0x3fdd4a8e, 0x9adb1e69, 0x62a69526, 0xd43161c1,
0xa41d570d, 0x7938dad4, 0xa40e329c, 0xcff46aaa, 0x36ad004c, 0xf600c838, 0x1e425a31, 0xd951ae64,
0xfdb23fce, 0xc9509d43, 0x687feb69, 0xedd1cc5e, 0x0b8cc3bd, 0xf64b10ef, 0x86b63142, 0xa3ab8829,
0x555b2f74, 0x7c932665, 0xcb2c0f1c, 0xc01bd702, 0x29388839, 0xd2af05e4, 0x54504ac7, 0x8b758282,
0x2846c0ba, 0x35c35f5c, 0x59160cc0, 0x46fd8251, 0x541fc68c, 0x9c86b022, 0xbb709987, 0x6a460e74,
0x51a8a931, 0x09703fee, 0x1c217e6c, 0x3826e52c, 0x51aa691e, 0x0e423cfc, 0x99e9e316, 0x50c1217b,
0x624816cd, 0xad9a95f9, 0xd5b80194, 0x88d9c0a0, 0xa1fe3075, 0xa577e231, 0x83f81d4a, 0x3f2fa457,
0x1efc8ce0, 0xba8a4fe8, 0xb6855dfe, 0x72b0a66e, 0xded2fbab, 0xfbe58a30, 0xfafabe1c, 0x5d71a87e,
0x2f741ef8, 0xc1fe86fe, 0xa6bbfde5, 0x30677f0d, 0x97d11d49, 0xf7a8443d, 0x0822e506, 0xa9f4614e,
0x011e2a94, 0x838ff88c, 0xd68c8bb7, 0xc51eef6d, 0x49ea8ab4, 0xf2c3df5b, 0xb4e0735a, 0xb0d68749
// 0x2fe26dd4, ...
// 256 32bit words for the mantissa -- about 2464 valid decimal digits
};
// above value was calculated using Big<1,300> on 32bit platform
// and then the first 128 words were taken,
// above value was calculated using Big<1,400> type on a 32bit platform
// and then the first 256 words were taken,
// the calculating was made by using ExpSurrounding0(1) method
// which took 1110 iterations
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 128,
// and on 64bit platform value 64 (128/2=64))
// which took 1420 iterations
// (the result was compared with e taken from http://antwrp.gsfc.nasa.gov/htmltest/gifcity/e.2mil)
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
// and on 64bit platform value 128 (256/2=128))
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
@@ -328,18 +360,35 @@ public:
0x57339ba2, 0xbeba7d05, 0x2ac5b61c, 0xc4e9207c, 0xef2f0ce2, 0xd7373958, 0xd7622658, 0x901e646a,
0x95184460, 0xdc4e7487, 0x156e0c29, 0x2413d5e3, 0x61c1696d, 0xd24aaebd, 0x473826fd, 0xa0c238b9,
0x0ab111bb, 0xbd67c724, 0x972cd18b, 0xfbbd9d42, 0x6c472096, 0xe76115c0, 0x5f6f7ceb, 0xac9f45ae,
0xcecb72f1, 0x9c38339d, 0x8f682625, 0x0dea891e, 0xf07afff3, 0xa892374e, 0x175eb4af, 0xc8daadd9 // (last one was: 0xc8daadd8)
// 0x85db6ab0, ...
// (the last word was rounded up because the next one is 0x85db6ab0 -- first bit is one 0x8..)
// 128 32bit words for the mantissa -- about 1232 valid digits (decimal)
0xcecb72f1, 0x9c38339d, 0x8f682625, 0x0dea891e, 0xf07afff3, 0xa892374e, 0x175eb4af, 0xc8daadd8,
0x85db6ab0, 0x3a49bd0d, 0xc0b1b31d, 0x8a0e23fa, 0xc5e5767d, 0xf95884e0, 0x6425a415, 0x26fac51c,
0x3ea8449f, 0xe8f70edd, 0x062b1a63, 0xa6c4c60c, 0x52ab3316, 0x1e238438, 0x897a39ce, 0x78b63c9f,
0x364f5b8a, 0xef22ec2f, 0xee6e0850, 0xeca42d06, 0xfb0c75df, 0x5497e00c, 0x554b03d7, 0xd2874a00,
0x0ca8f58d, 0x94f0341c, 0xbe2ec921, 0x56c9f949, 0xdb4a9316, 0xf281501e, 0x53daec3f, 0x64f1b783,
0x154c6032, 0x0e2ff793, 0x33ce3573, 0xfacc5fdc, 0xf1178590, 0x3155bbd9, 0x0f023b22, 0x0224fcd8,
0x471bf4f4, 0x45f0a88a, 0x14f0cd97, 0x6ea354bb, 0x20cdb5cc, 0xb3db2392, 0x88d58655, 0x4e2a0e8a,
0x6fe51a8c, 0xfaa72ef2, 0xad8a43dc, 0x4212b210, 0xb779dfe4, 0x9d7307cc, 0x846532e4, 0xb9694eda,
0xd162af05, 0x3b1751f3, 0xa3d091f6, 0x56658154, 0x12b5e8c2, 0x02461069, 0xac14b958, 0x784934b8,
0xd6cce1da, 0xa5053701, 0x1aa4fb42, 0xb9a3def4, 0x1bda1f85, 0xef6fdbf2, 0xf2d89d2a, 0x4b183527,
0x8fd94057, 0x89f45681, 0x2b552879, 0xa6168695, 0xc12963b0, 0xff01eaab, 0x73e5b5c1, 0x585318e7,
0x624f14a5, 0x1a4a026b, 0x68082920, 0x57fd99b6, 0x6dc085a9, 0x8ac8d8ca, 0xf9eeeea9, 0x8a2400ca,
0xc95f260f, 0xd10036f9, 0xf91096ac, 0x3195220a, 0x1a356b2a, 0x73b7eaad, 0xaf6d6058, 0x71ef7afb,
0x80bc4234, 0x33562e94, 0xb12dfab4, 0x14451579, 0xdf59eae0, 0x51707062, 0x4012a829, 0x62c59cab,
0x347f8304, 0xd889659e, 0x5a9139db, 0x14efcc30, 0x852be3e8, 0xfc99f14d, 0x1d822dd6, 0xe2f76797,
0xe30219c8, 0xaa9ce884, 0x8a886eb3, 0xc87b7295, 0x988012e8, 0x314186ed, 0xbaf86856, 0xccd3c3b6,
0xee94e62f, 0x110a6783, 0xd2aae89c, 0xcc3b76fc, 0x435a0ce1, 0x34c2838f, 0xd571ec6c, 0x1366a993 // last one was: 0x1366a992
//0xcbb9ac40, ...
// (the last word 0x1366a992 was rounded up because the next one is 0xcbb9ac40 -- first bit is one 0xc..)
// 256 32bit words for the mantissa -- about 2464 valid decimal digits
};
// above value was calculated using Big<1,300> on 32bit platform
// and then the first 128 words were taken,
// above value was calculated using Big<1,400> type on a 32bit platform
// and then the first 256 words were taken,
// the calculating was made by using LnSurrounding1(2) method
// which took 3030 iterations
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 128,
// and on 64bit platform value 64 (128/2=64))
// which took 4035 iterations
// (the result was compared with ln(2) taken from http://ja0hxv.calico.jp/pai/estart.html)
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
// and on 64bit platform value 128 (256/2=128))
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT);
@@ -379,21 +428,38 @@ public:
0xed69b13d, 0xc1a03730, 0xb6524dc1, 0x8c167e86, 0x99d6d20e, 0xa2defd2b, 0xd006f8b4, 0xbe145a2a,
0xdf3ccbb3, 0x189da49d, 0xbc1261c8, 0xb3e4daad, 0x6a36cecc, 0xb2d5ae5b, 0x89bf752f, 0xb5dfb353,
0xff3065c4, 0x0cfceec8, 0x1be5a9a9, 0x67fddc57, 0xc4b83301, 0x006bf062, 0x4b40ed7a, 0x56c6cdcd,
0xa2d6fe91, 0x388e9e3e, 0x48a93f5f, 0x5e3b6eb4, 0xb81c4a5b, 0x53d49ea6, 0x8e668aea, 0xba83c7f9 // (last one was: 0xba83c7f8)
///0xfb5f06c3, ...
//(the last word was rounded up because the next one is 0xfb5f06c3 -- first bit is one 0xf..)
// 128 32bit words for the mantissa -- about 1232 valid digits (decimal)
0xa2d6fe91, 0x388e9e3e, 0x48a93f5f, 0x5e3b6eb4, 0xb81c4a5b, 0x53d49ea6, 0x8e668aea, 0xba83c7f8,
0xfb5f06c3, 0x58ac8f70, 0xfa9d8c59, 0x8c574502, 0xbaf54c96, 0xc84911f0, 0x0482d095, 0x1a0af022,
0xabbab080, 0xec97efd3, 0x671e4e0e, 0x52f166b6, 0xcd5cd226, 0x0dc67795, 0x2e1e34a3, 0xf799677f,
0x2c1d48f1, 0x2944b6c5, 0x2ba1307e, 0x704d67f9, 0x1c1035e4, 0x4e927c63, 0x03cf12bf, 0xe2cd2e31,
0xf8ee4843, 0x344d51b0, 0xf37da42b, 0x9f0b0fd9, 0x134fb2d9, 0xf815e490, 0xd966283f, 0x23962766,
0xeceab1e4, 0xf3b5fc86, 0x468127e2, 0xb606d10d, 0x3a45f4b6, 0xb776102d, 0x2fdbb420, 0x80c8fa84,
0xd0ff9f45, 0xc58aef38, 0xdb2410fd, 0x1f1cebad, 0x733b2281, 0x52ca5f36, 0xddf29daa, 0x544334b8,
0xdeeaf659, 0x4e462713, 0x1ed485b4, 0x6a0822e1, 0x28db471c, 0xa53938a8, 0x44c3bef7, 0xf35215c8,
0xb382bc4e, 0x3e4c6f15, 0x6285f54c, 0x17ab408e, 0xccbf7f5e, 0xd16ab3f6, 0xced2846d, 0xf457e14f,
0xbb45d9c5, 0x646ad497, 0xac697494, 0x145de32e, 0x93907128, 0xd263d521, 0x79efb424, 0xd64651d6,
0xebc0c9f0, 0xbb583a44, 0xc6412c84, 0x85bb29a6, 0x4d31a2cd, 0x92954469, 0xa32b1abd, 0xf7f5202c,
0xa4aa6c93, 0x2e9b53cf, 0x385ab136, 0x2741f356, 0x5de9c065, 0x6009901c, 0x88abbdd8, 0x74efcf73,
0x3f761ad4, 0x35f3c083, 0xfd6b8ee0, 0x0bef11c7, 0xc552a89d, 0x58ce4a21, 0xd71e54f2, 0x4157f6c7,
0xd4622316, 0xe98956d7, 0x450027de, 0xcbd398d8, 0x4b98b36a, 0x0724c25c, 0xdb237760, 0xe9324b68,
0x7523e506, 0x8edad933, 0x92197f00, 0xb853a326, 0xb330c444, 0x65129296, 0x34bc0670, 0xe177806d,
0xe338dac4, 0x5537492a, 0xe19add83, 0xcf45000f, 0x5b423bce, 0x6497d209, 0xe30e18a1, 0x3cbf0687,
0x67973103, 0xd9485366, 0x81506bba, 0x2e93a9a4, 0x7dd59d3f, 0xf17cd746, 0x8c2075be, 0x552a4348 // last one was: 0x552a4347
// 0xb4a638ef, ...
//(the last word 0x552a4347 was rounded up because the next one is 0xb4a638ef -- first bit is one 0xb..)
// 256 32bit words for the mantissa -- about 2464 valid digits (decimal)
};
// above value was calculated using Big<1,300> on 32bit platform
// and then the first 128 32bit words were taken,
// above value was calculated using Big<1,400> type on a 32bit platform
// and then the first 256 32bit words were taken,
// the calculating was made by using LnSurrounding1(10) method
// which took 16555 iterations
// which took 22080 iterations
// (the result was compared with ln(10) taken from http://ja0hxv.calico.jp/pai/estart.html)
// (the formula used in LnSurrounding1(x) converges badly when
// the x is greater than one but in fact we can use it, only the
// number of iterations will be greater)
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 128,
// and on 64bit platform value 64 (128/2=64))
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
// and on 64bit platform value 128 (256/2=128))
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
@@ -561,9 +627,9 @@ public:
}
if( exp_offset > mantissa_size_in_bits )
if( exp_offset >= mantissa_size_in_bits )
{
// the second value is too short for taking into consideration in the sum
// the second value is too small for taking into consideration in the sum
return 0;
}
else
@@ -572,13 +638,6 @@ public:
// (2) moving 'exp_offset' times
ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
}
else
{
// (3)
// exp_offset == mantissa_size_in_bits
// we're rounding 'this' about one (up or down depending on a ss2 sign)
ss2.mantissa.SetOne();
}
if( IsSign() == ss2.IsSign() )
@@ -594,8 +653,8 @@ public:
{
// values have different signs
// there shouldn't be a carry here because
// (1) (2) and (3) guarantee that the mantissa of this
// is greater than the mantissa of the ss2
// (1) (2) guarantee that the mantissa of this
// is greater than or equal to the mantissa of the ss2
uint c_temp = mantissa.Sub(ss2.mantissa);
TTMATH_ASSERT( c_temp == 0 )
@@ -653,7 +712,7 @@ public:
if( exp_offset >= mantissa_size_in_bits )
{
// the second value is too short
// the second value is too small
SetZero();
return 0;
}
@@ -700,7 +759,7 @@ public:
}
if( exp_offset >= mantissa_size_in_bits )
// the second value is too short
// the second value is too small
return 0;
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
@@ -745,7 +804,7 @@ public:
}
if( exp_offset >= mantissa_size_in_bits )
// the second value is too short
// the second value is too small
return 0;
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
@@ -944,7 +1003,7 @@ public:
-12.6 mod -3 = -0.6
it means:
in other words: this(old) = ss2 * q + this(new)(result)
in other words: this(old) = ss2 * q + this(new -- result)
*/
uint Mod(const Big<exp, man> & ss2)
{
@@ -966,18 +1025,23 @@ public:
/*!
power this = this ^ pow
pow without a sign
(pow without a sign)
binary algorithm (r-to-l)
return values:
0 - ok
1 - carry
2 - incorrect arguments (0^0)
*/
template<uint pow_size>
uint PowUInt(UInt<pow_size> pow)
uint Pow(UInt<pow_size> pow)
{
if(pow.IsZero() && IsZero())
// we don't define zero^zero
return 1;
return 2;
Big<exp, man> start(*this);
Big<exp, man> start(*this), start_temp;
Big<exp, man> result;
result.SetOne();
@@ -987,7 +1051,8 @@ public:
if( result.Mul(start) )
return 1;
if( start.Mul(start) )
start_temp = start;
if( start.Mul(start_temp) )
return 1;
pow.Rcr(1);
@@ -1001,27 +1066,31 @@ public:
/*!
power this = this ^ pow
p can be with a sign
p can be negative
return values:
0 - ok
1 - carry
2 - incorrect arguments 0^0 or 0^(-something)
*/
template<uint pow_size>
uint PowInt(Int<pow_size> pow)
uint Pow(Int<pow_size> pow)
{
if( !pow.IsSign() )
return PowUInt(pow);
return Pow( UInt<pow_size>(pow) );
if( IsZero() )
// if 'p' is negative then
// 'this' must be different from zero
return 1;
return 2;
if( pow.ChangeSign() )
return 1;
Big<exp, man> t(*this);
if( t.PowUInt(pow) )
return 1;
uint c_temp = t.Pow( UInt<pow_size>(pow) );
if( c_temp > 0 )
return c_temp;
SetOne();
if( Div(t) )
@@ -1032,33 +1101,40 @@ public:
/*!
this method returns true if 'this' mod 2 is equal one
this method returns: 'this' mod 2
(either zero or one)
this method is much faster than using Mod( object_with_value_two )
*/
bool Mod2() const
uint Mod2() const
{
if( exponent>sint(0) || exponent<=-sint(man*TTMATH_BITS_PER_UINT) )
return false;
return 0;
sint exp_int = exponent.ToInt();
// 'exp_int' is negative (or zero), we set its as positive
// 'exp_int' is negative (or zero), we set it as positive
exp_int = -exp_int;
// !!! here we'll use a new method (method for testing a bit)
uint value = mantissa.table[ exp_int / TTMATH_BITS_PER_UINT ];
value >>= (uint(exp_int) % TTMATH_BITS_PER_UINT);
return bool(value & 1);
return mantissa.GetBit(exp_int);
}
/*!
power this = this ^ abs([pow])
pow without a sign and without a fraction
pow is treated as a value without a sign and without a fraction
if pow has a sign then the method pow.Abs() is used
if pow has a fraction the fraction is skipped (not used in calculation)
return values:
0 - ok
1 - carry
2 - incorrect arguments (0^0)
*/
uint PowBUInt(Big<exp, man> pow)
uint PowUInt(Big<exp, man> pow)
{
if( pow.IsZero() && IsZero() )
return 1;
return 2;
if( pow.IsSign() )
pow.Abs();
@@ -1070,7 +1146,7 @@ public:
e_one.SetOne();
one.SetOne();
result.SetOne();
result = one;
while( pow >= one )
{
@@ -1093,24 +1169,30 @@ public:
/*!
power this = this ^ [pow]
pow without a fraction
pow is treated as a value without a fraction
pow can be negative
return values:
0 - ok
1 - carry
2 - incorrect arguments 0^0 or 0^(-something)
*/
uint PowBInt(const Big<exp, man> & pow)
uint PowInt(const Big<exp, man> & pow)
{
TTMATH_REFERENCE_ASSERT( pow )
if( !pow.IsSign() )
return PowBUInt(pow);
return PowUInt(pow);
if( IsZero() )
// if 'pow' is negative then
// 'this' must be different from zero
return 1;
return 2;
Big<exp, man> temp(*this);
if( temp.PowBUInt(pow) )
return 1;
uint c_temp = temp.PowUInt(pow);
if( c_temp > 0 )
return c_temp;
SetOne();
if( Div(temp) )
@@ -1122,13 +1204,13 @@ public:
/*!
power this = this ^ pow
this *must* be greater than zero (this > 0)
this must be greater than zero (this > 0)
pow can be negative and with fraction
return values:
0 - ok
1 - carry
2 - incorrect argument ('this')
2 - incorrect argument ('this' <= 0)
*/
uint PowFrac(const Big<exp, man> & pow)
{
@@ -1147,6 +1229,7 @@ public:
}
/*!
power this = this ^ pow
pow can be negative and with fraction
@@ -1171,14 +1254,14 @@ public:
return 0;
}
Big<exp, man> pow_frac( pow );
pow_frac.RemainFraction();
if( pow.exponent>-int(man*TTMATH_BITS_PER_UINT) && pow.exponent<=0 )
{
Big<exp, man> pow_frac( pow );
pow_frac.RemainFraction();
if( pow_frac.IsZero() )
return PowBInt( pow );
// pow is with fraction (not integer)
// result = e^(pow * ln(this) ) where 'this' must be greater than 0
if( pow_frac.IsZero() )
return PowInt( pow );
}
return PowFrac(pow);
}
@@ -1186,12 +1269,16 @@ public:
private:
#ifdef CONSTANTSGENERATOR
public:
#endif
/*!
Exponent this = exp(x) = e^x where x is in (-1,1)
we're using the formula exp(x) = 1 + (x)/(1!) + (x^2)/(2!) + (x^3)/(3!) + ...
*/
void ExpSurrounding0(const Big<exp,man> & x)
void ExpSurrounding0(const Big<exp,man> & x, uint * steps = 0)
{
TTMATH_REFERENCE_ASSERT( x )
@@ -1204,22 +1291,20 @@ private:
denominator.SetOne();
denominator_i.SetOne();
// this is only to avoid getting a warning about an uninitialized object
// gcc 4.1.2 reports: 'old_value.info' may be used uninitialized in this function
// (in fact we will initialize it later when the condition 'testing' is fulfilled)
old_value.info = 0;
// every 'step_test' times we make a test
const uint step_test = 5;
uint i;
old_value = *this;
// we begin from 1 in order to not testing at the start
for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
// we begin from 1 in order to not testing at the beginning
#ifdef CONSTANTSGENERATOR
for(i=1 ; true ; ++i)
#else
for(i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
#endif
{
bool testing = ((i % step_test) == 0);
if( testing )
old_value = *this;
next_part = numerator;
if( next_part.Div( denominator ) )
@@ -1232,9 +1317,12 @@ private:
Add( next_part );
if( testing && old_value==*this )
// we've added a next part of the formula but the result
// we've added next few parts of the formula but the result
// is still the same then we break the loop
break;
else
old_value = *this;
// we set the denominator and the numerator for a next part of the formula
if( denominator_i.Add(one) )
@@ -1247,10 +1335,11 @@ private:
if( numerator.Mul(x) )
break;
}
if( steps )
*steps = i;
}
public:
@@ -1318,7 +1407,7 @@ public:
else
{
ExpSurrounding0(m);
c += PowBUInt(e_);
c += PowUInt(e_);
}
return (c==0)? 0 : 1;
@@ -1329,13 +1418,17 @@ public:
private:
#ifdef CONSTANTSGENERATOR
public:
#endif
/*!
Natural logarithm this = ln(x) where x in range <1,2)
we're using the formula:
ln x = 2 * [ (x-1)/(x+1) + (1/3)((x-1)/(x+1))^3 + (1/5)((x-1)/(x+1))^5 + ... ]
*/
void LnSurrounding1(const Big<exp,man> & x)
void LnSurrounding1(const Big<exp,man> & x, uint * steps = 0)
{
Big<exp,man> old_value, next_part, denominator, one, two, x1(x), x2(x);
@@ -1360,16 +1453,19 @@ private:
denominator.SetOne();
SetZero();
// this is only to avoid getting a warning about an uninitialized object
// gcc 4.1.2 reports: 'old_value.info' may be used uninitialized in this function
// (in fact we will initialize it later when the condition 'testing' is fulfilled)
old_value.info = 0;
old_value = *this;
// every 'step_test' times we make a test
const uint step_test = 5;
uint i;
#ifdef CONSTANTSGENERATOR
for(i=1 ; true ; ++i)
#else
// we begin from 1 in order to not testing at the beginning
for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
for(i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
#endif
{
bool testing = ((i % step_test) == 0);
@@ -1381,9 +1477,6 @@ private:
// it means there are too many parts of the formula
break;
if( testing )
old_value = *this;
// there shouldn't be a carry here
Add(next_part);
@@ -1391,6 +1484,8 @@ private:
// we've added next (step_test) parts of the formula but the result
// is still the same then we break the loop
break;
else
old_value = *this;
if( x1.Mul(x2) )
// if there is a carry here the result we return as good
@@ -1402,7 +1497,10 @@ private:
// this = this * 2
// ( there can't be a carry here because we calculate the logarithm between <1,2) )
exponent.AddOne();
exponent.AddOne();
if( steps )
*steps = i;
}
@@ -1427,8 +1525,6 @@ public:
0 - ok
1 - overflow
2 - incorrect argument (x<=0)
parts: look at the LnSurrounding1() method
*/
uint Ln(const Big<exp,man> & x)
{
@@ -1460,7 +1556,7 @@ public:
/*!
Logarithm with a base 'base' -- this = Log(x) with a base 'base'
Logarithm from 'x' with a 'base'
we're using the formula:
Log(x) with 'base' = ln(x) / ln(base)
@@ -1470,12 +1566,6 @@ public:
1 - overflow
2 - incorrect argument (x<=0)
3 - incorrect base (a<=0 lub a=1)
parts: look at the LnSurrounding1() method
we pass this value only into 'ln(x)' method
because if we passed 'parts' into 'ln(base)' as well then
the error (after dividing) would be too great
*/
uint Log(const Big<exp,man> & x, const Big<exp,man> & base)
{
@@ -1502,7 +1592,6 @@ public:
// there can be only a carry
uint c = Ln(x);
// we don't pass the 'parts' here (the error after dividing would be to great)
c += denominator.Ln(base);
c += Div(denominator);
@@ -1514,7 +1603,7 @@ public:
/*!
*
* convertion methods
* converting methods
*
*/
@@ -1532,17 +1621,42 @@ public:
uint man_len_min = (man < another_man)? man : another_man;
uint i;
uint c = 0;
for( i = 0 ; i<man_len_min ; ++i )
mantissa.table[man-1-i] = another.mantissa.table[another_man-1-i];
for( ; i<man ; ++i )
mantissa.table[man-1-i] = 0;
// mantissa is standardized
//c += Standardizing();
return 0;
// MS Visual Express 2005 reports a warning (in the lines with 'uint man_diff = ...'):
// warning C4307: '*' : integral constant overflow
// but we're using 'if( man > another_man )' and 'if( man < another_man )' and there'll be no such a situation here
#ifndef __GNUC__
#pragma warning( disable: 4307 )
#endif
if( man > another_man )
{
uint man_diff = (man - another_man) * TTMATH_BITS_PER_UINT;
c += exponent.SubInt(man_diff, 0);
}
else
if( man < another_man )
{
uint man_diff = (another_man - man) * TTMATH_BITS_PER_UINT;
c += exponent.AddInt(man_diff, 0);
}
#ifndef __GNUC__
#pragma warning( default: 4307 )
#endif
// mantissa doesn't have to be standardized (either the highest bit is set or all bits are equal zero)
CorrectZero();
return (c == 0 )? 0 : 1;
}
@@ -1793,7 +1907,7 @@ public:
// where "1.F" is intended to represent the binary number
// created by prefixing F with an implicit leading 1 and a binary point.
FromDouble_SetExpAndMan(bool(temp.u[1] & 0x80000000u),
FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
e - 1023 - man*TTMATH_BITS_PER_UINT + 1, 0x80000000u,
m1, m2);
@@ -1815,7 +1929,7 @@ public:
m.table[0] = m2;
uint moved = m.CompensationToLeft();
FromDouble_SetExpAndMan(bool(temp.u[1] & 0x80000000u),
FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
e - 1022 - man*TTMATH_BITS_PER_UINT + 1 - moved, 0,
m.table[1], m.table[2]);
}
@@ -1906,7 +2020,7 @@ public:
// where "1.F" is intended to represent the binary number
// created by prefixing F with an implicit leading 1 and a binary point.
FromDouble_SetExpAndMan(bool(temp.u & 0x8000000000000000ul),
FromDouble_SetExpAndMan((temp.u & 0x8000000000000000ul) != 0,
e - 1023 - man*TTMATH_BITS_PER_UINT + 1,
0x8000000000000000ul, m);
@@ -2118,6 +2232,17 @@ public:
}
/*!
an operator= for converting 'double' to this class
*/
Big<exp, man> & operator=(double value)
{
FromDouble(value);
return *this;
}
/*!
a constructor for converting 'sint' to this class
*/
@@ -2135,6 +2260,15 @@ public:
}
/*!
a constructor for converting 'double' to this class
*/
Big(double value)
{
FromDouble(value);
}
#ifdef TTMATH_PLATFORM64
/*!
@@ -3091,39 +3225,48 @@ public:
a method for converting a string into its value
it returns 1 if the value will be too big -- we cannot pass it into the range
of our class Big<exp,man>
of our class Big<exp,man> (or if the base is incorrect)
that means only digits before the comma operator can make this value too big,
all digits after the comma we can ignore
'source' - pointer to the string for parsing
if 'after_source' is set that when this method have finished its job
it set the pointer to the new first character after parsed value
if 'after_source' is set that when this method finishes
it sets the pointer to the new first character after parsed value
'value_read' - if the pointer is provided that means the value_read will be true
only when a value has been actually read, there can be situation where only such
a string '-' or '+' will be parsed -- 'after_source' will be different from 'source' but
no value has been read (there are no digits)
on other words if 'value_read' is true -- there is at least one digit in the string
*/
uint FromString(const char * source, uint base = 10, const char ** after_source = 0)
uint FromString(const char * source, uint base = 10, const char ** after_source = 0, bool * value_read = 0)
{
bool is_sign;
bool value_read_temp = false;
if( base<2 || base>16 )
{
if( after_source )
*after_source = source;
if( value_read )
*value_read = value_read_temp;
return 1;
}
SetZero();
FromString_TestNewBase( source, base );
FromString_TestSign( source, is_sign );
uint c = FromString_ReadPartBeforeComma( source, base );
uint c = FromString_ReadPartBeforeComma( source, base, value_read_temp );
if( FromString_TestCommaOperator(source) )
c += FromString_ReadPartAfterComma( source, base );
c += FromString_ReadPartAfterComma( source, base, value_read_temp );
if( base==10 && FromString_TestScientific(source) )
c += FromString_ReadPartScientific( source );
if( value_read_temp && base == 10 )
c += FromString_ReadScientificIfExists( source );
if( is_sign && !IsZero() )
ChangeSign();
@@ -3131,6 +3274,9 @@ public:
if( after_source )
*after_source = source;
if( value_read )
*value_read = value_read_temp;
return (c==0)? 0 : 1;
}
@@ -3139,30 +3285,6 @@ public:
private:
/*!
we're testing whether a user wants to change the base
if there's a '#' character it means that the user wants the base to be 16,
if '&' the base will be 2
*/
void FromString_TestNewBase( const char * & source, uint & base )
{
UInt<man>::SkipWhiteCharacters(source);
if( *source == '#' )
{
base = 16;
++source;
}
else
if( *source == '&' )
{
base = 2;
++source;
}
}
/*!
we're testing whether the value is with the sign
@@ -3208,7 +3330,7 @@ private:
this method reads the first part of a string
(before the comma operator)
*/
uint FromString_ReadPartBeforeComma( const char * & source, uint base )
uint FromString_ReadPartBeforeComma( const char * & source, uint base, bool & value_read )
{
sint character;
Big<exp, man> temp;
@@ -3218,6 +3340,8 @@ private:
for( ; (character=UInt<man>::CharToDigit(*source, base)) != -1 ; ++source )
{
value_read = true;
temp = character;
if( Mul(base_) )
@@ -3235,7 +3359,7 @@ private:
this method reads the second part of a string
(after the comma operator)
*/
uint FromString_ReadPartAfterComma( const char * & source, uint base )
uint FromString_ReadPartAfterComma( const char * & source, uint base, bool & value_read )
{
sint character;
uint c = 0, index = 1;
@@ -3252,6 +3376,8 @@ private:
for( ; (character=UInt<man>::CharToDigit(*source, base)) != -1 ; ++source, ++index )
{
value_read = true;
part = character;
if( power.Mul( base_ ) )
@@ -3287,6 +3413,29 @@ private:
}
/*!
this method checks whether there is a scientific part: [e|E][-|+]value
it is called when the base is 10 and some digits were read before
*/
int FromString_ReadScientificIfExists(const char * & source)
{
int c = 0;
bool scientific_read = false;
const char * before_scientific = source;
if( FromString_TestScientific(source) )
c += FromString_ReadPartScientific( source, scientific_read );
if( !scientific_read )
source = before_scientific;
return (c==0)? 0 : 1;
}
/*!
we're testing whether is there the character 'e'
@@ -3311,21 +3460,24 @@ private:
this method reads the exponent (after 'e' character) when there's a scientific
format of value and only when we're using the base equals 10
*/
uint FromString_ReadPartScientific( const char * & source )
uint FromString_ReadPartScientific( const char * & source, bool & scientific_read )
{
uint c = 0;
Big<exp, man> new_exponent, temp;
bool was_sign = false;
FromString_TestSign( source, was_sign );
FromString_ReadPartScientific_ReadExponent( source, new_exponent );
c += FromString_ReadPartScientific_ReadExponent( source, new_exponent, scientific_read );
if( was_sign )
new_exponent.ChangeSign();
if( scientific_read )
{
if( was_sign )
new_exponent.ChangeSign();
temp = 10;
c += temp.PowBInt( new_exponent );
c += Mul(temp);
temp = 10;
c += temp.Pow( new_exponent );
c += Mul(temp);
}
return (c==0)? 0 : 1;
}
@@ -3335,7 +3487,7 @@ private:
this method reads the value of the extra exponent when scientific format is used
(only when base == 10)
*/
uint FromString_ReadPartScientific_ReadExponent( const char * & source, Big<exp, man> & new_exponent )
uint FromString_ReadPartScientific_ReadExponent( const char * & source, Big<exp, man> & new_exponent, bool & scientific_read )
{
sint character;
Big<exp, man> base, temp;
@@ -3347,6 +3499,8 @@ private:
for( ; (character=UInt<man>::CharToDigit(*source, 10)) != -1 ; ++source )
{
scientific_read = true;
temp = character;
if( new_exponent.Mul(base) )

View File

@@ -1,11 +1,11 @@
/*
* This file is a part of TTMath Mathematical Library
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* Copyright (c) 2006-2008, Tomasz Sowa
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -469,6 +469,70 @@ public:
private:
/*!
power this = this ^ pow
this can be negative
pow is >= 0
*/
uint Pow2(const Int<value_size> & pow)
{
bool was_sign = IsSign();
uint c = 0;
if( was_sign )
c += Abs();
uint c_temp = UInt<value_size>::Pow(pow);
if( c_temp > 0 )
return c_temp; // c_temp can be: 0, 1 or 2
if( was_sign && (pow.table[0] & 1) == 1 )
// negative value to the power of odd number is negative
c += ChangeSign();
return (c==0)? 0 : 1;
}
public:
/*!
power this = this ^ pow
return values:
0 - ok
1 - carry
2 - incorrect arguments 0^0 or 0^(-something)
*/
uint Pow(Int<value_size> pow)
{
if( !pow.IsSign() )
return Pow2(pow);
if( UInt<value_size>::IsZero() )
// if 'p' is negative then
// 'this' must be different from zero
return 2;
if( pow.ChangeSign() )
return 1;
Int<value_size> t(*this);
uint c_temp = t.Pow2(pow);
if( c_temp > 0 )
return c_temp;
UInt<value_size>::SetOne();
if( Div(t) )
return 1;
return 0;
}
/*!
*
@@ -836,8 +900,12 @@ public:
existing first white characters will be ommited
(between '-' and a first digit can be white characters too)
after_source (if exists) is pointing at the end of the parsed string
value_read (if exists) tells whether something has actually been read (at least one digit)
*/
uint FromString(const char * s, uint b = 10)
uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
{
bool is_sign = false;
@@ -854,7 +922,7 @@ public:
UInt<value_size>::SkipWhiteCharacters(++s);
}
if( UInt<value_size>::FromString(s,b) )
if( UInt<value_size>::FromString(s,b,after_source,value_read) )
return 1;
if( is_sign )
@@ -865,12 +933,15 @@ public:
/*
the reference to mmin will be automatically converted to the reference
to a UInt type
to UInt type
(this value can be equal mmin -- look at a description in ChangeSign())
*/
if( UInt<value_size>::operator>( mmin ) )
return 1;
/*
if the value is equal mmin the method ChangeSign() does nothing (only returns 1 but we ignore it)
*/
ChangeSign();
}
else

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2008, Tomasz Sowa
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -130,6 +130,21 @@ public:
}
/*!
this method returns true if such an object is defined (name exists)
*/
bool IsDefined(const std::string & name)
{
Iterator i = table.find(name);
if( i != table.end() )
// we have this object in our table
return true;
return false;
}
/*!
this method adds one object (variable of function) into the table
*/
@@ -258,7 +273,7 @@ public:
/*!
this method sets the value of a specific object
this method gets the value of a specific object
*/
ErrorCode GetValue(const std::string & name, std::string & value) const
{
@@ -280,7 +295,7 @@ public:
/*!
this method sets the value of a specific object
this method gets the value of a specific object
(this version is used for not copying the whole string)
*/
ErrorCode GetValue(const std::string & name, const char ** value) const
@@ -303,7 +318,7 @@ public:
/*!
this method sets the value and the number of parameters
this method gets the value and the number of parameters
of a specific object
*/
ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2008, Tomasz Sowa
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -61,14 +61,14 @@ namespace ttmath
/*!
\brief Mathematical parser
let x will be an input string means an expression for converting:
let x will be an input string meaning an expression for converting:
x = [+|-]Value[operator[+|-]Value][operator[+|-]Value]...
where:
an operator can be:
^ (pow) (almost the heighest priority, look below at 'short mul')
^ (pow) (the heighest priority)
* (mul)
* (mul) (or multiplication without an operator -- short mul)
/ (div) (* and / have the same priority)
+ (add)
@@ -86,14 +86,22 @@ 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)
if the second Value (Var below) is either a variable or function there might not be
an operator between them, e.g.
"[+|-]Value Var" is treated as "[+|-]Value * Var" and the multiplication
has the same priority as a normal multiplication:
4x = 4 * x
2^3m = (2^3)* m
6h^3 = 6 * (h^3)
2sin(pi) = 2 * sin(pi)
etc.
and Value can be:
constant e.g. 100
Value can be:
constant e.g. 100, can be preceded by operators for changing the base (radix): [#|&]
# - hex
& - bin
sample: #10 = 16
&10 = 2
variable e.g. pi
another expression between brackets e.g (x)
function e.g. sin(x)
@@ -112,7 +120,11 @@ 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)
"2+x" (of course if the variable 'x' is defined)
"4x+10"
"#20+10" = 32 + 10 = 42
"10 ^ -&101" = 10 ^ -5 = 0.00001
"8 * -&10" = 8 * -2 = -16
etc.
we can also use a semicolon for separating any 'x' input strings
@@ -137,7 +149,7 @@ private:
pow (^)
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)' )
(the 'shortmul' has the same priority as the normal multiplication )
*/
class MatOperator
{
@@ -182,6 +194,7 @@ private:
break;
case mul:
case shortmul:
case div:
priority = 12;
break;
@@ -190,10 +203,6 @@ private:
priority = 14;
break;
case shortmul:
priority = 20;
break;
default:
Error( err_internal_error );
break;
@@ -309,11 +318,21 @@ const char * pstring;
/*!
the base of the mathematic system (for example it may be '10')
the base (radix) of the mathematic system (for example it may be '10')
*/
int base;
/*!
the unit of angles used in: sin,cos,tan,cot,asin,acos,atan,acot
0 - deg
1 - rad (default)
2 - grad
*/
int deg_rad_grad;
/*!
a pointer to an object which tell us whether we should stop calculating or not
*/
@@ -406,7 +425,6 @@ typedef std::map<std::string, pfunction_var> VariablesTable;
VariablesTable variables_table;
/*!
you can't calculate the factorial if the argument is greater than 'factorial_max'
default value is zero which means there are not any limitations
@@ -423,8 +441,6 @@ static void Error(ErrorCode code)
}
/*!
this method skips the white character from the string
@@ -437,7 +453,6 @@ void SkipWhiteCharacters()
}
/*!
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/
@@ -467,6 +482,7 @@ void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::stri
visited_functions.insert( name );
}
/*!
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/
@@ -478,6 +494,7 @@ void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::s
visited_functions.erase( name );
}
/*!
this method returns the value of a variable or function
by creating a new instance of the mathematical parser
@@ -612,7 +629,53 @@ private:
/*!
'silnia' in polish language
used by: sin,cos,tan,cot
*/
ValueType ConvertAngleToRad(const ValueType & input)
{
if( deg_rad_grad == 1 ) // rad
return input;
ValueType result;
ErrorCode err;
if( deg_rad_grad == 0 ) // deg
result = ttmath::DegToRad(input, &err);
else // grad
result = ttmath::GradToRad(input, &err);
if( err != err_ok )
Error( err );
return result;
}
/*!
used by: asin,acos,atan,acot
*/
ValueType ConvertRadToAngle(const ValueType & input)
{
if( deg_rad_grad == 1 ) // rad
return input;
ValueType result;
ErrorCode err;
if( deg_rad_grad == 0 ) // deg
result = ttmath::RadToDeg(input, &err);
else // grad
result = ttmath::RadToGrad(input, &err);
if( err != err_ok )
Error( err );
return result;
}
/*!
factorial
result = 1 * 2 * 3 * 4 * .... * x
*/
void Factorial(int sindex, int amount_of_args, ValueType & result)
@@ -645,7 +708,7 @@ void Sin(int sindex, int amount_of_args, ValueType & result)
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
result = ttmath::Sin(stack[sindex].value);
result = ttmath::Sin( ConvertAngleToRad(stack[sindex].value) );
}
void Cos(int sindex, int amount_of_args, ValueType & result)
@@ -653,7 +716,7 @@ void Cos(int sindex, int amount_of_args, ValueType & result)
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
result = ttmath::Cos(stack[sindex].value);
result = ttmath::Cos( ConvertAngleToRad(stack[sindex].value) );
}
void Tan(int sindex, int amount_of_args, ValueType & result)
@@ -662,7 +725,7 @@ void Tan(int sindex, int amount_of_args, ValueType & result)
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::Tan(stack[sindex].value, &err);
result = ttmath::Tan(ConvertAngleToRad(stack[sindex].value), &err);
if(err != err_ok)
Error( err );
@@ -674,7 +737,7 @@ void Cot(int sindex, int amount_of_args, ValueType & result)
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::Cot(stack[sindex].value, &err);
result = ttmath::Cot(ConvertAngleToRad(stack[sindex].value), &err);
if(err != err_ok)
Error( err );
@@ -779,10 +842,12 @@ void ASin(int sindex, int amount_of_args, ValueType & result)
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::ASin(stack[sindex].value, &err);
ValueType temp = ttmath::ASin(stack[sindex].value, &err);
if(err != err_ok)
Error( err );
result = ConvertRadToAngle(temp);
}
@@ -792,10 +857,12 @@ void ACos(int sindex, int amount_of_args, ValueType & result)
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::ACos(stack[sindex].value, &err);
ValueType temp = ttmath::ACos(stack[sindex].value, &err);
if(err != err_ok)
Error( err );
result = ConvertRadToAngle(temp);
}
@@ -804,7 +871,7 @@ void ATan(int sindex, int amount_of_args, ValueType & result)
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
result = ttmath::ATan(stack[sindex].value);
result = ConvertRadToAngle(ttmath::ATan(stack[sindex].value));
}
@@ -813,7 +880,7 @@ void ACot(int sindex, int amount_of_args, ValueType & result)
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
result = ttmath::ACot(stack[sindex].value);
result = ConvertRadToAngle(ttmath::ACot(stack[sindex].value));
}
@@ -954,6 +1021,72 @@ void DegToDeg(int sindex, int amount_of_args, ValueType & result)
Error( err );
}
void GradToRad(int sindex, int amount_of_args, ValueType & result)
{
ErrorCode err;
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
result = ttmath::GradToRad(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void RadToGrad(int sindex, int amount_of_args, ValueType & result)
{
ErrorCode err;
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
result = ttmath::RadToGrad(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void DegToGrad(int sindex, int amount_of_args, ValueType & result)
{
ErrorCode err;
if( amount_of_args == 1 )
{
result = ttmath::DegToGrad(stack[sindex].value, &err);
}
else
if( amount_of_args == 3 )
{
result = ttmath::DegToGrad( stack[sindex].value, stack[sindex+2].value,
stack[sindex+4].value, &err);
}
else
Error( err_improper_amount_of_arguments );
if( err != err_ok )
Error( err );
}
void GradToDeg(int sindex, int amount_of_args, ValueType & result)
{
ErrorCode err;
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
result = ttmath::GradToDeg(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void Ceil(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
@@ -1282,9 +1415,9 @@ void CallFunction(const std::string & function_name, int amount_of_args, int sin
function_name - name of the function
pf - pointer to the function (to the wrapper)
*/
void InsertFunctionToTable(const std::string & function_name, pfunction pf)
void InsertFunctionToTable(const char * function_name, pfunction pf)
{
functions_table.insert( std::make_pair(function_name, pf));
functions_table.insert( std::make_pair(std::string(function_name), pf));
}
@@ -1295,9 +1428,9 @@ void InsertFunctionToTable(const std::string & function_name, pfunction pf)
variable_name - name of the function
pf - pointer to the function
*/
void InsertVariableToTable(const std::string & variable_name, pfunction_var pf)
void InsertVariableToTable(const char * variable_name, pfunction_var pf)
{
variables_table.insert( std::make_pair(variable_name, pf));
variables_table.insert( std::make_pair(std::string(variable_name), pf));
}
@@ -1309,60 +1442,64 @@ void CreateFunctionsTable()
/*
names of functions should consist of small letters
*/
InsertFunctionToTable(std::string("factorial"), &Parser<ValueType>::Factorial);
InsertFunctionToTable(std::string("abs"), &Parser<ValueType>::Abs);
InsertFunctionToTable(std::string("sin"), &Parser<ValueType>::Sin);
InsertFunctionToTable(std::string("cos"), &Parser<ValueType>::Cos);
InsertFunctionToTable(std::string("tan"), &Parser<ValueType>::Tan);
InsertFunctionToTable(std::string("tg"), &Parser<ValueType>::Tan);
InsertFunctionToTable(std::string("cot"), &Parser<ValueType>::Cot);
InsertFunctionToTable(std::string("ctg"), &Parser<ValueType>::Cot);
InsertFunctionToTable(std::string("int"), &Parser<ValueType>::Int);
InsertFunctionToTable(std::string("round"), &Parser<ValueType>::Round);
InsertFunctionToTable(std::string("ln"), &Parser<ValueType>::Ln);
InsertFunctionToTable(std::string("log"), &Parser<ValueType>::Log);
InsertFunctionToTable(std::string("exp"), &Parser<ValueType>::Exp);
InsertFunctionToTable(std::string("max"), &Parser<ValueType>::Max);
InsertFunctionToTable(std::string("min"), &Parser<ValueType>::Min);
InsertFunctionToTable(std::string("asin"), &Parser<ValueType>::ASin);
InsertFunctionToTable(std::string("acos"), &Parser<ValueType>::ACos);
InsertFunctionToTable(std::string("atan"), &Parser<ValueType>::ATan);
InsertFunctionToTable(std::string("atg"), &Parser<ValueType>::ATan);
InsertFunctionToTable(std::string("acot"), &Parser<ValueType>::ACot);
InsertFunctionToTable(std::string("actg"), &Parser<ValueType>::ACot);
InsertFunctionToTable(std::string("sgn"), &Parser<ValueType>::Sgn);
InsertFunctionToTable(std::string("mod"), &Parser<ValueType>::Mod);
InsertFunctionToTable(std::string("if"), &Parser<ValueType>::If);
InsertFunctionToTable(std::string("or"), &Parser<ValueType>::Or);
InsertFunctionToTable(std::string("and"), &Parser<ValueType>::And);
InsertFunctionToTable(std::string("not"), &Parser<ValueType>::Not);
InsertFunctionToTable(std::string("degtorad"), &Parser<ValueType>::DegToRad);
InsertFunctionToTable(std::string("radtodeg"), &Parser<ValueType>::RadToDeg);
InsertFunctionToTable(std::string("degtodeg"), &Parser<ValueType>::DegToDeg);
InsertFunctionToTable(std::string("ceil"), &Parser<ValueType>::Ceil);
InsertFunctionToTable(std::string("floor"), &Parser<ValueType>::Floor);
InsertFunctionToTable(std::string("sqrt"), &Parser<ValueType>::Sqrt);
InsertFunctionToTable(std::string("sinh"), &Parser<ValueType>::Sinh);
InsertFunctionToTable(std::string("cosh"), &Parser<ValueType>::Cosh);
InsertFunctionToTable(std::string("tanh"), &Parser<ValueType>::Tanh);
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);
InsertFunctionToTable("factorial", &Parser<ValueType>::Factorial);
InsertFunctionToTable("abs", &Parser<ValueType>::Abs);
InsertFunctionToTable("sin", &Parser<ValueType>::Sin);
InsertFunctionToTable("cos", &Parser<ValueType>::Cos);
InsertFunctionToTable("tan", &Parser<ValueType>::Tan);
InsertFunctionToTable("tg", &Parser<ValueType>::Tan);
InsertFunctionToTable("cot", &Parser<ValueType>::Cot);
InsertFunctionToTable("ctg", &Parser<ValueType>::Cot);
InsertFunctionToTable("int", &Parser<ValueType>::Int);
InsertFunctionToTable("round", &Parser<ValueType>::Round);
InsertFunctionToTable("ln", &Parser<ValueType>::Ln);
InsertFunctionToTable("log", &Parser<ValueType>::Log);
InsertFunctionToTable("exp", &Parser<ValueType>::Exp);
InsertFunctionToTable("max", &Parser<ValueType>::Max);
InsertFunctionToTable("min", &Parser<ValueType>::Min);
InsertFunctionToTable("asin", &Parser<ValueType>::ASin);
InsertFunctionToTable("acos", &Parser<ValueType>::ACos);
InsertFunctionToTable("atan", &Parser<ValueType>::ATan);
InsertFunctionToTable("atg", &Parser<ValueType>::ATan);
InsertFunctionToTable("acot", &Parser<ValueType>::ACot);
InsertFunctionToTable("actg", &Parser<ValueType>::ACot);
InsertFunctionToTable("sgn", &Parser<ValueType>::Sgn);
InsertFunctionToTable("mod", &Parser<ValueType>::Mod);
InsertFunctionToTable("if", &Parser<ValueType>::If);
InsertFunctionToTable("or", &Parser<ValueType>::Or);
InsertFunctionToTable("and", &Parser<ValueType>::And);
InsertFunctionToTable("not", &Parser<ValueType>::Not);
InsertFunctionToTable("degtorad", &Parser<ValueType>::DegToRad);
InsertFunctionToTable("radtodeg", &Parser<ValueType>::RadToDeg);
InsertFunctionToTable("degtodeg", &Parser<ValueType>::DegToDeg);
InsertFunctionToTable("gradtorad", &Parser<ValueType>::GradToRad);
InsertFunctionToTable("radtograd", &Parser<ValueType>::RadToGrad);
InsertFunctionToTable("degtograd", &Parser<ValueType>::DegToGrad);
InsertFunctionToTable("gradtodeg", &Parser<ValueType>::GradToDeg);
InsertFunctionToTable("ceil", &Parser<ValueType>::Ceil);
InsertFunctionToTable("floor", &Parser<ValueType>::Floor);
InsertFunctionToTable("sqrt", &Parser<ValueType>::Sqrt);
InsertFunctionToTable("sinh", &Parser<ValueType>::Sinh);
InsertFunctionToTable("cosh", &Parser<ValueType>::Cosh);
InsertFunctionToTable("tanh", &Parser<ValueType>::Tanh);
InsertFunctionToTable("tgh", &Parser<ValueType>::Tanh);
InsertFunctionToTable("coth", &Parser<ValueType>::Coth);
InsertFunctionToTable("ctgh", &Parser<ValueType>::Coth);
InsertFunctionToTable("root", &Parser<ValueType>::Root);
InsertFunctionToTable("asinh", &Parser<ValueType>::ASinh);
InsertFunctionToTable("acosh", &Parser<ValueType>::ACosh);
InsertFunctionToTable("atanh", &Parser<ValueType>::ATanh);
InsertFunctionToTable("atgh", &Parser<ValueType>::ATanh);
InsertFunctionToTable("acoth", &Parser<ValueType>::ACoth);
InsertFunctionToTable("actgh", &Parser<ValueType>::ACoth);
InsertFunctionToTable("bitand", &Parser<ValueType>::BitAnd);
InsertFunctionToTable("bitor", &Parser<ValueType>::BitOr);
InsertFunctionToTable("bitxor", &Parser<ValueType>::BitXor);
InsertFunctionToTable("band", &Parser<ValueType>::BitAnd);
InsertFunctionToTable("bor", &Parser<ValueType>::BitOr);
InsertFunctionToTable("bxor", &Parser<ValueType>::BitXor);
InsertFunctionToTable("sum", &Parser<ValueType>::Sum);
InsertFunctionToTable("avg", &Parser<ValueType>::Avg);
}
@@ -1374,8 +1511,8 @@ void CreateVariablesTable()
/*
names of variables should consist of small letters
*/
InsertVariableToTable(std::string("pi"), &ValueType::SetPi);
InsertVariableToTable(std::string("e"), &ValueType::SetE);
InsertVariableToTable("pi", &ValueType::SetPi);
InsertVariableToTable("e", &ValueType::SetE);
}
@@ -1498,17 +1635,21 @@ return is_it_name_of_function;
/*!
we're reading a numerical value directly from the string
we're reading a numerical value directly from the string
*/
void ReadValue(Item & result)
void ReadValue(Item & result, int reading_base)
{
const char * new_stack_pointer;
bool value_read;
int carry = result.value.FromString(pstring, base, &new_stack_pointer);
int carry = result.value.FromString(pstring, reading_base, &new_stack_pointer, &value_read);
pstring = new_stack_pointer;
if( carry )
Error( err_overflow );
if( !value_read )
Error( err_unknown_character );
}
@@ -1537,6 +1678,24 @@ return c;
}
/*!
this method returns true if 'character' is a proper first digit for the value (or a comma -- can be first too)
*/
bool ValueStarts(int character, int base)
{
if( character == TTMATH_COMMA_CHARACTER_1 )
return true;
if( TTMATH_COMMA_CHARACTER_2 != 0 && character == TTMATH_COMMA_CHARACTER_2 )
return true;
if( CharToDigit(character, base) != -1 )
return true;
return false;
}
/*!
we're reading the item
@@ -1596,19 +1755,33 @@ int character;
return 2;
}
else
if( character=='#' || character=='&' ||
character==TTMATH_COMMA_CHARACTER_1 ||
(character==TTMATH_COMMA_CHARACTER_2 && TTMATH_COMMA_CHARACTER_2 != 0) ||
CharToDigit(character, base)!=-1 )
if( character == '#' )
{
/*
warning:
if we're using for example the base equal 16
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)
*/
ReadValue( result );
++pstring;
SkipWhiteCharacters();
// after '#' character we do not allow '-' or '+' (can be white characters)
if( ValueStarts(*pstring, 16) )
ReadValue( result, 16 );
else
Error( err_unknown_character );
}
else
if( character == '&' )
{
++pstring;
SkipWhiteCharacters();
// after '&' character we do not allow '-' or '+' (can be white characters)
if( ValueStarts(*pstring, 2) )
ReadValue( result, 2 );
else
Error( err_unknown_character );
}
else
if( ValueStarts(character, base) )
{
ReadValue( result, base );
}
else
if( character>='a' && character<='z' )
@@ -1911,9 +2084,9 @@ void TryRollingUpStack()
*/
int ReadValueVariableOrFunctionAndPushItIntoStack(Item & temp)
{
int kod = ReadValueVariableOrFunction( temp );
int code = ReadValueVariableOrFunction( temp );
if( kod == 0 )
if( code == 0 )
{
if( stack_index < stack.size() )
stack[stack_index] = temp;
@@ -1923,13 +2096,13 @@ int kod = ReadValueVariableOrFunction( temp );
++stack_index;
}
if( kod == 2 )
if( code == 2 )
// there was a final bracket, we didn't push it into the stack
// (it'll be read by the 'ReadOperatorAndCheckFinalBracket' method next)
kod = 0;
code = 0;
return kod;
return code;
}
@@ -2218,6 +2391,7 @@ Parser(): default_stack_size(100)
puser_functions = 0;
pfunction_local_variables = 0;
base = 10;
deg_rad_grad = 1;
error = err_ok;
factorial_max.SetZero();
@@ -2237,6 +2411,7 @@ Parser<ValueType> & operator=(const Parser<ValueType> & p)
puser_functions = p.puser_functions;
pfunction_local_variables = 0;
base = p.base;
deg_rad_grad = p.deg_rad_grad;
error = err_ok;
factorial_max = p.factorial_max;
@@ -2274,6 +2449,18 @@ void SetBase(int b)
}
/*!
the unit of angles used in: sin,cos,tan,cot,asin,acos,atan,acot
0 - deg
1 - rad (default)
2 - grad
*/
void SetDegRadGrad(int angle)
{
if( angle >= 0 || angle <= 2 )
deg_rad_grad = angle;
}
/*!
this method sets a pointer to the object which tell us whether we should stop
calculations

View File

@@ -1,11 +1,11 @@
/*
* This file is a part of TTMath Mathematical Library
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* Copyright (c) 2006-2008, Tomasz Sowa
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -64,7 +64,7 @@
*/
#define TTMATH_MAJOR_VER 0
#define TTMATH_MINOR_VER 8
#define TTMATH_REVISION_VER 2
#define TTMATH_REVISION_VER 3
#define TTMATH_PRERELEASE_VER 0
@@ -141,7 +141,7 @@ namespace ttmath
which are kept in built-in variables for a Big<> type
(these variables are defined in ttmathbig.h)
*/
#define TTMATH_BUILTIN_VARIABLES_SIZE 128u
#define TTMATH_BUILTIN_VARIABLES_SIZE 256u
#else
@@ -172,7 +172,7 @@ namespace ttmath
which are kept in built-in variables for a Big<> type
(these variables are defined in ttmathbig.h)
*/
#define TTMATH_BUILTIN_VARIABLES_SIZE 64ul
#define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
#endif
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,11 @@
/*
* This file is a part of TTMath Mathematical Library
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* Copyright (c) 2006-2008, Tomasz Sowa
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -210,10 +210,12 @@ namespace ttmath
register uint * p2 = const_cast<uint*>(ss2.table);
// we don't have to use TTMATH_REFERENCE_ASSERT here
// this algorithm doesn't require it
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
/*
@@ -221,48 +223,28 @@ namespace ttmath
*/
__asm__ __volatile__(
"push %%rbx \n"
"push %%rcx \n"
"push %%rdx \n"
"push %%rcx \n"
"movq $0, %%rax \n"
"subq %%rsi, %%rax \n"
"xorq %%rax, %%rax \n"
"movq %%rax, %%rdx \n"
"subq %%rdi, %%rax \n"
"1: \n"
"movq (%%rbx),%%rax \n"
"adcq (%%rdx),%%rax \n"
"movq %%rax,(%%rbx) \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"loop 1b \n"
"movq $0, %%rax \n"
"adcq %%rax,%%rax \n"
"movq %%rax, %%rsi \n"
"1: \n"
"movq (%%rsi,%%rdx,8),%%rax \n"
"adcq %%rax, (%%rbx,%%rdx,8) \n"
"incq %%rdx \n"
"decq %%rcx \n"
"jnz 1b \n"
"pop %%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
"setc %%al \n"
"movzx %%al,%%rdx \n"
: "=S" (c)
: "0" (c), "c" (b), "b" (p1), "d" (p2)
"pop %%rcx \n"
: "=d" (c)
: "D" (c), "c" (b), "b" (p1), "S" (p2)
: "%rax", "cc", "memory" );
#endif
@@ -301,54 +283,39 @@ namespace ttmath
register uint * p1 = table;
register uint c;
TTMATH_ASSERT( index < value_size )
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rbx \n"
"push %%rax \n"
"push %%rcx \n"
"push %%rdx \n"
"subq %%rdx, %%rcx \n"
"leaq (%%rbx,%%rdx,8), %%rbx \n"
"movq %%rsi, %%rdx \n"
"clc \n"
"1: \n"
"movq (%%rbx), %%rax \n"
"adcq %%rdx, %%rax \n"
"movq %%rax, (%%rbx) \n"
"addq %%rax, (%%rbx,%%rdx,8) \n"
"jnc 2f \n"
"movq $0, %%rdx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"loop 1b \n"
"movq $1, %%rax \n"
"incq %%rdx \n"
"decq %%rcx \n"
"jnz 1b \n"
"2: \n"
"setc %%al \n"
"movzx %%al, %%rdx \n"
"movq $0, %%rax \n"
"adcq %%rax,%%rax \n"
"pop %%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
"pop %%rax \n"
: "=a" (c)
: "c" (b), "d" (index), "b" (p1), "S" (value)
: "=d" (c)
: "a" (value), "c" (b), "0" (index), "b" (p1)
: "cc", "memory" );
#endif
@@ -398,6 +365,8 @@ namespace ttmath
register uint * p1 = table;
register uint c;
TTMATH_ASSERT( index < value_size - 1 )
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
@@ -405,67 +374,33 @@ namespace ttmath
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rbx \n"
"push %%rcx \n"
"push %%rdx \n"
"subq %%rdx, %%rcx \n"
"leaq (%%rbx,%%rdx,8), %%rbx \n"
"movq $0, %%rdx \n"
"movq (%%rbx), %%rax \n"
"addq %%rsi, %%rax \n"
"movq %%rax, (%%rbx) \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"movq (%%rbx), %%rax \n"
"adcq %%rdi, %%rax \n"
"movq %%rax, (%%rbx) \n"
"jnc 2f \n"
"dec %%rcx \n"
"dec %%rcx \n"
"jz 2f \n"
"addq %%rsi, (%%rbx,%%rdx,8) \n"
"incq %%rdx \n"
"decq %%rcx \n"
"1: \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"movq (%%rbx), %%rax \n"
"adcq %%rdx, %%rax \n"
"movq %%rax, (%%rbx) \n"
"adcq %%rax, (%%rbx,%%rdx,8) \n"
"jnc 2f \n"
"loop 1b \n"
"mov $0, %%rax \n"
"incq %%rdx \n"
"decq %%rcx \n"
"jnz 1b \n"
"2: \n"
"movq $0, %%rax \n"
"adcq %%rax,%%rax \n"
"setc %%al \n"
"movzx %%al, %%rax \n"
"pop %%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
: "=a" (c)
: "c" (b), "d" (index), "b" (p1), "S" (x1), "D" (x2)
: "c" (b), "d" (index), "b" (p1), "S" (x1), "0" (x2)
: "cc", "memory" );
#endif
@@ -495,6 +430,9 @@ namespace ttmath
register uint * p1 = table;
register uint * p2 = const_cast<uint*>(ss2.table);
// we don't have to use TTMATH_REFERENCE_ASSERT here
// this algorithm doesn't require it
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
@@ -502,50 +440,31 @@ namespace ttmath
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rbx \n"
"push %%rcx \n"
"push %%rdx \n"
"push %%rcx \n"
"xorq %%rax, %%rax \n"
"movq %%rax, %%rdx \n"
"subq %%rdi, %%rax \n"
"movq $0, %%rax \n"
"subq %%rsi, %%rax \n"
"1: \n"
"movq (%%rbx),%%rax \n"
"sbbq (%%rdx),%%rax \n"
"movq %%rax,(%%rbx) \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"loop 1b \n"
"1: \n"
"movq (%%rsi,%%rdx,8),%%rax \n"
"sbbq %%rax, (%%rbx,%%rdx,8) \n"
"incq %%rdx \n"
"decq %%rcx \n"
"jnz 1b \n"
"movq $0, %%rax \n"
"adcq %%rax,%%rax \n"
"movq %%rax, %%rsi \n"
"setc %%al \n"
"movzx %%al,%%rdx \n"
"pop %%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
"pop %%rcx \n"
: "=S" (c)
: "0" (c), "c" (b), "b" (p1), "d" (p2)
: "=d" (c)
: "D" (c), "c" (b), "b" (p1), "S" (p2)
: "%rax", "cc", "memory" );
#endif
@@ -579,6 +498,8 @@ namespace ttmath
register uint * p1 = table;
register uint c;
TTMATH_ASSERT( index < value_size )
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
@@ -586,48 +507,29 @@ namespace ttmath
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rbx \n"
"push %%rax \n"
"push %%rcx \n"
"push %%rdx \n"
"subq %%rdx, %%rcx \n"
"leaq (%%rbx,%%rdx,8), %%rbx \n"
"movq %%rsi, %%rdx \n"
"clc \n"
"1: \n"
"movq (%%rbx), %%rax \n"
"sbbq %%rdx, %%rax \n"
"movq %%rax, (%%rbx) \n"
"subq %%rax, (%%rbx,%%rdx,8) \n"
"jnc 2f \n"
"movq $0, %%rdx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"loop 1b \n"
"movq $1, %%rax \n"
"incq %%rdx \n"
"decq %%rcx \n"
"jnz 1b \n"
"2: \n"
"setc %%al \n"
"movzx %%al, %%rdx \n"
"movq $0, %%rax \n"
"adcq %%rax,%%rax \n"
"pop %%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
"pop %%rax \n"
: "=a" (c)
: "c" (b), "d" (index), "b" (p1), "S" (value)
: "=d" (c)
: "a" (value), "c" (b), "0" (index), "b" (p1)
: "cc", "memory" );
#endif
@@ -637,6 +539,119 @@ namespace ttmath
}
/*!
this method moves all bits into the left hand side
return value <- this <- c
the lowest *bit* 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_one(1) there'll be 010100001 and Rcl2_one returns 0
***this method is created only on a 64bit platform***
*/
template<uint value_size>
uint UInt<value_size>::Rcl2_one(uint c)
{
register sint b = value_size;
register uint * p1 = table;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rdx \n"
"push %%rcx \n"
"xorq %%rdx, %%rdx \n" // rdx=0
"neg %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
"1: \n"
"rclq $1, (%%rbx, %%rdx, 8) \n"
"incq %%rdx \n"
"decq %%rcx \n"
"jnz 1b \n"
"setc %%al \n"
"movzx %%al, %%rax \n"
"pop %%rcx \n"
"pop %%rdx \n"
: "=a" (c)
: "0" (c), "c" (b), "b" (p1)
: "cc", "memory" );
#endif
return c;
}
/*!
this method moves all bits into the right hand side
c -> this -> return value
the highest *bit* 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_one(1) there'll be 100000001 and Rcr2_one returns 0
***this method is created only on a 64bit platform***
*/
template<uint value_size>
uint UInt<value_size>::Rcr2_one(uint c)
{
register sint b = value_size;
register uint * p1 = table;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rcx \n"
"neg %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
"1: \n"
"rcrq $1, -8(%%rbx, %%rcx, 8) \n"
"decq %%rcx \n"
"jnz 1b \n"
"setc %%al \n"
"movzx %%al, %%rax \n"
"pop %%rcx \n"
: "=a" (c)
: "0" (c), "c" (b), "b" (p1)
: "cc", "memory" );
#endif
return c;
}
/*!
this method moves all bits into the left hand side
return value <- this <- c
@@ -654,13 +669,11 @@ namespace ttmath
template<uint value_size>
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;
register uint mask;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
@@ -669,46 +682,46 @@ namespace ttmath
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rsi \n"
"push %%rdx \n"
"push %%rsi \n"
"push %%rdi \n"
"2: \n"
"movq %%rcx, %%rsi \n"
"movq $64, %%rcx \n"
"subq %%rsi, %%rcx \n"
"movq $-1, %%rdx \n"
"shrq %%cl, %%rdx \n"
"movq %%rdx, %[amask] \n"
"movq %%rsi, %%rcx \n"
"xorq %%rax,%%rax \n"
"subq %%rdx,%%rax \n"
"xorq %%rdx, %%rdx \n"
"movq %%rdx, %%rsi \n"
"push %%rbx \n"
"push %%rcx \n"
"orq %%rax, %%rax \n"
"cmovnz %[amask], %%rsi \n"
"1: \n"
"rclq $1,(%%rbx) \n"
"1: \n"
"rolq %%cl, (%%rbx,%%rdx,8) \n"
"movq (%%rbx,%%rdx,8), %%rax \n"
"andq %[amask], %%rax \n"
"xorq %%rax, (%%rbx,%%rdx,8) \n"
"orq %%rsi, (%%rbx,%%rdx,8) \n"
"movq %%rax, %%rsi \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"incq %%rdx \n"
"decq %%rdi \n"
"jnz 1b \n"
"loop 1b \n"
"pop %%rcx \n"
"pop %%rbx \n"
"and $1, %%rax \n"
"decq %%rsi \n"
"pop %%rdi \n"
"pop %%rsi \n"
"pop %%rdx \n"
"jnz 2b \n"
"movq $0, %%rdx \n"
"adcq %%rdx, %%rdx \n"
"pop %%rsi \n"
: "=d" (c)
: "0" (c), "c" (b), "b" (p1), "S" (bits)
: "%rax", "cc", "memory" );
: "=a" (c)
: "0" (c), "D" (b), "b" (p1), "c" (bits), [amask] "m" (mask)
: "cc", "memory" );
#endif
@@ -734,14 +747,11 @@ namespace ttmath
template<uint value_size>
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;
register uint mask;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
@@ -751,49 +761,49 @@ namespace ttmath
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rsi \n"
"2: \n"
"push %%rbx \n"
"push %%rcx \n"
"leaq (%%rbx,%%rcx,8),%%rbx \n"
"xorq %%rax, %%rax \n"
"subq %%rdx, %%rax \n"
"1: \n"
"dec %%rbx \n"
"dec %%rbx \n"
"dec %%rbx \n"
"dec %%rbx \n"
"dec %%rbx \n"
"dec %%rbx \n"
"dec %%rbx \n"
"dec %%rbx \n"
"push %%rdx \n"
"push %%rsi \n"
"push %%rdi \n"
"rcrq $1,(%%rbx) \n"
"movq %%rcx, %%rsi \n"
"movq $64, %%rcx \n"
"subq %%rsi, %%rcx \n"
"movq $-1, %%rdx \n"
"shlq %%cl, %%rdx \n"
"movq %%rdx, %[amask] \n"
"movq %%rsi, %%rcx \n"
"xorq %%rdx, %%rdx \n"
"movq %%rdx, %%rsi \n"
"addq %%rdi, %%rdx \n"
"decq %%rdx \n"
"orq %%rax, %%rax \n"
"cmovnz %[amask], %%rsi \n"
"1: \n"
"rorq %%cl, (%%rbx,%%rdx,8) \n"
"movq (%%rbx,%%rdx,8), %%rax \n"
"andq %[amask], %%rax \n"
"xorq %%rax, (%%rbx,%%rdx,8) \n"
"orq %%rsi, (%%rbx,%%rdx,8) \n"
"movq %%rax, %%rsi \n"
"loop 1b \n"
"decq %%rdx \n"
"decq %%rdi \n"
"jnz 1b \n"
"rolq $1, %%rax \n"
"andq $1, %%rax \n"
"pop %%rcx \n"
"pop %%rbx \n"
"pop %%rdi \n"
"pop %%rsi \n"
"pop %%rdx \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), "S" (bits)
: "%rax", "cc", "memory" );
: "=a" (c)
: "0" (c), "D" (b), "b" (p1), "c" (bits), [amask] "m" (mask)
: "cc", "memory" );
#endif
@@ -820,14 +830,13 @@ namespace ttmath
#ifdef __GNUC__
__asm__ __volatile__(
"bsrq %%rbx, %%rax \n"
"bsrq %1, %0 \n"
"jnz 1f \n"
"movq $-1, %%rax \n"
"1: \n"
"movq $-1, %0 \n"
"1: \n"
: "=a" (result)
: "b" (x)
: "=R" (result)
: "R" (x)
: "cc" );
#endif
@@ -839,20 +848,26 @@ namespace ttmath
/*!
this method sets a special bit in the 'value'
and returns the result
and returns the last state of the bit (zero or one)
***this method is created only on a 64bit platform***
bit is from <0,31>
bit is from <0,63>
e.g.
SetBitInWord(0,0) = 1
SetBitInWord(0,2) = 4
SetBitInWord(10, 8) = 266
uint x = 100;
uint bit = SetBitInWord(x, 3);
now: x = 108 and bit = 0
*/
template<uint value_size>
uint UInt<value_size>::SetBitInWord(uint value, uint bit)
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
{
TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT )
uint old_bit;
uint v = value;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
@@ -860,15 +875,20 @@ namespace ttmath
#ifdef __GNUC__
__asm__ __volatile__(
"btsq %%rbx,%%rax \n"
"btsq %%rbx, %%rax \n"
: "=a" (value)
: "0" (value), "b" (bit)
"setc %%bl \n"
"movzx %%bl, %%rbx \n"
: "=a" (v), "=b" (old_bit)
: "0" (v), "1" (bit)
: "cc" );
#endif
return value;
value = v;
return old_bit;
}