40 Commits
0.8.1 ... 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
98c2379182 changed: small changes especially cosmetic in documentation (commentaries)
changed: version of the library: now 0.8.2


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


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@67 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-06-07 16:17:37 +00:00
4d0241c9c9 changed: the way of using Big::SetSign()
the method do not check whether there is a zero or not now
         (even if there's a zero the method can set a sign bit)
         I changed this due to some prior errors
         (errors corrected in revision 17, 49 and 58)
added:   in Big::MulInt() checking whether the values are zeros
         and if so the metdhod returns zero immediately
removed: file TODO (I didn't use it)



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


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


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


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


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


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


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


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


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


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


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@41 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-04-23 21:35:55 +00:00
21 changed files with 3997 additions and 1499 deletions

384
CHANGELOG
View File

@@ -1,122 +1,262 @@
Version 0.8.1 (2007.04.17): Version 0.8.3 (2009.04.06):
* fixed: Big::PowFrac(..) didn't return a correct error code * fixed: RclMoveAllWords() and RcrMoveAllWords() sometimes didn't return
(when 'this' was negative) the proper carry, (when 'bits' was greater than or equal to 'value_size')
* added: Root(x; index) (and to the parser as well) this had impact on Rcl() and Rcr(), they also returned the wrong carry
* added: macro: TTMATH_PRERELEASE_VER (can be either zero or one) * fixed: UInt::Div() didn't return a correct result when the divisor was equal 1
* added: UInt::MulInt(int, UInt<int another_size>::&) there was an error in UInt::DivInt() - when the divisor was 1 it returned
* added: Big::MulUInt(uint) zero and the carry was set
* changed: Big::MulInt(sint) * fixed: there was a TTMATH_REREFENCE_ASSERT error in Big::PowUInt() caused by: start.Mul(start)
* added: Big::ToUInt(uint &) * fixed: Big::Add incorrectly rounded 'this' when both exponents were equal
* changed: Big::ToInt(sint&) it caused that sometimes when adding a zero the result has changed
* changed: Factorial() it uses Big::MulUInt() at the beginning this had impact among other things on FromString() method
(faster now especially more on a 32bit platform) "0,8" had different binary representation from "0,80"
* added: doxygen.cfg for generating a documentation from the doxygen * fixed: template Big::FromBig(const Big<another_exp, another_man> & another)
* changed: UInt::Rcl(uint c=0) and UInt::Rcr(uint c=0) into didn't correctly set the exponent (when the mantisses had different size -
UInt::Rcl2(uint bits, uint c) and UInt::Rcr2(uint bits, uint c) when 'man' was different from 'another_man')
now they can move more than one bit and they are only private this had impact on operator= too
* fixed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c) sample:
didn't correctly return a carry if the 'bits' were equal Big<2,3> a = 100;
to 'value_size*TTMATH_BITS_PER_UINT' Big<3,5> b;
* changed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c) b = a; // b had a wrong value
into UInt::Rcl(uint bits, uint c=0) and * fixed: Big::Pow(const Big<exp, man> & pow)
UInt::Rcr(uint bits, uint c=0) it's using PowInt() only when pow.exponent is in range (-man*TTMATH_BITS_PER_UINT; 0]
they are faster now when the bits is greater than a half of previously the powering 'hung' on an input like this: "(1+ 1e-10000) ^ 10e100000000"
the TTMATH_BITS_PER_UINT (there was 10e100000000 iterations in PowInt())
* changed: UInt::CompensationToLeft() it's faster now * fixed: in function DegToRad(const ValueType & x, ErrorCode * err = 0) it is better
* changed: more small changes where there were UInt::Rcl(uint c=0) and to make division first and then mutliplication -- the result is more
UInt::Rcr(uint c=0) used accurate especially when x is: 90,180,270 or 360
* changed: as the Big type uses UInt::Rcl() and UInt::Rcr() a lot then * fixed: the parser didn't correctly treat operators for changing the base
it is much faster now (about 5-25%) (radix) -- operators '#' and '&', e.g.:
* added: ASinh(), ACosh(), ATanh() /ATgh()/, ACoth() /ACtgh()/ '#sin(1)' was equal '0' -- there was a zero from '#' and then
and to the parser as well it was multipied by 'sin(1)'
* added: UInt::BitAnd(), UInt::BitOr(), UInt::BitXor(), UInt::BitNot(), the parser didn't check whether Big::FromString() has actually
Big::BitAnd(), Big::BitOr(), Big::BitXor() read a proper value -- the method Big::FromString() didn't have
* added: to the parser: bitand(), bitor(), bitxor() something to report such a situation
/band(), bor(), bxor()/ * fixed: Big::FromString() when the base is 10, the method reads the scientific
* changed: the way of parsing operators in the mathematical parser part only if such a part it correctly supplied, e.g:
(the parser is not too much greedy now) '1234e10', '1234e+10', '1234e-5'
previous '1234e' was treated as: '1234e0' (now parsing stops on 'e' and
Version 0.8.0 (2007.03.28): the 'e' can be parsed by other parsers, e.g. the mathematical
* added: into the parser: SetFactorialMax() parser -- now in the parser would be: '1234e' = '1234 * e' = '3354,3597...' )
* added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec), * changed: renamed: Big::PowUInt(UInt<pow_size> pow) -> Big::Pow(UInt<pow_size> pow)
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x), it returns 2 when there is: 0^0
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/ * changed: renamed: Big::PowInt(Int<pow_size> pow) -> Big::Pow(Int<pow_size> pow)
* changed: class Objects in ttmathobjects.h has been completely rewritten, it returns 2 when there is: 0^0 or 0^(-something)
we can change the names of user-defined variables or functions, and the * changed: renamed: Big::PowBUInt() -> PowUInt(), Big::PowBInt() -> Big::PowInt()
names are case-sensitive now they return 2 when the arguments are incorrect (like above)
* added: class History which is used in functions which take a lot of time * changed: UInt::SetBitInWord(uint & value, uint bit) is taking the first argument by a reference now,
during calculating e.g. Factorial(x) the specific bit is set in the 'value' and the method returns the last state of the bit (zero or one)
* added: Tg(x) a wrapper for Tan(x) * changed: UInt::SetBit(uint bit_index) - it's using TTMATH_ASSERT now
* changed: CTan(x) is Cot(x) now * changed: the size of built-in variables (constants) in ttmathbig.h
* added: Ctg(x) a wrapper for Cot(x) now they consist of 256 32bit words
* added: ATg(x) a wrapper for ATan(x) macro TTMATH_BUILTIN_VARIABLES_SIZE is equal: 256u on a 32bit platform and 128ul on a 64bit platform
* changed: ACTan(x) is ACot(x) now * changed: the asm code in ttmathuint.h and ttmathuint64.h has been completely rewritten
* added: ACtg(x) a wrapper for ACot(x) now UInt<> is faster about 15-30% than UInt<> from 0.8.2
* added: UInt::PrintTable() (for debugging etc.) this has impact on Big<> too - it's faster about 10% now
* changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have * changed: in the parser: the form with operators '#' and '&' is as follows:
been rewritten, now they have 128 32bit words (it's about 1232 valid [-|+][#|&]numeric_value
decimal digits) previous was: [-|+][#|&][-|+]numeric_value
* fixed: previous values from Big::SetPi() Big::SetE() and * changed: in the parser: the short form of multiplication has the same
Big::SetLn2() were not too much accurate (last 2-3 words were wrong) priority as the normal multiplication, e.g.:
* added: Big::SetLn10() (128 32bit words as well) '2x^3' = 2 * (x^3)
* added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on previous the priority was greater than powering priority
32bit platforms and 64ul on 64bit platforms (128/2=64) previous: '2x^3' = (2*x) ^ 3
* added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64 * added: UInt::GetBit(uint bit_index) - returning the state of the specific bit
* changed: a small optimisation in UInt::Mul2Big() * added: Big::operator=(double) and Big::Big(double)
* added: at the end of ttmath.h: #include "ttmathparser.h" * added: UInt::Pow(UInt<value_size> pow) and Int::Pow(Int<value_size> pow)
this is for convenience for a programmer, he can only use #include * added: global template functions in ttmath.h:
with ttmath.h even if he uses the parser ValueType GradToRad(const ValueType & x, ErrorCode * err = 0)
* added: to samples: big.cpp, parser.cpp ValueType RadToGrad(const ValueType & x, ErrorCode * err = 0)
* added/changes/fixed: in copy-constructors and operators= in Int, ValueType DegToGrad(const ValueType & x, ErrorCode * err = 0)
Uint and Big (more info in the commit log) ValueType DegToGrad(const ValueType & d, const ValueType & m,
* renamed Big::SetDotOne() into Big::Set05() const ValueType & s, ErrorCode * err = 0)
* changes: a few small optimisations in Big ValueType GradToDeg(const ValueType & x, ErrorCode * err = 0)
* deleted: the word 'virtual' from destructors: UInt, Int, Big * added: Parser::SetDegRadGrad(int angle) - 0 deg, 1 rad (default), 2 grad
(types in this library are not projected to be base-classes for this affects following functions (in the parser only): sin, cos, tan, cot,
another ones derived from them) asin, acos, atan, acot
* and more small changes (look at the commit log) * added: functions to the parser: gradtorad(grad), radtograd(rad), degtograd(deg),
degtograd(d,m,s), gradtodeg(grad)
Version 0.7.2 (2007.03.09): * added: UInt::FromString, added a parametr 'after_source'
* added: Big::Mod - the remainder from a division which is pointing at the end of the parsed string
* added: Big::Sgn - the 'sign' from the value (-1,0,1) * added: Int::FromString(): parameter 'const char ** after_source = 0'
* added: global functions Mod and Sgn too if exists it's pointing at the end of the parsed string
* added: checking whether a user gives a correct value of a variable or function * added: to UInt::FromString(), Int::FromString(), Big::FromString():
(user-defined variables/functions in the mathematical parser) parameter 'bool * value_read = 0' - (if exists) tells
* added: into the parser: logical operators: > < >= <= == != && || whether something has actually been read (at least one digit)
* added: into the parser: logical functions: and() or() not() if() * added: Objects::IsDefined(const std::string & name)
* added: ErrorCode::err_unknown_operator when the parser couldn't read an operator returning true if such an object is defined
* removed: Big::FromString() this method doesn't longer recognize operators
Version 0.7.1 (2007.02.27): for changing the base ('#' and '&')
* 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 Version 0.8.2 (2008.06.18):
* added ATan (arctan), ACTan (arc ctan) functions * added: UInt::BitNot2() this method has been proposed by
Arek <kmicicc AnTispam users.sourceforge.net>
Version 0.7.0 (2007.02.24): * changed: Int::FromInt(const Int<argument_size> & p),
* finished support for 64bit platforms Int::FromInt(sint value) (it returns zero now)
* added ASin (arcsin), ACos (arccos) functions Int::operator=(uint i)
Int::Int(uint i)
Version 0.6.4 (2007.01.29): * added: Int::FromUInt(const UInt<argument_size> & p),
* fixed the problem with a sign in the mathematical parser /-(1) was 1/ Int::FromUInt(uint value)
* added UInt::AddInt and UInt::SubInt and appropriate constructors and assignment
* changed UInt::AddOne and UInt::SubOne (much faster now) operators as well
* added UInt::SetBitInWord * changed: Big::FromInt(Int<int_size> value),
* changed UInt::SetBit (much faster now) * added: Big::FromUInt(UInt<int_size> value),
* UInt::AddTwoUints renamed to UInt::AddTwoInts Big::operator=(const UInt<int_size> & value)
* UInt::FindLeadingBit32 renamed to UInt::FindLeadingBitInWord Big::Big(const UInt<int_size> & value)
* added UInt::SetBitInWord * changed: the parser is allowed to recognize values which
* UInt::Mul64 renamed to UInt::MulTwoWords begin with a dot, e.g '.5' is treated as '0.5'
* UInt::Div64 renamed to UInt::DivTwoWords * added: a method Big::FromDouble(double) which converts from
* and more small changes in UInt type standard double into a Big
* start adding support for Amd64 (not finished yet) (added ttmathuint64.h) * added: uint Big::ToDouble(double&) - converting into double
* added: Big::FromBig() and an operator= and a contructor
Version 0.6.3 (2007.01.22): for converting from another kind of a Big class
* position of arguments (x and base) in logarithm functions are swapped * added: to the parser: avg(), sum()
* it's possible to use any multiplication algorithms in the same time * added: 'decimal_point' parameter into Big::ToString(...)
(macros UINT_MUL_VERSION_'X' have gone) * fixed: Big::operator>> didn't use TTMATH_COMMA_CHARACTER_2 macro
* added ExceptionInfo, ReferenceError and RuntimeError classes * added: a short form of multiplication (without the '*' character)
* the mess in macros has been cleaned up e.g. '5y', (it's used only if the second parameter
* added TTMATH_RELEASE macro is a variable or function)
* changed: variables and functions are case-sensitive now
Version 0.6.2 (2007.01.10): * added: variables and functions can have underline characters
* New division algorithm (radix b) where b is 2^32 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-2007, Tomasz Sowa Copyright (c) 2006-2009, Tomasz Sowa
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, * Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright * Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
* Neither the name Tomasz Sowa nor the names of contributors to this * Neither the name Tomasz Sowa nor the names of contributors to this
project may be used to endorse or promote products derived project may be used to endorse or promote products derived
from this software without specific prior written permission. from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE. THE POSSIBILITY OF SUCH DAMAGE.

50
README
View File

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

5
TODO
View File

@@ -1,5 +0,0 @@
TODO TTMath Library
===================
* Add functions for generating random values
* Add something like NaN to the Big<> type

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

@@ -31,7 +31,7 @@ PROJECT_NAME = TTMath
# This could be handy for archiving the generated documentation or # This could be handy for archiving the generated documentation or
# if some version control system is used. # if some version control system is used.
PROJECT_NUMBER = 0.8.0 PROJECT_NUMBER = 0.8.2
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put. # base path where the generated documentation will be put.

View File

@@ -32,20 +32,21 @@ MyBig atemp;
if( !atemp.Add(b) ) if( !atemp.Add(b) )
std::cout << "a + b = " << atemp << std::endl; std::cout << "a + b = " << atemp << std::endl;
else 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; atemp = a;
if( !atemp.Sub(b) ) if( !atemp.Sub(b) )
std::cout << "a - b = " << atemp << std::endl; std::cout << "a - b = " << atemp << std::endl;
else else
std::cout << "a - b = (carry) " << atemp << std::endl; std::cout << "a - b = (carry)" << std::endl;
atemp = a; atemp = a;
if( !atemp.Mul(b) ) if( !atemp.Mul(b) )
std::cout << "a * b = " << atemp << std::endl; std::cout << "a * b = " << atemp << std::endl;
else else
std::cout << "a * b = (carry: the result is too big) " << std::endl; std::cout << "a * b = (carry)" << std::endl;
// it have no sense to print 'atemp' (it's undefined)
atemp = a; atemp = a;
if( !atemp.Div(b) ) 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' will have the max value which can be held in this type
a.SetMax(); a.SetMax();
// at the moment conversions from double (or float etc.) are not supported // conversion from double
// you cannot do that: b = 456.32f b = 456.32;
b = "456.32";
// Look at the value 'a' and the product from a+b and a-b // 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 // Don't worry this is the nature of floating point numbers
@@ -89,9 +89,9 @@ a * b = 12193540837712.2708
a / b = 0.0012499665458095765 a / b = 0.0012499665458095765
Calculating with a carry Calculating with a carry
a = 1.624801256070839555e+646457012 a = 1.624801256070839555e+646457012
b = 456.32 b = 456.31999999999999
a + b = 1.624801256070839555e+646457012 a + b = 1.624801256070839555e+646457012
a - b = 1.624801256070839555e+646457012 a - b = 1.624801256070839555e+646457012
a * b = (carry: the result is too big) a * b = (carry)
a / b = 3.56066193914542329e+646457009 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. * and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl> * Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/ */
/* /*
* Copyright (c) 2006-2007, Tomasz Sowa * Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -275,6 +275,11 @@ namespace ttmath
* *
*/ */
/*
this namespace consists of auxiliary functions
(something like 'private' in a class)
*/
namespace auxiliaryfunctions namespace auxiliaryfunctions
{ {
@@ -1342,7 +1347,7 @@ namespace ttmath
/* /*
* *
* functions for converting between degrees and radians * functions for converting between degrees, radians and gradians
* *
* *
*/ */
@@ -1356,14 +1361,18 @@ namespace ttmath
template<class ValueType> template<class ValueType>
ValueType DegToRad(const ValueType & x, ErrorCode * err = 0) ValueType DegToRad(const ValueType & x, ErrorCode * err = 0)
{ {
ValueType result, delimiter; ValueType result, temp;
uint c = 0; uint c = 0;
result.SetPi(); result = x;
c += result.Mul(x);
delimiter = 180; // it is better to make division first and then multiplication
c += result.Div(delimiter); // 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 ) if( err )
*err = c ? err_overflow : err_ok; *err = c ? err_overflow : err_ok;
@@ -1463,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 * another functions
@@ -1536,7 +1667,7 @@ namespace ttmath
{ {
if( x.IsZero() ) if( x.IsZero() )
{ {
// there isn't root(0;0) // there isn't root(0;0) - we assume it's not defined
if( err ) if( err )
*err = err_improper_argument; *err = err_improper_argument;
@@ -1685,7 +1816,14 @@ namespace ttmath
c += x.PowFrac(newindex); // here can only be a carry c += x.PowFrac(newindex); // here can only be a carry
if( change_sign ) if( change_sign )
{
// the value of x should be different from zero
// (x is actually tested by RootCheckXZero)
TTMATH_ASSERT( x.IsZero() == false )
x.SetSign(); x.SetSign();
}
if( err ) if( err )
*err = c ? err_overflow : err_ok; *err = c ? err_overflow : err_ok;

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. * and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl> * Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/ */
/* /*
* Copyright (c) 2006-2007, Tomasz Sowa * Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -208,7 +208,7 @@ private:
public: public:
/*! /*!
this method adds two value with a sign and returns carry this method adds two value with a sign and returns a carry
we're using methods from the base class because values are stored with U2 we're using methods from the base class because values are stored with U2
we must only make the carry correction we must only make the carry correction
@@ -469,23 +469,84 @@ 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;
}
/*! /*!
* *
* convertion methods * convertion methods
* *
*/ */
private:
/*! /*!
this method convert an UInt<another_size> type to this class an auxiliary method for converting both from UInt and Int
this operation has mainly sense if the value from p
can be held in this type
it returns a carry if the value 'p' is too big
*/ */
template<uint argument_size> template<uint argument_size>
uint FromInt(const Int<argument_size> & p) uint FromUIntOrInt(const UInt<argument_size> & p, bool UInt_type)
{ {
uint min_size = (value_size < argument_size)? value_size : argument_size; uint min_size = (value_size < argument_size)? value_size : argument_size;
uint i; uint i;
@@ -496,15 +557,25 @@ public:
if( value_size > argument_size ) if( value_size > argument_size )
{ {
// 'this' is longer than 'p' uint fill;
uint fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)? TTMATH_UINT_MAX_VALUE : 0;
if( UInt_type )
fill = 0;
else
fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)?
TTMATH_UINT_MAX_VALUE : 0;
// 'this' is longer than 'p'
for( ; i<value_size ; ++i) for( ; i<value_size ; ++i)
UInt<value_size>::table[i] = fill; UInt<value_size>::table[i] = fill;
} }
else else
{ {
uint test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)? TTMATH_UINT_MAX_VALUE : 0; uint test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)?
TTMATH_UINT_MAX_VALUE : 0;
if( UInt_type && test!=0 )
return 1;
for( ; i<argument_size ; ++i) for( ; i<argument_size ; ++i)
if( p.table[i] != test ) if( p.table[i] != test )
@@ -514,11 +585,27 @@ public:
return 0; return 0;
} }
public:
/*!
this method converts an Int<another_size> type into this class
this operation has mainly sense if the value from p
can be held in this type
it returns a carry if the value 'p' is too big
*/
template<uint argument_size>
uint FromInt(const Int<argument_size> & p)
{
return FromUIntOrInt(p, false);
}
/*! /*!
this method converts the sint type into this class this method converts the sint type into this class
*/ */
void FromInt(sint value) uint FromInt(sint value)
{ {
uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0; uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0;
@@ -526,16 +613,46 @@ public:
UInt<value_size>::table[i] = fill; UInt<value_size>::table[i] = fill;
UInt<value_size>::table[0] = uint(value); UInt<value_size>::table[0] = uint(value);
// there'll never be a carry here
return 0;
} }
/*! /*!
this operator converts an UInt<another_size> type to this class this method converts UInt<another_size> into this class
it doesn't return a carry
*/ */
template<uint argument_size> template<uint argument_size>
Int<value_size> & operator=(const Int<argument_size> & p) uint FromUInt(const UInt<argument_size> & p)
{
return FromUIntOrInt(p, true);
}
/*!
this method converts the uint type into this class
*/
uint FromUInt(uint value)
{
for(uint i=1 ; i<value_size ; ++i)
UInt<value_size>::table[i] = 0;
UInt<value_size>::table[0] = value;
// there can be a carry here when the size of this value is equal one word
// and the 'value' has the highest bit set
if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 )
return 1;
return 0;
}
// converting from Int
/*!
the default assignment operator
*/
Int<value_size> & operator=(const Int<value_size> & p)
{ {
FromInt(p); FromInt(p);
@@ -544,9 +661,12 @@ public:
/*! /*!
the default assignment operator this operator converts an Int<another_size> type to this class
it doesn't return a carry
*/ */
Int<value_size> & operator=(const Int<value_size> & p) template<uint argument_size>
Int<value_size> & operator=(const Int<argument_size> & p)
{ {
FromInt(p); FromInt(p);
@@ -575,11 +695,47 @@ public:
/*! /*!
this method converts the uint type to this class a copy constructor
*/
Int(const Int<value_size> & u)
{
FromInt(u);
}
/*!
a constructor for copying from another types
*/
template<uint argument_size>
Int(const Int<argument_size> & u)
{
// look that 'size' we still set as 'value_size' and not as u.value_size
FromInt(u);
}
// converting from UInt
/*!
this operator converts an UInt<another_size> type to this class
it doesn't return a carry
*/
template<uint argument_size>
Int<value_size> & operator=(const UInt<argument_size> & p)
{
FromUInt(p);
return *this;
}
/*!
this method converts the Uint type to this class
*/ */
Int<value_size> & operator=(uint i) Int<value_size> & operator=(uint i)
{ {
UInt<value_size>::FromUInt(i); FromUInt(i);
return *this; return *this;
} }
@@ -590,10 +746,23 @@ public:
*/ */
Int(uint i) Int(uint i)
{ {
UInt<value_size>::FromUInt(i); FromUInt(i);
} }
/*!
a constructor for copying from another types
*/
template<uint argument_size>
Int(const UInt<argument_size> & u)
{
// look that 'size' we still set as 'value_size' and not as u.value_size
FromUInt(u);
}
//
#ifdef TTMATH_PLATFORM64 #ifdef TTMATH_PLATFORM64
/*! /*!
@@ -630,7 +799,7 @@ public:
*/ */
Int<value_size> & operator=(unsigned int i) Int<value_size> & operator=(unsigned int i)
{ {
UInt<value_size>::FromUInt(uint(i)); FromUInt(uint(i));
return *this; return *this;
} }
@@ -644,7 +813,7 @@ public:
*/ */
Int(unsigned int i) Int(unsigned int i)
{ {
UInt<value_size>::FromUInt(uint(i)); FromUInt(uint(i));
} }
#endif #endif
@@ -678,18 +847,6 @@ public:
} }
/*!
the copy constructor
*/
template<uint argument_size>
Int(const Int<argument_size> & u) : UInt<value_size>::size(value_size)
{
// look that 'size' we still set as 'value_size' and not as u.value_size
operator=(u);
}
/*! /*!
the destructor the destructor
*/ */
@@ -697,6 +854,7 @@ public:
{ {
} }
/*! /*!
this method returns the lowest value from table with a sign this method returns the lowest value from table with a sign
@@ -742,8 +900,12 @@ public:
existing first white characters will be ommited existing first white characters will be ommited
(between '-' and a first digit can be white characters too) (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; bool is_sign = false;
@@ -760,7 +922,7 @@ public:
UInt<value_size>::SkipWhiteCharacters(++s); 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; return 1;
if( is_sign ) if( is_sign )
@@ -771,12 +933,15 @@ public:
/* /*
the reference to mmin will be automatically converted to the reference 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()) (this value can be equal mmin -- look at a description in ChangeSign())
*/ */
if( UInt<value_size>::operator>( mmin ) ) if( UInt<value_size>::operator>( mmin ) )
return 1; return 1;
/*
if the value is equal mmin the method ChangeSign() does nothing (only returns 1 but we ignore it)
*/
ChangeSign(); ChangeSign();
} }
else else

View File

@@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2006-2007, Tomasz Sowa * Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -102,7 +102,7 @@ public:
if( (c>='a' && c<='z') || (c>='A' && c<='Z') ) if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
return true; return true;
if( can_be_digit && (c>='0' && c<='9') ) if( can_be_digit && ((c>='0' && c<='9') || c=='_') )
return true; return true;
return false; return false;
@@ -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 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 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) (this version is used for not copying the whole string)
*/ */
ErrorCode GetValue(const std::string & name, const char ** value) const 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 of a specific object
*/ */
ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const

View File

@@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2006-2007, Tomasz Sowa * Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -61,14 +61,14 @@ namespace ttmath
/*! /*!
\brief Mathematical parser \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]... x = [+|-]Value[operator[+|-]Value][operator[+|-]Value]...
where: where:
an operator can be: an operator can be:
^ (pow) (the highest priority) ^ (pow) (the heighest priority)
* (mul) * (mul) (or multiplication without an operator -- short mul)
/ (div) (* and / have the same priority) / (div) (* and / have the same priority)
+ (add) + (add)
@@ -85,9 +85,23 @@ namespace ttmath
|| (logical or) (the lowest priority) || (logical or) (the lowest priority)
short mul:
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: Value can be:
constant e.g. 100 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 variable e.g. pi
another expression between brackets e.g (x) another expression between brackets e.g (x)
function e.g. sin(x) function e.g. sin(x)
@@ -106,6 +120,11 @@ namespace ttmath
for separating parameters for separating parameters
"1 < 2" (the result will be: 1) "1 < 2" (the result will be: 1)
"4 < 3" (the result will be: 0) "4 < 3" (the result will be: 0)
"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. etc.
we can also use a semicolon for separating any 'x' input strings we can also use a semicolon for separating any 'x' input strings
@@ -122,13 +141,15 @@ class Parser
private: private:
/*! /*!
there are 5 mathematical operators as follows: there are 5 mathematical operators as follows (with their standard priorities):
add (+) add (+)
sub (-) sub (-)
mul (*) mul (*)
div (/) div (/)
pow (^) pow (^)
with their standard priorities and 'shortmul' used when there is no any operators between
a first parameter and a variable or function
(the 'shortmul' has the same priority as the normal multiplication )
*/ */
class MatOperator class MatOperator
{ {
@@ -136,7 +157,7 @@ private:
enum Type enum Type
{ {
none,add,sub,mul,div,pow,lt,gt,let,get,eq,neq,lor,land none,add,sub,mul,div,pow,lt,gt,let,get,eq,neq,lor,land,shortmul
}; };
@@ -173,6 +194,7 @@ private:
break; break;
case mul: case mul:
case shortmul:
case div: case div:
priority = 12; priority = 12;
break; break;
@@ -296,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; 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 a pointer to an object which tell us whether we should stop calculating or not
*/ */
@@ -393,7 +425,6 @@ typedef std::map<std::string, pfunction_var> VariablesTable;
VariablesTable variables_table; VariablesTable variables_table;
/*! /*!
you can't calculate the factorial if the argument is greater than 'factorial_max' 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 default value is zero which means there are not any limitations
@@ -410,8 +441,6 @@ static void Error(ErrorCode code)
} }
/*! /*!
this method skips the white character from the string this method skips the white character from the string
@@ -424,9 +453,8 @@ void SkipWhiteCharacters()
} }
/*! /*!
a auxiliary method for RecurrenceParsingVariablesOrFunction(...) an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/ */
void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const std::string & name) void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const std::string & name)
{ {
@@ -444,7 +472,7 @@ void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, cons
/*! /*!
a auxiliary method for RecurrenceParsingVariablesOrFunction(...) an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/ */
void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::string & name) void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::string & name)
{ {
@@ -454,8 +482,9 @@ void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::stri
visited_functions.insert( name ); visited_functions.insert( name );
} }
/*! /*!
a auxiliary method for RecurrenceParsingVariablesOrFunction(...) an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/ */
void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::string & name) void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::string & name)
{ {
@@ -465,6 +494,7 @@ void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::s
visited_functions.erase( name ); visited_functions.erase( name );
} }
/*! /*!
this method returns the value of a variable or function this method returns the value of a variable or function
by creating a new instance of the mathematical parser by creating a new instance of the mathematical parser
@@ -599,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 result = 1 * 2 * 3 * 4 * .... * x
*/ */
void Factorial(int sindex, int amount_of_args, ValueType & result) void Factorial(int sindex, int amount_of_args, ValueType & result)
@@ -632,7 +708,7 @@ void Sin(int sindex, int amount_of_args, ValueType & result)
if( amount_of_args != 1 ) if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments ); 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) void Cos(int sindex, int amount_of_args, ValueType & result)
@@ -640,7 +716,7 @@ void Cos(int sindex, int amount_of_args, ValueType & result)
if( amount_of_args != 1 ) if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments ); 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) void Tan(int sindex, int amount_of_args, ValueType & result)
@@ -649,7 +725,7 @@ void Tan(int sindex, int amount_of_args, ValueType & result)
Error( err_improper_amount_of_arguments ); Error( err_improper_amount_of_arguments );
ErrorCode err; ErrorCode err;
result = ttmath::Tan(stack[sindex].value, &err); result = ttmath::Tan(ConvertAngleToRad(stack[sindex].value), &err);
if(err != err_ok) if(err != err_ok)
Error( err ); Error( err );
@@ -661,7 +737,7 @@ void Cot(int sindex, int amount_of_args, ValueType & result)
Error( err_improper_amount_of_arguments ); Error( err_improper_amount_of_arguments );
ErrorCode err; ErrorCode err;
result = ttmath::Cot(stack[sindex].value, &err); result = ttmath::Cot(ConvertAngleToRad(stack[sindex].value), &err);
if(err != err_ok) if(err != err_ok)
Error( err ); Error( err );
@@ -766,10 +842,12 @@ void ASin(int sindex, int amount_of_args, ValueType & result)
Error( err_improper_amount_of_arguments ); Error( err_improper_amount_of_arguments );
ErrorCode err; ErrorCode err;
result = ttmath::ASin(stack[sindex].value, &err); ValueType temp = ttmath::ASin(stack[sindex].value, &err);
if(err != err_ok) if(err != err_ok)
Error( err ); Error( err );
result = ConvertRadToAngle(temp);
} }
@@ -779,10 +857,12 @@ void ACos(int sindex, int amount_of_args, ValueType & result)
Error( err_improper_amount_of_arguments ); Error( err_improper_amount_of_arguments );
ErrorCode err; ErrorCode err;
result = ttmath::ACos(stack[sindex].value, &err); ValueType temp = ttmath::ACos(stack[sindex].value, &err);
if(err != err_ok) if(err != err_ok)
Error( err ); Error( err );
result = ConvertRadToAngle(temp);
} }
@@ -791,7 +871,7 @@ void ATan(int sindex, int amount_of_args, ValueType & result)
if( amount_of_args != 1 ) if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments ); Error( err_improper_amount_of_arguments );
result = ttmath::ATan(stack[sindex].value); result = ConvertRadToAngle(ttmath::ATan(stack[sindex].value));
} }
@@ -800,7 +880,7 @@ void ACot(int sindex, int amount_of_args, ValueType & result)
if( amount_of_args != 1 ) if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments ); Error( err_improper_amount_of_arguments );
result = ttmath::ACot(stack[sindex].value); result = ConvertRadToAngle(ttmath::ACot(stack[sindex].value));
} }
@@ -941,6 +1021,72 @@ void DegToDeg(int sindex, int amount_of_args, ValueType & result)
Error( err ); 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) void Ceil(int sindex, int amount_of_args, ValueType & result)
{ {
if( amount_of_args != 1 ) if( amount_of_args != 1 )
@@ -1158,6 +1304,35 @@ void BitXor(int sindex, int amount_of_args, ValueType & result)
} }
} }
void Sum(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args == 0 )
Error( err_improper_amount_of_arguments );
result = stack[sindex].value;
for(int i=1 ; i<amount_of_args ; ++i )
if( result.Add( stack[ sindex + i*2 ].value ) )
Error( err_overflow );
}
void Avg(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args == 0 )
Error( err_improper_amount_of_arguments );
result = stack[sindex].value;
for(int i=1 ; i<amount_of_args ; ++i )
if( result.Add( stack[ sindex + i*2 ].value ) )
Error( err_overflow );
if( result.Div( amount_of_args ) )
Error( err_overflow );
}
/*! /*!
this method returns the value from a user-defined function this method returns the value from a user-defined function
@@ -1235,27 +1410,27 @@ void CallFunction(const std::string & function_name, int amount_of_args, int sin
/*! /*!
insert a function to the functions' table inserting a function to the functions' table
function_name - name of the function function_name - name of the function
pf - pointer to the function (to the wrapper) 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));
} }
/*! /*!
insert a function to the variables' table inserting a function to the variables' table
(this function returns value of variable) (this function returns value of variable)
variable_name - name of the function variable_name - name of the function
pf - pointer to 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));
} }
@@ -1267,76 +1442,82 @@ void CreateFunctionsTable()
/* /*
names of functions should consist of small letters names of functions should consist of small letters
*/ */
InsertFunctionToTable(std::string("factorial"), &Parser<ValueType>::Factorial); InsertFunctionToTable("factorial", &Parser<ValueType>::Factorial);
InsertFunctionToTable(std::string("abs"), &Parser<ValueType>::Abs); InsertFunctionToTable("abs", &Parser<ValueType>::Abs);
InsertFunctionToTable(std::string("sin"), &Parser<ValueType>::Sin); InsertFunctionToTable("sin", &Parser<ValueType>::Sin);
InsertFunctionToTable(std::string("cos"), &Parser<ValueType>::Cos); InsertFunctionToTable("cos", &Parser<ValueType>::Cos);
InsertFunctionToTable(std::string("tan"), &Parser<ValueType>::Tan); InsertFunctionToTable("tan", &Parser<ValueType>::Tan);
InsertFunctionToTable(std::string("tg"), &Parser<ValueType>::Tan); InsertFunctionToTable("tg", &Parser<ValueType>::Tan);
InsertFunctionToTable(std::string("cot"), &Parser<ValueType>::Cot); InsertFunctionToTable("cot", &Parser<ValueType>::Cot);
InsertFunctionToTable(std::string("ctg"), &Parser<ValueType>::Cot); InsertFunctionToTable("ctg", &Parser<ValueType>::Cot);
InsertFunctionToTable(std::string("int"), &Parser<ValueType>::Int); InsertFunctionToTable("int", &Parser<ValueType>::Int);
InsertFunctionToTable(std::string("round"), &Parser<ValueType>::Round); InsertFunctionToTable("round", &Parser<ValueType>::Round);
InsertFunctionToTable(std::string("ln"), &Parser<ValueType>::Ln); InsertFunctionToTable("ln", &Parser<ValueType>::Ln);
InsertFunctionToTable(std::string("log"), &Parser<ValueType>::Log); InsertFunctionToTable("log", &Parser<ValueType>::Log);
InsertFunctionToTable(std::string("exp"), &Parser<ValueType>::Exp); InsertFunctionToTable("exp", &Parser<ValueType>::Exp);
InsertFunctionToTable(std::string("max"), &Parser<ValueType>::Max); InsertFunctionToTable("max", &Parser<ValueType>::Max);
InsertFunctionToTable(std::string("min"), &Parser<ValueType>::Min); InsertFunctionToTable("min", &Parser<ValueType>::Min);
InsertFunctionToTable(std::string("asin"), &Parser<ValueType>::ASin); InsertFunctionToTable("asin", &Parser<ValueType>::ASin);
InsertFunctionToTable(std::string("acos"), &Parser<ValueType>::ACos); InsertFunctionToTable("acos", &Parser<ValueType>::ACos);
InsertFunctionToTable(std::string("atan"), &Parser<ValueType>::ATan); InsertFunctionToTable("atan", &Parser<ValueType>::ATan);
InsertFunctionToTable(std::string("atg"), &Parser<ValueType>::ATan); InsertFunctionToTable("atg", &Parser<ValueType>::ATan);
InsertFunctionToTable(std::string("acot"), &Parser<ValueType>::ACot); InsertFunctionToTable("acot", &Parser<ValueType>::ACot);
InsertFunctionToTable(std::string("actg"), &Parser<ValueType>::ACot); InsertFunctionToTable("actg", &Parser<ValueType>::ACot);
InsertFunctionToTable(std::string("sgn"), &Parser<ValueType>::Sgn); InsertFunctionToTable("sgn", &Parser<ValueType>::Sgn);
InsertFunctionToTable(std::string("mod"), &Parser<ValueType>::Mod); InsertFunctionToTable("mod", &Parser<ValueType>::Mod);
InsertFunctionToTable(std::string("if"), &Parser<ValueType>::If); InsertFunctionToTable("if", &Parser<ValueType>::If);
InsertFunctionToTable(std::string("or"), &Parser<ValueType>::Or); InsertFunctionToTable("or", &Parser<ValueType>::Or);
InsertFunctionToTable(std::string("and"), &Parser<ValueType>::And); InsertFunctionToTable("and", &Parser<ValueType>::And);
InsertFunctionToTable(std::string("not"), &Parser<ValueType>::Not); InsertFunctionToTable("not", &Parser<ValueType>::Not);
InsertFunctionToTable(std::string("degtorad"), &Parser<ValueType>::DegToRad); InsertFunctionToTable("degtorad", &Parser<ValueType>::DegToRad);
InsertFunctionToTable(std::string("radtodeg"), &Parser<ValueType>::RadToDeg); InsertFunctionToTable("radtodeg", &Parser<ValueType>::RadToDeg);
InsertFunctionToTable(std::string("degtodeg"), &Parser<ValueType>::DegToDeg); InsertFunctionToTable("degtodeg", &Parser<ValueType>::DegToDeg);
InsertFunctionToTable(std::string("ceil"), &Parser<ValueType>::Ceil); InsertFunctionToTable("gradtorad", &Parser<ValueType>::GradToRad);
InsertFunctionToTable(std::string("floor"), &Parser<ValueType>::Floor); InsertFunctionToTable("radtograd", &Parser<ValueType>::RadToGrad);
InsertFunctionToTable(std::string("sqrt"), &Parser<ValueType>::Sqrt); InsertFunctionToTable("degtograd", &Parser<ValueType>::DegToGrad);
InsertFunctionToTable(std::string("sinh"), &Parser<ValueType>::Sinh); InsertFunctionToTable("gradtodeg", &Parser<ValueType>::GradToDeg);
InsertFunctionToTable(std::string("cosh"), &Parser<ValueType>::Cosh); InsertFunctionToTable("ceil", &Parser<ValueType>::Ceil);
InsertFunctionToTable(std::string("tanh"), &Parser<ValueType>::Tanh); InsertFunctionToTable("floor", &Parser<ValueType>::Floor);
InsertFunctionToTable(std::string("tgh"), &Parser<ValueType>::Tanh); InsertFunctionToTable("sqrt", &Parser<ValueType>::Sqrt);
InsertFunctionToTable(std::string("coth"), &Parser<ValueType>::Coth); InsertFunctionToTable("sinh", &Parser<ValueType>::Sinh);
InsertFunctionToTable(std::string("ctgh"), &Parser<ValueType>::Coth); InsertFunctionToTable("cosh", &Parser<ValueType>::Cosh);
InsertFunctionToTable(std::string("root"), &Parser<ValueType>::Root); InsertFunctionToTable("tanh", &Parser<ValueType>::Tanh);
InsertFunctionToTable(std::string("asinh"), &Parser<ValueType>::ASinh); InsertFunctionToTable("tgh", &Parser<ValueType>::Tanh);
InsertFunctionToTable(std::string("acosh"), &Parser<ValueType>::ACosh); InsertFunctionToTable("coth", &Parser<ValueType>::Coth);
InsertFunctionToTable(std::string("atanh"), &Parser<ValueType>::ATanh); InsertFunctionToTable("ctgh", &Parser<ValueType>::Coth);
InsertFunctionToTable(std::string("atgh"), &Parser<ValueType>::ATanh); InsertFunctionToTable("root", &Parser<ValueType>::Root);
InsertFunctionToTable(std::string("acoth"), &Parser<ValueType>::ACoth); InsertFunctionToTable("asinh", &Parser<ValueType>::ASinh);
InsertFunctionToTable(std::string("actgh"), &Parser<ValueType>::ACoth); InsertFunctionToTable("acosh", &Parser<ValueType>::ACosh);
InsertFunctionToTable(std::string("bitand"), &Parser<ValueType>::BitAnd); InsertFunctionToTable("atanh", &Parser<ValueType>::ATanh);
InsertFunctionToTable(std::string("bitor"), &Parser<ValueType>::BitOr); InsertFunctionToTable("atgh", &Parser<ValueType>::ATanh);
InsertFunctionToTable(std::string("bitxor"), &Parser<ValueType>::BitXor); InsertFunctionToTable("acoth", &Parser<ValueType>::ACoth);
InsertFunctionToTable(std::string("band"), &Parser<ValueType>::BitAnd); InsertFunctionToTable("actgh", &Parser<ValueType>::ACoth);
InsertFunctionToTable(std::string("bor"), &Parser<ValueType>::BitOr); InsertFunctionToTable("bitand", &Parser<ValueType>::BitAnd);
InsertFunctionToTable(std::string("bxor"), &Parser<ValueType>::BitXor); 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);
} }
/*! /*!
this method create the table of variables this method creates the table of variables
*/ */
void CreateVariablesTable() void CreateVariablesTable()
{ {
/* /*
names of variables should consist of small letters names of variables should consist of small letters
*/ */
InsertVariableToTable(std::string("pi"), &ValueType::SetPi); InsertVariableToTable("pi", &ValueType::SetPi);
InsertVariableToTable(std::string("e"), &ValueType::SetE); InsertVariableToTable("e", &ValueType::SetE);
} }
/*! /*!
convert from a big letter to a small one converting from a big letter to a small one
*/ */
int ToLowerCase(int c) int ToLowerCase(int c)
{ {
@@ -1347,8 +1528,6 @@ return c;
} }
/*! /*!
this method read the name of a variable or a function this method read the name of a variable or a function
@@ -1365,29 +1544,31 @@ int character;
result.erase(); result.erase();
character = ToLowerCase(*pstring); character = *pstring;
/* /*
the first letter must be from range 'a' - 'z' the first letter must be from range 'a' - 'z' or 'A' - 'Z'
*/ */
if( character<'a' || character>'z' ) if( ! (( character>='a' && character<='z' ) || ( character>='A' && character<='Z' )) )
Error( err_unknown_character ); Error( err_unknown_character );
do do
{ {
result += character; result += character;
character = ToLowerCase( * ++pstring ); character = * ++pstring;
} }
while( (character>='a' && character<='z') || while( (character>='a' && character<='z') ||
(character>='0' && character<='9') ); (character>='A' && character<='Z') ||
(character>='0' && character<='9') ||
character=='_' );
SkipWhiteCharacters(); SkipWhiteCharacters();
/* /*
if there's character '(' that means this name is a name of a function if there's a character '(' that means this name is a name of a function
*/ */
if( *pstring == '(' ) if( *pstring == '(' )
{ {
@@ -1454,19 +1635,22 @@ 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; 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; pstring = new_stack_pointer;
if( carry ) if( carry )
Error( err_overflow ); Error( err_overflow );
}
if( !value_read )
Error( err_unknown_character );
}
/*! /*!
@@ -1494,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 we're reading the item
@@ -1553,16 +1755,33 @@ int character;
return 2; return 2;
} }
else else
if( character=='#' || character=='&' || CharToDigit(character, base)!=-1 ) if( character == '#' )
{ {
/* ++pstring;
warning: SkipWhiteCharacters();
if we're using for example the base equal 16
we can find a first character like 'e' that is there is not e=2.71.. // after '#' character we do not allow '-' or '+' (can be white characters)
but the value 14, for this case we must use something like var::e for variables if( ValueStarts(*pstring, 16) )
(not implemented yet) ReadValue( result, 16 );
*/ else
ReadValue( result ); 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 else
if( character>='a' && character<='z' ) if( character>='a' && character<='z' )
@@ -1598,6 +1817,7 @@ void InsertOperatorToTable(const std::string & name, typename MatOperator::Type
operators_table.insert( std::make_pair(name, type) ); operators_table.insert( std::make_pair(name, type) );
} }
/*! /*!
this method creates the table of operators this method creates the table of operators
*/ */
@@ -1698,6 +1918,14 @@ int ReadOperator(Item & result)
result.type = Item::semicolon; result.type = Item::semicolon;
++pstring; ++pstring;
} }
else
if( (*pstring>='a' && *pstring<='z') || (*pstring>='A' && *pstring<='Z') )
{
// short mul (without any operators)
result.type = Item::mat_operator;
result.moperator.SetType( MatOperator::shortmul );
}
else else
ReadMathematicalOperator(result); ReadMathematicalOperator(result);
@@ -1760,6 +1988,7 @@ int res;
break; break;
case MatOperator::mul: case MatOperator::mul:
case MatOperator::shortmul:
if( value1.Mul(value2) ) Error( err_overflow ); if( value1.Mul(value2) ) Error( err_overflow );
break; break;
@@ -1777,6 +2006,7 @@ int res;
break; break;
default: default:
/* /*
on the stack left an unknown operator but we had to recognize its before on the stack left an unknown operator but we had to recognize its before
@@ -1854,9 +2084,9 @@ void TryRollingUpStack()
*/ */
int ReadValueVariableOrFunctionAndPushItIntoStack(Item & temp) int ReadValueVariableOrFunctionAndPushItIntoStack(Item & temp)
{ {
int kod = ReadValueVariableOrFunction( temp ); int code = ReadValueVariableOrFunction( temp );
if( kod == 0 ) if( code == 0 )
{ {
if( stack_index < stack.size() ) if( stack_index < stack.size() )
stack[stack_index] = temp; stack[stack_index] = temp;
@@ -1866,20 +2096,20 @@ int kod = ReadValueVariableOrFunction( temp );
++stack_index; ++stack_index;
} }
if( kod == 2 ) if( code == 2 )
// there was a final bracket, we didn't push it into the stack // there was a final bracket, we didn't push it into the stack
// (it'll be read by the 'ReadOperatorAndCheckFinalBracket' method next) // (it'll be read by the 'ReadOperatorAndCheckFinalBracket' method next)
kod = 0; code = 0;
return kod; return code;
} }
/*! /*!
this method calculate how many parameters there are on the stack this method calculate how many parameters there are on the stack
and index of the first parameter and the index of the first parameter
if there aren't any parameters on the stack this method returns if there aren't any parameters on the stack this method returns
'size' equals zero and 'index' pointing after the first bracket 'size' equals zero and 'index' pointing after the first bracket
@@ -2161,6 +2391,7 @@ Parser(): default_stack_size(100)
puser_functions = 0; puser_functions = 0;
pfunction_local_variables = 0; pfunction_local_variables = 0;
base = 10; base = 10;
deg_rad_grad = 1;
error = err_ok; error = err_ok;
factorial_max.SetZero(); factorial_max.SetZero();
@@ -2180,6 +2411,7 @@ Parser<ValueType> & operator=(const Parser<ValueType> & p)
puser_functions = p.puser_functions; puser_functions = p.puser_functions;
pfunction_local_variables = 0; pfunction_local_variables = 0;
base = p.base; base = p.base;
deg_rad_grad = p.deg_rad_grad;
error = err_ok; error = err_ok;
factorial_max = p.factorial_max; factorial_max = p.factorial_max;
@@ -2217,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 this method sets a pointer to the object which tell us whether we should stop
calculations 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. * and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl> * Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/ */
/* /*
* Copyright (c) 2006-2007, Tomasz Sowa * Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -64,7 +64,7 @@
*/ */
#define TTMATH_MAJOR_VER 0 #define TTMATH_MAJOR_VER 0
#define TTMATH_MINOR_VER 8 #define TTMATH_MINOR_VER 8
#define TTMATH_REVISION_VER 1 #define TTMATH_REVISION_VER 3
#define TTMATH_PRERELEASE_VER 0 #define TTMATH_PRERELEASE_VER 0
@@ -141,7 +141,7 @@ namespace ttmath
which are kept in built-in variables for a Big<> type which are kept in built-in variables for a Big<> type
(these variables are defined in ttmathbig.h) (these variables are defined in ttmathbig.h)
*/ */
#define TTMATH_BUILTIN_VARIABLES_SIZE 128u #define TTMATH_BUILTIN_VARIABLES_SIZE 256u
#else #else
@@ -172,7 +172,7 @@ namespace ttmath
which are kept in built-in variables for a Big<> type which are kept in built-in variables for a Big<> type
(these variables are defined in ttmathbig.h) (these variables are defined in ttmathbig.h)
*/ */
#define TTMATH_BUILTIN_VARIABLES_SIZE 64ul #define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
#endif #endif
} }
@@ -182,7 +182,7 @@ namespace ttmath
/*! /*!
characters which represent the comma operator characters which represent the comma operator
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing (default, can be overwritten in ToString() function)
TTMATH_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character TTMATH_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character
that means you can input values for example 1.2345 and 1,2345 as well that means you can input values for example 1.2345 and 1,2345 as well
@@ -197,6 +197,7 @@ namespace ttmath
#define TTMATH_COMMA_CHARACTER_2 ',' #define TTMATH_COMMA_CHARACTER_2 ','
/*! /*!
this variable defines how many iterations are performed this variable defines how many iterations are performed
during some kind of calculating when we're making any long formulas during some kind of calculating when we're making any long formulas
@@ -247,7 +248,8 @@ namespace ttmath
err_object_exists, err_object_exists,
err_unknown_object, err_unknown_object,
err_still_calculating, err_still_calculating,
err_too_big_factorial err_too_big_factorial,
err_in_short_form_used_function
}; };

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