Compare commits

...

148 Commits

Author SHA1 Message Date
Tomasz Sowa aad580f51e in ASin() and Gamma() there is used SetZeroNan() to suppress a warning about an uninitialized variable (for gcc)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1229 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-10-23 16:09:19 +00:00
Tomasz Sowa 3b113374b7 removed: white characters from tests2/Makefile
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1228 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-10-23 13:24:37 +00:00
Tomasz Sowa 0f2fcaf547 updated tests2 output for big_64_64 (tests2/big_64_64.expected)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1227 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-10-23 13:06:01 +00:00
Tomasz Sowa f88cba2688 fixed: in Parser: there was an error returned when we parsed a string which at the end had a percentage operator e.g. "10+20%"
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1226 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-10-23 12:38:22 +00:00
Tomasz Sowa 48d694a47f added: some tests for Big<> and Parser<> classes (tests2 directory)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1225 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-10-15 19:14:08 +00:00
Tomasz Sowa 9a93db39c4 updated doxygen.cfg (clear config generated from 1.8.15 version)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1224 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-10-09 21:00:20 +00:00
Tomasz Sowa f98c434fc4 updated CHANGELOG
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1198 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-07-31 07:21:10 +00:00
Tomasz Sowa 132fa10cd4 fixed: cannot compile on MS Windows when compiling with GCC (Mingw) for 64 bit platform:
incorrect size of ttmath::uint and ::sint were used
       they were 'long' but 'long' is a 32bit type on Windows




git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1197 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-07-31 07:14:21 +00:00
Tomasz Sowa dcdb1db9ec fixed: a crash in Big::Add() (buffer overflow)
there was an offset calculated from Int type by using Abs() method and a carry was not checked
       (if there is a carry we should not make addition -- the argument is too small)
       this had no impact on calculated values because there was a crash (bus error) immediately

       following program could crash (64bit):
       typedef ttmath::Big<1, 8> MyBig;
       ttmath::Parser<MyBig> parser;
       parser.Parse("2^(2^63) + 1");


fixed: similar problems were in methods Big::BitAnd() Big::BitOr() and Big::BitXor() (bitwise operations)
       and they could return incorrect values



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1189 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-04-11 16:14:04 +00:00
Tomasz Sowa d93d5ffd74 some work in the parser and refactoring
added a new math operator: assign
now we can assign a value to a variable (not finished yet)




git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1137 e52654a7-88a9-db11-a3e9-0013d4bc506e
2018-10-30 21:04:06 +00:00
Tomasz Sowa 9b279276f2 changed: commentaries to be more doxygen friendly
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1054 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-03-12 17:28:38 +00:00
Tomasz Sowa 83b5ab7170 changed: commentaries to be more doxygen friendly
changed: put block characters {...} is some places



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1053 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-03-12 17:13:37 +00:00
Tomasz Sowa 35333b1e32 added: makerelease.sh script to generate the source package tarball
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1052 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-03-12 15:18:16 +00:00
Tomasz Sowa c73af9c116 - changed info in headers in source files: (new) BSD licence -> 3-Clause BSD Licence
- added svn:ignore in some places




git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1051 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-03-12 14:51:21 +00:00
Tomasz Sowa f06592376f changed: some return values has been cleaned in ttmathuint.h
(eclipse builtin parser reported errors but actually the code was correct)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1050 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-03-12 12:35:50 +00:00
Tomasz Sowa b36821024b changed: in Parser: the last commit has been changed to:
oper.erase(oper.begin() + oper.size() - 1)
	 because oper.pop_back() is available from c++11 



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1049 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-03-12 12:34:01 +00:00
Tomasz Sowa cd740c5924 changed: in Parser: oper.erase( --oper.end() ) changed to oper.pop_back()
to allow use of the STL port
         (reported on the ttmath forum by Sebo)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1047 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-02-08 09:02:52 +00:00
Tomasz Sowa 46ed8c3108 fixed: in Object::GetValueAndParam() there was value.empty() used instead of value.clear()
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1046 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-02-08 08:42:02 +00:00
Tomasz Sowa f4f7882387 changed: changed code in some places to remove warnings generated by Visual Studio
added:   file win64_assemble.bat to compile (assemble) *.asm file for Win64



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1045 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-02-07 20:42:43 +00:00
Tomasz Sowa 86dc01cdee updated: CHANGELOG, COPYRIGHT, doxygen.cfg
added:   directory 'res' with logos
added:   empty directory 'doc'




git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1044 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-02-07 14:24:58 +00:00
Tomasz Sowa 2067301d1c changed: get rid of some warnings generated by gcc and clang
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1043 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-02-07 14:19:59 +00:00
Tomasz Sowa e2cdeac423 fixed: in x86_64 asm code (for Win64) there were in some places the esp register used,
there should be rsp used instead
       (reported by Villi on the tttmath forum)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1042 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-02-06 02:13:05 +00:00
Tomasz Sowa 5893ffa9e3 added: CMakeLists.txt files for building samples by using cmake system
submitted by Mateusz Loskot <mateusz at loskot dot net>


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@997 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-11-28 15:59:08 +00:00
Tomasz Sowa b862422bd9 fixed: in Parser: in method SetDegRadGrad(int angle)
there is incorrectly use || operator (the && shoud be used)
       reported by heby on the ttmath forum


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@450 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-04-04 23:36:48 +00:00
Tomasz Sowa cb15ac0cd8 removed: some warning messages generated by GCC from ttmathuint.h (Mul3Big3)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@441 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-06-13 21:31:53 +00:00
Tomasz Sowa 77c41e644a corrected: the date in CHANGELOG (2012.12->2012.11)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@438 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-11-28 16:24:00 +00:00
Tomasz Sowa 506840787a added: some pragmas for the clang compiler:
#pragma clang diagnostic ignored "-Wtautological-compare"
         to get rid off some warning messages
changed: changing version number to 0.9.3 release



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@436 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-11-28 16:19:05 +00:00
Tomasz Sowa e58253a078 fixed: in Big::FromDouble(double value) (32 bit version)
buffer overflow in referencing to UInt<2>
       (instead of m.table[2] should be m.table[0])
       this was used when: E=0 and F is nonzero (double "unnormalized" values)
       it produced incorrect mantissa (on about 8th decimal digit up)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@435 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-10-30 13:07:38 +00:00
Tomasz Sowa 6862321fad added: ttmath/ttmathdec.h
starting work on a Decimal template type


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@381 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-02-04 16:26:11 +00:00
Tomasz Sowa 2e192969b0 changed: Big::FromString_ReadPartAfterComma()
now we're reading the all part as integer and 
         at the end we're dividing it by (base ^ how_many_digits_there_were)

         it's faster and should be a little accurate in some cases



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@342 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-02-27 18:13:32 +00:00
Tomasz Sowa e8daa77d75 changed: UInt::ToString() had O(n^2) complexity
where n was the number of digits to print
         now it has O(n)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@340 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-02-07 22:37:44 +00:00
Tomasz Sowa 231164f6ea added: option 'group_digits' to Conv struct
you can set how many digits should be grouped



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@338 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-01-30 17:34:42 +00:00
Tomasz Sowa c51b2fdcc9 changed: small improvements in UInt::Pow() and Big::Pow()
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@325 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-10-14 23:21:16 +00:00
Tomasz Sowa 84f34ebe52 added: Parser::InitCGamma()
initializing coefficients used when calculating the gamma (or factorial) function
       this speed up the next calculations
       you don't have to call this method explicitly
       these coefficients will be calculated when needed



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@324 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-29 21:14:32 +00:00
Tomasz Sowa 3190f3011f changing version number to 0.9.2 release
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@320 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-23 20:52:20 +00:00
Tomasz Sowa a34cf55155 added TTMATH_LOG to UInt::FromUInt(ulint n)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@319 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-23 19:51:55 +00:00
Tomasz Sowa 648de47400 fixed: Int::ToUInt(unsigned int & result)
wrong carry was returned


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@318 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-23 19:25:26 +00:00
Tomasz Sowa 362207e2f1 added some missing methods: ToUInt, ToInt, FromUInt, FromInt in Big<> class
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@317 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-23 18:56:55 +00:00
Tomasz Sowa a40e951923 fixed: Big::ToDouble(double &) set always +INF (infinity)
when the value was too large (even for negative values)
       (it should set -INF in such a case)
added: some missing methods for converting
       for UInt<>, Int<> and Big<> classes:
       uint ToUInt()
       sint ToInt()
       ToUInt(uint32_t &)
       ToInt(uint32_t &)
       ToInt(int32_t &)
       ToUInt(uint64_t &)
       ToInt(uint64_t &)
       ToInt(int64_t &)
       FromUInt(uint32_t &)
       FromInt(uint32_t &)
       FromInt(int32_t &)
       FromUInt(uint64_t &)
       FromInt(uint64_t &)
       FromInt(int64_t &)
       and appropriate constructors and operators
       *** version for 64 bit platforms are not tested yet ***
added: double Big::ToDouble() /there was only Big::ToDouble(double &) /
       uint Big::ToFloat(float &)
       float Big::ToFloat()



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@316 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-22 19:43:12 +00:00
Tomasz Sowa b028896118 added: some missing methods: ::FromUInt ::FromInt
now ::FromInt can be used in place of ::FromUint
       sample:
       UInt<1> a;
       a.FromInt(10); // previous was only: a.FromUInt(10)
changed: std::string Big::ToString(uint base = 10) const
         std::wstring Big::ToWString(uint base = 10) const
         can take optional parameter (base)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@315 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-21 22:31:07 +00:00
Tomasz Sowa a67a088e3a removed: macro TTMATH_REFERENCE_ASSERT from all methods from public interface
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@314 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-21 15:52:48 +00:00
Tomasz Sowa 996fac15f1 in Big::ToString_CreateNewMantissaTryExponent():
ToString_BaseRound can be called only for non integer values



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@313 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-19 21:58:51 +00:00
Tomasz Sowa 1e268f1808 fixed: Big::ToString method
in some cases when in the output string the exponent should be equal zero
       the method changes the exponent to one so the last digit from the mantissa
       was lost
 
       sample:
       Big<1,1> a;
       a.info = 0;
       a.mantissa = 2147483649u; // (bin) 10000000000000000000000000000001
       // first and last bit in the mantissa is set
       a.exponent = 0;
       std::cout << a << std::endl;

       priovious result: 2147483640
       it was treated as 214748364e+1

       also the method has been a little improved




git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@312 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-19 21:54:46 +00:00
Tomasz Sowa 90674c9505 added: on 32bit platforms:
uint UInt::FromUInt(uint64_t n)
        uint Int::FromInt(int64_t n)
        void Big::FromUInt(uint64_t n)
        void Big::FromInt(int64_t n)        
        and appropriate constructors and operators
added:  TTMATH_FORCEASM macro
        asm version of the library is available by default only for:
        x86 and amd64 platforms and for Microsoft Visual and GCC compilers,
        but you can force using asm version (the same asm as for Microsoft Visual)
        by defining TTMATH_FORCEASM macro
        you have to be sure that your compiler accept such an asm format
                        


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@311 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-19 17:23:39 +00:00
Tomasz Sowa b6fe168e3c added: Big::operator++()
Big::operator++(int)
         Big::operator--()
         Big::operator--(int)
         Big::AddOne()
         Big::SubOne()
changed: Big::SetOne()
         a little faster now



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@310 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-18 01:35:16 +00:00
Tomasz Sowa ae61b302a8 fixed: TTMATH_DEBUG_LOG has generated different carry-flags in UInt<> (when TTMATH_NOASM was used)
fixed: some GCC warnings about uninitialized variables
added: macro TTMATH_BIG_DEFAULT_CLEAR
       when defined the default constructor from Big<> clears its mantissa and exponent
       Big<1, 2> var;
       var.mantissa and var.exponent will be set to zero
       (but var has the NaN flag set too - it is not zero value, this is mainly for debug purposes)
added: Big::SetZeroNan()
       this method sets NaN flag (Not a Number)
       also clears the mantissa and exponent (similarly as it would be a zero value)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@309 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-15 20:43:21 +00:00
Tomasz Sowa a1c41c02db added: bool UInt::IsOnlyTheHighestBitSet()
bool UInt::IsOnlyTheLowestBitSet()
         returning true if only the highest/lowest bit is set
added:   uint Int::MulInt(sint ss2)       
added:   void UInt::Swap(UInt<value_size> & ss2)       
         void Big::Swap(UInt<value_size> & ss2)
         method for swapping this for an argument
changed: small optimization in Big::Sub()
changed: now asm version is available only on x86 and amd64
         (and only for GCC and MS VC compilers)
removed: macro TTMATH_RELEASE
         for debug version define TTMATH_DEBUG macro
         TTMATH_DEBUG is also automatically defined when DEBUG or _DEBUG is set



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@304 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-05 18:21:58 +00:00
Tomasz Sowa 69f065245e fixed: Big::Add sometimes incorrectly rounded the last bit from mantissa
(when exp_offset == mantissa_size_in_bits ) the rounding_up was always false


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@303 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-18 23:31:58 +00:00
Tomasz Sowa c65dac524a fixed: Big::BigAnd() Big::BigOr() Big::BigXor() should have set NaN
when the argument was negative (they only returned 2)
added: some missing operators 
       UInt::operator~()    /* bitwise neg  */
       UInt::operator&()    /* bitwise and  */
       UInt::operator&=()
       UInt::operator|()    /* bitwise or   */
       UInt::operator|=()
       UInt::operator^()    /* bitwise xor  */
       UInt::operator^=()
       Big::operator&()
       Big::operator&=()
       Big::operator|()
       Big::operator|=()
       Big::operator^()
       Big::operator^=()
       for Big<> we do not define bitwise neg



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@302 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-18 18:09:16 +00:00
Tomasz Sowa b3c3dd8c3f fixed: recurrence calling in Big::FromString(const std::string &, uint, const wchar_t **, bool *)
it should have the signature: Big::FromString(const std::string &, uint, const char **, bool *) 


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@301 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-18 09:22:38 +00:00
Tomasz Sowa 1b7e13a9fd added: macro TTMATH_DONT_USE_WCHAR
if defined then the library does not use wide characters
         (wchar_t, std::wstring, ...) this is a workaround for some compilers



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@294 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-03-01 13:08:50 +00:00
Tomasz Sowa aeadb8a04a changed: version of the library: 0.9.1 now
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@286 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-07 18:17:24 +00:00
Tomasz Sowa 053861655d added: to samples: big2.cpp with TTMATH_BITS() macro
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@285 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-07 13:36:39 +00:00
Tomasz Sowa 35f2a8a28b the half-to-even rounding was turned off (some 'return' statement left)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@284 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-02 21:05:08 +00:00
Tomasz Sowa d5a5ea1a7d removed: from Big::ToString() the feature with calculating how many valid digits there are
after the comma operator
         this was not correctly calculated - sometimes gives unexpected results,
         e.g. 0.5/2/2=0.125 (only one bit in the mantissa) gives 0.1 as the result
changed: cosmetic changes in Big::Add()




git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@283 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-02-02 21:02:10 +00:00
Tomasz Sowa 32b8c7a957 removed: from parser: SetSmallToZero(bool zero)
this was actually a bad feature


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@277 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-06 00:54:01 +00:00
Tomasz Sowa e727eacce0 added: static sint UInt<value_size>::FindLowestBitInWord(uint x)
(asm_vc_32, asm_gcc_32, no_asm, and intrinsic for vc64)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@275 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-01-03 01:10:37 +00:00
Tomasz Sowa 39db6fc469 fixed: in Big::ToString_CreateNewMantissaAndExponent() changed the formula:
new_exp_ = [log base (2^exponent)] + 1
       now the part '+ 1' is only made when the logarithm is positive and with fraction
       if the value is negative we can only skip the fraction, previously
       we lost some last digits from the new mantissa
       
       Consider this binary value (32 bit mantissa):
       (bin)1.0000000000000000000000000000011
       previously ToString() gave 1, now we have: 1.000000001



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@274 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-28 15:41:28 +00:00
Tomasz Sowa 0ada20b4cb fixed: added in the parser: operator's associativity
operator ^ (powering) is right-associative:
        sample: 2^3^4 is equal 2^(3^4) and it is: 2.41e+24
        previously was: 2^3^4 = (2^3)^4 = 4096



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@273 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-25 22:06:49 +00:00
Tomasz Sowa 31563ce343 fixed: I have forgotten to remove rounding down from division (Big::div)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@264 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-14 15:54:23 +00:00
Tomasz Sowa 418db51f46 added: to Big::Add Big::Sub Big::Mul Big::Div
second parameter 'bool round = true'
         the rounding is made if it is true
changed: in Big::ToString_CreateNewMantissaAndExponent()
         we should use dividing without rounding
         consider this 32 bit binary value:
         1.1111111111111111111111111111111
         previous the result from converting (to the base 10) was equal 2
         now is 1.999999
      



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@263 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-14 12:16:32 +00:00
Tomasz Sowa 82711f4441 fixed: Big::Add() should make the half-to-even rounding
by analizing the old ss2 parameter,
        and when it does substraction too
added:  UInt::AreFirstBitsZero(uint bits)
        returning true if first bits are cleared


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@262 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-12 20:45:18 +00:00
Tomasz Sowa e5fc7a52e8 fixed: base rounding in Big::ToString
if the result were integer we shoud not round the value
          3.0001 should be 3.0001 and
          2.9999 should be 2.9999



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@259 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-06 23:18:05 +00:00
Tomasz Sowa 357524ae13 added: IEEE 754 half-to-even rounding (bankers' rounding) to the following
floating point algorithms:
         Big::Add
         Big::Sub
         Big::Mul
         Big::Div



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@258 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-06 01:09:55 +00:00
Tomasz Sowa 72052420dd fixed: the parser didn't use characters for changing the base (# and &)
those characters were skipped
         (this bug was introduced in 0.9.0)
added:   to Big::ToString() - additional rounding when conv.base_round is used
         if the value is not an integer we calculate how many valid digits there are
         after the comma operator (in conv.base radix) and then we skipped the rest
         digits, after skipping the base-rounding is made
         this helps to print values which have some last clear bits in the mantissa
         consider this 32 bit value:
         (binary)0.00011100001010001111010111000000000
         which has mantissa equal: (binary)11100001010001111010111000000000 (32 bits)
         previous the ToString() method gave: (decimal)0.10999999[...] 
         now we have: (decimal)0.11
added:   Parser::SetSmallToZero(bool zero) (default true)
         if true then the parser changes small values into zero
         small value means:
         - if the mantissa of the value consists only of one, two or three set bits
         - and these bits are next to each other
         - and the exponent is smaller than about 2 times the number of bits from the mantissa
         this helps to correctly calculate expressions such as: "0.80-3*0.34+0.22"
         now the parser gives zero (previous there was a value very closed to zero)
added:   UInt::FindLowestBit(uint & table_id, uint & index)
         /temporary version - asm version is missing /



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@256 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-05 18:13:53 +00:00
Tomasz Sowa 321953e833 fixed: the parser didn't use characters for changing the base (# and &)
those characters were skipped
       (this bug was introduced in 0.9.0)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@255 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-02 11:38:17 +00:00
Tomasz Sowa 125c051ea1 changed: version of the library: 0.9.0 now
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@251 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-25 13:49:38 +00:00
Tomasz Sowa de150d00ec added: UInt::operator>>(int)
UInt::operator>>=(int)
       UInt::operator<<(int)
       UInt::operator<<=(int)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@250 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-25 12:57:06 +00:00
Tomasz Sowa 2d821bbad9 added: std::string UInt::ToString(uint b = 10)
std::wstring UInt::ToWString(uint b = 10)
        std::string  Int::ToString(uint b = 10)
        std::wstring Int::ToWString(uint b = 10)
        std::wstring Big::ToWString(const Conv & conv)
        std::wstring Big::ToWString()



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@248 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-24 20:39:36 +00:00
Tomasz Sowa e083c5f889 added: const char * UInt::LibTypeStr()
const char * Big::LibTypeStr()
         LibTypeCode UInt::LibType()
         LibTypeCode Big::LibType()
         returning a string/enum represents the currect type of the library
         we have following types:
             asm_vc_32   - with asm code designed for Microsoft Visual C++ (32 bits)
             asm_gcc_32  - with asm code designed for GCC (32 bits)
             asm_vc_64   - with asm for VC (64 bit)
             asm_gcc_64  - with asm for GCC (64 bit)
             no_asm_32   - pure C++ version (32 bit) - without any asm code
             no_asm_64   - pure C++ version (64 bit) - without any asm code
changed: another compilers than MS VC or GCC by default use no asm version (TTMATH_NOASM)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@247 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-24 20:15:46 +00:00
Tomasz Sowa 11b9f389b9 fixed: Int::DivInt() should take parameters as 'sint' and not 'int'
this has impact on 64 bit platforms
fixed: some warnings from Visual C++ (64 bit)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@245 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-24 06:12:46 +00:00
Tomasz Sowa bac79e0bfa renamed: Conv::comma_digits to Conv::round
added:   bool Conv::base_round
         if 'base_round' is true and 'base' is different from 2, 4, 8, or 16
         and the result value is not an integer then we make an additional rounding
         (after converting the last digit from the result is skipped)
changed: in Big::ToString() some additional rounding (base_round) is now made only 
         when the value is not an integer


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@244 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-24 05:14:54 +00:00
Tomasz Sowa 0d1a57bdb4 added: Int::DivInt(int divisor, int * remainder)
changed: added specializations to Big::ToString() when the base is equal 4, 8 or 16
         the previous version was not accurate on some last digits (after the comma operator)
         consider this binary value (32 bit mantissa):
         base 2: 1.1111 1111 1111 1111 1111 1111 1110 101
         previous ToString() gave:
            base 4:  1.33333333333332
            base 8:  1.777777777
            base 16: 1.FFFFFF
         now we have:
            base 4:  1.3333333333333222
            base 8:  1.77777777724
            base 16: 1.FFFFFFEA



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@238 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-09 17:42:10 +00:00
Tomasz Sowa 4b4b30392a changed: algorithms in Big::Sqrt() and ttmath::Root(x ; n)
they were not too much accurate for some integers
         e.g. Root(16;4) returned a value very closed to 2 (not exactly 2)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@231 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-01 20:26:01 +00:00
Tomasz Sowa 4f1763d773 added: to the parser: function frac() - remains fraction
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@230 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-01 14:20:48 +00:00
Tomasz Sowa cccf82797f added: Big::Sqrt()
global algorithm ttmath::Sqrt() moved to Big::Sqrt()


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@229 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-01 13:41:29 +00:00
Tomasz Sowa e73ce2f8bc added: UInt::Sqrt() - a new algorithm for calculating the square root
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@228 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-01 13:26:19 +00:00
Tomasz Sowa 2feabc64e2 added: struct: Conv
consists of some parameters used
         in ToString() and FromString()
added:   Big::ToString() can group digits
         e.g. 1234567 -> 1`234`567
added:   Parser::SetGroup(int g)
         Parser::SetComma(int c, int c2 = 0)
         Parser::SetParamSep(int s)
added:   uint Big::ToString(std::string & result, const Conv & conv)
         uint Big::ToString(std::wstring & result, const Conv & conv)
         std::string Big::ToString(const Conv & conv) const
         std::string Big::ToString()
added:   uint FromString(const char * source, const Conv & conv, const char **, bool *)
         uint FromString(const wchar_t * source, const Conv & conv, const wchar_t **, bool *)
         uint FromString(const std::string & string, const Conv & conv, const wchar_t **, bool *)
         uint FromString(const std::wstring & string, const Conv & conv, const wchar_t **, bool *)
removed: macros: TTMATH_COMMA_CHARACTER_1 and TTMATH_COMMA_CHARACTER_2
         the comma characters we have in Conv struct now



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@226 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-11-01 01:40:40 +00:00
Tomasz Sowa 413c83de45 updated: CHANGELOG and README
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@224 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-10-25 16:42:41 +00:00
Tomasz Sowa bf520689fb added: to the parser: operator percentage
e.g. 1000-50%=1000-(1000*0,5)=500



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@217 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-10-18 12:37:14 +00:00
Tomasz Sowa af4fbf3098 fixed: powering algorithm in:
UInt::Pow(UInt<value_size> pow)
       Big::Pow(UInt<pow_size> pow)
       Big::PowUInt(Big<exp, man> pow)
       when 'pow' was sufficient large the algorithm returned carry
       but the result could have been calculated correctly



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@213 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-10-16 16:56:49 +00:00
Tomasz Sowa 462ff7cc65 fixed: buffer overflow in Big::ToInt(Int<int_size> & result)
changed: small optimization in ToInt(Int<int_size> & result)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@210 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-10-15 01:34:13 +00:00
Tomasz Sowa 02da809583 added: bool Parser::Calculated()
this method returns true is something was calculated
       (at least one mathematical operator was used or a function or variable)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@207 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-10-13 22:38:08 +00:00
Tomasz Sowa 32ebbbfd9e removed: Big::AboutEqualWithoutSign()
it was broken (it lacks the case when either 'this' or 'ss2' is zero)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@206 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-10-12 23:27:14 +00:00
Tomasz Sowa e765fba8a1 changed: Big::AboutEqual()
it lacks the case when either 'this' or 'ss2' is zero


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@205 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-10-12 23:25:35 +00:00
Tomasz Sowa a8eb29e57d fixed: UInt::SetBitInWord(uint & value, uint bit) set 1 if the bit was
equal 1 (should be set 2)
       this affected only no-asm parts - when macro TTMATH_NOASM was defined
fixed: UInt<value_size>::MulInt(uint ss2)
       there was a buffer overflow when value_size was equal 1
fixed: UInt::AddVector() and UInt::SubVector() didn't want to compile
       when macro TTMATH_NOASM was defined
added: macros:
       TTMATH_LOGC(msg, carry)
       TTMATH_VECTOR_LOG(msg, vector, len)
       TTMATH_VECTOR_LOGC(msg, carry, vector, len)
added: UInt::PrintVectorLog() for debugging purposes
changed: UInt<> class uses new log macros



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@203 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-10-03 01:10:08 +00:00
Tomasz Sowa 31b8c242bd changed: if TTMATH_DEBUG_LOG is defined then TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE is always 3
(regardless of the compiler)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@202 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-20 20:41:11 +00:00
Tomasz Sowa 4c0d8c26ff changed: small optimization in ttmath_subindexed_x64()
(asm for x86_64 on MS VC)
changed: removed some MS VC warnings
changed: if TTMATH_DEBUG_LOG is defined then UInt::UInt()
         constructor fills the table with special values
added:   macro: TTMATH_BITS(min_bits)
         which returns the number of machine words
         capable to hold min_bits bits


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@201 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-20 20:10:29 +00:00
Tomasz Sowa 01a86e40d9 changed: small changes in UInt::Div_CalculatingSize()
some warnings were raported by GCC
         (uninitialized variable)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@200 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-20 12:47:44 +00:00
Tomasz Sowa f19078f9f1 fixed: Factorial(const ValueType & x, ErrorCode * err = 0)
didn't want to compile
moved: UInt<>::SkipWhiteCharacters() to Misc::SkipWhiteCharacters()
       UInt<>::CharToDigit() to Misc::CharToDigit()
       UInt<>::DigitToChar() to Misc::DigitToChar()
removed: Parser::CharToDigit() - was duplicated (it's the same as Misc::CharToDigit())



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@198 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-17 23:18:11 +00:00
Tomasz Sowa adc5015ad9 small optimization in Parser::Parse(const wchar_t *)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@194 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-13 19:29:29 +00:00
Tomasz Sowa da730d1c70 fixed: Big::operator>> didn't correctly recognize values in scientific mode (with 'e' character)
added:   wide characters can be used simultaneously with ascii characters
         now we have two kind of methods: one for ascii characters and the other for wide characters
         e.g.
           void UInt::ToString(std::string & result)
           void UInt::ToString(std::wstring & result)
         previous was only one:
           void UInt::ToString(tt_string & result)
         and the 'tt_string' was a typedef to either std::string or std::wstring
         and it was a little misleading to a user (he has to know what the tt_string is)
added:   file: ttmathmisc.h some useful functions
changed: classes: ExceptionInfo, ReferenceError and RuntimeError are used only with ascii characters
removed: macros: TTMATH_USE_WCHAR,  TTMATH_TEXT()
removed: typedefs: tt_char, tt_string, tt_ostringstream, tt_ostream, tt_istream


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@193 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-13 19:16:42 +00:00
Tomasz Sowa 9ccacd8817 added: uint __fastcall ttmath_addvector_x64(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
uint __fastcall ttmath_subvector_x64(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
       asm code for AddVector() and SubVector() for MS VC x86_64
changed: added prefixes "ttmath_" to all public procedures from ttmathuint_x86_64_msvc.asm


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@192 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-11 23:55:44 +00:00
Tomasz Sowa b3d27979d0 changed: removing some MS VC warnings when compiling x86_64 target
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@191 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-11 20:48:52 +00:00
Tomasz Sowa e13e5eb329 added: flag TTMATH_BIG_ZERO to Big<> class
if this flag is set then there is a value zero
added:   Big::ClearInfoBit(unsigned char)
         Big::SetInfoBit(unsigned char)
         Big::IsInfoBit(unsigned char)
         some methods for manipulating the info flags
changed: IsZero() is using TTMATH_BIG_ZERO flag
         now it has O(1) complexity
         previously was O(n)
changed: optimized some methods
         they are using IsZero() for testing at the beginning
         because this method is much faster now
changed: Big::Div(ss2)
         Big::Mod(ss2)
         they return 2 when ss2 is zero
         previously returned 1



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@190 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-11 04:24:42 +00:00
Tomasz Sowa 74b31b1f54 fixed/optimized: Big::AboutEqual() didn't compile on GCC
(there was used ttmath::Abs() function which is unknown in Big<> class)
         AboutEqual() returned true for: "2345.5" and "-2345.5" (the sign was not checked)
renamed: Big::AboutEqual() to Big::AboutEqualWithoutSign()
added:   Big::AboutEqual()



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@189 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-10 16:28:05 +00:00
Tomasz Sowa 28964d30f7 merged: x86_64 asm code for Microsoft Visual compiler
file: ttmathuint_x86_64_msvc.asm from chk branch (original was: ttmathuint_x86_amd64_msvc.asm)
        (this file should be compiled first because MS VC doesn't support inline assembler in x86_64 mode) 



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@187 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-07 02:03:00 +00:00
Tomasz Sowa 0d71b0cec2 merged: AboutEqual() from chk branch
deleted: properties svn:mime-type from ttmath.h
         (it was for testing viewvc)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@186 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-05 16:43:38 +00:00
Tomasz Sowa 3544a1df3c setting svn:mime-type to text/plain for ttmath.h
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@185 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-08-24 05:08:13 +00:00
Tomasz Sowa 00519ff26d added/fixed: special version of ToString_LogBase() method
in single thread environment
             the previous version of the method didn't store
             the calculated logarithms


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@184 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-08-04 18:55:18 +00:00
Tomasz Sowa 799e2c32a7 added: multithread support for Big<> class
you should compile with TTMATH_MULTITHREADS
        and use TTMATH_MULTITHREADS_HELPER macro somewhere in your *.cpp file
        added file: ttmaththreads.h (look there for more info)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@183 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-08-04 18:23:35 +00:00
Tomasz Sowa 53547cfab5 * added: global Gamma() function
* added:   gamma() function to the parser
* added:   Big::IsInteger() method
           returns true if the value is integer
* added:   CGamma<ValueType> class
           is used with Gamma() and Factorial() in multithreaded environment
* changed: Factorial() is using the Gamma() function now
* removed: Parser<>::SetFactorialMax() method
           the factorial() is such a fast now that we don't need the method longer
* removed: ErrorCode::err_too_big_factorial



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@178 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-07-16 03:22:29 +00:00
Tomasz Sowa d3a64b79ca added: support for wide characters (wchar_t)
wide characters are used when macro TTMATH_USE_WCHAR is defined
       this macro is defined automatically when there is macro UNICODE or _UNICODE defined
       some types have been changed
        char               -> tt_char
        std::string        -> tt_string
        std::ostringstream -> tt_ostringstream
        std::ostream       -> tt_ostream
        std::istream       -> tt_istream
       normally tt_char is equal char but when you are using wide characters then tt_char will be wchar_t (and so on)
       (all typedef's are in ttmathtypes.h)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@177 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-07-02 01:04:25 +00:00
Tomasz Sowa c70a947c07 updated changelog to previous commit
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@164 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-16 18:33:20 +00:00
Tomasz Sowa 8972fdfdb3 fixed: Sqrt(), Root() and Factorial() didn't correctly treat the NaN flag
fixed: some methods should set 'err_improper_argument' when the argument is a NaN object
       (was: err_overflow)
changed: version of the library: 0.8.5 now



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@163 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-16 18:31:39 +00:00
Tomasz Sowa 019a902fed changed: small optimization in Big::ExpSurrounding0() and Big::LnSurrounding1()
the remainder from a division '%' was changed with a bitwise And operation '&'
         ((i % 5) == 0) was changed to: ((i & 3) == 0) - it means ((i % 4) == 0)
         now the test if performed after 4 iterations (early were after 5 iterations)
         we can do that when the divisor is a power of 2
changed: optimization in Factorial()
         we're testing WasStopSignal() only after a few iterations
         it's faster now about 4 times on GCC 4.3.3 (when stop object is provided to the factorial)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@161 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-14 19:55:15 +00:00
Tomasz Sowa 74553109a5 fixed: (performance) in Big::LnSurrounding1() and Big::ExpSurrounding0()
we can copy 'old_value = *this' only when 'testing' is true


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@160 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-14 18:45:36 +00:00
Tomasz Sowa 9e42a5a9fd fixed: Big::FromDouble() on a 32 bit platform:
SetNaN() should be SetNan() /*compilation error*/


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@158 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-11 15:03:22 +00:00
Tomasz Sowa 1b6858616d fixed: in Big::FromDouble(): SetNaN() should be SetNan();
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@157 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-11 10:04:50 +00:00
Tomasz Sowa d789ac5396 added: using NaN flag in method Big::ToDouble() and Big::FromDouble()
changed: some cosmetic changes to get rid of warnings generated by 
         MS Visual 2008 when warning level is 4
changed: names of labels in asm code: p to ttmath_loop, end to ttmath_end
         p2 to ttmath_loop2
         Robert Muir reported that there was a confict with boost::end


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@156 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-11 02:31:41 +00:00
Tomasz Sowa bb2583649e added: to Big<> class: support for NaN flag (Not a Number)
bool Big::IsNan() - returns true if the NaN flag is set
       void Big::SetNan() - sets the NaN flag
       The NaN flag is set by default after creating an object:
         Big<1, 2> a;    // NaN is set (it means the object has not a valid number)
         std::cout << a; // cout gives "NaN"
         a = 123;        // now NaN is not set
         std::cout << a; // cout gives "123"
       The NaN is set if there was a carry during calculations
         a.Mul(very_big_value); // a will have a NaN set
	   The NaN is set if an argument is NaN too
	     b.SetNan();
	     a.Add(b);  // a will have NaN because b has NaN too
       If you try to do something on a NaN object, the result is a NaN too
         a.SetNan();
         a.Add(2);  // a is still a NaN 
       The NaN is set if you use incorrect arguments
         a.Ln(-10); // a will have the NaN flag
       The only way to clear the NaN flag is to assign a correct value or other correct object
         supposing 'a' has NaN flag, to remove the flag you can either:
         a = 10;
         a.FromInt(30);
         a.SetOne(); 
         a.FromBig(other_object_without_nan);
         etc.
changed: renamed macro CONSTANTSGENERATOR to TTMATH_CONSTANTSGENERATOR



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@152 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-26 23:13:22 +00:00
Tomasz Sowa 5e5a106605 changed: a little changes in all asm code
it should be a little faster


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@149 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-17 00:04:42 +00:00
Tomasz Sowa eaa19dd46a added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
         a new multiplication algorithm: Karatsuba multiplication,
         on a vector UInt<100> with all items different from zero this algorithm is faster
         about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
         zero this algorithm is faster more than 5 times than Mul2Big()
         (measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added:   uint MulFastest(const UInt<value_size> & ss2)
         void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
         those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
         void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
         those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added:   uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
         uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
         three forms: asm x86, asm x86_64, no-asm
         those methods are used by the Karatsuba multiplication algorithm



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-15 22:27:04 +00:00
Tomasz Sowa 939d0f7519 fixed: Big::Mod(x) didn't correctly return a carry
and the result was sometimes very big (even greater than x)
fixed:   global function Mod(x) didn't set an ErrorCode object
fixed:   global function Round() didn't test a carry
         now it sets ErrorCode object
changed: function Sin(x) to Sin(x, ErrorCode * err=0)
         when x was very big the function returns zero
         now it sets ErrorCode object to err_overflow
         and the result is undefined
         the same is to Cos() function
changed: PrepareSin(x) is using Big::Mod() now when reducing 2PI period
         should be a little accurate especially on a very big 'x'



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@143 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-11 01:50:00 +00:00
Tomasz Sowa 05b67e7103 changed: corrected spaces in changelog
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@142 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-09 01:34:45 +00:00
Tomasz Sowa 3231780a85 changed: version of the library: 0.8.4
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@138 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-08 19:13:25 +00:00
Tomasz Sowa 1bae0d6cb8 changed: in ttmathtypes.h
'typedef unsigned long long int ulint' has been put inside '#ifdef TTMATH_NOASM'
         in order to not confuse a compiler while compiling with strict iso c++
         (errors about not defining 'long long' in the c++ standard)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@137 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-08 18:40:32 +00:00
Tomasz Sowa 277dd72fb6 fixed: UInt::AddInt() in no-asm code has incorrect assertion
changed: UInt::SubInt() in no-asm code is a little faster now
changed: small cosmetic changes in commentaries
deleted: some debug #ifdef's from UInt::Div() (in no-asm code)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@136 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-08 18:14:00 +00:00
Tomasz Sowa a7a7eb7808 fixed: deleted default values for variables in some methods (file ttmathuint_x86.h)
(they should only be put in declaration)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@128 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-05 07:47:10 +00:00
Tomasz Sowa e665f91682 fixed: the problem with GCC optimization on x86_64
sometimes when using -O2 or -O3 GCC doesn't set correctly
         the stack pointer (actually the stack is used for other things)
         and you can't use instructions like push/pop in assembler code.
         All the asm code in x86_64 have been rewritten, now instructions
         push/pop are not used, other thing which have access to stack 
         (like "m" (mask) constraints in Rcl2 and Rcr2) have also gone away,
         now the library works well with -O2 and -O3 and the asm code
         is a little faster



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@127 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-05 07:20:10 +00:00
Tomasz Sowa 85945b2bb0 added: ttmathuint_x86.h, ttmathuint_x86_64.h, ttmathuint_noasm.h,
all the methods which are using assembler code have been 
         rewritten to no-asm forms, now we have:
         1. asm for x86      file: ttmathuint_x86.h
         2. asm for x86_64   file: ttmathuint_x86_64.h
         3. no asm           file: ttmathuint_noasm.h
            (it's used when macro TTMATH_NOASM is defined)
            The third form can be used on x86 and x86_64 as well and
            on other platforms with a little effort.
            (Temporarily I left there some '#ifdef's for debugging.)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@126 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-04 20:51:12 +00:00
Tomasz Sowa 1efe39686b added: UInt::PrintLog(const char * msg, std::ostream & output)
used for debugging purposes by macro TTMATH_LOG(msg)
         (it is used in nearly all methods in UInt class)
added:   macro TTMATH_DEBUG_LOG: when defined then TTMATH_LOG() 
         put some debug information (to std::cout)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@125 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-01 14:53:21 +00:00
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
Tomasz Sowa 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
52 changed files with 47486 additions and 6328 deletions

791
CHANGELOG
View File

@ -1,171 +1,620 @@
Version 0.8.2 (2008.06.18):
* added: UInt::BitNot2() this method has been proposed by
Arek <kmicicc AnTispam users.sourceforge.net>
* changed: Int::FromInt(const Int<argument_size> & p),
Int::FromInt(sint value) (it returns zero now)
Int::operator=(uint i)
Int::Int(uint i)
* added: Int::FromUInt(const UInt<argument_size> & p),
Int::FromUInt(uint value)
and appropriate constructors and assignment
operators as well
* changed: Big::FromInt(Int<int_size> value),
* added: Big::FromUInt(UInt<int_size> value),
Big::operator=(const UInt<int_size> & value)
Big::Big(const UInt<int_size> & value)
* changed: the parser is allowed to recognize values which
begin with a dot, e.g '.5' is treated as '0.5'
* added: a method Big::FromDouble(double) which converts from
standard double into a Big
* added: uint Big::ToDouble(double&) - converting into double
* added: Big::FromBig() and an operator= and a contructor
for converting from another kind of a Big class
* added: to the parser: avg(), sum()
* added: 'decimal_point' parameter into Big::ToString(...)
* fixed: Big::operator>> didn't use TTMATH_COMMA_CHARACTER_2 macro
* added: a short form of multiplication (without the '*' character)
e.g. '5y', (it's used only if the second parameter
is a variable or function)
* changed: variables and functions are case-sensitive now
* added: variables and functions can have underline characters
in their names
* changed: 'max_digit_after_comma' in Big::ToString()
remove the -2 state
* added: 'remove_trailing_zeroes' in Big::ToString()
it's either true or false
* fixed/changed: the way of using Big::SetSign()
the method do not check whether there is a zero or not now
(even if there's a zero the method can set a sign bit)
I changed this due to some prior errors
(errors corrected in revision 17, 49 and 58)
Version 0.8.1 (2007.04.17):
* fixed: Big::PowFrac(..) didn't return a correct error code
(when 'this' was negative)
* added: Root(x; index) (and to the parser as well)
* added: macro: TTMATH_PRERELEASE_VER (can be either zero or one)
* added: UInt::MulInt(int, UInt<int another_size>::&)
* added: Big::MulUInt(uint)
* changed: Big::MulInt(sint)
* added: Big::ToUInt(uint &)
* changed: Big::ToInt(sint&)
* changed: Factorial() it uses Big::MulUInt() at the beginning
(faster now especially more on a 32bit platform)
* added: doxygen.cfg for generating a documentation from the doxygen
* changed: UInt::Rcl(uint c=0) and UInt::Rcr(uint c=0) into
UInt::Rcl2(uint bits, uint c) and UInt::Rcr2(uint bits, uint c)
now they can move more than one bit and they are only private
* fixed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c)
didn't correctly return a carry if the 'bits' were equal
to 'value_size*TTMATH_BITS_PER_UINT'
* changed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c)
into UInt::Rcl(uint bits, uint c=0) and
UInt::Rcr(uint bits, uint c=0)
they are faster now when the bits is greater than a half of
the TTMATH_BITS_PER_UINT
* changed: UInt::CompensationToLeft() it's faster now
* changed: more small changes where there were UInt::Rcl(uint c=0) and
UInt::Rcr(uint c=0) used
* changed: as the Big type uses UInt::Rcl() and UInt::Rcr() a lot then
it is much faster now (about 5-25%)
* added: ASinh(), ACosh(), ATanh() /ATgh()/, ACoth() /ACtgh()/
and to the parser as well
* added: UInt::BitAnd(), UInt::BitOr(), UInt::BitXor(), UInt::BitNot(),
Big::BitAnd(), Big::BitOr(), Big::BitXor()
* added: to the parser: bitand(), bitor(), bitxor()
/band(), bor(), bxor()/
* changed: the way of parsing operators in the mathematical parser
(the parser is not too much greedy now)
Version 0.8.0 (2007.03.28):
* added: into the parser: SetFactorialMax()
* added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
* changed: class Objects in ttmathobjects.h has been completely rewritten,
we can change the names of user-defined variables or functions,
and the names are case-sensitive now
* added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
* added: Tg(x) a wrapper for Tan(x)
* changed: CTan(x) is Cot(x) now
* added: Ctg(x) a wrapper for Cot(x)
* added: ATg(x) a wrapper for ATan(x)
* changed: ACTan(x) is ACot(x) now
* added: ACtg(x) a wrapper for ACot(x)
* added: UInt::PrintTable() (for debugging etc.)
* changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have
been rewritten, now they have 128 32bit words (it's about
1232 valid decimal digits)
* fixed: previous values from Big::SetPi() Big::SetE() and
Big::SetLn2() were not too much accurate (last 2-3 words were wrong)
* added: Big::SetLn10() (128 32bit words as well)
* added: macro TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on
32bit platforms and 64ul on 64bit platforms (128/2=64)
* added: macros TTMATH_PLATFORM32 and TTMATH_PLATFORM64
* changed: a small optimisation in UInt::Mul2Big()
* added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
* added: to samples: big.cpp, parser.cpp
* added/changes/fixed: in copy-constructors and operators= in Int,
Uint and Big (more info in the commit log)
* renamed: Big::SetDotOne() into Big::Set05()
* changes: a few small optimisations in Big
* deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
* and more small changes (look at the commit log)
Version 0.7.2 (2007.03.09):
* added: Big::Mod - the remainder from a division
* added: Big::Sgn - the 'sign' from the value (-1,0,1)
* added: global functions Mod and Sgn too
* added: checking whether a user gives a correct value of a variable or function
(user-defined variables/functions in the mathematical parser)
* added: into the parser: logical operators: > < >= <= == != && ||
* added: into the parser: logical functions: and() or() not() if()
* added: ErrorCode::err_unknown_operator when the parser couldn't read an operator
Version 0.7.1 (2007.02.27):
* fixed: the error 'overflow during printing' which was caused
by Big::FromInt(Int<int_size> value) (the sign has to be set at the end)
* fixed: many small errors
* added: ATan (arctan), ACTan (arc ctan) functions
Version 0.7.0 (2007.02.24):
* finished: support for 64bit platforms
* added: ASin (arcsin), ACos (arccos) functions
Version 0.6.4 (2007.01.29):
* fixed: the problem with a sign in the mathematical parser /-(1) was 1/
* added: UInt::AddInt and UInt::SubInt
* changed: UInt::AddOne and UInt::SubOne (much faster now)
* added: UInt::SetBitInWord
* changed: UInt::SetBit (much faster now)
UInt::AddTwoUints renamed to UInt::AddTwoInts
UInt::FindLeadingBit32 renamed to UInt::FindLeadingBitInWord
UInt::Mul64 renamed to UInt::MulTwoWords
UInt::Div64 renamed to UInt::DivTwoWords
* added: UInt::SetBitInWord
* and more small changes in UInt type
* start adding support for Amd64 (not finished yet) (added ttmathuint64.h)
Version 0.6.3 (2007.01.22):
* changed: position of arguments (x and base) in logarithm functions are swapped
* changed: it's possible to use any multiplication algorithms in the same time
(macros UINT_MUL_VERSION_'X' have gone)
* added: ExceptionInfo, ReferenceError and RuntimeError classes
* changed: the mess in macros has been cleaned up
* added: TTMATH_RELEASE macro
Version 0.6.2 (2007.01.10):
* added: New division algorithm (radix b) where b is 2^32
Version 0.9.4_prerelease (....):
* fixed: cannot compile on MS Windows when compiling with GCC (Mingw) for 64 bit platform:
incorrect size of ttmath::uint and ::sint were used
they were 'long' but 'long' is a 32bit type on Windows
* fixed: a crash in Big::Add() (buffer overflow)
there was an offset calculated from Int type by using Abs() method and a carry was not checked
(if there is a carry we should not make addition -- the argument is too small)
this had no impact on calculated values because there was a crash (bus error) immediately
following program could crash (64bit):
typedef ttmath::Big<1, 8> MyBig;
ttmath::Parser<MyBig> parser;
parser.Parse("2^(2^63) + 1");
* fixed: similar problems were in methods Big::BitAnd() Big::BitOr() and Big::BitXor() (bitwise operations)
and they could return incorrect values
* fixed: in x86_64 asm code (*.asm for Win64) there was in some places esp register used,
there should be rsp used instead
this affects MS Windows users when they use the asm version (ttmathuint_x86_64_msvc.asm)
Version 0.9.3 (2012.11.28):
* fixed: in Big::FromDouble(double value) (only 32 bit version)
buffer overflow in referencing to UInt<2>
this was used when 'value' was in so called "unnormalized" state
(E=0 and F is nonzero)
it produced incorrect mantissa (on about 8th decimal digit up)
* added: Parser::InitCGamma()
initializing coefficients used when calculating the gamma (or factorial) function
this speed up the next calculations
you don't have to call this method explicitly
these coefficients will be calculated when needed
* added: option 'group_digits' to Conv struct
you can set how many digits should be grouped
* changed: small optimizations in UInt::ToString() and Big::FromString()
Version 0.9.2 (2010.09.23):
* fixed: Big::Add() sometimes incorrectly rounded the last bit from its mantissa
* fixed: Big::BigAnd() Big::BigOr() Big::BigXor() should have set NaN
when the argument was negative (they only returned 2)
* fixed: recurrence calling in Big::FromString(const std::string &, uint, const wchar_t **, bool *)
it should have the signature: Big::FromString(const std::string &, uint, const char **, bool *)
* fixed: Big::ToString method
in some cases when in the output string the exponent should be equal zero
the method changes the exponent to one so the last digit from the mantissa
was lost
* fixed: Big::ToDouble(double &) set always +INF (infinity)
when the value was too large (even for negative values)
(it should set -INF in such a case)
* added: some missing operators
UInt::operator~() /* bitwise neg */
UInt::operator&() /* bitwise and */
UInt::operator&=()
UInt::operator|() /* bitwise or */
UInt::operator|=()
UInt::operator^() /* bitwise xor */
UInt::operator^=()
Big::operator&()
Big::operator&=()
Big::operator|()
Big::operator|=()
Big::operator^()
Big::operator^=()
for Big<> we do not define bitwise neg
Big::operator++()
Big::operator++(int)
Big::operator--()
Big::operator--(int)
* added: macro TTMATH_DONT_USE_WCHAR
if defined then the library does not use wide characters
(wchar_t, std::wstring, ...) this is a workaround for some compilers
* added: bool UInt::IsOnlyTheHighestBitSet()
bool UInt::IsOnlyTheLowestBitSet()
returning true if only the highest/lowest bit is set
* added: uint Int::MulInt(sint ss2)
* added: void UInt::Swap(UInt<value_size> & ss2)
void Big::Swap(UInt<value_size> & ss2)
method for swapping this for an argument
* added: macro TTMATH_BIG_DEFAULT_CLEAR
when defined the default constructor from Big<> clears its mantissa and exponent
Big<1, 2> var;
var.mantissa and var.exponent will be set to zero
(but var has the NaN flag set too - it is not zero value, this is mainly for debug purposes)
* added: only on 32bit platforms:
uint UInt::FromUInt(uint64_t n)
uint Int::FromInt(int64_t n)
void Big::FromUInt(uint64_t n)
void Big::FromInt(int64_t n)
and appropriate constructors and operators
* added: TTMATH_FORCEASM macro
asm version of the library is available by default only for:
x86 and amd64 platforms and for Microsoft Visual and GCC compilers,
but you can force using asm version (the same asm as for Microsoft Visual)
by defining TTMATH_FORCEASM macro
you have to be sure that your compiler accept such an asm format
* added: some missing methods for converting
for UInt<>, Int<> and Big<> classes:
uint ToUInt()
sint ToInt()
ToUInt(uint32_t &)
ToInt(uint32_t &)
ToInt(int32_t &)
ToUInt(uint64_t &)
ToInt(uint64_t &)
ToInt(int64_t &)
FromUInt(uint32_t &)
FromInt(uint32_t &)
FromInt(int32_t &)
FromUInt(uint64_t &)
FromInt(uint64_t &)
FromInt(int64_t &)
and appropriate constructors and operators
* added: double Big::ToDouble() /there was only Big::ToDouble(double &) /
uint Big::ToFloat(float &)
float Big::ToFloat()
* changed: now asm version is available only on x86 and amd64
(and only for GCC and MS VC compilers)
* removed: macro TTMATH_RELEASE (now the 'release' version is default)
for debug version define TTMATH_DEBUG macro
TTMATH_DEBUG is also automatically defined when DEBUG or _DEBUG is set
* removed: macro TTMATH_REFERENCE_ASSERT from all methods in public interface
Version 0.9.1 (2010.02.07):
* fixed: the parser didn't use characters for changing the base (# and &)
those characters were skipped
(this bug was introduced in 0.9.0)
* fixed: added in the parser: operator's associativity
operator ^ (powering) is right-associative:
sample: 2^3^4 is equal 2^(3^4) and it is: 2.41e+24
previously was: 2^3^4 = (2^3)^4 = 4096
* fixed: in Big::ToString_CreateNewMantissaAndExponent() changed the formula:
new_exp_ = [log base (2^exponent)] + 1
now the part '+ 1' is only made when the logarithm is positive and with fraction
if the value is negative we can only skip the fraction, previously
we lost some last digits from the new mantissa
Consider this binary value (32 bit mantissa):
(bin)1.0000000000000000000000000000011
previously ToString() gave 1, now we have: 1.000000001
* changed: in Big::ToString() the base rounding is made only if the result value
would not be an integer, e.g. if the value is 1.999999999999 then
the base rounding will not be done - because as the result would be 2
* added: IEEE 754 half-to-even rounding (bankers' rounding) to the following
floating point algorithms: Big::Add, Big::Sub, Big::Mul, Big::Div
* added: static sint UInt<value_size>::FindLowestBitInWord(uint x)
this method is looking for the lowest set bit in a word
* added: UInt::FindLowestBit(uint & table_id, uint & index)
this method is looking for the lowest set bit
Version 0.9.0 (2009.11.25):
* added: support for wide characters (wchar_t, std::wstring)
* added: Big::IsInteger()
returns true if the value is integer (without fraction)
(NaN flag is not checked)
* added: global Gamma() function
* added: gamma() function to the parser
* added: CGamma<ValueType> class
is used with Gamma() and Factorial() in multithreaded environment
* added: multithread support for Big<> class
you should compile with TTMATH_MULTITHREADS
and use TTMATH_MULTITHREADS_HELPER macro somewhere in your *.cpp file
* added: x86_64 asm code for Microsoft Visual compiler
file: ttmathuint_x86_64_msvc.asm
(this file should be compiled first because MS VC doesn't support inline assembler in x86_64 mode)
* added: flag TTMATH_BIG_ZERO to Big<> class
if this flag is set then there is a value zero
Big::IsZero() is faster now
* added: Big::ClearInfoBit(unsigned char)
Big::SetInfoBit(unsigned char)
Big::IsInfoBit(unsigned char)
some methods for manipulating the info flags
* added: macro: TTMATH_BITS(min_bits)
which returns the number of machine words
capable to hold min_bits bits
* added: bool Parser::Calculated()
this method returns true is something was calculated
(at least one mathematical operator was used or a function or variable)
* added: to the parser: operator percentage
e.g. 1000-50%=1000-(1000*0,5)=500
* added: struct: Conv
consists of some parameters used
in ToString() and FromString()
* added: Big::ToString() can group digits
e.g. 1234567 -> 1`234`567
* added: Parser::SetGroup(int g)
Parser::SetComma(int c, int c2 = 0)
Parser::SetParamSep(int s)
* added: std::string UInt::ToString(uint b = 10)
std::wstring UInt::ToWString(uint b = 10)
std::string Int::ToString(uint b = 10)
std::wstring Int::ToWString(uint b = 10)
uint Big::ToString(std::string & result, const Conv & conv)
uint Big::ToString(std::wstring & result, const Conv & conv)
std::string Big::ToString(const Conv & conv)
std::string Big::ToString()
std::wstring Big::ToWString(const Conv & conv)
std::wstring Big::ToWString()
* added: uint FromString(const char * source, const Conv & conv, const char **, bool *)
uint FromString(const wchar_t * source, const Conv & conv, const wchar_t **, bool *)
uint FromString(const std::string & string, const Conv & conv, const wchar_t **, bool *)
uint FromString(const std::wstring & string, const Conv & conv, const wchar_t **, bool *)
* added: UInt::Sqrt() - a new algorithm for calculating the square root
* added: to the parser: function frac() - returns a value without the integer part
(only fraction remains)
* added: Int::DivInt(sint divisor, sint * remainder)
* added: const char * UInt::LibTypeStr()
const char * Big::LibTypeStr()
LibTypeCode UInt::LibType()
LibTypeCode Big::LibType()
returning a string/enum represents the currect type of the library
we have following types:
asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
asm_gcc_32 - with asm code designed for GCC (32 bits)
asm_vc_64 - with asm for VC (64 bit)
asm_gcc_64 - with asm for GCC (64 bit)
no_asm_32 - pure C++ version (32 bit) - without any asm code
no_asm_64 - pure C++ version (64 bit) - without any asm code
* added: UInt::operator>>(int)
UInt::operator>>=(int)
UInt::operator<<(int)
UInt::operator<<=(int)
* changed: Factorial() is using the Gamma() function now
* changed: Big::Div(ss2)
Big::Mod(ss2)
they return 2 when ss2 is zero
previously returned 1
* changed: algorithms in Big::Sqrt() and ttmath::Root(x ; n)
they were not too much accurate for some integers
e.g. Root(16;4) returned a value very closed to 2 (not exactly 2)
* changed: added specializations to Big::ToString() when the base is equal 4, 8 or 16
the previous version was not accurate on some last digits (after the comma operator)
consider this binary value (32 bit mantissa):
base 2: 1.1111 1111 1111 1111 1111 1111 1110 101
previous ToString() gave:
base 4: 1.33333333333332
base 8: 1.777777777
base 16: 1.FFFFFF
now we have:
base 4: 1.3333333333333222
base 8: 1.77777777724
base 16: 1.FFFFFFEA
* changed: in Big::ToString() some additional rounding (base_round) is now made only
when the value is not an integer
* changed: another compilers than MS VC or GCC by default use no asm version (TTMATH_NOASM)
* removed: Parser<>::SetFactorialMax() method
the factorial() is such a fast now that we don't need the method longer
* removed: ErrorCode::err_too_big_factorial
* removed: macros: TTMATH_COMMA_CHARACTER_1 and TTMATH_COMMA_CHARACTER_2
the comma characters we have in Conv struct now
Version 0.8.6 (2009.10.25):
* fixed: UInt::SetBitInWord(uint & value, uint bit) set 1 if the bit was
equal 1 (should be set 2)
this affected only no-asm parts - when macro TTMATH_NOASM was defined
* fixed: UInt<value_size>::MulInt(uint ss2)
there was a buffer overflow when value_size was equal 1
* fixed: UInt::AddVector() and UInt::SubVector() didn't want to compile
when macro TTMATH_NOASM was defined
* fixed: Big::operator>> didn't correctly recognize values in scientific mode (with 'e' character)
* fixed: Int::FromString(const tt_string & s, uint b = 10)
didn't use 'b' (always was '10')
* fixed: buffer overflow in Big::ToInt(Int<int_size> & result)
* fixed: powering algorithm in:
UInt::Pow(UInt<value_size> pow)
Big::Pow(UInt<pow_size> pow)
Big::PowUInt(Big<exp, man> pow)
when 'pow' was sufficient large the algorithm returned carry
but the result could have been calculated correctly
Version 0.8.5 (2009.06.16):
* fixed: Big::Mod(x) didn't correctly return a carry
and the result was sometimes very big (even greater than x)
* fixed: global function Mod(x) didn't set an ErrorCode object
* fixed: global function Round() didn't test a carry
now it sets ErrorCode object
* changed: function Sin(x) to Sin(x, ErrorCode * err=0)
when x was very big the function returns zero
now it sets ErrorCode object to err_overflow
and the result has a NaN flag set
the same is to Cos() function
* changed: PrepareSin(x) is using Big::Mod() now when reducing 2PI period
should be a little accurate especially on a very big 'x'
* changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
* changed: changed a little Mul2Big() to cooperate with Mul3Big()
* added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
* added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
* added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
* added: to Big<> class: support for NaN flag (Not a Number)
bool Big::IsNan() - returns true if the NaN flag is set
void Big::SetNan() - sets the NaN flag
The NaN flag is set by default after creating an object:
Big<1, 2> a; // NaN is set (it means the object has not a valid number)
std::cout << a; // cout gives "NaN"
a = 123; // now NaN is not set
std::cout << a; // cout gives "123"
The NaN is set if there was a carry during calculations
a.Mul(very_big_value); // a will have a NaN set
The NaN is set if an argument is NaN too
b.SetNan();
a.Add(b); // a will have NaN because b has NaN too
If you try to do something on a NaN object, the result is a NaN too
a.SetNan();
a.Add(2); // a is still a NaN
The NaN is set if you use incorrect arguments
a.Ln(-10); // a will have the NaN flag
The only way to clear the NaN flag is to assign a correct value or other correct object,
supposing 'a' has NaN flag, to remove the flag you can either:
a = 10;
a.FromInt(30);
a.SetOne();
a.FromBig(other_object_without_nan);
etc.
Version 0.8.4 (2009.05.08):
* fixed: UInt::DivInt() didn't check whether the divisor is zero
there was a hardware interruption when the divisor was zero
(now the method returns one)
* fixed: the problem with GCC optimization on x86_64
sometimes when using -O2 or -O3 GCC doesn't set correctly
the stack pointer (actually the stack is used for other things)
and you can't use instructions like push/pop in assembler code.
All the asm code in x86_64 have been rewritten, now instructions
push/pop are not used, other thing which have access to stack
(like "m" (mask) constraints in Rcl2 and Rcr2) have also gone away,
now the library works well with -O2 and -O3 and the asm code
is a little faster
* added: UInt::PrintLog(const char * msg, std::ostream & output)
used (for debugging purposes) by macro TTMATH_LOG(msg)
(it is used in nearly all methods in UInt class)
* added: macro TTMATH_DEBUG_LOG: when defined then TTMATH_LOG()
put some debug information (to std::cout)
* added: ttmathuint_x86.h, ttmathuint_x86_64.h, ttmathuint_noasm.h,
all the methods which are using assembler code have been
rewritten to no-asm forms, now we have:
1. asm for x86 file: ttmathuint_x86.h
2. asm for x86_64 file: ttmathuint_x86_64.h
3. no asm file: ttmathuint_noasm.h
(it's used when macro TTMATH_NOASM is defined)
The third form can be used on x86 and x86_64 as well and
on other platforms with a little effort.
Version 0.8.3 (2009.04.06):
* fixed: RclMoveAllWords() and RcrMoveAllWords() sometimes didn't return
the proper carry, (when 'bits' was greater than or equal to 'value_size')
this had impact on Rcl() and Rcr(), they also returned the wrong carry
* fixed: UInt::Div() didn't return a correct result when the divisor was equal 1
there was an error in UInt::DivInt() - when the divisor was 1 it returned
zero and the carry was set
* fixed: there was a TTMATH_REREFENCE_ASSERT error in Big::PowUInt() caused by: start.Mul(start)
* fixed: Big::Add incorrectly rounded 'this' when both exponents were equal
it caused that sometimes when adding a zero the result has changed
this had impact among other things on FromString() method
"0,8" had different binary representation from "0,80"
* fixed: template Big::FromBig(const Big<another_exp, another_man> & another)
didn't correctly set the exponent (when the mantisses had different size -
when 'man' was different from 'another_man')
this had impact on operator= too
sample:
Big<2,3> a = 100;
Big<3,5> b;
b = a; // b had a wrong value
* fixed: Big::Pow(const Big<exp, man> & pow)
it's using PowInt() only when pow.exponent is in range (-man*TTMATH_BITS_PER_UINT; 0]
previously the powering 'hung' on an input like this: "(1+ 1e-10000) ^ 10e100000000"
(there was 10e100000000 iterations in PowInt())
* fixed: in function DegToRad(const ValueType & x, ErrorCode * err = 0) it is better
to make division first and then mutliplication -- the result is more
accurate especially when x is: 90,180,270 or 360
* fixed: the parser didn't correctly treat operators for changing the base
(radix) -- operators '#' and '&', e.g.:
'#sin(1)' was equal '0' -- there was a zero from '#' and then
it was multipied by 'sin(1)'
the parser didn't check whether Big::FromString() has actually
read a proper value -- the method Big::FromString() didn't have
something to report such a situation
* fixed: Big::FromString() when the base is 10, the method reads the scientific
part only if such a part it correctly supplied, e.g:
'1234e10', '1234e+10', '1234e-5'
previous '1234e' was treated as: '1234e0' (now parsing stops on 'e' and
the 'e' can be parsed by other parsers, e.g. the mathematical
parser -- now in the parser would be: '1234e' = '1234 * e' = '3354,3597...' )
* changed: renamed: Big::PowUInt(UInt<pow_size> pow) -> Big::Pow(UInt<pow_size> pow)
it returns 2 when there is: 0^0
* changed: renamed: Big::PowInt(Int<pow_size> pow) -> Big::Pow(Int<pow_size> pow)
it returns 2 when there is: 0^0 or 0^(-something)
* changed: renamed: Big::PowBUInt() -> PowUInt(), Big::PowBInt() -> Big::PowInt()
they return 2 when the arguments are incorrect (like above)
* changed: UInt::SetBitInWord(uint & value, uint bit) is taking the first argument by a reference now,
the specific bit is set in the 'value' and the method returns the last state of the bit (zero or one)
* changed: UInt::SetBit(uint bit_index) - it's using TTMATH_ASSERT now
* changed: the size of built-in variables (constants) in ttmathbig.h
now they consist of 256 32bit words
macro TTMATH_BUILTIN_VARIABLES_SIZE is equal: 256u on a 32bit platform and 128ul on a 64bit platform
* changed: the asm code in ttmathuint.h and ttmathuint64.h has been completely rewritten
now UInt<> is faster about 15-30% than UInt<> from 0.8.2
this has impact on Big<> too - it's faster about 10% now
* changed: in the parser: the form with operators '#' and '&' is as follows:
[-|+][#|&]numeric_value
previous was: [-|+][#|&][-|+]numeric_value
* changed: in the parser: the short form of multiplication has the same
priority as the normal multiplication, e.g.:
'2x^3' = 2 * (x^3)
previous the priority was greater than powering priority
previous: '2x^3' = (2*x) ^ 3
* added: UInt::GetBit(uint bit_index) - returning the state of the specific bit
* added: Big::operator=(double) and Big::Big(double)
* added: UInt::Pow(UInt<value_size> pow) and Int::Pow(Int<value_size> pow)
* added: global template functions in ttmath.h:
ValueType GradToRad(const ValueType & x, ErrorCode * err = 0)
ValueType RadToGrad(const ValueType & x, ErrorCode * err = 0)
ValueType DegToGrad(const ValueType & x, ErrorCode * err = 0)
ValueType DegToGrad(const ValueType & d, const ValueType & m,
const ValueType & s, ErrorCode * err = 0)
ValueType GradToDeg(const ValueType & x, ErrorCode * err = 0)
* added: Parser::SetDegRadGrad(int angle) - 0 deg, 1 rad (default), 2 grad
this affects following functions (in the parser only): sin, cos, tan, cot,
asin, acos, atan, acot
* added: functions to the parser: gradtorad(grad), radtograd(rad), degtograd(deg),
degtograd(d,m,s), gradtodeg(grad)
* added: UInt::FromString, added a parametr 'after_source'
which is pointing at the end of the parsed string
* added: Int::FromString(): parameter 'const char ** after_source = 0'
if exists it's pointing at the end of the parsed string
* added: to UInt::FromString(), Int::FromString(), Big::FromString():
parameter 'bool * value_read = 0' - (if exists) tells
whether something has actually been read (at least one digit)
* added: Objects::IsDefined(const std::string & name)
returning true if such an object is defined
* removed: Big::FromString() this method doesn't longer recognize operators
for changing the base ('#' and '&')
Version 0.8.2 (2008.06.18):
* added: UInt::BitNot2() this method has been proposed by
Arek <kmicicc AnTispam users.sourceforge.net>
* changed: Int::FromInt(const Int<argument_size> & p),
Int::FromInt(sint value) (it returns zero now)
Int::operator=(uint i)
Int::Int(uint i)
* added: Int::FromUInt(const UInt<argument_size> & p),
Int::FromUInt(uint value)
and appropriate constructors and assignment
operators as well
* changed: Big::FromInt(Int<int_size> value),
* added: Big::FromUInt(UInt<int_size> value),
Big::operator=(const UInt<int_size> & value)
Big::Big(const UInt<int_size> & value)
* changed: the parser is allowed to recognize values which
begin with a dot, e.g '.5' is treated as '0.5'
* added: a method Big::FromDouble(double) which converts from
standard double into a Big
* added: uint Big::ToDouble(double&) - converting into double
* added: Big::FromBig() and an operator= and a contructor
for converting from another kind of a Big class
* added: to the parser: avg(), sum()
* added: 'decimal_point' parameter into Big::ToString(...)
* fixed: Big::operator>> didn't use TTMATH_COMMA_CHARACTER_2 macro
* added: a short form of multiplication (without the '*' character)
e.g. '5y', (it's used only if the second parameter
is a variable or function)
* changed: variables and functions are case-sensitive now
* added: variables and functions can have underline characters
in their names
* changed: 'max_digit_after_comma' in Big::ToString()
remove the -2 state
* added: 'remove_trailing_zeroes' in Big::ToString()
it's either true or false
* fixed/changed: the way of using Big::SetSign()
the method do not check whether there is a zero or not now
(even if there's a zero the method can set a sign bit)
I changed this due to some prior errors
(errors corrected in revision 17, 49 and 58)
Version 0.8.1 (2007.04.17):
* fixed: Big::PowFrac(..) didn't return a correct error code
(when 'this' was negative)
* added: Root(x; index) (and to the parser as well)
* added: macro: TTMATH_PRERELEASE_VER (can be either zero or one)
* added: UInt::MulInt(int, UInt<int another_size>::&)
* added: Big::MulUInt(uint)
* changed: Big::MulInt(sint)
* added: Big::ToUInt(uint &)
* changed: Big::ToInt(sint&)
* changed: Factorial() it uses Big::MulUInt() at the beginning
(faster now especially more on a 32bit platform)
* added: doxygen.cfg for generating a documentation from the doxygen
* changed: UInt::Rcl(uint c=0) and UInt::Rcr(uint c=0) into
UInt::Rcl2(uint bits, uint c) and UInt::Rcr2(uint bits, uint c)
now they can move more than one bit and they are only private
* fixed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c)
didn't correctly return a carry if the 'bits' were equal
to 'value_size*TTMATH_BITS_PER_UINT'
* changed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c)
into UInt::Rcl(uint bits, uint c=0) and
UInt::Rcr(uint bits, uint c=0)
they are faster now when the bits is greater than a half of
the TTMATH_BITS_PER_UINT
* changed: UInt::CompensationToLeft() it's faster now
* changed: more small changes where there were UInt::Rcl(uint c=0) and
UInt::Rcr(uint c=0) used
* changed: as the Big type uses UInt::Rcl() and UInt::Rcr() a lot then
it is much faster now (about 5-25%)
* added: ASinh(), ACosh(), ATanh() /ATgh()/, ACoth() /ACtgh()/
and to the parser as well
* added: UInt::BitAnd(), UInt::BitOr(), UInt::BitXor(), UInt::BitNot(),
Big::BitAnd(), Big::BitOr(), Big::BitXor()
* added: to the parser: bitand(), bitor(), bitxor()
/band(), bor(), bxor()/
* changed: the way of parsing operators in the mathematical parser
(the parser is not too much greedy now)
Version 0.8.0 (2007.03.28):
* added: into the parser: SetFactorialMax()
* added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
* changed: class Objects in ttmathobjects.h has been completely rewritten,
we can change the names of user-defined variables or functions,
and the names are case-sensitive now
* added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
* added: Tg(x) a wrapper for Tan(x)
* changed: CTan(x) is Cot(x) now
* added: Ctg(x) a wrapper for Cot(x)
* added: ATg(x) a wrapper for ATan(x)
* changed: ACTan(x) is ACot(x) now
* added: ACtg(x) a wrapper for ACot(x)
* added: UInt::PrintTable() (for debugging etc.)
* changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have
been rewritten, now they have 128 32bit words (it's about
1232 valid decimal digits)
* fixed: previous values from Big::SetPi() Big::SetE() and
Big::SetLn2() were not too much accurate (last 2-3 words were wrong)
* added: Big::SetLn10() (128 32bit words as well)
* added: macro TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on
32bit platforms and 64ul on 64bit platforms (128/2=64)
* added: macros TTMATH_PLATFORM32 and TTMATH_PLATFORM64
* changed: a small optimisation in UInt::Mul2Big()
* added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
* added: to samples: big.cpp, parser.cpp
* added/changes/fixed: in copy-constructors and operators= in Int,
Uint and Big (more info in the commit log)
* renamed: Big::SetDotOne() into Big::Set05()
* changes: a few small optimisations in Big
* deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
* and more small changes (look at the commit log)
Version 0.7.2 (2007.03.09):
* added: Big::Mod - the remainder from a division
* added: Big::Sgn - the 'sign' from the value (-1,0,1)
* added: global functions Mod and Sgn too
* added: checking whether a user gives a correct value of a variable or function
(user-defined variables/functions in the mathematical parser)
* added: into the parser: logical operators: > < >= <= == != && ||
* added: into the parser: logical functions: and() or() not() if()
* added: ErrorCode::err_unknown_operator when the parser couldn't read an operator
Version 0.7.1 (2007.02.27):
* fixed: the error 'overflow during printing' which was caused
by Big::FromInt(Int<int_size> value) (the sign has to be set at the end)
* fixed: many small errors
* added: ATan (arctan), ACTan (arc ctan) functions
Version 0.7.0 (2007.02.24):
* finished: support for 64bit platforms
* added: ASin (arcsin), ACos (arccos) functions
Version 0.6.4 (2007.01.29):
* fixed: the problem with a sign in the mathematical parser /-(1) was 1/
* added: UInt::AddInt and UInt::SubInt
* changed: UInt::AddOne and UInt::SubOne (much faster now)
* added: UInt::SetBitInWord
* changed: UInt::SetBit (much faster now)
UInt::AddTwoUints renamed to UInt::AddTwoInts
UInt::FindLeadingBit32 renamed to UInt::FindLeadingBitInWord
UInt::Mul64 renamed to UInt::MulTwoWords
UInt::Div64 renamed to UInt::DivTwoWords
* added: UInt::SetBitInWord
* and more small changes in UInt type
* start adding support for Amd64 (not finished yet) (added ttmathuint64.h)
Version 0.6.3 (2007.01.22):
* changed: position of arguments (x and base) in logarithm functions are swapped
* changed: it's possible to use any multiplication algorithms in the same time
(macros UINT_MUL_VERSION_'X' have gone)
* added: ExceptionInfo, ReferenceError and RuntimeError classes
* changed: the mess in macros has been cleaned up
* added: TTMATH_RELEASE macro
Version 0.6.2 (2007.01.10):
* added: New division algorithm (radix b) where b is 2^32

6
CMakeLists.txt Normal file
View File

@ -0,0 +1,6 @@
# CMake configuration for ttmath
cmake_minimum_required (VERSION 3.0)
project(ttmath)
enable_testing()
include_directories(${ttmath_SOURCE_DIR})
add_subdirectory(samples)

View File

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

49
README
View File

@ -1,26 +1,23 @@
TTMath - a bignum library for C++
TTMath is a small library which allows one to perform arithmetic operations
with big unsigned integer, big signed integer and big floating point
numbers. It provides standard mathematical operations like adding,
subtracting, multiplying, dividing etc. With the library also goes
a mathematical parser which helps you solving input formulas read directly
from a user.
TTMath is developed under the BSD licence which means that it is free
for both personal and commercial use.
The library has some technical limitations:
* there are only two platforms that are supported: x86 and x86_64,
* you can use this library only with the C++ programming language.
The main goal of the library is to allow one to use big values in the same
way as the standard types like int, float, etc. It does not need to be
compiled first because the whole library is written as the C++ templates.
This means only C++ developers can use this library and one thing they have
to do is to use 'include' directive of the preprocessor. How big the
values can be is set directly in the source code by the programmer.
Author: Tomasz Sowa <t.sowa@slimaczek.pl>
Project pages: http://ttmath.slimaczek.pl
http://sourceforge.net/projects/ttmath
A bignum library for C++
TTMath is a small library which allows one to perform arithmetic operations
with big unsigned integer, big signed integer and big floating point numbers.
It provides standard mathematical operations like adding, subtracting,
multiplying, dividing. With the library also goes a mathematical parser to
help you solving mathematical expressions.
TTMath is developed under the BSD licence which means that it is free for
both personal and commercial use.
The main goal of the library is to allow one to use big values in the same
way as the standard types like int or float. It does not need to be compiled
first because the whole library is written as the C++ templates. This means
only C++ developers can use this library and one thing they have to do is
to use 'include' directive of the preprocessor. How big the values can be
is set at compile time.
Author: Tomasz Sowa <t.sowa@ttmath.org>
WWW: http://www.ttmath.org
Contributors:
Christian Kaiser <chk@online.de>

27
constgen/Makefile Normal file
View File

@ -0,0 +1,27 @@
o = main.o
CC = clang++
CFLAGS = -O2 -DTTMATH_CONSTANTSGENERATOR
name = gen
.SUFFIXES: .cpp .o
.cpp.o:
$(CC) -c $(CFLAGS) $<
all: $(name)
$(name): $(o)
$(CC) -o $(name) -s $(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 3-Clause BSD Licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* 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 TTMATH_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 TTMATH_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;
}

File diff suppressed because it is too large Load Diff

137
makerelease.sh Executable file
View File

@ -0,0 +1,137 @@
#!/usr/bin/env bash
a=""
b=""
c=""
p=""
d=""
doxygen=""
# reading until not empty
while [ -z $a ]
do
echo -n "Major: " ; read a
done
while [ -z $b ]
do
echo -n "Minor: " ; read b;
done
while [ -z $c ]
do
echo -n "Revision: " ; read c;
done
while [ -z $p ]
do
echo -n "Prerelease? (y/n): " ; read p;
done
while [ -z $d ]
do
echo -n "Add date? (y/n): " ; read d;
done
while [ -z $doxygen ]
do
echo -n "Clean make and add to the package doxygen doc? (y/n): " ; read doxygen;
done
mkdir -p releases
package_dir_name="ttmath-$a.$b.$c"
datestr=""
if [ $p = "y" -o $p = "Y" ]
then
package_dir_name=${package_dir_name}.prerelease
fi
package_dir_name=${package_dir_name}-src
if [ $d = "y" -o $d = "Y" ]
then
datestr=`/bin/date "+%G.%m.%d"`;
package_dir_name=${package_dir_name}-$datestr
fi
dir="releases/"${package_dir_name}
package=${package_dir_name}.tar.gz
if [ -d $dir ]
then
echo "Directory $dir exists! (exiting)";
exit 1;
fi
if [ -f "releases/"${package} ] ; then
echo "File releases/${package} exists! (exiting)"
exit 1;
fi
mkdir $dir
if [ $doxygen = "y" -o $doxygen = "Y" ]
then
echo "------------------------------------------------------"
echo "creating doxygen doc"
echo "------------------------------------------------------"
rm -rf doc/doxygen
doxygen doxygen.cfg
cp -r doc $dir/
fi
echo "------------------------------------------------------"
echo "make clean in samples"
echo "------------------------------------------------------"
make -C samples clean
make -C constgen clean
echo "------------------------------------------------------"
echo "making source package"
echo "------------------------------------------------------"
mkdir $dir/ttmath
mkdir $dir/samples
mkdir $dir/res
cp ttmath/* $dir/ttmath/
cp samples/* $dir/samples/
# cmake is not ready yet (cmake will generate Makefile which overwrites our own one)
rm $dir/samples/CMakeLists.txt
cp COPYRIGHT $dir/
cp README $dir/
cp CHANGELOG $dir/
cp res/ttmath_logo.svg $dir/res/
cd releases
tar -czf $package ${package_dir_name}
echo "the package has been created to:" releases/${package}
exit 0

96
res/ttmath_logo.svg Normal file
View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="38.084499"
height="38.083"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="ttmath_logo.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="11.2"
inkscape:cx="24.511255"
inkscape:cy="17.621314"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1440"
inkscape:window-height="830"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-350.08291,-424.26987)">
<path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.625;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 369.125,424.28125 c -10.50699,0 -19.03125,8.52426 -19.03125,19.03125 0,10.50603 8.52426,19.03125 19.03125,19.03125 10.50746,0 19.03125,-8.52522 19.03125,-19.03125 0,-10.50699 -8.52379,-19.03125 -19.03125,-19.03125 z"
id="path3773" />
<path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffaa35;fill-opacity:1;stroke:none;stroke-width:1.62500000000000000;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 369.125,425.90625 c 9.62928,0 17.40625,7.77748 17.40625,17.40625 0,9.62773 -7.77697,17.40625 -17.40625,17.40625 -9.62877,0 -17.40625,-7.77852 -17.40625,-17.40625 0,-9.62877 7.77748,-17.40625 17.40625,-17.40625 z"
id="path2999-2" />
<path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 368.1875,432.65625 -0.1875,0.5 -6.34375,16.71875 -1.40625,-4 -0.5,-1.40625 -0.84375,1.25 -2.0625,3.125 1.25,0.8125 1.25,-1.875 1.5625,4.53125 0.6875,1.9375 0.71875,-1.9375 6.90625,-18.15625 8.65625,0 0,-1.5 -9.15625,0 -0.53125,0 z"
id="path3003-3"
inkscape:connector-curvature="0" />
<path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 359.84375,434.34375 0,3 -3,0 0,1.5 3,0 0,3.21875 1.5,0 0,-3.21875 3,0 0,-1.5 -3,0 0,-3 -1.5,0 z"
id="path3005-3"
inkscape:connector-curvature="0" />
<path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.9375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 371.0625,443.5625 0,0.46875 -0.125,4.6875 0,0.15625 0.125,0.15625 c 0,0 0.37411,0.46147 0.9375,0.9375 0.2817,0.23802 0.59509,0.49145 0.96875,0.6875 0.37366,0.19605 0.8013,0.32003 1.25,0.34375 0.93515,0.0491 1.77613,-0.36791 2.40625,-0.78125 0.63012,-0.41334 1.0625,-0.84375 1.0625,-0.84375 l 0.125,-0.15625 0,-0.1875 -0.0937,-5 0,-0.46875 -0.46875,0 -5.71875,0 -0.46875,0 z"
id="path3009-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccsscsccccccccc" />
<path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.9375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 377.65625,450.375 -0.0312,0.0312 -0.21875,0.125 c -2.30252,1.65271 -4.15395,1.52806 -6.1125,-0.1562 -1.78014,2.66032 -3.73192,7.25254 -4.29375,8.18745 -0.56183,0.93491 -0.17739,2.37424 -0.28125,3.375 l 0.5625,-0.0312 8.03125,-0.71875 0.125,-0.0312 0.0937,-0.0625 6.96875,-4.5625 0.1875,-0.125 0.0937,-0.0625 -0.0625,-0.3125 c 0.0108,-0.11043 0.0366,-0.43638 0,-0.96875 -0.0466,-1.03041 -0.48309,-1.60724 -0.93745,-2.24995 -0.5467,-0.58055 -1.33798,-1.08483 -2.15625,-1.5 -0.91162,-0.46254 -1.66155,-0.7891 -1.71875,-0.8125 l -0.0625,-0.0312 -0.1875,-0.0937 z"
id="path3013-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccczcccccccccccscccc" />
<path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.625;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 374.0625,438.21875 c -1.68685,0.1362 -5.3125,0.8125 -5.3125,0.8125 l -0.125,0.0312 -0.0625,0.125 -1.375,2.09375 -0.0312,0.0625 0,0.0937 0.1875,6.15625 0.0312,0.15625 0.125,0.0937 0.3125,0.21875 0.5,0.3125 -0.0312,-0.59375 -0.0937,-5.90625 c 0.081,-0.0694 0.35604,-0.32331 0.6875,-0.4375 l 0.0312,0 c 0.0323,-0.01 0.0883,0.01 0.125,0 l 1.46875,-0.0937 c 0.1093,0.60186 0.39332,1.20774 0.4812,1.8125 1.27397,-0.0782 2.40491,-0.17552 3.5031,-0.16892 1.08715,0.0103 2.17115,0.13001 3.2344,0.12517 l 0.0312,-0.6125 c 0,0 0.0422,-0.16533 0.0625,-0.28125 l 0.40625,-0.9375 c 0.004,-0.005 -0.004,-0.0267 0,-0.0312 l 0.0312,0 c 0.17093,-0.1709 0.53319,-0.25585 0.8125,-0.375 0.26159,-0.11159 0.42068,-0.28594 0.75,-0.375 l 0.0312,0 0.125,-0.0312 2.28125,-0.1875 0.0312,0 0.28125,0 0,-0.0312 0,-0.28125 0,-0.71875 0,-0.25 -0.25,-0.0625 -3.75,-0.71875 c -0.0114,-10e-4 -0.02,0.001 -0.0312,0 -1.37083,-0.13192 -2.78705,-0.1247 -4.40625,0 l -0.0312,0 -0.0312,0 z"
id="path3017-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccccccccccccccccsccccccccccccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

16
samples/CMakeLists.txt Normal file
View File

@ -0,0 +1,16 @@
# CMake configuration for ttmath/samples
# Building with Visual C++ x86_64 needs to compile the asm utilities first
if (MSVC AND "x${CMAKE_VS_PLATFORM_NAME}" STREQUAL "xx64")
set(TTMATH_MSVC64_ASM ttmathuint_x86_64_msvc.asm)
enable_language(ASM_MASM)
message(STATUS "Enabled MASM to compile '${TTMATH_MSVC64_ASM}'")
set(TTMATH_SRC_ASM ${ttmath_SOURCE_DIR}/ttmath/${TTMATH_MSVC64_ASM})
endif()
set(SAMPLES big big2 int uint parser)
foreach(sample ${SAMPLES})
add_executable(${sample} ${sample}.cpp ${TTMATH_SRC_ASM})
# Allow to run all utilities at once as a test
add_test(${sample} ${sample})
endforeach()

View File

@ -1,5 +1,6 @@
CC = g++
CFLAGS = -Wall -pedantic -s -O2 -I..
#CC = clang++
CFLAGS = -Wall -pedantic -O2 -I.. -DTTMATH_DONT_USE_WCHAR
.SUFFIXES: .cpp .o
@ -8,25 +9,29 @@ CFLAGS = -Wall -pedantic -s -O2 -I..
$(CC) -c $(CFLAGS) $<
all: uint int big parser
all: uint int big big2 parser
uint: uint.o
$(CC) -o uint $(CFLAGS) uint.o
$(CC) -o uint -s $(CFLAGS) uint.o
int: int.o
$(CC) -o int $(CFLAGS) int.o
$(CC) -o int -s $(CFLAGS) int.o
big: big.o
$(CC) -o big $(CFLAGS) big.o
$(CC) -o big -s $(CFLAGS) big.o
big2: big2.o
$(CC) -o big2 -s $(CFLAGS) big2.o
parser: parser.o
$(CC) -o parser $(CFLAGS) parser.o
$(CC) -o parser -s $(CFLAGS) parser.o
uint.o: uint.cpp
int.o: int.cpp
big.o: big.cpp
big2.o: big2.cpp
parser.o: parser.cpp
@ -36,6 +41,7 @@ clean:
rm -f uint
rm -f int
rm -f big
rm -f big2
rm -f parser
# on MS Windows can automatically be added suffixes .exe to the names of output programs
# on MS Windows suffixes .exe will be automatically added
rm -f *.exe

View File

@ -5,8 +5,10 @@
// this type has 2 words for its mantissa and 1 word for its exponent
// (on a 32bit platform one word means a word of 32 bits,
// and on a 64bit platform one word means a word of 64 bits)
// Big<exponent, mantissa>
typedef ttmath::Big<1,2> MyBig;
void SimpleCalculating(const MyBig & a, const MyBig & b)
{
@ -32,20 +34,21 @@ MyBig atemp;
if( !atemp.Add(b) )
std::cout << "a + b = " << atemp << std::endl;
else
std::cout << "a + b = (carry) " << atemp << std::endl;
std::cout << "a + b = (carry)" << std::endl;
// it have no sense to print 'atemp' (it's undefined)
atemp = a;
if( !atemp.Sub(b) )
std::cout << "a - b = " << atemp << std::endl;
else
std::cout << "a - b = (carry) " << atemp << std::endl;
std::cout << "a - b = (carry)" << std::endl;
atemp = a;
if( !atemp.Mul(b) )
std::cout << "a * b = " << atemp << std::endl;
else
std::cout << "a * b = (carry: the result is too big) " << std::endl;
// it have no sense to print 'atemp' (it's undefined)
std::cout << "a * b = (carry)" << std::endl;
atemp = a;
if( !atemp.Div(b) )
@ -55,6 +58,7 @@ MyBig atemp;
}
int main()
{
MyBig a,b;
@ -68,9 +72,8 @@ MyBig a,b;
// 'a' will have the max value which can be held in this type
a.SetMax();
// at the moment conversions from double (or float etc.) are not supported
// you cannot do that: b = 456.32f
b = "456.32";
// conversion from double
b = 456.32;
// Look at the value 'a' and the product from a+b and a-b
// Don't worry this is the nature of floating point numbers
@ -85,13 +88,13 @@ a = 123456.543456
b = 98767878.124322
a + b = 98891334.667778
a - b = -98644421.580866
a * b = 12193540837712.2708
a / b = 0.0012499665458095765
a * b = 12193540837712.27076
a / b = 0.00124996654580957646
Calculating with a carry
a = 1.624801256070839555e+646457012
b = 456.32
a + b = 1.624801256070839555e+646457012
a - b = 1.624801256070839555e+646457012
a * b = (carry: the result is too big)
a / b = 3.56066193914542329e+646457009
a = 1.6248012560666408782e+646457012
b = 456.319999999999993
a + b = 1.6248012560666408782e+646457012
a - b = 1.6248012560666408782e+646457012
a * b = (carry)
a / b = 3.560661939136222174e+646457009
*/

113
samples/big2.cpp Normal file
View File

@ -0,0 +1,113 @@
#include <ttmath/ttmath.h>
#include <iostream>
// this is a similar example to big.cpp
// but now we're using TTMATH_BITS() macro
// this macro returns how many words we need to store
// the given number of bits
// TTMATH_BITS(64)
// on a 32bit platform the macro returns 2 (2*32=64)
// on a 64bit platform the macro returns 1
// TTMATH_BITS(128)
// on a 32bit platform the macro returns 4 (4*32=128)
// on a 64bit platform the macro returns 2 (2*64=128)
// Big<exponent, mantissa>
typedef ttmath::Big<TTMATH_BITS(64), TTMATH_BITS(128)> MyBig;
// consequently on a 32bit platform we define: Big<2, 4>
// and on a 64bit platform: Big<1, 2>
// and the calculations will be the same on both platforms
void SimpleCalculating(const MyBig & a, const MyBig & b)
{
std::cout << "Simple calculating" << std::endl;
std::cout << "a = " << a << std::endl;
std::cout << "b = " << b << std::endl;
std::cout << "a + b = " << a+b << std::endl;
std::cout << "a - b = " << a-b << std::endl;
std::cout << "a * b = " << a*b << std::endl;
std::cout << "a / b = " << a/b << std::endl;
}
void CalculatingWithCarry(const MyBig & a, const MyBig & b)
{
MyBig atemp;
std::cout << "Calculating with a carry" << std::endl;
std::cout << "a = " << a << std::endl;
std::cout << "b = " << b << std::endl;
atemp = a;
if( !atemp.Add(b) )
std::cout << "a + b = " << atemp << std::endl;
else
std::cout << "a + b = (carry)" << std::endl;
// it have no sense to print 'atemp' (it's undefined)
atemp = a;
if( !atemp.Sub(b) )
std::cout << "a - b = " << atemp << std::endl;
else
std::cout << "a - b = (carry)" << std::endl;
atemp = a;
if( !atemp.Mul(b) )
std::cout << "a * b = " << atemp << std::endl;
else
std::cout << "a * b = (carry)" << std::endl;
atemp = a;
if( !atemp.Div(b) )
std::cout << "a / b = " << atemp << std::endl;
else
std::cout << "a / b = (carry or division by zero) " << std::endl;
}
int main()
{
MyBig a,b;
// conversion from 'const char *'
a = "123456.543456";
b = "98767878.124322";
SimpleCalculating(a,b);
// 'a' will have the max value which can be held in this type
a.SetMax();
// conversion from double
b = 456.32;
// Look at the value 'a' and the product from a+b and a-b
// Don't worry this is the nature of floating point numbers
CalculatingWithCarry(a,b);
}
/*
the result (the same on a 32 or 64bit platform):
Simple calculating
a = 123456.543456
b = 98767878.124322
a + b = 98891334.667778
a - b = -98644421.580866
a * b = 12193540837712.270763536832
a / b = 0.0012499665458095764605964485261668609133
Calculating with a carry
a = 2.34953455457111777368832820909595050034e+2776511644261678604
b = 456.3199999999999931787897367030382156
a + b = 2.34953455457111777368832820909595050034e+2776511644261678604
a - b = 2.34953455457111777368832820909595050034e+2776511644261678604
a * b = (carry)
a / b = 5.1488748127873374141170361292780486452e+2776511644261678601
*/

View File

@ -29,6 +29,11 @@ const char equation[] = " (34 + 24) * 123 - 34.32 ^ 6 * sin(2.56) - atan(10)";
/*
the result (on 32 bit platform):
-897705014.52573107
-897705014.525731067
*/
/*
the result (on 64 bit platform):
-897705014.5257310676097719585259773124
*/

31
tests/Makefile Normal file
View File

@ -0,0 +1,31 @@
CC = clang++
o = main.o uinttest.o
CFLAGS = -Wall -O2
ttmath = ..
name = tests
.SUFFIXES: .cpp .o
.cpp.o:
$(CC) -c $(CFLAGS) -I$(ttmath) $<
all: $(name)
$(name): $(o)
$(CC) -o $(name) -s $(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 3-Clause BSD Licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* 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 3-Clause BSD Licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* 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 3-Clause BSD Licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* 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

133
tests2/Makefile Normal file
View File

@ -0,0 +1,133 @@
#CC = g++6
#CFLAGS = -Wall -pedantic -O3 -s -I.. -Wl,-rpath=/usr/local/lib/gcc6
#CFLAGS = -Wall -pedantic -O3 -DTTMATH_NOASM -s -I.. -Wl,-rpath=/usr/local/lib/gcc6
CC = clang++
CFLAGS = -Wall -pedantic -O3 -s -I..
#CFLAGS = -Wall -pedantic -O3 -DTTMATH_NOASM -s -I..
.SUFFIXES: .cpp .o
.cpp.o:
$(CC) -c $(CFLAGS) $<
all: big_64_64 big_64_128 big_64_192 big_64_256 big_64_512 big_64_1024 big_64_2048 big_64_4096 big_128_512 big_256_1024 big_512_2048 big_128_4096
big_64_64: main.cpp
$(CC) -o big_64_64 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=64 main.cpp
big_64_128: main.cpp
$(CC) -o big_64_128 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=128 main.cpp
big_64_192: main.cpp
$(CC) -o big_64_192 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=192 main.cpp
big_64_256: main.cpp
$(CC) -o big_64_256 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=256 main.cpp
big_64_512: main.cpp
$(CC) -o big_64_512 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=512 main.cpp
big_64_1024: main.cpp
$(CC) -o big_64_1024 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=1024 main.cpp
big_64_2048: main.cpp
$(CC) -o big_64_2048 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=2048 main.cpp
big_64_4096: main.cpp
$(CC) -o big_64_4096 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=4096 main.cpp
big_128_512: main.cpp
$(CC) -o big_128_512 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=128 -DTTMATH_TEST_BIG_MANTISSA=512 main.cpp
big_256_1024: main.cpp
$(CC) -o big_256_1024 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=256 -DTTMATH_TEST_BIG_MANTISSA=1024 main.cpp
big_512_2048: main.cpp
$(CC) -o big_512_2048 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=512 -DTTMATH_TEST_BIG_MANTISSA=2048 main.cpp
big_128_4096: main.cpp
$(CC) -o big_128_4096 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=128 -DTTMATH_TEST_BIG_MANTISSA=4096 main.cpp
test: all
@echo "****************************************************************************"
@echo "making tests for exponent=64 and mantissa=64"
@echo "****************************************************************************"
cat tests.txt | xargs -S 4096 -I foo ./big_64_64 "foo" | tee big_64_64.out
@echo "****************************************************************************"
@echo "making tests for exponent=64 and mantissa=128"
@echo "****************************************************************************"
cat tests.txt | xargs -S 4096 -I foo ./big_64_128 "foo" | tee big_64_128.out
@echo "****************************************************************************"
@echo "making tests for exponent=64 and mantissa=192"
@echo "****************************************************************************"
cat tests.txt | xargs -S 4096 -I foo ./big_64_192 "foo" | tee big_64_192.out
@echo "****************************************************************************"
@echo "making tests for exponent=64 and mantissa=256"
@echo "****************************************************************************"
cat tests.txt | xargs -S 4096 -I foo ./big_64_256 "foo" | tee big_64_256.out
@echo "****************************************************************************"
@echo "making tests for exponent=64 and mantissa=512"
@echo "****************************************************************************"
cat tests.txt | xargs -S 4096 -I foo ./big_64_512 "foo" | tee big_64_512.out
@echo "****************************************************************************"
@echo "making tests for exponent=64 and mantissa=1024"
@echo "****************************************************************************"
cat tests.txt | xargs -S 4096 -I foo ./big_64_1024 "foo" | tee big_64_1024.out
@echo "****************************************************************************"
@echo "making tests for exponent=64 and mantissa=2048"
@echo "****************************************************************************"
cat tests.txt | xargs -S 4096 -I foo ./big_64_2048 "foo" | tee big_64_2048.out
@echo "****************************************************************************"
@echo "making tests for exponent=64 and mantissa=4096"
@echo "****************************************************************************"
cat tests.txt | xargs -S 4096 -I foo ./big_64_4096 "foo" | tee big_64_4096.out
@echo "****************************************************************************"
@echo "making tests for exponent=128 and mantissa=512"
@echo "****************************************************************************"
cat tests.txt | xargs -S 4096 -I foo ./big_128_512 "foo" | tee big_128_512.out
@echo "****************************************************************************"
@echo "making tests for exponent=128 and mantissa=4096"
@echo "****************************************************************************"
cat tests.txt | xargs -S 4096 -I foo ./big_128_4096 "foo" | tee big_128_4096.out
@echo "****************************************************************************"
@echo "making tests for exponent=256 and mantissa=1024"
@echo "****************************************************************************"
cat tests.txt | xargs -S 4096 -I foo ./big_256_1024 "foo" | tee big_256_1024.out
@echo "****************************************************************************"
@echo "making tests for exponent=512 and mantissa=2048"
@echo "****************************************************************************"
cat tests.txt | xargs -S 4096 -I foo ./big_512_2048 "foo" | tee big_512_2048.out
./check_files.sh
clean:
rm -f *.out
rm -f big_64_64 big_64_128 big_64_192 big_64_256 big_64_512 big_64_1024 big_64_2048 big_64_4096 big_128_512 big_256_1024 big_512_2048 big_128_4096
# on MS Windows suffixes .exe will be automatically added
rm -f *.exe

2161
tests2/big_128_4096.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_128_512.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_256_1024.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_512_2048.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_64_1024.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_64_128.expected Normal file

File diff suppressed because it is too large Load Diff

2161
tests2/big_64_192.expected Normal file

File diff suppressed because it is too large Load Diff

2161
tests2/big_64_2048.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_64_256.expected Normal file

File diff suppressed because it is too large Load Diff

2161
tests2/big_64_4096.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_64_512.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_64_64.expected Normal file

File diff suppressed because it is too large Load Diff

31
tests2/check_files.sh Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh
was_error=0
for expected in *.expected ; do
out=`basename $expected .expected`.out
if [ -f $out ] ; then
diff -u $out $expected
if [ `diff -u $out $expected | wc -l` -ne 0 ] ; then
was_error=1
fi
else
echo "there is no file: $out"
was_error=1
fi
done
if [ $was_error -eq 0 ] ; then
echo "****************************************************************************"
echo " congratulations: all tests passed successfully"
echo "****************************************************************************"
else
echo "****************************************************************************"
echo " error: not all tests passed successfully"
echo "****************************************************************************"
fi

39
tests2/main.cpp Normal file
View File

@ -0,0 +1,39 @@
#include <ttmath/ttmath.h>
#include <iostream>
int main(int argc, char ** argv)
{
typedef ttmath::Big<TTMATH_BITS(TTMATH_TEST_BIG_EXPONENT), TTMATH_BITS(TTMATH_TEST_BIG_MANTISSA)> MyBig;
ttmath::Parser<MyBig> parser;
std::string all_input;
for(int i=1 ; i<argc ; ++i)
{
if( i > 1 )
all_input += ' ';
all_input += argv[i];
}
std::cout << all_input << " = ";
ttmath::ErrorCode err = parser.Parse(all_input);
if( err == ttmath::err_ok )
{
for(size_t i=0 ; i < parser.stack.size() ; ++i)
{
if( i > 0 )
std::cout << " ; ";
std::cout << parser.stack[i].value;
}
std::cout << std::endl;
}
else
{
std::cout << "error: " << static_cast<int>(err) << std::endl;
}
return 0;
}

2161
tests2/tests.txt Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

419
ttmath/ttmathdec.h Normal file
View File

@ -0,0 +1,419 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the 3-Clause BSD Licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2012, 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 headerfilettmathdec
#define headerfilettmathdec
#include "ttmathtypes.h"
#include "ttmaththreads.h"
#include "ttmathuint.h"
namespace ttmath
{
template<uint value_size, uint dec_digits>
class Dec
{
public:
UInt<value_size> value;
unsigned char info;
/*!
Sign
the mask of a bit from 'info' which means that there is a sign
(when the bit is set)
*/
#define TTMATH_DEC_SIGN 128
/*!
Not a number
if this bit is set that there is not a valid number
*/
#define TTMATH_DEC_NAN 64
Dec()
{
info = TTMATH_DEC_NAN;
}
Dec(const char * s)
{
info = TTMATH_DEC_NAN;
FromString(s);
}
Dec<value_size, dec_digits> & operator=(const char * s)
{
FromString(s);
return *this;
}
uint FromString(const char * s, const char ** after_source = 0, bool * value_read = 0)
{
return FromStringBase(s, after_source, value_read);
}
void ToString(std::string & result) const
{
ToStringBase(result);
}
/*!
this method clears a specific bit in the 'info' variable
bit is one of:
*/
void ClearInfoBit(unsigned char bit)
{
info = info & (~bit);
}
/*!
this method sets a specific bit in the 'info' variable
bit is one of:
*/
void SetInfoBit(unsigned char bit)
{
info = info | bit;
}
/*!
this method returns true if a specific bit in the 'info' variable is set
bit is one of:
*/
bool IsInfoBit(unsigned char bit) const
{
return (info & bit) != 0;
}
bool IsNan() const
{
return IsInfoBit(TTMATH_DEC_NAN);
}
bool IsSign() const
{
return IsInfoBit(TTMATH_DEC_SIGN);
}
/*!
this method sets the sign
e.g.
-1 -> -1
2 -> -2
we do not check whether there is a zero or not, if you're using this method
you must be sure that the value is (or will be afterwards) different from zero
*/
void SetSign()
{
SetInfoBit(TTMATH_DEC_SIGN);
}
void SetNaN()
{
SetInfoBit(TTMATH_DEC_NAN);
}
void Abs()
{
ClearInfoBit(TTMATH_DEC_SIGN);
}
uint Add(const Dec<value_size, dec_digits> & arg)
{
uint c = 0;
if( IsSign() == arg.IsSign() )
{
c += value.Add(arg.value);
}
else
{
bool is_sign;
if( value > arg.value )
{
is_sign = IsSign();
value.Sub(arg.value);
}
else
{
is_sign = arg.IsSign();
UInt<value_size> temp(this->value);
value = arg.value;
value.Sub(temp);
}
is_sign ? SetSign() : Abs();
}
if( c )
SetNaN();
return (c==0)? 0 : 1;
}
/*
uint Sub(const Dec<value_size, dec_digits> & arg)
{
}
*/
private:
#ifndef TTMATH_MULTITHREADS
/*!
*/
void SetMultipler(UInt<value_size> & result)
{
// this guardian is initialized before the program runs (static POD type)
static int guardian = 0;
static UInt<value_size> multipler;
if( guardian == 0 )
{
multipler = 10;
multipler.Pow(dec_digits);
guardian = 1;
}
result = multipler;
}
#else
/*!
*/
void SetMultipler(UInt<value_size> & result)
{
// this guardian is initialized before the program runs (static POD type)
volatile static sig_atomic_t guardian = 0;
static UInt<value_size> * pmultipler;
// double-checked locking
if( guardian == 0 )
{
ThreadLock thread_lock;
// locking
if( thread_lock.Lock() )
{
static UInt<value_size> multipler;
if( guardian == 0 )
{
pmultipler = &multipler;
multipler = 10;
multipler.Pow(dec_digits);
guardian = 1;
}
}
else
{
// there was a problem with locking, we store the result directly in 'result' object
result = 10;
result.Pow(dec_digits);
return;
}
// automatically unlocking
}
result = *pmultipler;
}
#endif
/*!
an auxiliary method for converting from a string
*/
template<class char_type>
uint FromStringBase(const char_type * s, const char_type ** after_source = 0, bool * value_read = 0)
{
UInt<value_size> multipler;
const char_type * after;
uint c = 0;
info = 0;
Misc::SkipWhiteCharacters(s);
if( *s == '-' )
{
s += 1;
SetSign();
}
else
if( *s == '+' )
{
s += 1;
}
c += value.FromString(s, 10, &after, value_read);
if( after_source )
*after_source = after;
SetMultipler(multipler);
c += value.Mul(multipler);
if( *after == '.' )
c += FromStringBaseAfterComma(after+1, after_source);
if( c )
SetInfoBit(TTMATH_DEC_NAN);
return (c==0)? 0 : 1;
}
template<class char_type>
uint FromStringBaseAfterComma(const char_type * s, const char_type ** after_source = 0, bool * value_read = 0)
{
UInt<value_size> temp;
UInt<value_size> multipler;
sint z;
uint c = 0;
size_t i = dec_digits;
SetMultipler(multipler);
for( ; i>0 && (z=Misc::CharToDigit(*s, 10)) != -1 ; --i, ++s )
{
multipler.DivInt(10);
temp.SetZero();
if( value_read )
*value_read = true;
if( c == 0 )
{
temp.table[0] = z;
c += temp.Mul(multipler);
c += value.Add(temp);
}
}
if( i == 0 && (z=Misc::CharToDigit(*s, 10)) != -1 && z >= 5 )
c += value.AddOne();
if( after_source )
{
while( (z=Misc::CharToDigit(*s, 10)) != -1 )
s += 1;
*after_source = s;
}
return c;
}
template<class string_type>
void ToStringBase(string_type & result) const
{
if( IsNan() )
{
result = "NaN";
return;
}
value.ToStringBase(result, 10, IsSign());
if( dec_digits > 0 )
{
size_t size = result.size();
if( IsSign() && size > 0 )
size -= 1;
if( dec_digits >= size )
{
size_t zeroes = dec_digits - size + 1;
size_t start = IsSign() ? 1 : 0;
result.insert(start, zeroes, '0');
}
result.insert(result.end() - dec_digits, '.');
}
}
};
} // namespace
#endif

File diff suppressed because it is too large Load Diff

250
ttmath/ttmathmisc.h Normal file
View File

@ -0,0 +1,250 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the 3-Clause BSD Licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2006-2010, 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 headerfilettmathmisc
#define headerfilettmathmisc
/*!
\file ttmathmisc.h
\brief some helpful functions
*/
#include <string>
namespace ttmath
{
/*!
some helpful functions
*/
class Misc
{
public:
/*
*
* AssignString(result, str)
* result = str
*
*/
/*!
result = str
*/
static void AssignString(std::string & result, const char * str)
{
result = str;
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
result = str
*/
static void AssignString(std::wstring & result, const char * str)
{
result.clear();
for( ; *str ; ++str )
result += *str;
}
/*!
result = str
*/
static void AssignString(std::wstring & result, const std::string & str)
{
return AssignString(result, str.c_str());
}
/*!
result = str
*/
static void AssignString(std::string & result, const wchar_t * str)
{
result.clear();
for( ; *str ; ++str )
result += static_cast<char>(*str);
}
/*!
result = str
*/
static void AssignString(std::string & result, const std::wstring & str)
{
return AssignString(result, str.c_str());
}
#endif
/*
*
* AddString(result, str)
* result += str
*
*/
/*!
result += str
*/
static void AddString(std::string & result, const char * str)
{
result += str;
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
result += str
*/
static void AddString(std::wstring & result, const char * str)
{
for( ; *str ; ++str )
result += *str;
}
#endif
/*
this method omits any white characters from the string
char_type is char or wchar_t
*/
template<class char_type>
static void SkipWhiteCharacters(const char_type * & c)
{
// 13 is at the end in a DOS text file (\r\n)
while( (*c==' ' ) || (*c=='\t') || (*c==13 ) || (*c=='\n') )
++c;
}
/*!
this static method converts one character into its value
for example:
- 1 -> 1
- 8 -> 8
- A -> 10
- f -> 15
this method don't check whether c is correct or not
*/
static uint CharToDigit(uint c)
{
if(c>='0' && c<='9')
return c-'0';
if(c>='a' && c<='z')
return c-'a'+10;
return c-'A'+10;
}
/*!
this method changes a character 'c' into its value
(if there can't be a correct value it returns -1)
for example:
- c=2, base=10 -> function returns 2
- c=A, base=10 -> function returns -1
- c=A, base=16 -> function returns 10
*/
static sint CharToDigit(uint c, uint base)
{
if( c>='0' && c<='9' )
c=c-'0';
else
if( c>='a' && c<='z' )
c=c-'a'+10;
else
if( c>='A' && c<='Z' )
c=c-'A'+10;
else
return -1;
if( c >= base )
return -1;
return sint(c);
}
/*!
this method converts a digit into a char
digit should be from <0,F>
(we don't have to get a base)
for example:
- 1 -> 1
- 8 -> 8
- 10 -> A
- 15 -> F
*/
static uint DigitToChar(uint digit)
{
if( digit < 10 )
return digit + '0';
return digit - 10 + 'A';
}
}; // struct Misc
}
#endif

View File

@ -1,11 +1,11 @@
/*
* This file is a part of TTMath Mathematical Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* and is distributed under the 3-Clause BSD Licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2006-2008, Tomasz Sowa
* Copyright (c) 2006-2017, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -44,12 +44,13 @@
\brief Mathematic functions.
*/
#include "ttmathtypes.h"
#include <string>
#include <vector>
#include <list>
#include <map>
#include "ttmathtypes.h"
#include "ttmathmisc.h"
namespace ttmath
@ -73,13 +74,14 @@ public:
struct Item
{
// name of a variable of a function
// internally we store variables and funcions as std::string (not std::wstring even when wide characters are used)
std::string value;
// number of parameters required by the function
// (if there's a variable this 'param' is ignored)
int param;
Item() {}
Item() { param = 0; }
Item(const std::string & v, int p) : value(v), param(p) {}
};
@ -112,7 +114,8 @@ public:
/*!
this method returns true if the name can be as a name of an object
*/
static bool IsNameCorrect(const std::string & name)
template<class string_type>
static bool IsNameCorrect(const string_type & name)
{
if( name.empty() )
return false;
@ -120,7 +123,7 @@ public:
if( !CorrectCharacter(name[0], false) )
return false;
std::string::const_iterator i=name.begin();
typename string_type::const_iterator i = name.begin();
for(++i ; i!=name.end() ; ++i)
if( !CorrectCharacter(*i, true) )
@ -130,6 +133,42 @@ 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;
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method returns true if such an object is defined (name exists)
*/
bool IsDefined(const std::wstring & name)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return false;
Misc::AssignString(str_tmp1, name);
return IsDefined(str_tmp1);
}
#endif
/*!
this method adds one object (variable of function) into the table
*/
@ -150,6 +189,27 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method adds one object (variable of function) into the table
*/
ErrorCode Add(const std::wstring & name, const std::wstring & value, int param = 0)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
Misc::AssignString(str_tmp2, value);
return Add(str_tmp1, str_tmp2, param);
}
#endif
/*!
this method returns 'true' if the table is empty
*/
@ -207,6 +267,28 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method changes the value and the number of parameters for a specific object
*/
ErrorCode EditValue(const std::wstring & name, const std::wstring & value, int param = 0)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
Misc::AssignString(str_tmp2, value);
return EditValue(str_tmp1, str_tmp2, param);
}
#endif
/*!
this method changes the name of a specific object
*/
@ -238,6 +320,29 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method changes the name of a specific object
*/
ErrorCode EditName(const std::wstring & old_name, const std::wstring & new_name)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, old_name);
Misc::AssignString(str_tmp2, new_name);
return EditName(str_tmp1, str_tmp2);
}
#endif
/*!
this method deletes an object
*/
@ -257,8 +362,29 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method sets the value of a specific object
this method deletes an object
*/
ErrorCode Delete(const std::wstring & name)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
return Delete(str_tmp1);
}
#endif
/*!
this method gets the value of a specific object
*/
ErrorCode GetValue(const std::string & name, std::string & value) const
{
@ -279,8 +405,30 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method sets the value of a specific object
this method gets the value of a specific object
*/
ErrorCode GetValue(const std::wstring & name, std::wstring & value)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
ErrorCode err = GetValue(str_tmp1, str_tmp2);
Misc::AssignString(value, str_tmp2);
return err;
}
#endif
/*!
this method gets the value of a specific object
(this version is used for not copying the whole string)
*/
ErrorCode GetValue(const std::string & name, const char ** value) const
@ -302,8 +450,29 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method sets the value and the number of parameters
this method gets the value of a specific object
(this version is used for not copying the whole string)
*/
ErrorCode GetValue(const std::wstring & name, const char ** value)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
return GetValue(str_tmp1, value);
}
#endif
/*!
this method gets the value and the number of parameters
of a specific object
*/
ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const
@ -315,7 +484,7 @@ public:
if( i == table.end() )
{
value.empty();
value.clear();
*param = 0;
return err_unknown_object;
}
@ -327,6 +496,29 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method gets the value and the number of parameters
of a specific object
*/
ErrorCode GetValueAndParam(const std::wstring & name, std::wstring & value, int * param)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
ErrorCode err = GetValueAndParam(str_tmp1, str_tmp2, param);
Misc::AssignString(value, str_tmp2);
return err;
}
#endif
/*!
this method sets the value and the number of parameters
of a specific object
@ -353,6 +545,31 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method sets the value and the number of parameters
of a specific object
(this version is used for not copying the whole string
but in fact we make one copying during AssignString())
*/
ErrorCode GetValueAndParam(const std::wstring & name, const char ** value, int * param)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
return GetValueAndParam(str_tmp1, value, param);
}
#endif
/*!
this method returns a pointer into the table
*/
@ -365,6 +582,7 @@ public:
private:
Table table;
std::string str_tmp1, str_tmp2;
}; // end of class Objects
@ -411,11 +629,11 @@ public:
/*!
default constructor
default max size of the History's container is 10 items
default max size of the History's container is 15 items
*/
History()
{
buffer_max_size = 10;
buffer_max_size = 15;
}
@ -472,10 +690,121 @@ public:
return false;
}
/*!
this methods deletes an item
we assume that there is only one item with the 'key'
(this methods removes the first one)
*/
bool Remove(const ValueType & key)
{
typename buffer_type::iterator i = buffer.begin();
for( ; i != buffer.end() ; ++i )
{
if( i->key == key )
{
buffer.erase(i);
return true;
}
}
return false;
}
}; // end of class History
/*!
this is an auxiliary class used when calculating Gamma() or Factorial()
in multithreaded environment you can provide an object of this class to
the Gamma() or Factorial() function, e.g;
typedef Big<1, 3> MyBig;
MyBig x = 123456;
CGamma<MyBig> cgamma;
std::cout << Gamma(x, cgamma);
each thread should have its own CGamma<> object
in a single-thread environment a CGamma<> object is a static variable
and you don't have to explicitly use it, e.g.
typedef Big<1, 3> MyBig;
MyBig x = 123456;
std::cout << Gamma(x);
*/
template<class ValueType>
struct CGamma
{
/*!
this table holds factorials
1
1
2
6
24
120
720
.......
*/
std::vector<ValueType> fact;
/*!
this table holds Bernoulli numbers
1
-0.5
0.166666666666666666666666667
0
-0.0333333333333333333333333333
0
0.0238095238095238095238095238
0
-0.0333333333333333333333333333
0
0.075757575757575757575757576
.....
*/
std::vector<ValueType> bern;
/*!
here we store some calculated values
(this is for speeding up, if the next argument of Gamma() or Factorial()
is in the 'history' then the result we are not calculating but simply
return from the 'history' object)
*/
History<ValueType> history;
/*!
this method prepares some coefficients: factorials and Bernoulli numbers
stored in 'fact' and 'bern' objects
how many values should be depends on the size of the mantissa - if
the mantissa is larger then we must calculate more values
for a mantissa which consists of 256 bits (8 words on a 32bit platform)
we have to calculate about 30 values (the size of fact and bern will be 30),
and for a 2048 bits mantissa we have to calculate 306 coefficients
you don't have to call this method, these coefficients will be automatically calculated
when they are needed
you must note that calculating these coefficients is a little time-consuming operation,
(especially when the mantissa is large) and first call to Gamma() or Factorial()
can take more time than next calls, and in the end this is the point when InitAll()
comes in handy: you can call this method somewhere at the beginning of your program
*/
void InitAll();
// definition is in ttmath.h
};
} // namespace

File diff suppressed because it is too large Load Diff

252
ttmath/ttmaththreads.h Normal file
View File

@ -0,0 +1,252 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the 3-Clause BSD Licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* 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 headerfilettmaththreads
#define headerfilettmaththreads
#include "ttmathtypes.h"
#ifdef TTMATH_WIN32_THREADS
#include <windows.h>
#include <cstdio>
#endif
#ifdef TTMATH_POSIX_THREADS
#include <pthread.h>
#endif
/*!
\file ttmaththreads.h
\brief Some objects used in multithreads environment
*/
namespace ttmath
{
#ifdef TTMATH_WIN32_THREADS
/*
we use win32 threads
*/
/*!
in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
somewhere in *.cpp file
(at the moment in win32 this macro does nothing)
*/
#define TTMATH_MULTITHREADS_HELPER
/*!
objects of this class are used to synchronize
*/
class ThreadLock
{
HANDLE mutex_handle;
void CreateName(char * buffer) const
{
#ifdef _MSC_VER
#pragma warning (disable : 4996)
// warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead.
#endif
sprintf(buffer, "TTMATH_LOCK_%ul", (unsigned long)GetCurrentProcessId());
#ifdef _MSC_VER
#pragma warning (default : 4996)
#endif
}
public:
bool Lock()
{
char buffer[50];
CreateName(buffer);
mutex_handle = CreateMutexA(0, false, buffer);
if( mutex_handle == 0 )
return false;
WaitForSingleObject(mutex_handle, INFINITE);
return true;
}
ThreadLock()
{
mutex_handle = 0;
}
~ThreadLock()
{
if( mutex_handle != 0 )
{
ReleaseMutex(mutex_handle);
CloseHandle(mutex_handle);
}
}
};
#endif // #ifdef TTMATH_WIN32_THREADS
#ifdef TTMATH_POSIX_THREADS
/*
we use posix threads
*/
/*!
in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
somewhere in *.cpp file
(this macro defines a pthread_mutex_t object used by TTMath library)
*/
#define TTMATH_MULTITHREADS_HELPER \
namespace ttmath \
{ \
pthread_mutex_t ttmath_mutex = PTHREAD_MUTEX_INITIALIZER; \
}
/*!
ttmath_mutex will be defined by TTMATH_MULTITHREADS_HELPER macro
*/
extern pthread_mutex_t ttmath_mutex;
/*!
\brief objects of this class are used to synchronize
this is a simple skeleton of a program in multithreads environment:
#define TTMATH_MULTITHREADS
#include<ttmath/ttmath.h>
TTMATH_MULTITHREADS_HELPER
int main()
{
[...]
}
make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file)
use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope)
*/
class ThreadLock
{
public:
/*!
lock the current thread
it uses a global mutex created by TTMATH_MULTITHREADS_HELPER macro
*/
bool Lock()
{
if( pthread_mutex_lock(&ttmath_mutex) != 0 )
return false;
return true;
}
~ThreadLock()
{
pthread_mutex_unlock(&ttmath_mutex);
}
};
#endif // #ifdef TTMATH_POSIX_THREADS
#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
/*!
we don't use win32 and pthreads
*/
/*!
*/
#define TTMATH_MULTITHREADS_HELPER
/*!
objects of this class are used to synchronize
actually we don't synchronize, the method Lock() returns always 'false'
*/
class ThreadLock
{
public:
bool Lock()
{
return false;
}
};
#endif // #if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
} // namespace
#endif

View File

@ -1,11 +1,11 @@
/*
* This file is a part of TTMath Mathematical Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* This file is a part of TTMath Bignum Library
* and is distributed under the 3-Clause BSD Licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2006-2008, Tomasz Sowa
* Copyright (c) 2006-2019, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -54,63 +54,123 @@
#include <stdexcept>
#include <sstream>
#include <vector>
/*!
the version of the library
TTMATH_PRERELEASE_VER is either zero or one
if zero that means this is the release version of the library
*/
#define TTMATH_MAJOR_VER 0
#define TTMATH_MINOR_VER 8
#define TTMATH_REVISION_VER 2
#define TTMATH_PRERELEASE_VER 0
/*!
TTMATH_DEBUG
this macro enables further testing during writing your code
you don't have to define it in a release mode
if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
are set as well and these macros can throw an exception if a condition in it
is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
TTMATH_RELEASE
if you are confident that your code is perfect you can define TTMATH_RELEASE
macro for example by using -D option in gcc
gcc -DTTMATH_RELEASE -o myprogram myprogram.cpp
or by defining this macro in your code before using any header files of this library
if TTMATH_RELEASE is not set then TTMATH_DEBUG is set
*/
#ifndef TTMATH_RELEASE
#define TTMATH_DEBUG
#ifndef _MSC_VER
#include <stdint.h>
// for uint64_t and int64_t on a 32 bit platform
#endif
/*!
the major version of the library
the version present to the end user is constructed in this way:
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
*/
#define TTMATH_MAJOR_VER 0
/*!
the minor version of the library
the version present to the end user is constructed in this way:
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
*/
#define TTMATH_MINOR_VER 9
/*!
the revision version of the library
the version present to the end user is constructed in this way:
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
*/
#define TTMATH_REVISION_VER 4
/*!
TTMATH_PRERELEASE_VER is either zero or one
zero means that this is the release version of the library
(one means something like beta)
the version present to the end user is constructed in this way:
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
*/
#define TTMATH_PRERELEASE_VER 1
/*!
you can define a platform explicitly by defining either
TTMATH_PLATFORM32 or TTMATH_PLATFORM64 macro
*/
#if !defined TTMATH_PLATFORM32 && !defined TTMATH_PLATFORM64
#if !defined _M_X64 && !defined __x86_64__
/*
other platforms than x86 and amd64 are not recognized at the moment
so you should set TTMATH_PLATFORMxx manually
*/
// we're using a 32bit platform
#define TTMATH_PLATFORM32
#else
// we're using a 64bit platform
#define TTMATH_PLATFORM64
#endif
#endif
/*!
asm version of the library is available by default only for:
x86 and amd64 platforms and for Microsoft Visual and GCC compilers
but you can force using asm version (the same asm as for Microsoft Visual)
by defining TTMATH_FORCEASM macro
you have to be sure that your compiler accept such an asm format
*/
#ifndef TTMATH_FORCEASM
#if !defined __i386__ && !defined _X86_ && !defined _M_IX86 && !defined __x86_64__ && !defined _M_X64
/*!
x86 architecture:
__i386__ defined by GNU C
_X86_ defined by MinGW32
_M_IX86 defined by Visual Studio, Intel C/C++, Digital Mars and Watcom C/C++
amd64 architecture:
__x86_64__ defined by GNU C, CLANG (LLVM) and Sun Studio
_M_X64 defined by Visual Studio
asm version is available only for x86 or amd64 platforms
*/
#define TTMATH_NOASM
#endif
#if !defined _MSC_VER && !defined __GNUC__
/*!
another compilers than MS VC or GCC or CLANG (LLVM) by default use no asm version
(CLANG defines __GNUC__ too)
*/
#define TTMATH_NOASM
#endif
#endif
namespace ttmath
{
#if !defined _M_X64 && !defined __x86_64__
/*!
we're using a 32bit platform
*/
#define TTMATH_PLATFORM32
#else
/*!
we're using a 64bit platform
*/
#define TTMATH_PLATFORM64
#endif
#ifdef TTMATH_PLATFORM32
@ -120,6 +180,21 @@ namespace ttmath
typedef unsigned int uint;
typedef signed int sint;
/*!
on 32 bit platform ulint and slint will be equal 64 bits
*/
#ifdef _MSC_VER
// long long on MS Windows (Visual and GCC mingw compilers) have 64 bits
// stdint.h is not available on Visual Studio prior to VS 2010 version
typedef unsigned long long int ulint;
typedef signed long long int slint;
#else
// we do not use 'long' here because there is a difference in unix and windows
// environments: in unix 'long' has 64 bits but in windows it has only 32 bits
typedef uint64_t ulint;
typedef int64_t slint;
#endif
/*!
how many bits there are in the uint type
*/
@ -141,15 +216,36 @@ namespace ttmath
which are kept in built-in variables for a Big<> type
(these variables are defined in ttmathbig.h)
*/
#define TTMATH_BUILTIN_VARIABLES_SIZE 128u
#define TTMATH_BUILTIN_VARIABLES_SIZE 256u
/*!
this macro returns the number of machine words
capable to hold min_bits bits
e.g. TTMATH_BITS(128) returns 4
*/
#define TTMATH_BITS(min_bits) ((min_bits-1)/32 + 1)
#else
#ifdef _MSC_VER
/* in VC 'long' type has 32 bits, __int64 is VC extension */
typedef unsigned __int64 uint;
typedef signed __int64 sint;
#else
/*!
on 64bit platforms one word (uint, sint) will be equal 64bits
*/
typedef uint64_t uint;
/*!
on 64bit platforms one word (uint, sint) will be equal 64bits
*/
typedef int64_t sint;
#endif
/*!
on 64bit platforms one word (uint, sint) will be equal 64bits
on 64bit platforms we do not define ulint and slint
*/
typedef unsigned long uint;
typedef signed long sint;
/*!
how many bits there are in the uint type
@ -172,29 +268,30 @@ namespace ttmath
which are kept in built-in variables for a Big<> type
(these variables are defined in ttmathbig.h)
*/
#define TTMATH_BUILTIN_VARIABLES_SIZE 64ul
#define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
/*!
this macro returns the number of machine words
capable to hold min_bits bits
e.g. TTMATH_BITS(128) returns 2
*/
#define TTMATH_BITS(min_bits) ((min_bits-1)/64 + 1)
#endif
}
#if defined(TTMATH_MULTITHREADS) && !defined(TTMATH_MULTITHREADS_NOSYNC)
#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
/*!
characters which represent the comma operator
#if defined(_WIN32)
#define TTMATH_WIN32_THREADS
#elif defined(unix) || defined(__unix__) || defined(__unix)
#define TTMATH_POSIX_THREADS
#endif
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing (default, can be overwritten in ToString() function)
TTMATH_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character
that means you can input values for example 1.2345 and 1,2345 as well
if you don't want it just put 0 there e.g.
#define TTMATH_COMMA_CHARACTER_2 0
then only TTMATH_COMMA_CHARACTER_1 will be used
don't put there any special character which is used by the parser
(for example a semicolon ';' shouldn't be there)
*/
#define TTMATH_COMMA_CHARACTER_1 '.'
#define TTMATH_COMMA_CHARACTER_2 ','
#endif
#endif
@ -214,10 +311,59 @@ namespace ttmath
/*!
this is a limit when calculating Karatsuba multiplication
if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
the Karatsuba algorithm will use standard schoolbook multiplication
*/
#ifdef TTMATH_DEBUG_LOG
// if TTMATH_DEBUG_LOG is defined then we should use the same size regardless of the compiler
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
#else
#ifdef __GNUC__
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
#else
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
#endif
#endif
/*!
this is a special value used when calculating the Gamma(x) function
if x is greater than this value then the Gamma(x) will be calculated using
some kind of series
don't use smaller values than about 100
*/
#define TTMATH_GAMMA_BOUNDARY 2000
namespace ttmath
{
/*!
lib type codes:
- asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
- asm_gcc_32 - with asm code designed for GCC (32 bits)
- asm_vc_64 - with asm for VC (64 bit)
- asm_gcc_64 - with asm for GCC (64 bit)
- no_asm_32 - pure C++ version (32 bit) - without any asm code
- no_asm_64 - pure C++ version (64 bit) - without any asm code
*/
enum LibTypeCode
{
asm_vc_32 = 0,
asm_gcc_32,
asm_vc_64,
asm_gcc_64,
no_asm_32,
no_asm_64
};
/*!
error codes
*/
@ -248,11 +394,142 @@ namespace ttmath
err_object_exists,
err_unknown_object,
err_still_calculating,
err_too_big_factorial,
err_in_short_form_used_function
err_in_short_form_used_function,
err_percent_from,
err_assignment_requires_variable
};
/*!
this struct is used when converting to/from a string
/temporarily only in Big::ToString() and Big::FromString()/
*/
struct Conv
{
/*!
base (radix) on which the value will be shown (or read)
default: 10
*/
uint base;
/*!
used only in Big::ToString()
if true the value will be always shown in the scientific mode, e.g: 123e+30
default: false
*/
bool scient;
/*!
used only in Big::ToString()
if scient is false then the value will be printed in the scientific mode
only if the exponent is greater than scien_from
default: 15
*/
sint scient_from;
/*!
if 'base_round' is true and 'base' is different from 2, 4, 8, or 16
and the result value is not an integer then we make an additional rounding
(after converting the last digit from the result is skipped)
default: true
e.g.
Conv c;
c.base_round = false;
Big<1, 1> a = "0.1"; // decimal input
std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999
*/
bool base_round;
/*!
used only in Big::ToString()
tells how many digits after comma are possible
default: -1 which means all digits are printed
set it to zero if you want integer value only
for example when the value is:
12.345678 and 'round' is 4
then the result will be
12.3457 (the last digit was rounded)
*/
sint round;
/*!
if true that not mattered digits in the mantissa will be cut off
(zero characters at the end -- after the comma operator)
e.g. 1234,78000 will be: 1234,78
default: true
*/
bool trim_zeroes;
/*!
the main comma operator (used when reading and writing)
default is a dot '.'
*/
uint comma;
/*!
additional comma operator (used only when reading)
if you don't want it just set it to zero
default is a comma ','
this allowes you to convert from a value:
123.45 as well as from 123,45
*/
uint comma2;
/*!
it sets the character which is used for grouping
if group=' ' then: 1234,56789 will be printed as: 1 234,567 89
if you don't want grouping just set it to zero (which is default)
*/
uint group;
/*!
how many digits should be grouped (it is used if 'group' is non zero)
default: 3
*/
uint group_digits;
/*!
*/
uint group_exp; // not implemented yet
Conv()
{
// default values
base = 10;
scient = false;
scient_from = 15;
base_round = true;
round = -1;
trim_zeroes = true;
comma = '.';
comma2 = ',';
group = 0;
group_digits = 3;
group_exp = 0;
}
};
/*!
this simple class can be used in multithreading model
(you can write your own class derived from this one)
@ -305,37 +582,24 @@ namespace ttmath
In the library is used macro TTMATH_REFERENCE_ASSERT which
can throw an exception of this type
** from version 0.9.2 this macro is removed from all methods
in public interface so you don't have to worry about it **
If you compile with gcc you can get a small benefit
from using method Where() (it returns std::string with
from using method Where() (it returns std::string) with
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
was used)
What is the 'reference' error?
Some kind of methods use a reference as their argument to another object,
and the another object not always can be the same which is calling, e.g.
Big<1,2> foo(10);
foo.Mul(foo); // this is incorrect
above method Mul is making something more with 'this' object and
'this' cannot be passed as the argument because the result will be undefined
macro TTMATH_REFERENCE_ASSERT helps us to solve the above problem
note! some methods can use 'this' object as the argument
for example this code is correct:
UInt<2> foo(10);
foo.Add(foo);
but there are only few methods which can do that
*/
class ReferenceError : public std::logic_error, ExceptionInfo
class ReferenceError : public std::logic_error, public ExceptionInfo
{
public:
ReferenceError() : std::logic_error ("reference error")
ReferenceError() : std::logic_error("reference error")
{
}
ReferenceError(const char * f, int l) :
std::logic_error ("reference error"), ExceptionInfo(f,l)
std::logic_error("reference error"), ExceptionInfo(f,l)
{
}
@ -354,20 +618,20 @@ namespace ttmath
of this type
if you compile with gcc you can get a small benefit
from using method Where() (it returns std::string with
from using method Where() (it returns std::string) with
the name and the line of a file where the macro TTMATH_ASSERT
was used)
*/
class RuntimeError : public std::runtime_error, ExceptionInfo
class RuntimeError : public std::runtime_error, public ExceptionInfo
{
public:
RuntimeError() : std::runtime_error ("internal error")
RuntimeError() : std::runtime_error("internal error")
{
}
RuntimeError(const char * f, int l) :
std::runtime_error ("internal error"), ExceptionInfo(f,l)
std::runtime_error("internal error"), ExceptionInfo(f,l)
{
}
@ -380,8 +644,21 @@ namespace ttmath
/*!
look at the description of macros TTMATH_RELEASE and TTMATH_DEBUG
TTMATH_DEBUG
this macro enables further testing during writing your code
you don't have to define it in a release mode
if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
are set as well and these macros can throw an exception if a condition in it
is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
TTMATH_DEBUG is set automatically if DEBUG or _DEBUG are defined
*/
#if defined DEBUG || defined _DEBUG
#define TTMATH_DEBUG
#endif
#ifdef TTMATH_DEBUG
#if defined(__FILE__) && defined(__LINE__)
@ -407,7 +684,24 @@ namespace ttmath
#endif
#ifdef TTMATH_DEBUG_LOG
#define TTMATH_LOG(msg) PrintLog(msg, std::cout);
#define TTMATH_LOGC(msg, carry) PrintLog(msg, carry, std::cout);
#define TTMATH_VECTOR_LOG(msg, vector, len) PrintVectorLog(msg, std::cout, vector, len);
#define TTMATH_VECTOR_LOGC(msg, carry, vector, len) PrintVectorLog(msg, carry, std::cout, vector, len);
#else
#define TTMATH_LOG(msg)
#define TTMATH_LOGC(msg, carry)
#define TTMATH_VECTOR_LOG(msg, vector, len)
#define TTMATH_VECTOR_LOGC(msg, carry, vector, len)
#endif
} // namespace
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,985 +0,0 @@
/*
* This file is a part of TTMath Mathematical Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* Copyright (c) 2006-2008, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name Tomasz Sowa nor the names of contributors to this
* project may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/*!
\file ttmathuint.h
\brief template class UInt<uint> for 64bit processors
*/
namespace ttmath
{
/*!
*
* basic mathematic functions
*
*/
#ifdef TTMATH_PLATFORM64
/*!
in 64bit platforms we must define additional operators and contructors
in order to allow a user initializing the objects in this way:
UInt<...> type = 20;
or
UInt<...> type;
type = 30;
decimal constants such as 20, 30 etc. are integer literal of type int,
if the value is greater it can even be long int,
0 is an octal integer of type int
(ISO 14882 p2.13.1 Integer literals)
*/
/*!
this operator converts the unsigned int type to this class
***this operator is created only on a 64bit platform***
it takes one argument of 32bit
*/
template<uint value_size>
UInt<value_size> & UInt<value_size>::operator=(unsigned int i)
{
FromUInt(uint(i));
return *this;
}
/*!
a constructor for converting the unsigned int to this class
***this constructor is created only on a 64bit platform***
it takes one argument of 32bit
*/
template<uint value_size>
UInt<value_size>::UInt(unsigned int i)
{
FromUInt(uint(i));
}
/*!
an operator for converting the signed int to this class
***this constructor is created only on a 64bit platform***
it takes one argument of 32bit
look at the description of UInt::operator=(sint)
*/
template<uint value_size>
UInt<value_size> & UInt<value_size>::operator=(signed int i)
{
FromUInt(uint(i));
return *this;
}
/*!
a constructor for converting the signed int to this class
***this constructor is created only on a 64bit platform***
it takes one argument of 32bit
look at the description of UInt::operator=(sint)
*/
template<uint value_size>
UInt<value_size>::UInt(signed int i)
{
FromUInt(uint(i));
}
/*!
this method copies the value stored in an another table
(warning: first values in temp_table are the highest words -- it's different
from our table)
***this method is created only on a 64bit platform***
we copy as many words as it is possible
if temp_table_len is bigger than value_size we'll try to round
the lowest word from table depending on the last not used bit in temp_table
(this rounding isn't a perfect rounding -- look at the description below)
and if temp_table_len is smaller than value_size we'll clear the rest words
in the table
warning: we're using 'temp_table' as a pointer at 32bit words
*/
template<uint value_size>
void UInt<value_size>::SetFromTable(const unsigned int * temp_table, uint temp_table_len)
{
uint temp_table_index = 0;
sint i; // 'i' with a sign
for(i=value_size-1 ; i>=0 && temp_table_index<temp_table_len; --i, ++temp_table_index)
{
table[i] = uint(temp_table[ temp_table_index ]) << 32;
++temp_table_index;
if( temp_table_index<temp_table_len )
table[i] |= temp_table[ temp_table_index ];
}
// rounding mantissa
if( temp_table_index < temp_table_len )
{
if( (temp_table[temp_table_index] & TTMATH_UINT_HIGHEST_BIT) != 0 )
{
/*
very simply rounding
if the bit from not used last word from temp_table is set to one
we're rouding the lowest word in the table
in fact there should be a normal addition but
we don't use Add() or AddTwoInts() because these methods
can set a carry and then there'll be a small problem
for optimization
*/
if( table[0] != TTMATH_UINT_MAX_VALUE )
++table[0];
}
}
// cleaning the rest of the mantissa
for( ; i >= 0 ; --i)
table[i] = 0;
}
/*!
this method adding ss2 to the this and adding carry if it's defined
(this = this + ss2 + c)
***this method is created only on a 64bit platform***
c must be zero or one (might be a bigger value than 1)
function returns carry (1) (if it was)
*/
template<uint value_size>
uint UInt<value_size>::Add(const UInt<value_size> & ss2, uint c)
{
register uint b = value_size;
register uint * p1 = table;
register uint * p2 = const_cast<uint*>(ss2.table);
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
/*
this part should be compiled with gcc
*/
__asm__ __volatile__(
"push %%rbx \n"
"push %%rcx \n"
"push %%rdx \n"
"movq $0, %%rax \n"
"subq %%rsi, %%rax \n"
"1: \n"
"movq (%%rbx),%%rax \n"
"adcq (%%rdx),%%rax \n"
"movq %%rax,(%%rbx) \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"loop 1b \n"
"movq $0, %%rax \n"
"adcq %%rax,%%rax \n"
"movq %%rax, %%rsi \n"
"pop %%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
: "=S" (c)
: "0" (c), "c" (b), "b" (p1), "d" (p2)
: "%rax", "cc", "memory" );
#endif
return c;
}
/*!
this method adds one word (at a specific position)
and returns a carry (if it was)
***this method is created only on a 64bit platform***
if we've got (value_size=3):
table[0] = 10;
table[1] = 30;
table[2] = 5;
and we call:
AddInt(2,1)
then it'll be:
table[0] = 10;
table[1] = 30 + 2;
table[2] = 5;
of course if there was a carry from table[3] it would be returned
*/
template<uint value_size>
uint UInt<value_size>::AddInt(uint value, uint index)
{
register uint b = value_size;
register uint * p1 = table;
register uint c;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rbx \n"
"push %%rcx \n"
"push %%rdx \n"
"subq %%rdx, %%rcx \n"
"leaq (%%rbx,%%rdx,8), %%rbx \n"
"movq %%rsi, %%rdx \n"
"clc \n"
"1: \n"
"movq (%%rbx), %%rax \n"
"adcq %%rdx, %%rax \n"
"movq %%rax, (%%rbx) \n"
"jnc 2f \n"
"movq $0, %%rdx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"loop 1b \n"
"2: \n"
"movq $0, %%rax \n"
"adcq %%rax,%%rax \n"
"pop %%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
: "=a" (c)
: "c" (b), "d" (index), "b" (p1), "S" (value)
: "cc", "memory" );
#endif
return c;
}
/*!
this method adds only two unsigned words to the existing value
and these words begin on the 'index' position
(it's used in the multiplication algorithm 2)
***this method is created only on a 64bit platform***
index should be equal or smaller than value_size-2 (index <= value_size-2)
x1 - lower word, x2 - higher word
for example if we've got value_size equal 4 and:
table[0] = 3
table[1] = 4
table[2] = 5
table[3] = 6
then let
x1 = 10
x2 = 20
and
index = 1
the result of this method will be:
table[0] = 3
table[1] = 4 + x1 = 14
table[2] = 5 + x2 = 25
table[3] = 6
and no carry at the end of table[3]
(of course if there was a carry in table[2](5+20) then
this carry would be passed to the table[3] etc.)
*/
template<uint value_size>
uint UInt<value_size>::AddTwoInts(uint x2, uint x1, uint index)
{
register uint b = value_size;
register uint * p1 = table;
register uint c;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rbx \n"
"push %%rcx \n"
"push %%rdx \n"
"subq %%rdx, %%rcx \n"
"leaq (%%rbx,%%rdx,8), %%rbx \n"
"movq $0, %%rdx \n"
"movq (%%rbx), %%rax \n"
"addq %%rsi, %%rax \n"
"movq %%rax, (%%rbx) \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"movq (%%rbx), %%rax \n"
"adcq %%rdi, %%rax \n"
"movq %%rax, (%%rbx) \n"
"jnc 2f \n"
"dec %%rcx \n"
"dec %%rcx \n"
"jz 2f \n"
"1: \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"movq (%%rbx), %%rax \n"
"adcq %%rdx, %%rax \n"
"movq %%rax, (%%rbx) \n"
"jnc 2f \n"
"loop 1b \n"
"2: \n"
"movq $0, %%rax \n"
"adcq %%rax,%%rax \n"
"pop %%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
: "=a" (c)
: "c" (b), "d" (index), "b" (p1), "S" (x1), "D" (x2)
: "cc", "memory" );
#endif
return c;
}
/*!
this method's subtracting ss2 from the 'this' and subtracting
carry if it has been defined
(this = this - ss2 - c)
***this method is created only on a 64bit platform***
c must be zero or one (might be a bigger value than 1)
function returns carry (1) (if it was)
*/
template<uint value_size>
uint UInt<value_size>::Sub(const UInt<value_size> & ss2, uint c)
{
register uint b = value_size;
register uint * p1 = table;
register uint * p2 = const_cast<uint*>(ss2.table);
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rbx \n"
"push %%rcx \n"
"push %%rdx \n"
"movq $0, %%rax \n"
"subq %%rsi, %%rax \n"
"1: \n"
"movq (%%rbx),%%rax \n"
"sbbq (%%rdx),%%rax \n"
"movq %%rax,(%%rbx) \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"inc %%rdx \n"
"loop 1b \n"
"movq $0, %%rax \n"
"adcq %%rax,%%rax \n"
"movq %%rax, %%rsi \n"
"pop %%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
: "=S" (c)
: "0" (c), "c" (b), "b" (p1), "d" (p2)
: "%rax", "cc", "memory" );
#endif
return c;
}
/*!
this method subtracts one word (at a specific position)
and returns a carry (if it was)
***this method is created only on a 64bit platform***
if we've got (value_size=3):
table[0] = 10;
table[1] = 30;
table[2] = 5;
and we call:
SubInt(2,1)
then it'll be:
table[0] = 10;
table[1] = 30 - 2;
table[2] = 5;
of course if there was a carry from table[3] it would be returned
*/
template<uint value_size>
uint UInt<value_size>::SubInt(uint value, uint index)
{
register uint b = value_size;
register uint * p1 = table;
register uint c;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rbx \n"
"push %%rcx \n"
"push %%rdx \n"
"subq %%rdx, %%rcx \n"
"leaq (%%rbx,%%rdx,8), %%rbx \n"
"movq %%rsi, %%rdx \n"
"clc \n"
"1: \n"
"movq (%%rbx), %%rax \n"
"sbbq %%rdx, %%rax \n"
"movq %%rax, (%%rbx) \n"
"jnc 2f \n"
"movq $0, %%rdx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"inc %%rbx \n"
"loop 1b \n"
"2: \n"
"movq $0, %%rax \n"
"adcq %%rax,%%rax \n"
"pop %%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
: "=a" (c)
: "c" (b), "d" (index), "b" (p1), "S" (value)
: "cc", "memory" );
#endif
return c;
}
/*!
this method moves all bits into the left hand side
return value <- this <- c
the lowest *bits* will be held the 'c' and
the state of one additional bit (on the left hand side)
will be returned
for example:
let this is 001010000
after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1
***this method is created only on a 64bit platform***
*/
template<uint value_size>
uint UInt<value_size>::Rcl2(uint bits, uint c)
{
if( bits == 0 )
return 0;
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
register sint b = value_size;
register uint * p1 = table;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rsi \n"
"2: \n"
"xorq %%rax,%%rax \n"
"subq %%rdx,%%rax \n"
"push %%rbx \n"
"push %%rcx \n"
"1: \n"
"rclq $1,(%%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"
"loop 1b \n"
"pop %%rcx \n"
"pop %%rbx \n"
"decq %%rsi \n"
"jnz 2b \n"
"movq $0, %%rdx \n"
"adcq %%rdx, %%rdx \n"
"pop %%rsi \n"
: "=d" (c)
: "0" (c), "c" (b), "b" (p1), "S" (bits)
: "%rax", "cc", "memory" );
#endif
return c;
}
/*!
this method moves all bits into the right hand side
C -> this -> return value
the highest *bits* will be held the 'c' and
the state of one additional bit (on the right hand side)
will be returned
for example:
let this is 000000010
after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1
***this method is created only on a 64bit platform***
*/
template<uint value_size>
uint UInt<value_size>::Rcr2(uint bits, uint c)
{
if( bits == 0 )
return 0;
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
register sint b = value_size;
register uint * p1 = table;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
"push %%rsi \n"
"2: \n"
"push %%rbx \n"
"push %%rcx \n"
"leaq (%%rbx,%%rcx,8),%%rbx \n"
"xorq %%rax, %%rax \n"
"subq %%rdx, %%rax \n"
"1: \n"
"dec %%rbx \n"
"dec %%rbx \n"
"dec %%rbx \n"
"dec %%rbx \n"
"dec %%rbx \n"
"dec %%rbx \n"
"dec %%rbx \n"
"dec %%rbx \n"
"rcrq $1,(%%rbx) \n"
"loop 1b \n"
"pop %%rcx \n"
"pop %%rbx \n"
"decq %%rsi \n"
"jnz 2b \n"
"movq $0, %%rdx \n"
"adcq %%rdx,%%rdx \n"
"pop %%rsi \n"
: "=d" (c)
: "0" (c), "c" (b), "b" (p1), "S" (bits)
: "%rax", "cc", "memory" );
#endif
return c;
}
/*
this method returns the number of the highest set bit in one 32-bit word
if the 'x' is zero this method returns '-1'
***this method is created only on a 64bit platform***
*/
template<uint value_size>
sint UInt<value_size>::FindLeadingBitInWord(uint x)
{
register sint result;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
"bsrq %%rbx, %%rax \n"
"jnz 1f \n"
"movq $-1, %%rax \n"
"1: \n"
: "=a" (result)
: "b" (x)
: "cc" );
#endif
return result;
}
/*!
this method sets a special bit in the 'value'
and returns the result
***this method is created only on a 64bit platform***
bit is from <0,31>
e.g.
SetBitInWord(0,0) = 1
SetBitInWord(0,2) = 4
SetBitInWord(10, 8) = 266
*/
template<uint value_size>
uint UInt<value_size>::SetBitInWord(uint value, uint bit)
{
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
"btsq %%rbx,%%rax \n"
: "=a" (value)
: "0" (value), "b" (bit)
: "cc" );
#endif
return value;
}
/*!
*
* Multiplication
*
*
*/
/*!
multiplication: result2:result1 = a * b
result2 - higher word
result1 - lower word of the result
this methos never returns a carry
***this method is created only on a 64bit platform***
it is an auxiliary method for version two of the multiplication algorithm
*/
template<uint value_size>
void UInt<value_size>::MulTwoWords(uint a, uint b, uint * result2, uint * result1)
{
/*
we must use these temporary variables in order to inform the compilator
that value pointed with result1 and result2 has changed
this has no effect in visual studio but it's usefull when
using gcc and options like -O
*/
register uint result1_;
register uint result2_;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
"mulq %%rdx \n"
: "=a" (result1_), "=d" (result2_)
: "0" (a), "1" (b)
: "cc" );
#endif
*result1 = result1_;
*result2 = result2_;
}
/*!
*
* Division
*
*
*/
/*!
this method calculates 64bits word a:b / 32bits c (a higher, b lower word)
r = a:b / c and rest - remainder
***this method is created only on a 64bit platform***
*
* WARNING:
* if r (one word) is too small for the result or c is equal zero
* there'll be a hardware interruption (0)
* and probably the end of your program
*
*/
template<uint value_size>
void UInt<value_size>::DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest)
{
register uint r_;
register uint rest_;
/*
these variables have similar meaning like those in
the multiplication algorithm MulTwoWords
*/
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
"divq %%rcx \n"
: "=a" (r_), "=d" (rest_)
: "d" (a), "a" (b), "c" (c)
: "cc" );
#endif
*r = r_;
*rest = rest_;
}
#endif
} //namespace

1038
ttmath/ttmathuint_noasm.h Normal file

File diff suppressed because it is too large Load Diff

1620
ttmath/ttmathuint_x86.h Normal file

File diff suppressed because it is too large Load Diff

1177
ttmath/ttmathuint_x86_64.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,551 @@
;
; This file is a part of TTMath Bignum Library
; and is distributed under the 3-Clause BSD Licence.
; Author: Christian Kaiser <chk@online.de>, Tomasz Sowa <t.sowa@ttmath.org>
;
;
; Copyright (c) 2009-2017, Christian Kaiser, 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 Christian Kaiser 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.
;
;
; compile with debug info: ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
; compile without debug info: ml64.exe /c ttmathuint_x86_64_msvc.asm
; this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program
;
; doxygen info is put to ttmathuint_x86_64.h file
PUBLIC ttmath_adc_x64
PUBLIC ttmath_addindexed_x64
PUBLIC ttmath_addindexed2_x64
PUBLIC ttmath_addvector_x64
PUBLIC ttmath_sbb_x64
PUBLIC ttmath_subindexed_x64
PUBLIC ttmath_subvector_x64
PUBLIC ttmath_rcl_x64
PUBLIC ttmath_rcr_x64
PUBLIC ttmath_rcl2_x64
PUBLIC ttmath_rcr2_x64
PUBLIC ttmath_div_x64
;
; Microsoft x86_64 convention: http://msdn.microsoft.com/en-us/library/9b372w95.aspx
;
; "rax, rcx, rdx, r8-r11 are volatile."
; "rbx, rbp, rdi, rsi, r12-r15 are nonvolatile."
;
.CODE
ALIGN 8
;----------------------------------------
ttmath_adc_x64 PROC
; rcx = p1
; rdx = p2
; r8 = nSize
; r9 = nCarry
xor rax, rax
xor r11, r11
sub rax, r9 ; sets CARRY if r9 != 0
ALIGN 16
loop1:
mov rax,qword ptr [rdx + r11 * 8]
adc qword ptr [rcx + r11 * 8], rax
lea r11, [r11+1]
dec r8
jnz loop1
setc al
movzx rax, al
ret
ttmath_adc_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
ttmath_addindexed_x64 PROC
; rcx = p1
; rdx = nSize
; r8 = nPos
; r9 = nValue
xor rax, rax ; rax = result
sub rdx, r8 ; rdx = remaining count of uints
add qword ptr [rcx + r8 * 8], r9
jc next1
ret
next1:
mov r9, 1
ALIGN 16
loop1:
dec rdx
jz done_with_cy
lea r8, [r8+1]
add qword ptr [rcx + r8 * 8], r9
jc loop1
ret
done_with_cy:
lea rax, [rax+1] ; rax = 1
ret
ttmath_addindexed_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
ttmath_addindexed2_x64 PROC
; rcx = p1 (pointer)
; rdx = b (value size)
; r8 = nPos
; r9 = nValue1
; [rsp+0x28] = nValue2
xor rax, rax ; return value
mov r11, rcx ; table
sub rdx, r8 ; rdx = remaining count of uints
mov r10, [rsp+028h] ; r10 = nValue2
add qword ptr [r11 + r8 * 8], r9
lea r8, [r8+1]
lea rdx, [rdx-1]
adc qword ptr [r11 + r8 * 8], r10
jc next
ret
ALIGN 16
loop1:
lea r8, [r8+1]
add qword ptr [r11 + r8 * 8], 1
jc next
ret
next:
dec rdx ; does not modify CY too...
jnz loop1
lea rax, [rax+1]
ret
ttmath_addindexed2_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
ttmath_addvector_x64 PROC
; rcx = ss1
; rdx = ss2
; r8 = ss1_size
; r9 = ss2_size
; [rsp+0x28] = result
mov r10, [rsp+028h]
sub r8, r9
xor r11, r11 ; r11=0, cf=0
ALIGN 16
loop1:
mov rax, qword ptr [rcx + r11 * 8]
adc rax, qword ptr [rdx + r11 * 8]
mov qword ptr [r10 + r11 * 8], rax
inc r11
dec r9
jnz loop1
adc r9, r9 ; r9 has the cf state
or r8, r8
jz done
neg r9 ; setting cf from r9
mov r9, 0 ; don't use xor here (cf is used)
loop2:
mov rax, qword ptr [rcx + r11 * 8]
adc rax, r9
mov qword ptr [r10 + r11 * 8], rax
inc r11
dec r8
jnz loop2
adc r8, r8
mov rax, r8
ret
done:
mov rax, r9
ret
ttmath_addvector_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
ttmath_sbb_x64 PROC
; rcx = p1
; rdx = p2
; r8 = nCount
; r9 = nCarry
xor rax, rax
xor r11, r11
sub rax, r9 ; sets CARRY if r9 != 0
ALIGN 16
loop1:
mov rax,qword ptr [rdx + r11 * 8]
sbb qword ptr [rcx + r11 * 8], rax
lea r11, [r11+1]
dec r8
jnz loop1
setc al
movzx rax, al
ret
ttmath_sbb_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
ttmath_subindexed_x64 PROC
; rcx = p1
; rdx = nSize
; r8 = nPos
; r9 = nValue
sub rdx, r8 ; rdx = remaining count of uints
ALIGN 16
loop1:
sub qword ptr [rcx + r8 * 8], r9
jnc done
lea r8, [r8+1]
mov r9, 1
dec rdx
jnz loop1
mov rax, 1
ret
done:
xor rax, rax
ret
ttmath_subindexed_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
; the same asm code as in addvector_x64 only two instructions 'adc' changed to 'sbb'
ttmath_subvector_x64 PROC
; rcx = ss1
; rdx = ss2
; r8 = ss1_size
; r9 = ss2_size
; [rsp+0x28] = result
mov r10, [rsp+028h]
sub r8, r9
xor r11, r11 ; r11=0, cf=0
ALIGN 16
loop1:
mov rax, qword ptr [rcx + r11 * 8]
sbb rax, qword ptr [rdx + r11 * 8]
mov qword ptr [r10 + r11 * 8], rax
inc r11
dec r9
jnz loop1
adc r9, r9 ; r9 has the cf state
or r8, r8
jz done
neg r9 ; setting cf from r9
mov r9, 0 ; don't use xor here (cf is used)
loop2:
mov rax, qword ptr [rcx + r11 * 8]
sbb rax, r9
mov qword ptr [r10 + r11 * 8], rax
inc r11
dec r8
jnz loop2
adc r8, r8
mov rax, r8
ret
done:
mov rax, r9
ret
ttmath_subvector_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
ttmath_rcl_x64 PROC
; rcx = p1
; rdx = b
; r8 = nLowestBit
mov r11, rcx ; table
xor r10, r10
neg r8 ; CY set if r8 <> 0
ALIGN 16
loop1:
rcl qword ptr [r11 + r10 * 8], 1
lea r10, [r10+1]
dec rdx
jnz loop1
setc al
movzx rax, al
ret
ttmath_rcl_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
ttmath_rcr_x64 PROC
; rcx = p1
; rdx = nSize
; r8 = nLowestBit
xor r10, r10
neg r8 ; CY set if r8 <> 0
ALIGN 16
loop1:
rcr qword ptr -8[rcx + rdx * 8], 1
dec rdx
jnz loop1
setc al
movzx rax, al
ret
ttmath_rcr_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
ttmath_div_x64 PROC
; rcx = &Hi
; rdx = &Lo
; r8 = nDiv
mov r11, rcx
mov r10, rdx
mov rdx, qword ptr [r11]
mov rax, qword ptr [r10]
div r8
mov qword ptr [r10], rdx ; remainder
mov qword ptr [r11], rax ; value
ret
ttmath_div_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
ttmath_rcl2_x64 PROC
; rcx = p1
; rdx = nSize
; r8 = bits
; r9 = c
push rbx
mov r10, rcx ; r10 = p1
xor rax, rax
mov rcx, 64
sub rcx, r8
mov r11, -1
shr r11, cl ; r11 = mask
mov rcx, r8 ; rcx = count of bits
mov rbx, rax ; rbx = old value = 0
or r9, r9
cmovnz rbx, r11 ; if (c) then old value = mask
mov r9, rax ; r9 = index (0..nSize-1)
ALIGN 16
loop1:
rol qword ptr [r10+r9*8], cl
mov rax, qword ptr [r10+r9*8]
and rax, r11
xor qword ptr [r10+r9*8], rax
or qword ptr [r10+r9*8], rbx
mov rbx, rax
lea r9, [r9+1]
dec rdx
jnz loop1
and rax, 1
pop rbx
ret
ttmath_rcl2_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
ttmath_rcr2_x64 PROC
; rcx = p1
; rdx = nSize
; r8 = bits
; r9 = c
push rbx
mov r10, rcx ; r10 = p1
xor rax, rax
mov rcx, 64
sub rcx, r8
mov r11, -1
shl r11, cl ; r11 = mask
mov rcx, r8 ; rcx = count of bits
mov rbx, rax ; rbx = old value = 0
or r9, r9
cmovnz rbx, r11 ; if (c) then old value = mask
mov r9, rdx ; r9 = index (0..nSize-1)
lea r9, [r9-1]
ALIGN 16
loop1:
ror qword ptr [r10+r9*8], cl
mov rax, qword ptr [r10+r9*8]
and rax, r11
xor qword ptr [r10+r9*8], rax
or qword ptr [r10+r9*8], rbx
mov rbx, rax
lea r9, [r9-1]
dec rdx
jnz loop1
rol rax, 1
and rax, 1
pop rbx
ret
ttmath_rcr2_x64 ENDP
END

View File

@ -0,0 +1,9 @@
rem make sure this is a proper path to the 64 bit assembler
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\ml64.exe" /c ttmathuint_x86_64_msvc.asm
rem ml64.exe will produce ttmathuint_x86_64_msvc.obj which should be added (linked) to your project
rem or you can assemble with debug info
rem ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
rem be nice, most Windows users just click on the file
pause