32 Commits
0.9.0 ... 0.9.2

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


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



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


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



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

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

       also the method has been a little improved




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


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



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



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



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


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



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


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



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




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


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



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



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



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



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


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



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



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



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



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@255 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-12-02 11:38:17 +00:00
19 changed files with 3251 additions and 829 deletions

114
CHANGELOG
View File

@@ -1,3 +1,117 @@
Version 0.9.2 (2010.09.23):
* fixed: Big::Add() sometimes incorrectly rounded the last bit from its mantissa
* fixed: Big::BigAnd() Big::BigOr() Big::BigXor() should have set NaN
when the argument was negative (they only returned 2)
* fixed: recurrence calling in Big::FromString(const std::string &, uint, const wchar_t **, bool *)
it should have the signature: Big::FromString(const std::string &, uint, const char **, bool *)
* fixed: Big::ToString method
in some cases when in the output string the exponent should be equal zero
the method changes the exponent to one so the last digit from the mantissa
was lost
* fixed: Big::ToDouble(double &) set always +INF (infinity)
when the value was too large (even for negative values)
(it should set -INF in such a case)
* added: some missing operators
UInt::operator~() /* bitwise neg */
UInt::operator&() /* bitwise and */
UInt::operator&=()
UInt::operator|() /* bitwise or */
UInt::operator|=()
UInt::operator^() /* bitwise xor */
UInt::operator^=()
Big::operator&()
Big::operator&=()
Big::operator|()
Big::operator|=()
Big::operator^()
Big::operator^=()
for Big<> we do not define bitwise neg
Big::operator++()
Big::operator++(int)
Big::operator--()
Big::operator--(int)
* added: macro TTMATH_DONT_USE_WCHAR
if defined then the library does not use wide characters
(wchar_t, std::wstring, ...) this is a workaround for some compilers
* added: bool UInt::IsOnlyTheHighestBitSet()
bool UInt::IsOnlyTheLowestBitSet()
returning true if only the highest/lowest bit is set
* added: uint Int::MulInt(sint ss2)
* added: void UInt::Swap(UInt<value_size> & ss2)
void Big::Swap(UInt<value_size> & ss2)
method for swapping this for an argument
* added: macro TTMATH_BIG_DEFAULT_CLEAR
when defined the default constructor from Big<> clears its mantissa and exponent
Big<1, 2> var;
var.mantissa and var.exponent will be set to zero
(but var has the NaN flag set too - it is not zero value, this is mainly for debug purposes)
* added: only on 32bit platforms:
uint UInt::FromUInt(uint64_t n)
uint Int::FromInt(int64_t n)
void Big::FromUInt(uint64_t n)
void Big::FromInt(int64_t n)
and appropriate constructors and operators
* added: TTMATH_FORCEASM macro
asm version of the library is available by default only for:
x86 and amd64 platforms and for Microsoft Visual and GCC compilers,
but you can force using asm version (the same asm as for Microsoft Visual)
by defining TTMATH_FORCEASM macro
you have to be sure that your compiler accept such an asm format
* added: some missing methods for converting
for UInt<>, Int<> and Big<> classes:
uint ToUInt()
sint ToInt()
ToUInt(uint32_t &)
ToInt(uint32_t &)
ToInt(int32_t &)
ToUInt(uint64_t &)
ToInt(uint64_t &)
ToInt(int64_t &)
FromUInt(uint32_t &)
FromInt(uint32_t &)
FromInt(int32_t &)
FromUInt(uint64_t &)
FromInt(uint64_t &)
FromInt(int64_t &)
and appropriate constructors and operators
* added: double Big::ToDouble() /there was only Big::ToDouble(double &) /
uint Big::ToFloat(float &)
float Big::ToFloat()
* changed: now asm version is available only on x86 and amd64
(and only for GCC and MS VC compilers)
* removed: macro TTMATH_RELEASE (now the 'release' version is default)
for debug version define TTMATH_DEBUG macro
TTMATH_DEBUG is also automatically defined when DEBUG or _DEBUG is set
* removed: macro TTMATH_REFERENCE_ASSERT from all methods in public interface
Version 0.9.1 (2010.02.07):
* fixed: the parser didn't use characters for changing the base (# and &)
those characters were skipped
(this bug was introduced in 0.9.0)
* fixed: added in the parser: operator's associativity
operator ^ (powering) is right-associative:
sample: 2^3^4 is equal 2^(3^4) and it is: 2.41e+24
previously was: 2^3^4 = (2^3)^4 = 4096
* fixed: in Big::ToString_CreateNewMantissaAndExponent() changed the formula:
new_exp_ = [log base (2^exponent)] + 1
now the part '+ 1' is only made when the logarithm is positive and with fraction
if the value is negative we can only skip the fraction, previously
we lost some last digits from the new mantissa
Consider this binary value (32 bit mantissa):
(bin)1.0000000000000000000000000000011
previously ToString() gave 1, now we have: 1.000000001
* changed: in Big::ToString() the base rounding is made only if the result value
would not be an integer, e.g. if the value is 1.999999999999 then
the base rounding will not be done - because as the result would be 2
* added: IEEE 754 half-to-even rounding (bankers' rounding) to the following
floating point algorithms: Big::Add, Big::Sub, Big::Mul, Big::Div
* added: static sint UInt<value_size>::FindLowestBitInWord(uint x)
this method is looking for the lowest set bit in a word
* added: UInt::FindLowestBit(uint & table_id, uint & index)
this method is looking for the lowest set bit
Version 0.9.0 (2009.11.25):
* added: support for wide characters (wchar_t, std::wstring)
* added: Big::IsInteger()

View File

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

View File

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

View File

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

View File

@@ -5,6 +5,8 @@
// this type has 2 words for its mantissa and 1 word for its exponent
// (on a 32bit platform one word means a word of 32 bits,
// and on a 64bit platform one word means a word of 64 bits)
// Big<exponent, mantissa>
typedef ttmath::Big<1,2> MyBig;
@@ -56,6 +58,7 @@ MyBig atemp;
}
int main()
{
MyBig a,b;
@@ -85,13 +88,13 @@ a = 123456.543456
b = 98767878.124322
a + b = 98891334.667778
a - b = -98644421.580866
a * b = 12193540837712.2708
a / b = 0.0012499665458095765
a * b = 12193540837712.27076
a / b = 0.00124996654580957646
Calculating with a carry
a = 1.624801256070839555e+646457012
b = 456.31999999999999
a + b = 1.624801256070839555e+646457012
a - b = 1.624801256070839555e+646457012
a = 1.6248012560666408782e+646457012
b = 456.319999999999993
a + b = 1.6248012560666408782e+646457012
a - b = 1.6248012560666408782e+646457012
a * b = (carry)
a / b = 3.56066193914542334e+646457009
a / b = 3.560661939136222174e+646457009
*/

113
samples/big2.cpp Normal file
View File

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

View File

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

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* Copyright (c) 2006-2010, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -273,12 +273,16 @@ namespace ttmath
template<class ValueType>
ValueType Log(const ValueType & x, const ValueType & base, ErrorCode * err = 0)
{
if( x.IsNan() || base.IsNan() )
if( x.IsNan() )
{
if( err )
*err = err_improper_argument;
if( err ) *err = err_improper_argument;
return x;
}
return ValueType(); // default NaN
if( base.IsNan() )
{
if( err ) *err = err_improper_argument;
return base;
}
ValueType result;
@@ -523,7 +527,7 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return result; // NaN is set by default
return x;
}
if( err )
@@ -854,7 +858,7 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return result; // NaN is set by default
return x;
}
if( x.GreaterWithoutSignThan(one) )
@@ -1080,7 +1084,7 @@ namespace ttmath
bool change_sign = false;
if( x.IsNan() )
return result; // NaN is set by default
return x;
// if x is negative we're using the formula:
// atan(-x) = -atan(x)
@@ -1548,7 +1552,7 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return result; // NaN is set by default
return x;
}
result = x;
@@ -1584,7 +1588,7 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return result; // NaN is set by default
return x;
}
result = 180;
@@ -1629,7 +1633,9 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return delimiter ; // NaN is set by default
delimiter.SetZeroNan(); // not needed, only to get rid of GCC warning about an uninitialized variable
return delimiter;
}
multipler = 60;
@@ -1683,7 +1689,7 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return result; // NaN is set by default
return x;
}
result = x;
@@ -1719,7 +1725,7 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return result; // NaN is set by default
return x;
}
result = 200;
@@ -1751,7 +1757,7 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return result; // NaN is set by default
return x;
}
result = x;
@@ -1801,7 +1807,7 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return result; // NaN is set by default
return x;
}
result = x;
@@ -1842,7 +1848,9 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return ValueType(); // NaN is set by default
x.SetNan();
return x;
}
uint c = x.Sqrt();
@@ -2065,7 +2073,9 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return ValueType(); // NaN is set by default
x.SetNan();
return x;
}
if( RootCheckIndexSign(x, index, err) ) return x;
@@ -2154,7 +2164,9 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return ValueType(); // NaN is set by default
a.SetNan();
return a;
}
uint c = a.Mod(b);
@@ -2652,7 +2664,7 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return result; // NaN is set by default
return n;
}
if( cgamma.history.Get(n, result, err_tmp) )
@@ -2731,7 +2743,9 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return result; // NaN set by default
x.SetNan();
return x;
}
one.SetOne();
@@ -2807,7 +2821,7 @@ namespace ttmath
}
// the simplest way to initialize is to call the Gamma function with (TTMATH_GAMMA_BOUNDARY + 1)
// when x is larger then less coefficients we need
// when x is larger then fewer coefficients we need
Gamma(x, *this);
}

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* Copyright (c) 2006-2010, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -104,13 +104,10 @@ public:
*/
uint ChangeSign()
{
Int<value_size> temp;
temp.SetMin();
/*
if the value is equal that one which has been returned from SetMin
that means we can't change sign because the value is too big (bigger about one)
(only the highest bit is set) that means we can't change sign
because the value is too big (bigger about one)
e.g. when value_size = 1 and value is -2147483648 we can't change it to the
2147483648 because the max value which can be held is 2147483647
@@ -119,13 +116,12 @@ public:
(if we look on our value without the sign we get the correct value
eg. -2147483648 in Int<1> will be 2147483648 on the UInt<1> type)
*/
if( operator==(temp) )
if( UInt<value_size>::IsOnlyTheHighestBitSet() )
return 1;
temp.SetZero();
temp.UInt<value_size>::Sub(*this);
operator=(temp);
UInt<value_size> temp(*this);
UInt<value_size>::SetZero();
UInt<value_size>::Sub(temp);
return 0;
}
@@ -350,33 +346,11 @@ public:
}
private:
/*!
multiplication this = this * ss2
it returns carry if the result is too big
(we're using the method from the base class but we have to make
one correction in account of signs)
*/
uint Mul(Int<value_size> ss2)
uint CheckMinCarry(bool ss1_is_sign, bool ss2_is_sign)
{
bool ss1_is_sign, ss2_is_sign;
ss1_is_sign = IsSign();
ss2_is_sign = ss2.IsSign();
/*
we don't have to check the carry from Abs (values will be correct
because next we're using the method Mul from the base class UInt
which is without a sign)
*/
Abs();
ss2.Abs();
if( UInt<value_size>::Mul(ss2) )
return 1;
/*
we have to examine the sign of the result now
but if the result is with the sign then:
@@ -391,36 +365,100 @@ public:
*/
if( IsSign() )
{
/*
there can be one case where signs are different and
the result will be equal the value from SetMin()
(this situation is ok)
*/
if( ss1_is_sign != ss2_is_sign )
{
Int<value_size> temp;
temp.SetMin();
if( operator!=(temp) )
/*
the result is too big
*/
/*
there can be one case where signs are different and
the result will be equal the value from SetMin() (only the highest bit is set)
(this situation is ok)
*/
if( !UInt<value_size>::IsOnlyTheHighestBitSet() )
return 1;
}
else
{
/*
the result is too big
*/
// signs were the same
return 1;
}
}
return 0;
}
public:
/*!
multiplication: this = this * ss2
it can return a carry
*/
uint MulInt(sint ss2)
{
bool ss1_is_sign, ss2_is_sign;
uint c;
ss1_is_sign = IsSign();
/*
we don't have to check the carry from Abs (values will be correct
because next we're using the method MulInt from the base class UInt
which is without a sign)
*/
Abs();
if( ss2 < 0 )
{
ss2 = -ss2;
ss2_is_sign = true;
}
else
{
ss2_is_sign = false;
}
c = UInt<value_size>::MulInt((uint)ss2);
c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
if( ss1_is_sign != ss2_is_sign )
SetSign();
return c;
}
return 0;
/*!
multiplication this = this * ss2
it returns carry if the result is too big
(we're using the method from the base class but we have to make
one correction in account of signs)
*/
uint Mul(Int<value_size> ss2)
{
bool ss1_is_sign, ss2_is_sign;
uint c;
ss1_is_sign = IsSign();
ss2_is_sign = ss2.IsSign();
/*
we don't have to check the carry from Abs (values will be correct
because next we're using the method Mul from the base class UInt
which is without a sign)
*/
Abs();
ss2.Abs();
c = UInt<value_size>::Mul(ss2);
c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
if( ss1_is_sign != ss2_is_sign )
SetSign();
return c;
}
@@ -688,6 +726,16 @@ public:
}
/*!
this method converts UInt<another_size> into this class
*/
template<uint argument_size>
uint FromInt(const UInt<argument_size> & p)
{
return FromUIntOrInt(p, true);
}
/*!
this method converts the uint type into this class
*/
@@ -707,6 +755,14 @@ public:
}
/*!
this method converts the uint type into this class
*/
uint FromInt(uint value)
{
return FromUInt(value);
}
/*!
the default assignment operator
@@ -820,63 +876,194 @@ public:
#ifdef TTMATH_PLATFORM32
/*!
this method converts unsigned 64 bit int type to this class
***this method is created only on a 32bit platform***
*/
uint FromUInt(ulint n)
{
uint c = UInt<value_size>::FromUInt(n);
if( c )
return 1;
if( value_size == 1 )
return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
if( value_size == 2 )
return ((UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
return 0;
}
/*!
this method converts unsigned 64 bit int type to this class
***this method is created only on a 32bit platform***
*/
uint FromInt(ulint n)
{
return FromUInt(n);
}
/*!
this method converts signed 64 bit int type to this class
***this method is created only on a 32bit platform***
*/
uint FromInt(slint n)
{
uint mask = (n < 0) ? TTMATH_UINT_MAX_VALUE : 0;
UInt<value_size>::table[0] = (uint)(ulint)n;
if( value_size == 1 )
{
if( uint(ulint(n) >> 32) != mask )
return 1;
return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1;
}
UInt<value_size>::table[1] = (uint)(ulint(n) >> 32);
for(uint i=2 ; i<value_size ; ++i)
UInt<value_size>::table[i] = mask;
return 0;
}
/*!
this operator converts unsigned 64 bit int type to this class
***this operator is created only on a 32bit platform***
*/
Int<value_size> & operator=(ulint n)
{
FromUInt(n);
return *this;
}
/*!
a constructor for converting unsigned 64 bit int to this class
***this constructor is created only on a 32bit platform***
*/
Int(ulint n)
{
FromUInt(n);
}
/*!
this operator converts signed 64 bit int type to this class
***this operator is created only on a 32bit platform***
*/
Int<value_size> & operator=(slint n)
{
FromInt(n);
return *this;
}
/*!
a constructor for converting signed 64 bit int to this class
***this constructor is created only on a 32bit platform***
*/
Int(slint n)
{
FromInt(n);
}
#endif
#ifdef TTMATH_PLATFORM64
/*!
this method converts the signed int type to this class
this method converts 32 bit unsigned int type to this class
***this operator is created only on a 64bit platform***
it takes one argument of 32bit
*/
Int<value_size> & operator=(signed int i)
uint FromUInt(unsigned int i)
{
FromInt(sint(i));
return *this;
return FromUInt(uint(i));
}
/*!
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
this method converts 32 bit unsigned int type to this class
***this operator is created only on a 64bit platform***
*/
Int(signed int i)
uint FromInt(unsigned int i)
{
FromInt(sint(i));
return FromUInt(i);
}
/*!
this method converts the unsigned int type to this class
this method converts 32 bit signed int type to this class
***this operator is created only on a 64bit platform***
*/
uint FromInt(signed int i)
{
return FromInt(sint(i));
}
/*!
this method converts 32 bit unsigned int type to this class
***this operator is created only on a 64bit platform***
it takes one argument of 32bit
*/
Int<value_size> & operator=(unsigned int i)
{
FromUInt(uint(i));
FromUInt(i);
return *this;
}
/*!
a constructor for converting the unsigned int to this class
a constructor for converting 32 bit unsigned int to this class
***this constructor is created only on a 64bit platform***
it takes one argument of 32bit
*/
Int(unsigned int i)
{
FromUInt(uint(i));
FromUInt(i);
}
/*!
this operator converts 32 bit signed int type to this class
***this operator is created only on a 64bit platform***
*/
Int<value_size> & operator=(signed int i)
{
FromInt(i);
return *this;
}
/*!
a constructor for converting 32 bit signed int to this class
***this constructor is created only on a 64bit platform***
*/
Int(signed int i)
{
FromInt(i);
}
#endif
/*!
a constructor for converting string to this class (with the base=10)
*/
@@ -886,15 +1073,6 @@ public:
}
/*!
a constructor for converting string to this class (with the base=10)
*/
Int(const wchar_t * s)
{
FromString(s);
}
/*!
a constructor for converting a string to this class (with the base=10)
*/
@@ -904,6 +1082,17 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
a constructor for converting string to this class (with the base=10)
*/
Int(const wchar_t * s)
{
FromString(s);
}
/*!
a constructor for converting a string to this class (with the base=10)
*/
@@ -912,6 +1101,8 @@ public:
FromString( s.c_str() );
}
#endif
/*!
a default constructor
@@ -943,6 +1134,175 @@ public:
}
/*!
this method converts the value to uint type
can return a carry if the value is too long to store it in uint type
*/
uint ToUInt(uint & result) const
{
uint c = UInt<value_size>::ToUInt(result);
if( value_size == 1 )
return (result & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
return c;
}
/*!
this method converts the value to uint type
can return a carry if the value is too long to store it in uint type
*/
uint ToInt(uint & result) const
{
return ToUInt(result);
}
/*!
this method converts the value to sint type
can return a carry if the value is too long to store it in sint type
*/
uint ToInt(sint & result) const
{
result = sint( UInt<value_size>::table[0] );
uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
if( (result & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
return 1;
for(uint i=1 ; i<value_size ; ++i)
if( UInt<value_size>::table[i] != mask )
return 1;
return 0;
}
#ifdef TTMATH_PLATFORM32
/*!
this method converts the value to ulint type (64 bit unsigned integer)
can return a carry if the value is too long to store it in ulint type
*** this method is created only on a 32 bit platform ***
*/
uint ToUInt(ulint & result) const
{
uint c = UInt<value_size>::ToUInt(result);
if( value_size == 1 )
return (UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
if( value_size == 2 )
return (UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
return c;
}
/*!
this method converts the value to ulint type (64 bit unsigned integer)
can return a carry if the value is too long to store it in ulint type
*** this method is created only on a 32 bit platform ***
*/
uint ToInt(ulint & result) const
{
return ToUInt(result);
}
/*!
this method converts the value to slint type (64 bit signed integer)
can return a carry if the value is too long to store it in slint type
*** this method is created only on a 32 bit platform ***
*/
uint ToInt(slint & result) const
{
if( value_size == 1 )
{
result = slint(sint(UInt<value_size>::table[0]));
}
else
{
uint low = UInt<value_size>::table[0];
uint high = UInt<value_size>::table[1];
result = low;
result |= (ulint(high) << TTMATH_BITS_PER_UINT);
uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
if( (high & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
return 1;
for(uint i=2 ; i<value_size ; ++i)
if( UInt<value_size>::table[i] != mask )
return 1;
}
return 0;
}
#endif
#ifdef TTMATH_PLATFORM64
/*!
this method converts the value to a 32 bit unsigned integer
can return a carry if the value is too long to store it in this type
*** this method is created only on a 64 bit platform ***
*/
uint ToUInt(unsigned int & result) const
{
uint c = UInt<value_size>::ToUInt(result);
if( c || IsSign() )
return 1;
return 0;
}
/*!
this method converts the value to a 32 bit unsigned integer
can return a carry if the value is too long to store it in this type
*** this method is created only on a 64 bit platform ***
*/
uint ToInt(unsigned int & result) const
{
return ToUInt(result);
}
/*!
this method converts the value to a 32 bit signed integer
can return a carry if the value is too long to store it in this type
*** this method is created only on a 64 bit platform ***
*/
uint ToInt(int & result) const
{
uint first = UInt<value_size>::table[0];
result = int(first);
uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
if( (first >> 31) != (mask >> 31) )
return 1;
for(uint i=1 ; i<value_size ; ++i)
if( UInt<value_size>::table[i] != mask )
return 1;
return 0;
}
#endif
private:
/*!
@@ -976,15 +1336,6 @@ public:
}
/*!
this method converts the value to a string with a base equal 'b'
*/
void ToString(std::wstring & result, uint b = 10) const
{
return ToStringBase(result, b);
}
/*!
this method converts the value to a string with a base equal 'b'
*/
@@ -997,6 +1348,17 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method converts the value to a string with a base equal 'b'
*/
void ToString(std::wstring & result, uint b = 10) const
{
return ToStringBase(result, b);
}
/*!
this method converts the value to a string with a base equal 'b'
*/
@@ -1008,6 +1370,9 @@ public:
return result;
}
#endif
private:
@@ -1111,16 +1476,6 @@ public:
}
/*!
this method converts a string into its value
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
*/
uint FromString(const std::wstring & s, uint b = 10)
{
return FromString( s.c_str(), b );
}
/*!
this operator converts a string into its value (with base = 10)
*/
@@ -1132,6 +1487,19 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method converts a string into its value
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
*/
uint FromString(const std::wstring & s, uint b = 10)
{
return FromString( s.c_str(), b );
}
/*!
this operator converts a string into its value (with base = 10)
*/
@@ -1143,6 +1511,19 @@ public:
}
/*!
this operator converts a string into its value (with base = 10)
*/
Int<value_size> & operator=(const std::wstring & s)
{
FromString( s.c_str() );
return *this;
}
#endif
/*!
this operator converts a string into its value (with base = 10)
*/
@@ -1154,16 +1535,6 @@ public:
}
/*!
this operator converts a string into its value (with base = 10)
*/
Int<value_size> & operator=(const std::wstring & s)
{
FromString( s.c_str() );
return *this;
}
/*!
*
@@ -1382,11 +1753,9 @@ public:
Int<value_size> & operator%=(const Int<value_size> & p2)
{
Int<value_size> temp(*this);
Int<value_size> remainder;
temp.Div(p2, remainder);
Div(p2, remainder);
operator=(remainder);
return *this;
@@ -1472,6 +1841,8 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
output to standard streams
*/
@@ -1480,6 +1851,8 @@ public:
return OutputToStream<std::wostream, std::wstring>(s, l);
}
#endif
private:
@@ -1532,6 +1905,8 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
input from standard streams
*/
@@ -1539,6 +1914,8 @@ public:
{
return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
}
#endif
};

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* Copyright (c) 2006-2010, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -75,6 +75,8 @@ static void AssignString(std::string & result, const char * str)
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
result = str
*/
@@ -116,6 +118,8 @@ static void AssignString(std::string & result, const std::wstring & str)
return AssignString(result, str.c_str());
}
#endif
/*
*
@@ -134,6 +138,8 @@ static void AddString(std::string & result, const char * str)
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
result += str
*/
@@ -143,6 +149,7 @@ static void AddString(std::wstring & result, const char * str)
result += *str;
}
#endif
/*

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* Copyright (c) 2006-2010, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -99,7 +99,7 @@ public:
if 'can_be_digit' is true that means when the 'c' is a digit this
method returns true otherwise it returns false
*/
static bool CorrectCharacter(wchar_t c, bool can_be_digit)
static bool CorrectCharacter(int c, bool can_be_digit)
{
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
return true;
@@ -148,6 +148,9 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method returns true if such an object is defined (name exists)
*/
@@ -163,6 +166,8 @@ public:
return IsDefined(str_tmp1);
}
#endif
/*!
this method adds one object (variable of function) into the table
@@ -184,6 +189,8 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method adds one object (variable of function) into the table
*/
@@ -200,6 +207,8 @@ public:
return Add(str_tmp1, str_tmp2, param);
}
#endif
/*!
this method returns 'true' if the table is empty
@@ -258,6 +267,9 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method changes the value and the number of parameters for a specific object
*/
@@ -274,6 +286,8 @@ public:
return EditValue(str_tmp1, str_tmp2, param);
}
#endif
/*!
this method changes the name of a specific object
@@ -306,6 +320,10 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method changes the name of a specific object
*/
@@ -322,6 +340,8 @@ public:
return EditName(str_tmp1, str_tmp2);
}
#endif
/*!
this method deletes an object
@@ -342,6 +362,9 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method deletes an object
*/
@@ -357,6 +380,8 @@ public:
return Delete(str_tmp1);
}
#endif
/*!
this method gets the value of a specific object
@@ -380,6 +405,8 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method gets the value of a specific object
*/
@@ -397,6 +424,8 @@ public:
return err;
}
#endif
/*!
this method gets the value of a specific object
@@ -421,6 +450,8 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method gets the value of a specific object
(this version is used for not copying the whole string)
@@ -437,6 +468,8 @@ public:
return GetValue(str_tmp1, value);
}
#endif
/*!
this method gets the value and the number of parameters
@@ -463,6 +496,8 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method gets the value and the number of parameters
of a specific object
@@ -481,6 +516,8 @@ public:
return err;
}
#endif
/*!
this method sets the value and the number of parameters
@@ -508,6 +545,9 @@ public:
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
this method sets the value and the number of parameters
of a specific object
@@ -527,6 +567,9 @@ public:
}
#endif
/*!
this method returns a pointer into the table
*/

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* Copyright (c) 2006-2010, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -131,8 +131,8 @@ namespace ttmath
for example:
"1+2;4+5"
the result will be on the stack as follows:
"3"
"9"
stack[0].value=3
stack[1].value=9
*/
template<class ValueType>
class Parser
@@ -159,14 +159,20 @@ private:
none,add,sub,mul,div,pow,lt,gt,let,get,eq,neq,lor,land,shortmul
};
enum Assoc
{
right, // right-associative
non_right // associative or left-associative
};
Type GetType() const { return type; }
int GetPriority() const { return priority; }
Type GetType() const { return type; }
int GetPriority() const { return priority; }
Assoc GetAssoc() const { return assoc; }
void SetType(Type t)
{
type = t;
type = t;
assoc = non_right;
switch( type )
{
@@ -200,6 +206,7 @@ private:
case pow:
priority = 14;
assoc = right;
break;
default:
@@ -208,15 +215,15 @@ private:
}
}
MatOperator(): type(none), priority(0)
MatOperator(): type(none), priority(0), assoc(non_right)
{
}
private:
Type type;
int priority;
Type type;
int priority;
Assoc assoc;
}; // end of MatOperator class
@@ -275,9 +282,16 @@ public:
/*!
stack on which we're keeping the Items
at the end of parsing we'll have the result on its
the result don't have to be one value, it can be a list
of values separated by the 'semicolon item'
at the end of parsing we'll have the result here
the result don't have to be one value, it can be
more than one if we have used a semicolon in the global space
e.g. such input string "1+2;3+4" will generate a result:
stack[0].value=3
stack[1].value=7
you should check if the stack is not empty, because if there was
a syntax error in the input string then we do not have any results
on the stack
*/
std::vector<Item> stack;
@@ -310,8 +324,6 @@ ErrorCode error;
/*!
pointer to the currently reading char
it's either char* or wchar_t*
when an error has occured it may be used to count the index of the wrong character
*/
const char * pstring;
@@ -464,6 +476,8 @@ int param_sep;
*/
bool calculated;
/*!
we're using this method for reporting an error
*/
@@ -1407,7 +1421,7 @@ void Frac(int sindex, int amount_of_args, ValueType & result)
*/
void Sprintf(char * buffer, int par)
{
char buf[30]; // char, not wchar_t etc.
char buf[30]; // char, not wchar_t
int i;
#ifdef _MSC_VER
@@ -1737,6 +1751,8 @@ return is_it_name_of_function;
}
/*!
we're reading a numerical value directly from the string
*/
@@ -1746,7 +1762,7 @@ const char * new_stack_pointer;
bool value_read;
Conv conv;
conv.base = base;
conv.base = reading_base;
conv.comma = comma;
conv.comma2 = comma2;
conv.group = group;
@@ -2149,10 +2165,20 @@ void TryRollingUpStackWithOperatorPriority()
{
while( stack_index>=4 &&
stack[stack_index-4].type == Item::numerical_value &&
stack[stack_index-3].type == Item::mat_operator &&
stack[stack_index-3].type == Item::mat_operator &&
stack[stack_index-2].type == Item::numerical_value &&
stack[stack_index-1].type == Item::mat_operator &&
stack[stack_index-3].moperator.GetPriority() >= stack[stack_index-1].moperator.GetPriority()
stack[stack_index-1].type == Item::mat_operator &&
(
(
// the first operator has greater priority
stack[stack_index-3].moperator.GetPriority() > stack[stack_index-1].moperator.GetPriority()
) ||
(
// or both operators have the same priority and the first operator is not right associative
stack[stack_index-3].moperator.GetPriority() == stack[stack_index-1].moperator.GetPriority() &&
stack[stack_index-3].moperator.GetAssoc() == MatOperator::non_right
)
)
)
{
MakeStandardMathematicOperation(stack[stack_index-4].value,
@@ -2687,6 +2713,8 @@ ErrorCode Parse(const std::string & str)
}
#ifndef TTMATH_DONT_USE_WCHAR
/*!
the main method using for parsing string
*/
@@ -2695,6 +2723,8 @@ ErrorCode Parse(const wchar_t * str)
Misc::AssignString(wide_to_ansi, str);
return Parse(wide_to_ansi.c_str());
// !! wide_to_ansi clearing can be added here
}
@@ -2706,11 +2736,13 @@ ErrorCode Parse(const std::wstring & str)
return Parse(str.c_str());
}
#endif
/*!
this method returns true is something was calculated
(at least one mathematical operator was used or a function or variable)
e.g. the string to Parse() looked like this:
e.g. true if the string to Parse() looked like this:
"1+1"
"2*3"
"sin(5)"
@@ -2722,6 +2754,7 @@ bool Calculated()
return calculated;
}
};

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* Copyright (c) 2006-2010, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -56,70 +56,95 @@
#include <sstream>
#include <vector>
#ifndef _MSC_VER
#include <stdint.h>
// for uint64_t and int64_t on a 32 bit platform
#endif
/*!
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
zero means that this is the release version of the library
(one means something like beta)
*/
#define TTMATH_MAJOR_VER 0
#define TTMATH_MINOR_VER 9
#define TTMATH_REVISION_VER 0
#define TTMATH_REVISION_VER 2
#define TTMATH_PRERELEASE_VER 0
/*!
TTMATH_DEBUG
this macro enables further testing during writing your code
you don't have to define it in a release mode
if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
are set as well and these macros can throw an exception if a condition in it
is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
TTMATH_RELEASE
if you are confident that your code is perfect you can define TTMATH_RELEASE
macro for example by using -D option in gcc
gcc -DTTMATH_RELEASE -o myprogram myprogram.cpp
or by defining this macro in your code before using any header files of this library
if TTMATH_RELEASE is not set then TTMATH_DEBUG is set automatically
you can define a platform explicitly by defining either
TTMATH_PLATFORM32 or TTMATH_PLATFORM64 macro
*/
#ifndef TTMATH_RELEASE
#define TTMATH_DEBUG
#if !defined TTMATH_PLATFORM32 && !defined TTMATH_PLATFORM64
#if !defined _M_X64 && !defined __x86_64__
/*
other platforms than x86 and amd64 are not recognized at the moment
so you should set TTMATH_PLATFORMxx manually
*/
// we're using a 32bit platform
#define TTMATH_PLATFORM32
#else
// we're using a 64bit platform
#define TTMATH_PLATFORM64
#endif
#endif
/*!
asm version of the library is available by default only for:
x86 and amd64 platforms and for Microsoft Visual and GCC compilers
but you can force using asm version (the same asm as for Microsoft Visual)
by defining TTMATH_FORCEASM macro
you have to be sure that your compiler accept such an asm format
*/
#ifndef TTMATH_FORCEASM
#if !defined __i386__ && !defined _X86_ && !defined _M_IX86 && !defined __x86_64__ && !defined _M_X64
/*!
x86 architecture:
__i386__ defined by GNU C
_X86_ defined by MinGW32
_M_IX86 defined by Visual Studio, Intel C/C++, Digital Mars and Watcom C/C++
amd64 architecture:
__x86_64__ defined by GNU C and Sun Studio
_M_X64 defined by Visual Studio
asm version is available only for x86 or amd64 platforms
*/
#define TTMATH_NOASM
#endif
#if !defined _MSC_VER && !defined __GNUC__
/*!
another compilers than MS VC or GCC by default use no asm version
*/
#define TTMATH_NOASM
#endif
#endif
namespace ttmath
{
#if !defined _M_X64 && !defined __x86_64__
/*!
we're using a 32bit platform
*/
#define TTMATH_PLATFORM32
#else
/*!
we're using a 64bit platform
*/
#define TTMATH_PLATFORM64
#endif
/*!
another compilers than MS VC or GCC by default use no asm version (TTMATH_NOASM)
*/
#if !defined _MSC_VER && !defined __GNUC__
#define TTMATH_NOASM
#endif
#ifdef TTMATH_PLATFORM32
@@ -130,17 +155,18 @@ namespace ttmath
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
on 32 bit platform ulint and slint will be equal 64 bits
*/
#ifdef TTMATH_NOASM
#ifdef _MSC_VER
// long long on MS Windows (Visual and GCC mingw compilers) have 64 bits
// stdint.h is not available on Visual Studio prior to VS 2010 version
typedef unsigned long long int ulint;
typedef signed long long int slint;
#else
// we do not use 'long' here because there is a difference in unix and windows
// environments: in unix 'long' has 64 bits but in windows it has only 32 bits
typedef uint64_t ulint;
typedef int64_t slint;
#endif
/*!
@@ -188,13 +214,8 @@ namespace ttmath
#endif
/*!
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
on 64bit platforms we do not define ulint and slint
*/
//typedef unsigned long long int ulint;
/*!
how many bits there are in the uint type
@@ -371,7 +392,7 @@ namespace ttmath
/*!
used only in Big::ToString()
if scient is false then the value will be print in the scientific mode
if scient is false then the value will be printed in the scientific mode
only if the exponent is greater than scien_from
default: 15
*/
@@ -521,26 +542,13 @@ namespace ttmath
In the library is used macro TTMATH_REFERENCE_ASSERT which
can throw an exception of this type
** from version 0.9.2 this macro is removed from all methods
in public interface so you don't have to worry about it **
If you compile with gcc you can get a small benefit
from using method Where() (it returns std::string) with
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
was used)
What is the 'reference' error?
Some kind of methods use a reference as their argument to another object,
and the another object not always can be the same which is calling, e.g.
Big<1,2> foo(10);
foo.Mul(foo); // this is incorrect
above method Mul is making something more with 'this' object and
'this' cannot be passed as the argument because the result will be undefined
macro TTMATH_REFERENCE_ASSERT helps us to solve the above problem
note! some methods can use 'this' object as the argument
for example this code is correct:
UInt<2> foo(10);
foo.Add(foo);
but there are only few methods which can do that
*/
class ReferenceError : public std::logic_error, public ExceptionInfo
{
@@ -596,8 +604,21 @@ namespace ttmath
/*!
look at the description of macros TTMATH_RELEASE and TTMATH_DEBUG
TTMATH_DEBUG
this macro enables further testing during writing your code
you don't have to define it in a release mode
if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
are set as well and these macros can throw an exception if a condition in it
is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
TTMATH_DEBUG is set automatically if DEBUG or _DEBUG are defined
*/
#if defined DEBUG || defined _DEBUG
#define TTMATH_DEBUG
#endif
#ifdef TTMATH_DEBUG
#if defined(__FILE__) && defined(__LINE__)

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* Copyright (c) 2006-2010, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -480,6 +480,8 @@ namespace ttmath
c = new_c;
}
c = (c != 0)? 1 : 0;
TTMATH_LOGC("UInt::Rcr2_one", c)
return c;
@@ -518,7 +520,7 @@ namespace ttmath
c = new_c;
}
TTMATH_LOGC("UInt::Rcl2", c)
TTMATH_LOGC("UInt::Rcl2", (c & 1))
return (c & 1);
}
@@ -557,9 +559,11 @@ namespace ttmath
c = new_c;
}
c = (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
TTMATH_LOGC("UInt::Rcr2", c)
return (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
return c;
}
@@ -588,6 +592,27 @@ namespace ttmath
/*!
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>::FindLowestBitInWord(uint x)
{
if( x == 0 )
return -1;
uint bit = 0;
while( (x & 1) == 0 )
{
x = x >> 1;
++bit;
}
return bit;
}
/*!

View File

@@ -1353,6 +1353,50 @@ namespace ttmath
/*
this method returns the number of the smallest set bit in one 32-bit word
if the 'x' is zero this method returns '-1'
*/
template<uint value_size>
sint UInt<value_size>::FindLowestBitInWord(uint x)
{
sint result;
#ifndef __GNUC__
__asm
{
push eax
push edx
mov edx,-1
bsf eax,[x]
cmovz eax,edx
mov [result], eax
pop edx
pop eax
}
#endif
#ifdef __GNUC__
uint dummy;
__asm__ (
"movl $-1, %1 \n"
"bsfl %2, %0 \n"
"cmovz %1, %0 \n"
: "=r" (result), "=&r" (dummy)
: "r" (x)
: "cc" );
#endif
return result;
}
/*!

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* Copyright (c) 2006-2010, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -51,7 +51,7 @@
this file is included at the end of ttmathuint.h
*/
#ifdef _MSC_VER
#ifndef __GNUC__
#include <intrin.h>
#endif
@@ -59,7 +59,7 @@
namespace ttmath
{
#ifdef _MSC_VER
#ifndef __GNUC__
extern "C"
{
@@ -92,7 +92,7 @@ namespace ttmath
template<uint value_size>
const char * UInt<value_size>::LibTypeStr()
{
#ifdef _MSC_VER
#ifndef __GNUC__
static const char info[] = "asm_vc_64";
#endif
@@ -110,7 +110,7 @@ namespace ttmath
template<uint value_size>
LibTypeCode UInt<value_size>::LibType()
{
#ifdef _MSC_VER
#ifndef __GNUC__
LibTypeCode info = asm_vc_64;
#endif
@@ -149,11 +149,7 @@ namespace ttmath
// we don't have to use TTMATH_REFERENCE_ASSERT here
// this algorithm doesn't require it
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
c = ttmath_adc_x64(p1,p2,b,c);
#endif
@@ -220,12 +216,7 @@ namespace ttmath
TTMATH_ASSERT( index < value_size )
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
c = ttmath_addindexed_x64(p1,b,index,value);
#endif
@@ -304,12 +295,7 @@ namespace ttmath
TTMATH_ASSERT( index < value_size - 1 )
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
c = ttmath_addindexed2_x64(p1,b,index,x1,x2);
#endif
@@ -378,12 +364,7 @@ namespace ttmath
uint c;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
c = ttmath_addvector_x64(ss1, ss2, ss1_size, ss2_size, result);
#endif
@@ -456,16 +437,10 @@ namespace ttmath
uint * p1 = table;
const uint * p2 = ss2.table;
// we don't have to use TTMATH_REFERENCE_ASSERT here
// this algorithm doesn't require it
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
c = ttmath_sbb_x64(p1,p2,b,c);
#endif
@@ -529,12 +504,7 @@ namespace ttmath
TTMATH_ASSERT( index < value_size )
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
c = ttmath_subindexed_x64(p1,b,index,value);
#endif
@@ -599,12 +569,7 @@ namespace ttmath
uint c;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
c = ttmath_subvector_x64(ss1, ss2, ss1_size, ss2_size, result);
#endif
@@ -682,12 +647,7 @@ namespace ttmath
uint * p1 = table;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
c = ttmath_rcl_x64(p1,b,c);
#endif
@@ -742,12 +702,7 @@ namespace ttmath
uint * p1 = table;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
c = ttmath_rcr_x64(p1,b,c);
#endif
@@ -803,12 +758,7 @@ namespace ttmath
uint * p1 = table;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
c = ttmath_rcl2_x64(p1,b,bits,c);
#endif
@@ -880,12 +830,8 @@ namespace ttmath
sint b = value_size;
uint * p1 = table;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
c = ttmath_rcr2_x64(p1,b,bits,c);
#endif
@@ -950,12 +896,7 @@ namespace ttmath
sint result;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
unsigned long nIndex = 0;
@@ -987,6 +928,50 @@ namespace ttmath
}
/*
this method returns the number of the highest set bit in one 64-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>::FindLowestBitInWord(uint x)
{
sint result;
#ifndef __GNUC__
unsigned long nIndex = 0;
if( _BitScanForward64(&nIndex,x) == 0 )
result = -1;
else
result = nIndex;
#endif
#ifdef __GNUC__
uint dummy;
__asm__ (
"movq $-1, %1 \n"
"bsfq %2, %0 \n"
"cmovz %1, %0 \n"
: "=r" (result), "=&r" (dummy)
: "r" (x)
: "cc" );
#endif
return result;
}
/*!
this method sets a special bit in the 'value'
and returns the last state of the bit (zero or one)
@@ -1008,12 +993,8 @@ namespace ttmath
uint old_bit;
uint v = value;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
old_bit = _bittestandset64((__int64*)&value,bit) != 0;
#endif
@@ -1069,12 +1050,8 @@ namespace ttmath
uint result1_;
uint result2_;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
result1_ = _umul128(a,b,&result2_);
#endif
@@ -1132,12 +1109,8 @@ namespace ttmath
TTMATH_ASSERT( c != 0 )
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
#ifndef __GNUC__
ttmath_div_x64(&a,&b,c);
r_ = a;

View File

@@ -36,9 +36,9 @@
;
;
; compile with debug info: ml64.exe /Zd /Zi ttmathuint_x86_64_msvc.asm
; compile without debug info: ml64.exe ttmathuint_x86_64_msvc.asm
; this create ttmathuint_x86_64_msvc.obj file which can be linked with your program
; compile with debug info: ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
; compile without debug info: ml64.exe /c ttmathuint_x86_64_msvc.asm
; this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program
;
PUBLIC ttmath_adc_x64