70 Commits
0.8.0 ... 0.8.x

Author SHA1 Message Date
5584adb23d changed version: 0.8.6 now
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/0.8.x@222 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-10-25 15:55:15 +00:00
a4bb0b6f64 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/branches/0.8.x@215 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-10-16 21:38:25 +00:00
e046aba6d2 fixed: buffer overflow in Big::ToInt(Int<int_size> & result)
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/0.8.x@211 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-10-15 01:40:13 +00:00
5ef27bdbd0 Some fixes from trunk:
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')


git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/0.8.x@204 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-10-07 17:33:03 +00:00
b80f73f16b creating 0.8.x branch of the ttmath library (copied from trunk)
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/0.8.x@166 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-16 20:28:52 +00:00
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
d8b829f4c5 changed: version of the library: 0.8.3 now
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@120 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-04-06 16:34:19 +00:00
fca1bc1a33 added: Objects::IsDefined(const std::string & name)
returning true if such an object is defined


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



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


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


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


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


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



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


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@104 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-11 19:05:13 +00:00
404727f3de changed: small changes in: UInt:: RclMoveAllWords, UInt::RcrMoveAllWords, UInt::SetBitInWord(),
UInt::FindLeadingBitInWord, UInt::SetBitInWord
fixed:   UInt::Div() didn't return a correct result when the divisor was equal 1
         there was an error in UInt::DivInt() - when the divisor was 1 it returned
         zero and the carry was set
         this error was from the beginning of the TTMath library


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


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



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


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


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


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


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


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


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


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


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


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@78 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-10-17 09:57:36 +00:00
98c2379182 changed: small changes especially cosmetic in documentation (commentaries)
changed: version of the library: now 0.8.2


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


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



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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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

453
CHANGELOG
View File

@@ -1,84 +1,369 @@
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
* added UInt::SetBitInWord
* UInt::Mul64 renamed to UInt::MulTwoWords
* UInt::Div64 renamed to UInt::DivTwoWords
* and more small changes in UInt type
* start adding support for Amd64 (not finished yet) (added ttmathuint64.h)
Version 0.6.3 (2007.01.22):
* position of arguments (x and base) in logarithm functions are swapped
* it's possible to use any multiplication algorithms in the same time
(macros UINT_MUL_VERSION_'X' have gone)
* added ExceptionInfo, ReferenceError and RuntimeError classes
* the mess in macros has been cleaned up
* added TTMATH_RELEASE macro
Version 0.6.2 (2007.01.10):
* New division algorithm (radix b) where b is 2^32
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

View File

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

50
README
View File

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

7
TODO
View File

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

27
constgen/Makefile Normal file
View File

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

126
constgen/main.cpp Normal file
View File

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

1257
doxygen.cfg Normal file

File diff suppressed because it is too large Load Diff

View File

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

31
tests/Makefile Normal file
View File

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

68
tests/main.cpp Normal file
View File

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

92
tests/tests.uint32 Normal file
View File

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

424
tests/uinttest.cpp Normal file
View File

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

105
tests/uinttest.h Normal file
View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,11 @@
/*
* This file is a part of TTMath Mathematical Library
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* Copyright (c) 2006-2007, Tomasz Sowa
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -208,7 +208,7 @@ private:
public:
/*!
this method adds two value with a sign and returns carry
this method adds two value with a sign and returns a carry
we're using methods from the base class because values are stored with U2
we must only make the carry correction
@@ -469,23 +469,84 @@ public:
private:
/*!
power this = this ^ pow
this can be negative
pow is >= 0
*/
uint Pow2(const Int<value_size> & pow)
{
bool was_sign = IsSign();
uint c = 0;
if( was_sign )
c += Abs();
uint c_temp = UInt<value_size>::Pow(pow);
if( c_temp > 0 )
return c_temp; // c_temp can be: 0, 1 or 2
if( was_sign && (pow.table[0] & 1) == 1 )
// negative value to the power of odd number is negative
c += ChangeSign();
return (c==0)? 0 : 1;
}
public:
/*!
power this = this ^ pow
return values:
0 - ok
1 - carry
2 - incorrect arguments 0^0 or 0^(-something)
*/
uint Pow(Int<value_size> pow)
{
if( !pow.IsSign() )
return Pow2(pow);
if( UInt<value_size>::IsZero() )
// if 'p' is negative then
// 'this' must be different from zero
return 2;
if( pow.ChangeSign() )
return 1;
Int<value_size> t(*this);
uint c_temp = t.Pow2(pow);
if( c_temp > 0 )
return c_temp;
UInt<value_size>::SetOne();
if( Div(t) )
return 1;
return 0;
}
/*!
*
* convertion methods
*
*/
private:
/*!
this method convert an UInt<another_size> type to this class
this operation has mainly sense if the value from p
can be held in this type
it returns a carry if the value 'p' is too big
an auxiliary method for converting both from UInt and Int
*/
template<uint argument_size>
uint FromInt(const Int<argument_size> & p)
uint FromUIntOrInt(const UInt<argument_size> & p, bool UInt_type)
{
uint min_size = (value_size < argument_size)? value_size : argument_size;
uint i;
@@ -496,15 +557,25 @@ public:
if( value_size > argument_size )
{
// 'this' is longer than 'p'
uint fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)? TTMATH_UINT_MAX_VALUE : 0;
uint fill;
if( UInt_type )
fill = 0;
else
fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)?
TTMATH_UINT_MAX_VALUE : 0;
// 'this' is longer than 'p'
for( ; i<value_size ; ++i)
UInt<value_size>::table[i] = fill;
}
else
{
uint test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)? TTMATH_UINT_MAX_VALUE : 0;
uint test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)?
TTMATH_UINT_MAX_VALUE : 0;
if( UInt_type && test!=0 )
return 1;
for( ; i<argument_size ; ++i)
if( p.table[i] != test )
@@ -514,11 +585,27 @@ public:
return 0;
}
public:
/*!
this method converts an Int<another_size> type into this class
this operation has mainly sense if the value from p
can be held in this type
it returns a carry if the value 'p' is too big
*/
template<uint argument_size>
uint FromInt(const Int<argument_size> & p)
{
return FromUIntOrInt(p, false);
}
/*!
this method converts the sint type into this class
*/
void FromInt(sint value)
uint FromInt(sint value)
{
uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0;
@@ -526,16 +613,46 @@ public:
UInt<value_size>::table[i] = fill;
UInt<value_size>::table[0] = uint(value);
// there'll never be a carry here
return 0;
}
/*!
this operator converts an UInt<another_size> type to this class
it doesn't return a carry
this method converts UInt<another_size> into this class
*/
template<uint argument_size>
Int<value_size> & operator=(const Int<argument_size> & p)
uint FromUInt(const UInt<argument_size> & p)
{
return FromUIntOrInt(p, true);
}
/*!
this method converts the uint type into this class
*/
uint FromUInt(uint value)
{
for(uint i=1 ; i<value_size ; ++i)
UInt<value_size>::table[i] = 0;
UInt<value_size>::table[0] = value;
// there can be a carry here when the size of this value is equal one word
// and the 'value' has the highest bit set
if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 )
return 1;
return 0;
}
/*!
the default assignment operator
*/
Int<value_size> & operator=(const Int<value_size> & p)
{
FromInt(p);
@@ -544,9 +661,12 @@ public:
/*!
the default assignment operator
this operator converts an Int<another_size> type to this class
it doesn't return a carry
*/
Int<value_size> & operator=(const Int<value_size> & p)
template<uint argument_size>
Int<value_size> & operator=(const Int<argument_size> & p)
{
FromInt(p);
@@ -575,11 +695,46 @@ public:
/*!
this method converts the uint type to this class
a copy constructor
*/
Int(const Int<value_size> & u)
{
FromInt(u);
}
/*!
a constructor for copying from another types
*/
template<uint argument_size>
Int(const Int<argument_size> & u)
{
// look that 'size' we still set as 'value_size' and not as u.value_size
FromInt(u);
}
/*!
this operator converts an UInt<another_size> type to this class
it doesn't return a carry
*/
template<uint argument_size>
Int<value_size> & operator=(const UInt<argument_size> & p)
{
FromUInt(p);
return *this;
}
/*!
this method converts the Uint type to this class
*/
Int<value_size> & operator=(uint i)
{
UInt<value_size>::FromUInt(i);
FromUInt(i);
return *this;
}
@@ -590,10 +745,23 @@ public:
*/
Int(uint i)
{
UInt<value_size>::FromUInt(i);
FromUInt(i);
}
/*!
a constructor for copying from another types
*/
template<uint argument_size>
Int(const UInt<argument_size> & u)
{
// look that 'size' we still set as 'value_size' and not as u.value_size
FromUInt(u);
}
#ifdef TTMATH_PLATFORM64
/*!
@@ -630,7 +798,7 @@ public:
*/
Int<value_size> & operator=(unsigned int i)
{
UInt<value_size>::FromUInt(uint(i));
FromUInt(uint(i));
return *this;
}
@@ -644,7 +812,7 @@ public:
*/
Int(unsigned int i)
{
UInt<value_size>::FromUInt(uint(i));
FromUInt(uint(i));
}
#endif
@@ -678,18 +846,6 @@ public:
}
/*!
the copy constructor
*/
template<uint argument_size>
Int(const Int<argument_size> & u) : UInt<value_size>::size(value_size)
{
// look that 'size' we still set as 'value_size' and not as u.value_size
operator=(u);
}
/*!
the destructor
*/
@@ -697,6 +853,7 @@ public:
{
}
/*!
this method returns the lowest value from table with a sign
@@ -742,8 +899,12 @@ public:
existing first white characters will be ommited
(between '-' and a first digit can be white characters too)
after_source (if exists) is pointing at the end of the parsed string
value_read (if exists) tells whether something has actually been read (at least one digit)
*/
uint FromString(const char * s, uint b = 10)
uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
{
bool is_sign = false;
@@ -760,7 +921,7 @@ public:
UInt<value_size>::SkipWhiteCharacters(++s);
}
if( UInt<value_size>::FromString(s,b) )
if( UInt<value_size>::FromString(s,b,after_source,value_read) )
return 1;
if( is_sign )
@@ -771,12 +932,15 @@ public:
/*
the reference to mmin will be automatically converted to the reference
to a UInt type
to UInt type
(this value can be equal mmin -- look at a description in ChangeSign())
*/
if( UInt<value_size>::operator>( mmin ) )
return 1;
/*
if the value is equal mmin the method ChangeSign() does nothing (only returns 1 but we ignore it)
*/
ChangeSign();
}
else
@@ -799,7 +963,7 @@ public:
*/
uint FromString(const std::string & s, uint b = 10)
{
return FromString( s.c_str() );
return FromString( s.c_str(), b );
}
@@ -1152,5 +1316,4 @@ public:
} // namespace
#endif

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,11 @@
/*
* This file is a part of TTMath Mathematical Library
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* Copyright (c) 2006-2007, Tomasz Sowa
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -58,10 +58,14 @@
/*!
the version of the library
TTMATH_PRERELEASE_VER is either zero or one
if zero that means this is the release version of the library
*/
#define TTMATH_MAJOR_VER 0
#define TTMATH_MINOR_VER 8
#define TTMATH_REVISION_VER 0
#define TTMATH_REVISION_VER 6
#define TTMATH_PRERELEASE_VER 0
/*!
@@ -79,7 +83,7 @@
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
if TTMATH_RELEASE is not set then TTMATH_DEBUG is set automatically
*/
#ifndef TTMATH_RELEASE
#define TTMATH_DEBUG
@@ -116,6 +120,20 @@ namespace ttmath
typedef unsigned int uint;
typedef signed int sint;
/*!
this type is twice bigger than uint
(64bit on a 32bit platforms)
although C++ Standard - ANSI ISO IEC 14882:2003 doesn't define such a type (long long)
but it is defined in C99 and in upcoming C++0x /3.9.1 (2)/ and many compilers support it
this type is used in UInt::MulTwoWords and UInt::DivTwoWords when macro TTMATH_NOASM is defined
but only on a 32bit platform
*/
#ifdef TTMATH_NOASM
typedef unsigned long long int ulint;
#endif
/*!
how many bits there are in the uint type
*/
@@ -137,7 +155,7 @@ namespace ttmath
which are kept in built-in variables for a Big<> type
(these variables are defined in ttmathbig.h)
*/
#define TTMATH_BUILTIN_VARIABLES_SIZE 128u
#define TTMATH_BUILTIN_VARIABLES_SIZE 256u
#else
@@ -147,6 +165,15 @@ namespace ttmath
typedef unsigned long uint;
typedef signed long sint;
/*!
on 64bit platform we do not define ulint
sizeof(long long) is 8 (64bit) but we need 128bit
on 64 bit platform (when there is defined TTMATH_NOASM macro)
methods UInt::MulTwoWords and UInt::DivTwoWords are using other algorithms than those on 32 bit
*/
//typedef unsigned long long int ulint;
/*!
how many bits there are in the uint type
*/
@@ -168,7 +195,7 @@ namespace ttmath
which are kept in built-in variables for a Big<> type
(these variables are defined in ttmathbig.h)
*/
#define TTMATH_BUILTIN_VARIABLES_SIZE 64ul
#define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
#endif
}
@@ -178,7 +205,7 @@ namespace ttmath
/*!
characters which represent the comma operator
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing (default, can be overwritten in ToString() function)
TTMATH_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character
that means you can input values for example 1.2345 and 1,2345 as well
@@ -193,6 +220,7 @@ namespace ttmath
#define TTMATH_COMMA_CHARACTER_2 ','
/*!
this variable defines how many iterations are performed
during some kind of calculating when we're making any long formulas
@@ -209,6 +237,17 @@ 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 __GNUC__
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
#else
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
#endif
namespace ttmath
{
@@ -243,7 +282,8 @@ namespace ttmath
err_object_exists,
err_unknown_object,
err_still_calculating,
err_too_big_factorial
err_too_big_factorial,
err_in_short_form_used_function
};
@@ -320,7 +360,7 @@ namespace ttmath
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:
@@ -352,7 +392,7 @@ namespace ttmath
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:
@@ -401,6 +441,19 @@ namespace ttmath
#endif
#ifdef TTMATH_DEBUG_LOG
#define TTMATH_LOG(msg) \
PrintLog(msg, std::cout);
#else
#define TTMATH_LOG(msg)
#endif
} // namespace

File diff suppressed because it is too large Load Diff

View File

@@ -1,943 +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-2007, 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 moving once all bits into the left side
return value <- this <- C
***this method is created only on a 64bit platform***
the lowest bit will hold value of 'c' and
function returns the highest bit
*/
template<uint value_size>
uint UInt<value_size>::Rcl(uint c)
{
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 %%rbx \n"
"push %%rcx \n"
"movq $0,%%rax \n"
"subq %%rdx,%%rax \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"
"movq $0, %%rdx \n"
"adcq %%rdx,%%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
: "=d" (c)
: "0" (c), "c" (b), "b" (p1)
: "%rax", "cc", "memory" );
#endif
return c;
}
/*!
this method moving once all bits into the right side
C -> *this -> return value
***this method is created only on a 64bit platform***
the highest bit will be held value of 'c' and
function returns the lowest bit
*/
template<uint value_size>
uint UInt<value_size>::Rcr(uint c)
{
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 %%rbx \n"
"push %%rcx \n"
"leaq (%%rbx,%%rcx,8),%%rbx \n"
"movq $0, %%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"
"movq $0, %%rdx \n"
"adcq %%rdx,%%rdx \n"
"pop %%rcx \n"
"pop %%rbx \n"
: "=d" (c)
: "0" (c), "c" (b), "b" (p1)
: "%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

937
ttmath/ttmathuint_noasm.h Normal file
View File

@@ -0,0 +1,937 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name Tomasz Sowa nor the names of contributors to this
* project may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef headerfilettmathuint_noasm
#define headerfilettmathuint_noasm
#ifdef TTMATH_NOASM
/*!
\file ttmathuint_noasm.h
\brief template class UInt<uint> with methods without any assembler code
this file is included at the end of ttmathuint.h
*/
namespace ttmath
{
template<uint value_size>
uint UInt<value_size>::AddTwoWords(uint a, uint b, uint carry, uint * result)
{
uint temp;
if( carry == 0 )
{
temp = a + b;
if( temp < a )
carry = 1;
}
else
{
carry = 1;
temp = a + b + carry;
if( temp > a ) // !(temp<=a)
carry = 0;
}
*result = temp;
return carry;
}
/*!
this method adding ss2 to the this and adding carry if it's defined
(this = this + ss2 + c)
c must be zero or one (might be a bigger value than 1)
function returns carry (1) (if it was)
*/
template<uint value_size>
uint UInt<value_size>::Add(const UInt<value_size> & ss2, uint c)
{
uint i;
for(i=0 ; i<value_size ; ++i)
c = AddTwoWords(table[i], ss2.table[i], c, &table[i]);
TTMATH_LOG("UInt::Add")
return c;
}
/*!
this method adds one word (at a specific position)
and returns a carry (if it was)
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[2] it would be returned
*/
template<uint value_size>
uint UInt<value_size>::AddInt(uint value, uint index)
{
uint i, c;
TTMATH_ASSERT( index < value_size )
c = AddTwoWords(table[index], value, 0, &table[index]);
for(i=index+1 ; i<value_size && c ; ++i)
c = AddTwoWords(table[i], 0, c, &table[i]);
TTMATH_LOG("UInt::AddInt")
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)
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)
{
uint i, c;
TTMATH_ASSERT( index < value_size - 1 )
c = AddTwoWords(table[index], x1, 0, &table[index]);
c = AddTwoWords(table[index+1], x2, c, &table[index+1]);
for(i=index+2 ; i<value_size && c ; ++i)
c = AddTwoWords(table[i], 0, c, &table[i]);
TTMATH_LOG("UInt::AddTwoInts")
return c;
}
/*!
this static method addes one vector to the other
'ss1' is larger in size or equal to 'ss2'
ss1 points to the first (larger) vector
ss2 points to the second vector
ss1_size - size of the ss1 (and size of the result too)
ss2_size - size of the ss2
result - is the result vector (which has size the same as ss1: ss1_size)
Example: ss1_size is 5, ss2_size is 3
ss1: ss2: result (output):
5 1 5+1
4 3 4+3
2 7 2+7
6 6
9 9
of course the carry is propagated and will be returned from the last item
(this method is used by the Karatsuba multiplication algorithm)
*/
template<uint value_size>
uint UInt<value_size>::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
{
uint i, c = 0;
TTMATH_ASSERT( ss1_size >= ss2_size )
for(i=0 ; i<ss2_size ; ++i)
c = AddTwoWords(ss1[i], ss2[i], c, &result[i]);
for( ; i<ss1_size ; ++i)
c = AddTwoWords(ss1[i], 0, c, &result[i]);
//TTMATH_LOG("UInt::AddVector")
return c;
}
template<uint value_size>
uint UInt<value_size>::SubTwoWords(uint a, uint b, uint carry, uint * result)
{
if( carry == 0 )
{
*result = a - b;
if( a < b )
carry = 1;
}
else
{
carry = 1;
*result = a - b - carry;
if( a > b ) // !(a <= b )
carry = 0;
}
return carry;
}
/*!
this method's subtracting ss2 from the 'this' and subtracting
carry if it has been defined
(this = this - ss2 - c)
c must be zero or one (might be a bigger value than 1)
function returns carry (1) (if it was)
*/
template<uint value_size>
uint UInt<value_size>::Sub(const UInt<value_size> & ss2, uint c)
{
uint i;
for(i=0 ; i<value_size ; ++i)
c = SubTwoWords(table[i], ss2.table[i], c, &table[i]);
TTMATH_LOG("UInt::Sub")
return c;
}
/*!
this method subtracts one word (at a specific position)
and returns a carry (if it was)
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[2] it would be returned
*/
template<uint value_size>
uint UInt<value_size>::SubInt(uint value, uint index)
{
uint i, c;
TTMATH_ASSERT( index < value_size )
c = SubTwoWords(table[index], value, 0, &table[index]);
for(i=index+1 ; i<value_size && c ; ++i)
c = SubTwoWords(table[i], 0, c, &table[i]);
TTMATH_LOG("UInt::SubInt")
return c;
}
/*!
this static method subtractes one vector from the other
'ss1' is larger in size or equal to 'ss2'
ss1 points to the first (larger) vector
ss2 points to the second vector
ss1_size - size of the ss1 (and size of the result too)
ss2_size - size of the ss2
result - is the result vector (which has size the same as ss1: ss1_size)
Example: ss1_size is 5, ss2_size is 3
ss1: ss2: result (output):
5 1 5-1
4 3 4-3
2 7 2-7
6 6-1 (the borrow from previous item)
9 9
return (carry): 0
of course the carry (borrow) is propagated and will be returned from the last item
(this method is used by the Karatsuba multiplication algorithm)
*/
template<uint value_size>
uint UInt<value_size>::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
{
uint i, c = 0;
TTMATH_ASSERT( ss1_size >= ss2_size )
for(i=0 ; i<ss2_size ; ++i)
c = SubTwoWords(ss1[i], ss2[i], c, &result[i]);
for( ; i<ss1_size ; ++i)
c = SubTwoWords(ss1[i], 0, c, &result[i]);
//TTMATH_LOG("UInt::SubVector")
return c;
}
/*!
this method moves all bits into the left hand side
return value <- this <- c
the lowest *bit* will be held the 'c' and
the state of one additional bit (on the left hand side)
will be returned
for example:
let this is 001010000
after Rcl2_one(1) there'll be 010100001 and Rcl2_one returns 0
*/
template<uint value_size>
uint UInt<value_size>::Rcl2_one(uint c)
{
uint i, new_c;
if( c != 0 )
c = 1;
for(i=0 ; i<value_size ; ++i)
{
new_c = (table[i] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
table[i] = (table[i] << 1) | c;
c = new_c;
}
TTMATH_LOG("UInt::Rcl2_one")
return c;
}
/*!
this method moves all bits into the right hand side
c -> this -> return value
the highest *bit* will be held the 'c' and
the state of one additional bit (on the right hand side)
will be returned
for example:
let this is 000000010
after Rcr2_one(1) there'll be 100000001 and Rcr2_one returns 0
*/
template<uint value_size>
uint UInt<value_size>::Rcr2_one(uint c)
{
sint i; // signed i
uint new_c;
if( c != 0 )
c = TTMATH_UINT_HIGHEST_BIT;
for(i=sint(value_size)-1 ; i>=0 ; --i)
{
new_c = (table[i] & 1) ? TTMATH_UINT_HIGHEST_BIT : 0;
table[i] = (table[i] >> 1) | c;
c = new_c;
}
TTMATH_LOG("UInt::Rcr2_one")
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
*/
template<uint value_size>
uint UInt<value_size>::Rcl2(uint bits, uint c)
{
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
uint move = TTMATH_BITS_PER_UINT - bits;
uint i, new_c;
if( c != 0 )
c = TTMATH_UINT_MAX_VALUE >> move;
for(i=0 ; i<value_size ; ++i)
{
new_c = table[i] >> move;
table[i] = (table[i] << bits) | c;
c = new_c;
}
TTMATH_LOG("UInt::Rcl2")
return (c & 1);
}
/*!
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
*/
template<uint value_size>
uint UInt<value_size>::Rcr2(uint bits, uint c)
{
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
uint move = TTMATH_BITS_PER_UINT - bits;
sint i; // signed
uint new_c;
if( c != 0 )
c = TTMATH_UINT_MAX_VALUE << move;
for(i=value_size-1 ; i>=0 ; --i)
{
new_c = table[i] << move;
table[i] = (table[i] >> bits) | c;
c = new_c;
}
TTMATH_LOG("UInt::Rcr2")
return (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
}
/*
this method returns the number of the highest set bit in x
if the 'x' is zero this method returns '-1'
*/
template<uint value_size>
sint UInt<value_size>::FindLeadingBitInWord(uint x)
{
if( x == 0 )
return -1;
uint bit = TTMATH_BITS_PER_UINT - 1;
while( (x & TTMATH_UINT_HIGHEST_BIT) == 0 )
{
x = x << 1;
--bit;
}
return bit;
}
/*!
this method sets a special bit in the 'value'
and returns the last state of the bit (zero or one)
bit is from <0,63>
e.g.
uint x = 100;
uint bit = SetBitInWord(x, 3);
now: x = 108 and bit = 0
*/
template<uint value_size>
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
{
TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT )
uint mask = 1;
if( bit > 0 )
mask = mask << bit;
uint last = value & mask;
value = value | mask;
return (last != 0) ? 1 : 0;
}
/*!
*
* Multiplication
*
*
*/
/*!
multiplication: result_high:result_low = a * b
result_high - higher word of the result
result_low - lower word of the result
this methos never returns a carry
this method is used in the second version of the multiplication algorithms
*/
template<uint value_size>
void UInt<value_size>::MulTwoWords(uint a, uint b, uint * result_high, uint * result_low)
{
#ifdef TTMATH_PLATFORM32
/*
on 32bit platforms we have defined 'unsigned long long int' type known as 'ulint' in ttmath namespace
this type has 64 bits, then we're using only one multiplication: 32bit * 32bit = 64bit
*/
union uint_
{
struct
{
uint low; // 32 bits
uint high; // 32 bits
} u_;
ulint u; // 64 bits
} res;
res.u = ulint(a) * ulint(b); // multiply two 32bit words, the result has 64 bits
*result_high = res.u_.high;
*result_low = res.u_.low;
#else
/*
64 bits platforms
we don't have a native type which has 128 bits
then we're splitting 'a' and 'b' to 4 parts (high and low halves)
and using 4 multiplications (with additions and carry correctness)
*/
uint_ a_;
uint_ b_;
uint_ res_high1, res_high2;
uint_ res_low1, res_low2;
a_.u = a;
b_.u = b;
/*
the multiplication is as follows (schoolbook algorithm with O(n^2) ):
32 bits 32 bits
+--------------------------------+
| a_.u_.high | a_.u_.low |
+--------------------------------+
| b_.u_.high | b_.u_.low |
+--------------------------------+--------------------------------+
| res_high1.u | res_low1.u |
+--------------------------------+--------------------------------+
| res_high2.u | res_low2.u |
+--------------------------------+--------------------------------+
64 bits 64 bits
*/
uint_ temp;
res_low1.u = uint(b_.u_.low) * uint(a_.u_.low);
temp.u = uint(res_low1.u_.high) + uint(b_.u_.low) * uint(a_.u_.high);
res_low1.u_.high = temp.u_.low;
res_high1.u_.low = temp.u_.high;
res_high1.u_.high = 0;
res_low2.u_.low = 0;
temp.u = uint(b_.u_.high) * uint(a_.u_.low);
res_low2.u_.high = temp.u_.low;
res_high2.u = uint(b_.u_.high) * uint(a_.u_.high) + uint(temp.u_.high);
uint c = AddTwoWords(res_low1.u, res_low2.u, 0, &res_low2.u);
AddTwoWords(res_high1.u, res_high2.u, c, &res_high2.u); // there is no carry from here
*result_high = res_high2.u;
*result_low = res_low2.u;
#endif
}
/*!
*
* Division
*
*
*/
/*!
this method calculates 64bits word a:b / 32bits c (a higher, b lower word)
r = a:b / c and rest - remainder
*
* WARNING:
* the c has to be suitably large for the result being keeped in one word,
* if 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)
{
// (a < c ) for the result to be one word
TTMATH_ASSERT( c != 0 && a < c )
#ifdef TTMATH_PLATFORM32
union
{
struct
{
uint low; // 32 bits
uint high; // 32 bits
} u_;
ulint u; // 64 bits
} ab;
ab.u_.high = a;
ab.u_.low = b;
*r = uint(ab.u / c);
*rest = uint(ab.u % c);
#else
uint_ c_;
c_.u = c;
if( a == 0 )
{
*r = b / c;
*rest = b % c;
}
else
if( c_.u_.high == 0 )
{
// higher half of 'c' is zero
// then higher half of 'a' is zero too (look at the asserts at the beginning - 'a' is smaller than 'c')
uint_ a_, b_, res_, temp1, temp2;
a_.u = a;
b_.u = b;
temp1.u_.high = a_.u_.low;
temp1.u_.low = b_.u_.high;
res_.u_.high = temp1.u / c;
temp2.u_.high = temp1.u % c;
temp2.u_.low = b_.u_.low;
res_.u_.low = temp2.u / c;
*rest = temp2.u % c;
*r = res_.u;
}
else
{
return DivTwoWords2(a, b, c, r, rest);
}
#endif
}
#ifdef TTMATH_PLATFORM64
/*!
this method is available only on 64bit platforms
the same algorithm like the third division algorithm in ttmathuint.h
but now with the radix=2^32
*/
template<uint value_size>
void UInt<value_size>::DivTwoWords2(uint a, uint b, uint c, uint * r, uint * rest)
{
// a is not zero
// c_.u_.high is not zero
uint_ a_, b_, c_, u_, q_;
unsigned int u3; // 32 bit
a_.u = a;
b_.u = b;
c_.u = c;
// normalizing
uint d = DivTwoWordsNormalize(a_, b_, c_);
// loop from j=1 to j=0
// the first step (for j=2) is skipped because our result is only in one word,
// (first 'q' were 0 and nothing would be changed)
u_.u_.high = a_.u_.high;
u_.u_.low = a_.u_.low;
u3 = b_.u_.high;
q_.u_.high = DivTwoWordsCalculate(u_, u3, c_);
MultiplySubtract(u_, u3, q_.u_.high, c_);
u_.u_.high = u_.u_.low;
u_.u_.low = u3;
u3 = b_.u_.low;
q_.u_.low = DivTwoWordsCalculate(u_, u3, c_);
MultiplySubtract(u_, u3, q_.u_.low, c_);
*r = q_.u;
// unnormalizing for the remainder
u_.u_.high = u_.u_.low;
u_.u_.low = u3;
*rest = DivTwoWordsUnnormalize(u_.u, d);
}
template<uint value_size>
uint UInt<value_size>::DivTwoWordsNormalize(uint_ & a_, uint_ & b_, uint_ & c_)
{
uint d = 0;
for( ; (c_.u & TTMATH_UINT_HIGHEST_BIT) == 0 ; ++d )
{
c_.u = c_.u << 1;
uint bc = b_.u & TTMATH_UINT_HIGHEST_BIT; // carry from 'b'
b_.u = b_.u << 1;
a_.u = a_.u << 1; // carry bits from 'a' are simply skipped
if( bc )
a_.u = a_.u | 1;
}
return d;
}
template<uint value_size>
uint UInt<value_size>::DivTwoWordsUnnormalize(uint u, uint d)
{
if( d == 0 )
return u;
u = u >> d;
return u;
}
template<uint value_size>
unsigned int UInt<value_size>::DivTwoWordsCalculate(uint_ u_, unsigned int u3, uint_ v_)
{
bool next_test;
uint_ qp_, rp_, temp_;
qp_.u = u_.u / uint(v_.u_.high);
rp_.u = u_.u % uint(v_.u_.high);
TTMATH_ASSERT( qp_.u_.high==0 || qp_.u_.high==1 )
do
{
bool decrease = false;
if( qp_.u_.high == 1 )
decrease = true;
else
{
temp_.u_.high = rp_.u_.low;
temp_.u_.low = u3;
if( qp_.u * uint(v_.u_.low) > temp_.u )
decrease = true;
}
next_test = false;
if( decrease )
{
--qp_.u;
rp_.u += v_.u_.high;
if( rp_.u_.high == 0 )
next_test = true;
}
}
while( next_test );
return qp_.u_.low;
}
template<uint value_size>
void UInt<value_size>::MultiplySubtract(uint_ & u_, unsigned int & u3, unsigned int & q, uint_ v_)
{
uint_ temp_;
uint res_high;
uint res_low;
MulTwoWords(v_.u, q, &res_high, &res_low);
uint_ sub_res_high_;
uint_ sub_res_low_;
temp_.u_.high = u_.u_.low;
temp_.u_.low = u3;
uint c = SubTwoWords(temp_.u, res_low, 0, &sub_res_low_.u);
temp_.u_.high = 0;
temp_.u_.low = u_.u_.high;
c = SubTwoWords(temp_.u, res_high, c, &sub_res_high_.u);
if( c )
{
--q;
c = AddTwoWords(sub_res_low_.u, v_.u, 0, &sub_res_low_.u);
AddTwoWords(sub_res_high_.u, 0, c, &sub_res_high_.u);
}
u_.u_.high = sub_res_high_.u_.low;
u_.u_.low = sub_res_low_.u_.high;
u3 = sub_res_low_.u_.low;
}
#endif // #ifdef TTMATH_PLATFORM64
} //namespace
#endif //ifdef TTMATH_NOASM
#endif

1514
ttmath/ttmathuint_x86.h Normal file

File diff suppressed because it is too large Load Diff

1013
ttmath/ttmathuint_x86_64.h Normal file

File diff suppressed because it is too large Load Diff