- "streamlined" ttmathconfig.h a bit:

a) Unicode support if TTMATH_USE_WCHAR is set (compiler must know wchar_t etc, of course)
  b) threading synchonisation uses WIN32 instead of __MSVC__ define, as this is OS dependent, not compiler dependent

git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@172 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Christian Kaiser 2009-06-26 11:14:51 +00:00
parent de58378488
commit 5597373093
2 changed files with 142 additions and 144 deletions

View File

@ -27,37 +27,36 @@
distribution. distribution.
*/ */
#ifndef headerfilettmathmathttconfig #ifndef headerfilettmathconfig
#define headerfilettmathmathttconfig #define headerfilettmathconfig
#pragma once #pragma once
#include <sstream> #include <sstream>
namespace ttmath namespace ttmath
{ {
#if defined(TTMATH_USE_WCHAR)
#if defined(_MSC_VER)
#include <windows.h>
#if defined(_UNICODE)
typedef wchar_t tchar_t; typedef wchar_t tchar_t;
typedef std::wstring tstr_t; typedef std::wstring tstr_t;
typedef std::wostringstream tostrstrm_t; typedef std::wostringstream tostrstrm_t;
typedef std::wostream tostrm_t; typedef std::wostream tostrm_t;
typedef std::wistream tistrm_t; typedef std::wistream tistrm_t;
#define __TTMATH_TEXT(quote) L ## quote
#else #else
typedef char tchar_t; typedef char tchar_t;
typedef std::string tstr_t; typedef std::string tstr_t;
typedef std::ostringstream tostrstrm_t; typedef std::ostringstream tostrstrm_t;
typedef std::ostream tostrm_t; typedef std::ostream tostrm_t;
typedef std::istream tistrm_t; typedef std::istream tistrm_t;
#define __TTMATH_TEXT(quote) quote
#endif #endif
#define TTMATH_TEXT(quote) __TTMATH_TEXT(quote)
#if defined(_UNICODE) #if defined(WIN32)
#define __TEXT(quote) L ## quote #include <windows.h>
#else
#define __TEXT(quote) quote
#endif
#define TTMATH_TEXT(quote) __TEXT(quote)
#if defined(_MT) #if defined(_MT)
class clsCrit class clsCrit
@ -116,19 +115,16 @@ namespace ttmath
} }
#define TTMATH_USE_THREADSAFE_OBJ(c) clsCritObj lock(c) #define TTMATH_USE_THREADSAFE_OBJ(c) clsCritObj lock(c)
#endif #endif
#else // not MS compiler #else // defined(WIN32)
typedef char tchar_t; // not Windows world: no threading synchronization for now
typedef std::string tstr_t;
typedef std::ostringstream tostrstrm_t;
typedef std::ostream tostrm_t;
typedef std::istream tistrm_t;
#endif #endif
#if !defined(TTMATH_IMPLEMENT_THREADSAFE_OBJ) #if !defined(TTMATH_IMPLEMENT_THREADSAFE_OBJ)
// if we don't know about serialization, make it a no-op
#define TTMATH_IMPLEMENT_THREADSAFE_OBJ /* */ #define TTMATH_IMPLEMENT_THREADSAFE_OBJ /* */
#define TTMATH_USE_THREADSAFE_OBJ(c) /* */ #define TTMATH_USE_THREADSAFE_OBJ(c) /* */
#endif #endif
} // namespace } // namespace
#endif // headerfilettmathmathttconfig #endif // headerfilettmathconfig

View File

@ -858,6 +858,7 @@ namespace ttmath
* *
*/ */
#ifndef __GNUC__
/*! /*!
this method calculates 64bits word a:b / 32bits c (a higher, b lower word) this method calculates 64bits word a:b / 32bits c (a higher, b lower word)
@ -911,131 +912,132 @@ namespace ttmath
*rest = rest_; *rest = rest_;
} }
template<uint value_size> template<uint value_size>
uint UInt<value_size>::AddTwoWords(uint a, uint b, uint carry, uint * result) uint UInt<value_size>::AddTwoWords(uint a, uint b, uint carry, uint * result)
{ {
uint temp; uint temp;
if( carry == 0 ) if( carry == 0 )
{ {
temp = a + b; temp = a + b;
if( temp < a ) if( temp < a )
carry = 1; carry = 1;
} }
else else
{ {
carry = 1; carry = 1;
temp = a + b + carry; temp = a + b + carry;
if( temp > a ) // !(temp<=a) if( temp > a ) // !(temp<=a)
carry = 0; carry = 0;
} }
*result = temp; *result = temp;
return carry; return carry;
} }
template<uint value_size> template<uint value_size>
uint UInt<value_size>::SubTwoWords(uint a, uint b, uint carry, uint * result) uint UInt<value_size>::SubTwoWords(uint a, uint b, uint carry, uint * result)
{ {
if( carry == 0 ) if( carry == 0 )
{ {
*result = a - b; *result = a - b;
if( a < b ) if( a < b )
carry = 1; carry = 1;
} }
else else
{ {
carry = 1; carry = 1;
*result = a - b - carry; *result = a - b - carry;
if( a > b ) // !(a <= b ) if( a > b ) // !(a <= b )
carry = 0; carry = 0;
} }
return carry; return carry;
} }
/*! /*!
this static method addes one vector to the other this static method addes one vector to the other
'ss1' is larger in size or equal to 'ss2' 'ss1' is larger in size or equal to 'ss2'
ss1 points to the first (larger) vector ss1 points to the first (larger) vector
ss2 points to the second vector ss2 points to the second vector
ss1_size - size of the ss1 (and size of the result too) ss1_size - size of the ss1 (and size of the result too)
ss2_size - size of the ss2 ss2_size - size of the ss2
result - is the result vector (which has size the same as ss1: ss1_size) result - is the result vector (which has size the same as ss1: ss1_size)
Example: ss1_size is 5, ss2_size is 3 Example: ss1_size is 5, ss2_size is 3
ss1: ss2: result (output): ss1: ss2: result (output):
5 1 5+1 5 1 5+1
4 3 4+3 4 3 4+3
2 7 2+7 2 7 2+7
6 6 6 6
9 9 9 9
of course the carry is propagated and will be returned from the last item of course the carry is propagated and will be returned from the last item
(this method is used by the Karatsuba multiplication algorithm) (this method is used by the Karatsuba multiplication algorithm)
*/ */
template<uint value_size> template<uint value_size>
uint UInt<value_size>::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result) uint UInt<value_size>::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
{ {
uint i, c = 0; uint i, c = 0;
TTMATH_ASSERT( ss1_size >= ss2_size ) TTMATH_ASSERT( ss1_size >= ss2_size )
for(i=0 ; i<ss2_size ; ++i) for(i=0 ; i<ss2_size ; ++i)
c = AddTwoWords(ss1[i], ss2[i], c, &result[i]); c = AddTwoWords(ss1[i], ss2[i], c, &result[i]);
for( ; i<ss1_size ; ++i) for( ; i<ss1_size ; ++i)
c = AddTwoWords(ss1[i], 0, c, &result[i]); c = AddTwoWords(ss1[i], 0, c, &result[i]);
TTMATH_LOG("UInt::AddVector") TTMATH_LOG("UInt::AddVector")
return c; return c;
} }
/*! /*!
this static method subtractes one vector from the other this static method subtractes one vector from the other
'ss1' is larger in size or equal to 'ss2' 'ss1' is larger in size or equal to 'ss2'
ss1 points to the first (larger) vector ss1 points to the first (larger) vector
ss2 points to the second vector ss2 points to the second vector
ss1_size - size of the ss1 (and size of the result too) ss1_size - size of the ss1 (and size of the result too)
ss2_size - size of the ss2 ss2_size - size of the ss2
result - is the result vector (which has size the same as ss1: ss1_size) result - is the result vector (which has size the same as ss1: ss1_size)
Example: ss1_size is 5, ss2_size is 3 Example: ss1_size is 5, ss2_size is 3
ss1: ss2: result (output): ss1: ss2: result (output):
5 1 5-1 5 1 5-1
4 3 4-3 4 3 4-3
2 7 2-7 2 7 2-7
6 6-1 (the borrow from previous item) 6 6-1 (the borrow from previous item)
9 9 9 9
return (carry): 0 return (carry): 0
of course the carry (borrow) is propagated and will be returned from the last item of course the carry (borrow) is propagated and will be returned from the last item
(this method is used by the Karatsuba multiplication algorithm) (this method is used by the Karatsuba multiplication algorithm)
*/ */
template<uint value_size> template<uint value_size>
uint UInt<value_size>::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result) uint UInt<value_size>::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
{ {
uint i, c = 0; uint i, c = 0;
TTMATH_ASSERT( ss1_size >= ss2_size ) TTMATH_ASSERT( ss1_size >= ss2_size )
for(i=0 ; i<ss2_size ; ++i) for(i=0 ; i<ss2_size ; ++i)
c = SubTwoWords(ss1[i], ss2[i], c, &result[i]); c = SubTwoWords(ss1[i], ss2[i], c, &result[i]);
for( ; i<ss1_size ; ++i) for( ; i<ss1_size ; ++i)
c = SubTwoWords(ss1[i], 0, c, &result[i]); c = SubTwoWords(ss1[i], 0, c, &result[i]);
TTMATH_LOG("UInt::SubVector") TTMATH_LOG("UInt::SubVector")
return c; return c;
} }
#endif // #ifndef __GNUC__
} //namespace } //namespace