23 Commits
0.8.6 ... chk

Author SHA1 Message Date
Christian Kaiser
51e938eaa7 - update to current root trunc's version
- update to root trunc's UNICODE support

git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@182 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-07-29 10:46:48 +00:00
Christian Kaiser
e102086f80 - fixed a bug in 64 bit ASM for MSVC
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@181 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-07-28 16:34:04 +00:00
53547cfab5 * added: global Gamma() function
* added:   gamma() function to the parser
* added:   Big::IsInteger() method
           returns true if the value is integer
* added:   CGamma<ValueType> class
           is used with Gamma() and Factorial() in multithreaded environment
* changed: Factorial() is using the Gamma() function now
* removed: Parser<>::SetFactorialMax() method
           the factorial() is such a fast now that we don't need the method longer
* removed: ErrorCode::err_too_big_factorial



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


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@177 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-07-02 01:04:25 +00:00
Christian Kaiser
51b2c974a1 - changed "AboutEqualWithoutSign()" to "AboutEqual()" because we need to take the sign into account!
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@173 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-26 15:24:27 +00:00
Christian Kaiser
5597373093 - "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
2009-06-26 11:14:51 +00:00
Christian Kaiser
de58378488 - added AboutEqualWithoutSign() to big<> to allow 'suppression' of some unexpected results (that are perfectly logical though, given the possibly unrepresentable nature of binary representation of decimals) like
big<>("10.456466") * 2 == big<>("20.912932")

resulting in FALSE result.

git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@171 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-25 14:11:17 +00:00
Christian Kaiser
de64608eba Merged against the current original ttmath trunk
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@170 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-25 11:07:55 +00:00
Christian Kaiser
be8913866a - 32 bit ASM code and ASSERTS did not work as the ASM code put its result in EAX, but the ASSERT afterwards did destroy the EAX's contents, of course.
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@155 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-28 14:42:19 +00:00
Christian Kaiser
b31d34ebdd - fixed a bug in ttmath.g (missing closing brace in Cos())
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@154 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-28 11:52:31 +00:00
Christian Kaiser
be821b59dd - optimizations
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@153 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-28 11:31:29 +00:00
Christian Kaiser
de1e7ac957 more optimizations for MSVC assembler (parallelism, prefetch optimization, loop alignment, ...)
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@151 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-20 08:48:51 +00:00
Christian Kaiser
fdc292e91a current chk version - too many changes on both sides for now ;-(
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@150 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-19 10:50:41 +00:00
Christian Kaiser
9b576ddbe2 - corrected 64 bit assembler code (ebx was not preserved)
- minor optimization

git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@147 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-15 14:42:43 +00:00
Christian Kaiser
a8c3a506ea MSVC ASM improvements (no register saves necessary, as this is done automatically by the C compiler)
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@146 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-14 12:59:12 +00:00
Christian Kaiser
3ba94dca90 git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@145 e52654a7-88a9-db11-a3e9-0013d4bc506e 2009-05-11 12:30:05 +00:00
Christian Kaiser
cae50cd425 - merged Tomasz' version 0.8.5
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@144 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-11 12:25:25 +00:00
Christian Kaiser
00e39d3608 added thread-safety to static history buffers (factorial and logarithm) for MSVC
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@135 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-07 11:37:10 +00:00
Christian Kaiser
37379d2f1f - fulfills test file log diff (32 and 64 bit)
- macro for issuing the debug output to something else than std::out if specified


git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@134 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-07 09:33:57 +00:00
Christian Kaiser
d7b67e4d47 - minor changes for ASSERT macros
- some more "unification" of 32 and 64 bits in typedefs
- use of 'char' instead of 'unsigned char', as I may hope that 'char' usually is set to 'unsigned' in most development environments

git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@133 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-06 15:47:15 +00:00
Christian Kaiser
c91bd24e98 - support for MS specific code (__int64 etc) and warnings
- support for AMD64 assembler (not thoroughly tested)
- support for UNICODE I/O (strings and streams)

git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@132 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-06 15:11:29 +00:00
Christian Kaiser
cbc12db22f dummy commit (user/password checking)
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@131 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-06 13:24:00 +00:00
3e9bd5b093 creating a chk branch for ChristianK
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@130 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-06 13:16:56 +00:00
13 changed files with 16704 additions and 15399 deletions

View File

@@ -1,3 +1,28 @@
Version 0.9.0 prerelease (2009.07.16):
* added: support for wide characters (wchar_t)
wide characters are used when macro TTMATH_USE_WCHAR is defined
this macro is defined automatically when there is macro UNICODE or _UNICODE defined
some types have been changed
char -> tt_char
std::string -> tt_string
std::ostringstream -> tt_ostringstream
std::ostream -> tt_ostream
std::istream -> tt_istream
normally tt_char is equal char but when you are using wide characters then tt_char will be wchar_t (and so on)
(all typedef's are in ttmathtypes.h)
* added: Big::IsInteger()
returns true if the value is integer (without fraction)
(NaN flag is not checked)
* added: global Gamma() function
* added: gamma() function to the parser
* added: CGamma<ValueType> class
is used with Gamma() and Factorial() in multithreaded environment
* changed: Factorial() is using the Gamma() function now
* removed: Parser<>::SetFactorialMax() method
the factorial() is such a fast now that we don't need the method longer
* removed: ErrorCode::err_too_big_factorial
Version 0.8.5 (2009.06.16): Version 0.8.5 (2009.06.16):
* fixed: Big::Mod(x) didn't correctly return a carry * fixed: Big::Mod(x) didn't correctly return a carry
and the result was sometimes very big (even greater than x) and the result was sometimes very big (even greater than x)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

110
ttmath/ttmathconfig.h Normal file
View File

@@ -0,0 +1,110 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the PNG licence.
* Author: Christian Kaiser <chk@online.de>
*/
/*
Copyright (c) 2009 Christian Kaiser
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#ifndef headerfilettmathconfig
#define headerfilettmathconfig
#pragma once
#include <sstream>
namespace ttmath
{
#if defined(WIN32)
#include <windows.h>
#if defined(_MT)
class clsCrit
{
private:
mutable CRITICAL_SECTION _Crit;
clsCrit(const clsCrit&) // inhibit copy (easy mistake to do; use clsCritObj instead!!!)
{
}
clsCrit& operator=(const clsCrit& rhs); // inhibit assignment
public:
clsCrit(void)
{
InitializeCriticalSection(&_Crit);
}
virtual ~clsCrit(void)
{
DeleteCriticalSection(&_Crit);
}
void Enter(void) const
{
EnterCriticalSection(&_Crit);
}
void Leave(void) const
{
LeaveCriticalSection(&_Crit);
}
};
class clsCritObj
{
private:
const clsCrit& _Crit;
clsCritObj& operator=(const clsCritObj& rhs); // not applicable
public:
clsCritObj(const clsCrit& Sync)
: _Crit(Sync)
{
_Crit.Enter();
}
~clsCritObj(void)
{
_Crit.Leave();
}
};
#define TTMATH_IMPLEMENT_THREADSAFE_OBJ \
private: \
clsCrit CritSect; \
public: \
operator clsCrit&() \
{ \
return(CritSect); \
}
#define TTMATH_USE_THREADSAFE_OBJ(c) clsCritObj lock(c)
#endif
#else // defined(WIN32)
// not Windows world: no threading synchronization for now
#endif
#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_USE_THREADSAFE_OBJ(c) /* */
#endif
} // namespace
#endif // headerfilettmathconfig

View File

@@ -1,7 +1,7 @@
/* /*
* This file is a part of TTMath Bignum Library * This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence. * and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl> * Author: Tomasz Sowa <t.sowa@ttmath.org>
*/ */
/* /*
@@ -47,6 +47,10 @@
#include "ttmathuint.h" #include "ttmathuint.h"
#if defined(_MSC_VER)
#pragma warning(disable:4127) // conditional expression is constant
#endif
namespace ttmath namespace ttmath
{ {
@@ -641,8 +645,14 @@ public:
// there can be a carry here when the size of this value is equal one word // there can be a carry here when the size of this value is equal one word
// and the 'value' has the highest bit set // and the 'value' has the highest bit set
#if defined(_MSC_VER)
#pragma warning(disable:4127) // conditional expression is constant
#endif
if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 ) if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 )
return 1; return 1;
#if defined(_MSC_VER)
#pragma warning(default:4127) // conditional expression is constant
#endif
return 0; return 0;
} }
@@ -821,7 +831,7 @@ public:
/*! /*!
a constructor for converting string to this class (with the base=10) a constructor for converting string to this class (with the base=10)
*/ */
Int(const char * s) Int(const tt_char * s)
{ {
FromString(s); FromString(s);
} }
@@ -830,7 +840,7 @@ public:
/*! /*!
a constructor for converting a string to this class (with the base=10) a constructor for converting a string to this class (with the base=10)
*/ */
Int(const std::string & s) Int(const tt_string & s)
{ {
FromString( s.c_str() ); FromString( s.c_str() );
} }
@@ -869,7 +879,7 @@ public:
/*! /*!
this method converts the value to a string with a base equal 'b' this method converts the value to a string with a base equal 'b'
*/ */
void ToString(std::string & result, uint b = 10) const void ToString(tt_string & result, uint b = 10) const
{ {
if( IsSign() ) if( IsSign() )
{ {
@@ -890,12 +900,14 @@ public:
/*! /*!
this method converts a string into its value this method converts a string into its value
string is given either as 'const char *' or 'const wchar_t *'
it returns carry=1 if the value will be too big or an incorrect base 'b' is given it returns carry=1 if the value will be too big or an incorrect base 'b' is given
string is ended with a non-digit value, for example: string is ended with a non-digit value, for example:
"-12" will be translated to -12 "-12" will be translated to -12
as well as: as well as:
"- 12foo" will be translated to 12 too "- 12foo" will be translated to -12 too
existing first white characters will be ommited existing first white characters will be ommited
(between '-' and a first digit can be white characters too) (between '-' and a first digit can be white characters too)
@@ -904,7 +916,7 @@ public:
value_read (if exists) tells whether something has actually been read (at least one digit) value_read (if exists) tells whether something has actually been read (at least one digit)
*/ */
uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0) uint FromString(const tt_char * s, uint b = 10, const tt_char ** after_source = 0, bool * value_read = 0)
{ {
bool is_sign = false; bool is_sign = false;
@@ -961,16 +973,16 @@ public:
this method converts a string into its value 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 it returns carry=1 if the value will be too big or an incorrect base 'b' is given
*/ */
uint FromString(const std::string & s, uint b = 10) uint FromString(const tt_string & s, uint b = 10)
{ {
return FromString( s.c_str() ); return FromString( s.c_str(), b );
} }
/*! /*!
this operator converts a string into its value (with base = 10) this operator converts a string into its value (with base = 10)
*/ */
Int<value_size> & operator=(const char * s) Int<value_size> & operator=(const tt_char * s)
{ {
FromString(s); FromString(s);
@@ -981,7 +993,7 @@ public:
/*! /*!
this operator converts a string into its value (with base = 10) this operator converts a string into its value (with base = 10)
*/ */
Int<value_size> & operator=(const std::string & s) Int<value_size> & operator=(const tt_string & s)
{ {
FromString( s.c_str() ); FromString( s.c_str() );
@@ -1268,9 +1280,14 @@ public:
* *
*/ */
friend std::ostream & operator<<(std::ostream & s, const Int<value_size> & l) /*!
output for standard streams
tt_ostream is either std::ostream or std::wostream
*/
friend tt_ostream & operator<<(tt_ostream & s, const Int<value_size> & l)
{ {
std::string ss; tt_string ss;
l.ToString(ss); l.ToString(ss);
s << ss; s << ss;
@@ -1279,13 +1296,17 @@ public:
} }
/*!
input from standard streams
friend std::istream & operator>>(std::istream & s, Int<value_size> & l) tt_istream is either std::istream or std::wistream
*/
friend tt_istream & operator>>(tt_istream & s, Int<value_size> & l)
{ {
std::string ss; tt_string ss;
// char for operator>> // tt_char for operator>>
unsigned char z; tt_char z;
// operator>> omits white characters if they're set for ommiting // operator>> omits white characters if they're set for ommiting
s >> z; s >> z;
@@ -1300,7 +1321,7 @@ public:
while( s.good() && UInt<value_size>::CharToDigit(z, 10)>=0 ) while( s.good() && UInt<value_size>::CharToDigit(z, 10)>=0 )
{ {
ss += z; ss += z;
z = s.get(); z = static_cast<tt_char>(s.get());
} }
// we're leaving the last readed character // we're leaving the last readed character
@@ -1316,4 +1337,9 @@ public:
} // namespace } // namespace
#if defined(_MSC_VER)
#pragma warning(default:4127) // conditional expression is constant
#endif
#endif #endif

View File

@@ -1,7 +1,7 @@
/* /*
* This file is a part of TTMath Mathematical Library * This file is a part of TTMath Mathematical Library
* and is distributed under the (new) BSD licence. * and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl> * Author: Tomasz Sowa <t.sowa@ttmath.org>
*/ */
/* /*
@@ -47,6 +47,7 @@
#include "ttmathtypes.h" #include "ttmathtypes.h"
#include <string> #include <string>
#include <vector>
#include <list> #include <list>
#include <map> #include <map>
@@ -73,18 +74,19 @@ public:
struct Item struct Item
{ {
// name of a variable of a function // name of a variable of a function
std::string value; // (either std::string or std::wstring)
tt_string value;
// number of parameters required by the function // number of parameters required by the function
// (if there's a variable this 'param' is ignored) // (if there's a variable this 'param' is ignored)
int param; int param;
Item() {} Item() {}
Item(const std::string & v, int p) : value(v), param(p) {} Item(const tt_string & v, int p) : value(v), param(p) {}
}; };
// 'Table' is the type of our table // 'Table' is the type of our table
typedef std::map<std::string, Item> Table; typedef std::map<tt_string, Item> Table;
typedef Table::iterator Iterator; typedef Table::iterator Iterator;
typedef Table::const_iterator CIterator; typedef Table::const_iterator CIterator;
@@ -112,7 +114,7 @@ public:
/*! /*!
this method returns true if the name can be as a name of an object this method returns true if the name can be as a name of an object
*/ */
static bool IsNameCorrect(const std::string & name) static bool IsNameCorrect(const tt_string & name)
{ {
if( name.empty() ) if( name.empty() )
return false; return false;
@@ -120,7 +122,7 @@ public:
if( !CorrectCharacter(name[0], false) ) if( !CorrectCharacter(name[0], false) )
return false; return false;
std::string::const_iterator i=name.begin(); tt_string::const_iterator i=name.begin();
for(++i ; i!=name.end() ; ++i) for(++i ; i!=name.end() ; ++i)
if( !CorrectCharacter(*i, true) ) if( !CorrectCharacter(*i, true) )
@@ -133,7 +135,7 @@ public:
/*! /*!
this method returns true if such an object is defined (name exists) this method returns true if such an object is defined (name exists)
*/ */
bool IsDefined(const std::string & name) bool IsDefined(const tt_string & name)
{ {
Iterator i = table.find(name); Iterator i = table.find(name);
@@ -148,7 +150,7 @@ public:
/*! /*!
this method adds one object (variable of function) into the table this method adds one object (variable of function) into the table
*/ */
ErrorCode Add(const std::string & name, const std::string & value, int param = 0) ErrorCode Add(const tt_string & name, const tt_string & value, int param = 0)
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -205,7 +207,7 @@ public:
/*! /*!
this method changes the value and the number of parameters for a specific object this method changes the value and the number of parameters for a specific object
*/ */
ErrorCode EditValue(const std::string & name, const std::string & value, int param = 0) ErrorCode EditValue(const tt_string & name, const tt_string & value, int param = 0)
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -225,7 +227,7 @@ public:
/*! /*!
this method changes the name of a specific object this method changes the name of a specific object
*/ */
ErrorCode EditName(const std::string & old_name, const std::string & new_name) ErrorCode EditName(const tt_string & old_name, const tt_string & new_name)
{ {
if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) ) if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
return err_incorrect_name; return err_incorrect_name;
@@ -256,7 +258,7 @@ public:
/*! /*!
this method deletes an object this method deletes an object
*/ */
ErrorCode Delete(const std::string & name) ErrorCode Delete(const tt_string & name)
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -275,7 +277,7 @@ public:
/*! /*!
this method gets the value of a specific object this method gets the value of a specific object
*/ */
ErrorCode GetValue(const std::string & name, std::string & value) const ErrorCode GetValue(const tt_string & name, tt_string & value) const
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -298,7 +300,7 @@ public:
this method gets the value of a specific object this method gets the value of a specific object
(this version is used for not copying the whole string) (this version is used for not copying the whole string)
*/ */
ErrorCode GetValue(const std::string & name, const char ** value) const ErrorCode GetValue(const tt_string & name, const tt_char ** value) const
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -321,7 +323,7 @@ public:
this method gets the value and the number of parameters this method gets the value and the number of parameters
of a specific object of a specific object
*/ */
ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const ErrorCode GetValueAndParam(const tt_string & name, tt_string & value, int * param) const
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -347,7 +349,7 @@ public:
of a specific object of a specific object
(this version is used for not copying the whole string) (this version is used for not copying the whole string)
*/ */
ErrorCode GetValueAndParam(const std::string & name, const char ** value, int * param) const ErrorCode GetValueAndParam(const tt_string & name, const tt_char ** value, int * param) const
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -430,7 +432,7 @@ public:
*/ */
History() History()
{ {
buffer_max_size = 10; buffer_max_size = 15;
} }
@@ -487,10 +489,118 @@ public:
return false; return false;
} }
/*!
this methods deletes an item
we assume that there is only one item with the 'key'
(this methods removes the first one)
*/
bool Remove(const ValueType & key)
{
typename buffer_type::iterator i = buffer.begin();
for( ; i != buffer.end() ; ++i )
{
if( i->key == key )
{
buffer.erase(i);
return true;
}
}
return false;
}
}; // end of class History }; // end of class History
/*!
this is an auxiliary class used when calculating Gamma() or Factorial()
in multithreaded environment you can provide an object of this class to
the Gamma() or Factorial() function, e.g;
typedef Big<1, 3> MyBig;
MyBig x = 123456;
CGamma<MyBig> cgamma;
std::cout << Gamma(x, cgamma);
each thread should have its own CGamma<> object
in a single-thread environment a CGamma<> object is a static variable
in a second version of Gamma() and you don't have to explicitly use it, e.g.
typedef Big<1, 3> MyBig;
MyBig x = 123456;
std::cout << Gamma(x);
*/
template<class ValueType>
struct CGamma
{
/*!
this table holds factorials
1
1
2
6
24
120
720
.......
*/
std::vector<ValueType> fact;
/*!
this table holds Bernoulli numbers
1
-0.5
0.166666666666666666666666667
0
-0.0333333333333333333333333333
0
0.0238095238095238095238095238
0
-0.0333333333333333333333333333
0
0.075757575757575757575757576
.....
*/
std::vector<ValueType> bern;
/*!
here we store some calculated values
(this is for speeding up, if the next argument of Gamma() or Factorial()
is in the 'history' then the result we are not calculating but simply
return from the 'history' object)
*/
History<ValueType> history;
/*!
this method prepares some coefficients: factorials and Bernoulli numbers
stored in 'fact' and 'bern' objects
how many values should be depends on the size of the mantissa - if
the mantissa is larger then we must calculate more values
for a mantissa which consists of 256 bits (8 words on a 32bit platform)
we have to calculate about 30 values (the size of fact and bern will be 30),
and for a 2048 bits mantissa we have to calculate 306 coefficients
you don't have to call this method, these coefficients will be automatically calculated
when they are needed
you must note that calculating of the coefficients is a little time-consuming operation,
(especially when the mantissa is large) and first called to Gamma() or Factorial()
can take more time than next calls, and in the end this is the point when InitAll()
comes in handy: you can call this method somewhere at the beginning of your program
*/
void InitAll();
// definition is in ttmath.h
};
} // namespace } // namespace

File diff suppressed because it is too large Load Diff

View File

@@ -1,460 +1,522 @@
/* /*
* This file is a part of TTMath Bignum Library * This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence. * and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl> * Author: Tomasz Sowa <t.sowa@ttmath.org>
*/ */
/* /*
* Copyright (c) 2006-2009, Tomasz Sowa * Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* * Redistributions of source code must retain the above copyright notice, * * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* *
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* *
* * Neither the name Tomasz Sowa nor the names of contributors to this * * Neither the name Tomasz Sowa nor the names of contributors to this
* project may be used to endorse or promote products derived * project may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef headerfilettmathtypes #ifndef headerfilettmathtypes
#define headerfilettmathtypes #define headerfilettmathtypes
/*! /*!
\file ttmathtypes.h \file ttmathtypes.h
\brief constants used in the library \brief constants used in the library
As our library is written in header files (templates) we cannot use As our library is written in header files (templates) we cannot use
constants like 'const int' etc. because we should have some source files constants like 'const int' etc. because we should have some source files
*.cpp to define this variables. Only what we can have are constants *.cpp to define this variables. Only what we can have are constants
defined by #define preprocessor macros. defined by #define preprocessor macros.
All macros are preceded by TTMATH_ prefix All macros are preceded by TTMATH_ prefix
*/ */
#include <stdexcept> #include <stdexcept>
#include <sstream> #include <sstream>
#include <vector>
/*! /*!
the version of the library the version of the library
TTMATH_PRERELEASE_VER is either zero or one TTMATH_PRERELEASE_VER is either zero or one
if zero that means this is the release version of the library if zero that means this is the release version of the library
*/ */
#define TTMATH_MAJOR_VER 0 #define TTMATH_MAJOR_VER 0
#define TTMATH_MINOR_VER 8 #define TTMATH_MINOR_VER 9
#define TTMATH_REVISION_VER 5 #define TTMATH_REVISION_VER 0
#define TTMATH_PRERELEASE_VER 0 #define TTMATH_PRERELEASE_VER 1
/*! /*!
TTMATH_DEBUG TTMATH_DEBUG
this macro enables further testing during writing your code this macro enables further testing during writing your code
you don't have to define it in a release mode you don't have to define it in a release mode
if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT 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 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) is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
TTMATH_RELEASE TTMATH_RELEASE
if you are confident that your code is perfect you can define 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 macro for example by using -D option in gcc
gcc -DTTMATH_RELEASE -o myprogram myprogram.cpp gcc -DTTMATH_RELEASE -o myprogram myprogram.cpp
or by defining this macro in your code before using any header files of this library 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 if TTMATH_RELEASE is not set then TTMATH_DEBUG is set automatically
*/ */
#ifndef TTMATH_RELEASE #ifndef TTMATH_RELEASE
#define TTMATH_DEBUG #define TTMATH_DEBUG
#endif #endif
namespace ttmath namespace ttmath
{ {
#if !defined _M_X64 && !defined __x86_64__ #if !defined _M_X64 && !defined __x86_64__
/*! /*!
we're using a 32bit platform we're using a 32bit platform
*/ */
#define TTMATH_PLATFORM32 #define TTMATH_PLATFORM32
#else #else
/*! /*!
we're using a 64bit platform we're using a 64bit platform
*/ */
#define TTMATH_PLATFORM64 #define TTMATH_PLATFORM64
#endif #endif
#ifdef TTMATH_PLATFORM32 #ifdef TTMATH_PLATFORM32
/*! /*!
on 32bit platforms one word (uint, sint) will be equal 32bits on 32bit platforms one word (uint, sint) will be equal 32bits
*/ */
typedef unsigned int uint; typedef unsigned int uint;
typedef signed int sint; typedef signed int sint;
/*!
this type is twice bigger than uint /*!
(64bit on a 32bit platforms) 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 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 this type is used in UInt::MulTwoWords and UInt::DivTwoWords when macro TTMATH_NOASM is defined
*/ */
#ifdef TTMATH_NOASM typedef unsigned long long int ulint;
typedef unsigned long long int ulint;
#endif /*!
the mask for the highest bit in the unsigned 32bit word (2^31)
/*! */
how many bits there are in the uint type const uint TTMATH_UINT_HIGHEST_BIT = 0x80000000ul;
*/
#define TTMATH_BITS_PER_UINT 32u /*!
the max value of the unsigned 32bit word (2^32 - 1)
/*! (all bits equal one)
the mask for the highest bit in the unsigned 32bit word (2^31) */
*/ const uint TTMATH_UINT_MAX_VALUE = 0xfffffffful;
#define TTMATH_UINT_HIGHEST_BIT 2147483648u
/*!
/*! the number of words (32bit words on 32bit platform)
the max value of the unsigned 32bit word (2^32 - 1) which are kept in built-in variables for a Big<> type
(all bits equal one) (these variables are defined in ttmathbig.h)
*/ */
#define TTMATH_UINT_MAX_VALUE 4294967295u const uint TTMATH_BUILTIN_VARIABLES_SIZE = 256u;
/*! #else
the number of words (32bit words on 32bit platform)
which are kept in built-in variables for a Big<> type /*!
(these variables are defined in ttmathbig.h) on 64bit platforms one word (uint, sint) will be equal 64bits
*/ */
#define TTMATH_BUILTIN_VARIABLES_SIZE 256u #if defined(_MSC_VER)
typedef unsigned __int64 uint;
#else typedef signed __int64 sint;
#else
/*! typedef unsigned long long uint;
on 64bit platforms one word (uint, sint) will be equal 64bits typedef signed long long sint;
*/ #endif
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 64bit platform we do not define ulint on 64 bit platform (when there is defined TTMATH_NOASM macro)
sizeof(long long) is 8 (64bit) but we need 128bit methods UInt::MulTwoWords and UInt::DivTwoWords are using other algorithms than those on 32 bit
*/
on 64 bit platform (when there is defined TTMATH_NOASM macro) //typedef unsigned long long int ulint;
methods UInt::MulTwoWords and UInt::DivTwoWords are using other algorithms than those on 32 bit
*/ /*!
//typedef unsigned long long int ulint; the mask for the highest bit in the unsigned 64bit word (2^63)
*/
/*! const uint TTMATH_UINT_HIGHEST_BIT = 0x8000000000000000ul;
how many bits there are in the uint type
*/ /*!
#define TTMATH_BITS_PER_UINT 64ul the max value of the unsigned 64bit word (2^64 - 1)
(all bits equal one)
/*! */
the mask for the highest bit in the unsigned 64bit word (2^63) const uint TTMATH_UINT_MAX_VALUE = 0xfffffffffffffffful;
*/
#define TTMATH_UINT_HIGHEST_BIT 9223372036854775808ul /*!
the number of words (64bit words on 64bit platforms)
/*! which are kept in built-in variables for a Big<> type
the max value of the unsigned 64bit word (2^64 - 1) (these variables are defined in ttmathbig.h)
(all bits equal one) */
*/ const uint TTMATH_BUILTIN_VARIABLES_SIZE = 128ul;
#define TTMATH_UINT_MAX_VALUE 18446744073709551615ul
#endif
/*!
the number of words (64bit words on 64bit platforms) const uint TTMATH_BITS_PER_UINT = (sizeof(uint)*8);
which are kept in built-in variables for a Big<> type
(these variables are defined in ttmathbig.h) }
*/
#define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
#if defined(UNICODE) || defined(_UNICODE)
#endif #define TTMATH_USE_WCHAR
} #endif
#ifdef TTMATH_USE_WCHAR
/*!
characters which represent the comma operator typedef wchar_t tt_char;
typedef std::wstring tt_string;
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing (default, can be overwritten in ToString() function) typedef std::wostringstream tt_ostringstream;
TTMATH_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character typedef std::wostream tt_ostream;
that means you can input values for example 1.2345 and 1,2345 as well typedef std::wistream tt_istream;
#define TTMATH_TEXT_HELPER(txt) L##txt
if you don't want it just put 0 there e.g.
#define TTMATH_COMMA_CHARACTER_2 0 #else
then only TTMATH_COMMA_CHARACTER_1 will be used
typedef char tt_char;
don't put there any special character which is used by the parser typedef std::string tt_string;
(for example a semicolon ';' shouldn't be there) typedef std::ostringstream tt_ostringstream;
*/ typedef std::ostream tt_ostream;
#define TTMATH_COMMA_CHARACTER_1 '.' typedef std::istream tt_istream;
#define TTMATH_COMMA_CHARACTER_2 ',' #define TTMATH_TEXT_HELPER(txt) txt
#endif
/*! #define TTMATH_TEXT(txt) TTMATH_TEXT_HELPER(txt)
this variable defines how many iterations are performed
during some kind of calculating when we're making any long formulas
(for example Taylor series)
it's used in ExpSurrounding0(...), LnSurrounding1(...), Sin0pi05(...), etc.
/*!
note! there'll not be so many iterations, iterations are stopped when characters which represent the comma operator
there is no sense to continue calculating (for example when the result
still remains unchanged after adding next series and we know that the next TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing (default, can be overwritten in ToString() function)
series are smaller than previous ones) 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
#define TTMATH_ARITHMETIC_MAX_LOOP 10000
if you don't want it just put 0 there e.g.
#define TTMATH_COMMA_CHARACTER_2 0
then only TTMATH_COMMA_CHARACTER_1 will be used
/*!
this is a limit when calculating Karatsuba multiplication don't put there any special character which is used by the parser
if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE (for example a semicolon ';' shouldn't be there)
the Karatsuba algorithm will use standard schoolbook multiplication */
*/ #define TTMATH_COMMA_CHARACTER_1 '.'
#ifdef __GNUC__ #define TTMATH_COMMA_CHARACTER_2 ','
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
#else
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
#endif /*!
this variable defines how many iterations are performed
during some kind of calculating when we're making any long formulas
namespace ttmath (for example Taylor series)
{
it's used in ExpSurrounding0(...), LnSurrounding1(...), Sin0pi05(...), etc.
/*!
error codes note! there'll not be so many iterations, iterations are stopped when
*/ there is no sense to continue calculating (for example when the result
enum ErrorCode still remains unchanged after adding next series and we know that the next
{ series are smaller than previous ones)
err_ok = 0, */
err_nothing_has_read, #define TTMATH_ARITHMETIC_MAX_LOOP 10000
err_unknown_character,
err_unexpected_final_bracket,
err_stack_not_clear,
err_unknown_variable, /*!
err_division_by_zero, this is a limit when calculating Karatsuba multiplication
err_interrupt, if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
err_overflow, the Karatsuba algorithm will use standard schoolbook multiplication
err_unknown_function, */
err_unknown_operator, #ifdef __GNUC__
err_unexpected_semicolon_operator, #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
err_improper_amount_of_arguments, #else
err_improper_argument, #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
err_unexpected_end, #endif
err_internal_error,
err_incorrect_name,
err_incorrect_value, /*!
err_variable_exists, this is a special value used when calculating the Gamma(x) function
err_variable_loop, if x is greater than this value then the Gamma(x) will be calculated using
err_functions_loop, some kind of series
err_must_be_only_one_value,
err_object_exists, don't use smaller values than about 100
err_unknown_object, */
err_still_calculating, #define TTMATH_GAMMA_BOUNDARY 2000
err_too_big_factorial,
err_in_short_form_used_function
};
namespace ttmath
/*! {
this simple class can be used in multithreading model
(you can write your own class derived from this one) /*!
error codes
for example: in some functions like Factorial() */
/at the moment only Factorial/ you can give a pointer to enum ErrorCode
the 'stop object', if the method WasStopSignal() of this {
object returns true that means we should break the calculating err_ok = 0,
and return err_nothing_has_read,
*/ err_unknown_character,
class StopCalculating err_unexpected_final_bracket,
{ err_stack_not_clear,
public: err_unknown_variable,
virtual bool WasStopSignal() const volatile { return false; } err_division_by_zero,
virtual ~StopCalculating(){} err_interrupt,
}; err_overflow,
err_unknown_function,
err_unknown_operator,
/*! err_unexpected_semicolon_operator,
a small class which is useful when compiling with gcc err_improper_amount_of_arguments,
err_improper_argument,
object of this type holds the name and the line of a file err_unexpected_end,
in which the macro TTMATH_ASSERT or TTMATH_REFERENCE_ASSERT was used err_internal_error,
*/ err_incorrect_name,
class ExceptionInfo err_incorrect_value,
{ err_variable_exists,
const char * file; err_variable_loop,
int line; err_functions_loop,
err_must_be_only_one_value,
public: err_object_exists,
ExceptionInfo() : file(0), line(0) {} err_unknown_object,
ExceptionInfo(const char * f, int l) : file(f), line(l) {} err_still_calculating,
err_in_short_form_used_function
std::string Where() const };
{
if( !file )
return "unknown"; /*!
this simple class can be used in multithreading model
std::ostringstream result; (you can write your own class derived from this one)
result << file << ":" << line;
for example: in some functions like Factorial()
return result.str(); /at the moment only Factorial/ you can give a pointer to
} the 'stop object', if the method WasStopSignal() of this
}; object returns true that means we should break the calculating
and return
*/
/*! class StopCalculating
A small class used for reporting 'reference' errors {
public:
In the library is used macro TTMATH_REFERENCE_ASSERT which virtual bool WasStopSignal() const volatile { return false; }
can throw an exception of this type virtual ~StopCalculating(){}
};
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) a small class which is useful when compiling with gcc
What is the 'reference' error? object of this type holds the name and the line of a file
Some kind of methods use a reference as their argument to another object, in which the macro TTMATH_ASSERT or TTMATH_REFERENCE_ASSERT was used
and the another object not always can be the same which is calling, e.g. */
Big<1,2> foo(10); class ExceptionInfo
foo.Mul(foo); // this is incorrect {
above method Mul is making something more with 'this' object and const tt_char * file;
'this' cannot be passed as the argument because the result will be undefined int line;
macro TTMATH_REFERENCE_ASSERT helps us to solve the above problem public:
ExceptionInfo() : file(0), line(0) {}
note! some methods can use 'this' object as the argument ExceptionInfo(const tt_char * f, int l) : file(f), line(l) {}
for example this code is correct:
UInt<2> foo(10); tt_string Where() const
foo.Add(foo); {
but there are only few methods which can do that if( !file )
*/ return TTMATH_TEXT("unknown");
class ReferenceError : public std::logic_error, public ExceptionInfo
{ tt_ostringstream result;
public: result << file << TTMATH_TEXT(":") << line;
ReferenceError() : std::logic_error ("reference error") return result.str();
{ }
} };
ReferenceError(const char * f, int l) :
std::logic_error ("reference error"), ExceptionInfo(f,l) /*!
{ A small class used for reporting 'reference' errors
}
In the library is used macro TTMATH_REFERENCE_ASSERT which
std::string Where() const can throw an exception of this type
{
return ExceptionInfo::Where(); If you compile with gcc you can get a small benefit
} from using method Where() (it returns std::string (or std::wstring) with
}; the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
was used)
/*! What is the 'reference' error?
a small class used for reporting errors 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.
in the library is used macro TTMATH_ASSERT which Big<1,2> foo(10);
(if the condition in it is false) throw an exception foo.Mul(foo); // this is incorrect
of this type above method Mul is making something more with 'this' object and
'this' cannot be passed as the argument because the result will be undefined
if you compile with gcc you can get a small benefit
from using method Where() (it returns std::string with macro TTMATH_REFERENCE_ASSERT helps us to solve the above problem
the name and the line of a file where the macro TTMATH_ASSERT
was used) note! some methods can use 'this' object as the argument
*/ for example this code is correct:
class RuntimeError : public std::runtime_error, public ExceptionInfo UInt<2> foo(10);
{ foo.Add(foo);
public: but there are only few methods which can do that
*/
RuntimeError() : std::runtime_error ("internal error") class ReferenceError : public std::logic_error, public ExceptionInfo
{ {
} public:
RuntimeError(const char * f, int l) : ReferenceError() : std::logic_error ("reference error")
std::runtime_error ("internal error"), ExceptionInfo(f,l) {
{ }
}
ReferenceError(const tt_char * f, int l) :
std::string Where() const std::logic_error ("reference error"), ExceptionInfo(f,l)
{ {
return ExceptionInfo::Where(); }
}
}; tt_string Where() const
{
return ExceptionInfo::Where();
}
/*! };
look at the description of macros TTMATH_RELEASE and TTMATH_DEBUG
*/
#ifdef TTMATH_DEBUG /*!
a small class used for reporting errors
#if defined(__FILE__) && defined(__LINE__)
in the library is used macro TTMATH_ASSERT which
#define TTMATH_REFERENCE_ASSERT(expression) \ (if the condition in it is false) throw an exception
if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__); of this type
#define TTMATH_ASSERT(expression) \ if you compile with gcc you can get a small benefit
if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__); from using method Where() (it returns std::string (or std::wstring) with
the name and the line of a file where the macro TTMATH_ASSERT
#else was used)
*/
#define TTMATH_REFERENCE_ASSERT(expression) \ class RuntimeError : public std::runtime_error, public ExceptionInfo
if( &(expression) == this ) throw ReferenceError(); {
public:
#define TTMATH_ASSERT(expression) \
if( !(expression) ) throw RuntimeError(); RuntimeError() : std::runtime_error ("internal error")
#endif {
}
#else
#define TTMATH_REFERENCE_ASSERT(expression) RuntimeError(const tt_char * f, int l) :
#define TTMATH_ASSERT(expression) std::runtime_error ("internal error"), ExceptionInfo(f,l)
#endif {
}
tt_string Where() const
#ifdef TTMATH_DEBUG_LOG {
return ExceptionInfo::Where();
#define TTMATH_LOG(msg) \ }
PrintLog(msg, std::cout); };
#else
#define TTMATH_LOG(msg) /*!
look at the description of macros TTMATH_RELEASE and TTMATH_DEBUG
#endif */
#ifdef TTMATH_DEBUG
} // namespace #if defined(__FILE__) && defined(__LINE__)
#ifdef TTMATH_USE_WCHAR
#endif #define TTMATH_FILE_HELPER2(arg) L##arg
#define TTMATH_FILE_HELPER(x) TTMATH_FILE_HELPER2(x)
#define TTMATH_FILE TTMATH_FILE_HELPER(__FILE__)
#else
#define TTMATH_FILE __FILE__
#endif
#define TTMATH_REFERENCE_ASSERT(expression) \
if( &(expression) == this ) throw ttmath::ReferenceError(TTMATH_FILE, __LINE__);
#define TTMATH_ASSERT(expression) \
if( !(expression) ) throw ttmath::RuntimeError(TTMATH_FILE, __LINE__);
#define TTMATH_VERIFY(expression) \
if( !(expression) ) throw ttmath::RuntimeError(TTMATH_TEXT(__FILE__), __LINE__);
#else
#define TTMATH_REFERENCE_ASSERT(expression) \
if( &(expression) == this ) throw ReferenceError();
#define TTMATH_ASSERT(expression) \
if( !(expression) ) throw RuntimeError();
#define TTMATH_VERIFY(expression) \
if( !(expression) ) throw RuntimeError();
#endif
#else
#define TTMATH_REFERENCE_ASSERT(expression)
#define TTMATH_ASSERT(expression)
#define TTMATH_VERIFY(expression) (void)(expression);
#endif
#if !defined(LOG_PRINTF)
#define LOG_PRINTF printf
#endif
#ifdef TTMATH_DEBUG_LOG
#ifdef TTMATH_USE_WCHAR
#define TTMATH_LOG_HELPER(msg) \
PrintLog(L##msg, std::wcout);
#else
#define TTMATH_LOG_HELPER(msg) \
PrintLog(msg, std::cout);
#endif
#define TTMATH_LOG(msg) TTMATH_LOG_HELPER(msg)
#else
#define TTMATH_LOG(msg)
#endif
} // namespace
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/* /*
* This file is a part of TTMath Bignum Library * This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence. * and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl> * Author: Tomasz Sowa <t.sowa@ttmath.org>
*/ */
/* /*
@@ -41,6 +41,8 @@
#ifdef TTMATH_NOASM #ifdef TTMATH_NOASM
#pragma message("TTMATH_NOASM")
/*! /*!
\file ttmathuint_noasm.h \file ttmathuint_noasm.h
\brief template class UInt<uint> with methods without any assembler code \brief template class UInt<uint> with methods without any assembler code

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,386 @@
PUBLIC adc_x64
PUBLIC addindexed_x64
PUBLIC addindexed2_x64
PUBLIC sbb_x64
PUBLIC subindexed_x64
PUBLIC rcl_x64
PUBLIC rcr_x64
PUBLIC rcl2_x64
PUBLIC rcr2_x64
PUBLIC div_x64
;
; "rax, rcx, rdx, r8-r11 are volatile."
; "rbx, rbp, rdi, rsi, r12-r15 are nonvolatile."
;
.CODE
ALIGN 8
;----------------------------------------
adc_x64 PROC
; rcx = p1
; rdx = p2
; r8 = nSize
; r9 = nCarry
xor rax, rax
xor r11, r11
sub rax, r9 ; sets CARRY if r9 != 0
ALIGN 16
loop1:
mov rax,qword ptr [rdx + r11 * 8]
adc qword ptr [rcx + r11 * 8], rax
lea r11, [r11+1]
dec r8
jnz loop1
setc al
movzx rax, al
ret
adc_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
addindexed_x64 PROC
; rcx = p1
; rdx = nSize
; r8 = nPos
; r9 = nValue
xor rax, rax ; rax = result
sub rdx, r8 ; rdx = remaining count of uints
add qword ptr [rcx + r8 * 8], r9
jc next1
ret
next1:
mov r9, 1
ALIGN 16
loop1:
dec rdx
jz done_with_cy
lea r8, [r8+1]
add qword ptr [rcx + r8 * 8], r9
jc loop1
ret
done_with_cy:
lea rax, [rax+1] ; rax = 1
ret
addindexed_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
addindexed2_x64 PROC
; rcx = p1 (pointer)
; rdx = b (value size)
; r8 = nPos
; r9 = nValue1
; [esp+0x28] = nValue2
xor rax, rax ; return value
mov r11, rcx ; table
sub rdx, r8 ; rdx = remaining count of uints
mov r10, [esp+028h] ; r10 = nValue2
add qword ptr [r11 + r8 * 8], r9
lea r8, [r8+1]
lea rdx, [rdx-1]
adc qword ptr [r11 + r8 * 8], r10
jc next
ret
ALIGN 16
loop1:
lea r8, [r8+1]
add qword ptr [r11 + r8 * 8], 1
jc next
ret
next:
dec rdx ; does not modify CY too...
jnz loop1
lea rax, [rax+1]
ret
addindexed2_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
sbb_x64 PROC
; rcx = p1
; rdx = p2
; r8 = nCount
; r9 = nCarry
xor rax, rax
xor r11, r11
sub rax, r9 ; sets CARRY if r9 != 0
ALIGN 16
loop1:
mov rax,qword ptr [rdx + r11 * 8]
sbb qword ptr [rcx + r11 * 8], rax
lea r11, [r11+1]
dec r8
jnz loop1
setc al
movzx rax, al
ret
sbb_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
subindexed_x64 PROC
; rcx = p1
; rdx = nSize
; r8 = nPos
; r9 = nValue
sub rdx, r8 ; rdx = remaining count of uints
ALIGN 16
loop1:
sub qword ptr [rcx + r8 * 8], r9
jnc done
lea r8, [r8+1]
mov r9, 1
dec rdx
jnz loop1
jc return_1 ; most of the times, there will be NO carry (I hope)
done:
xor rax, rax
ret
return_1:
mov rax, 1
ret
subindexed_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
rcl_x64 PROC
; rcx = p1
; rdx = b
; r8 = nLowestBit
mov r11, rcx ; table
xor r10, r10
neg r8 ; CY set if r8 <> 0
ALIGN 16
loop1:
rcl qword ptr [r11 + r10 * 8], 1
lea r10, [r10+1]
dec rdx
jnz loop1
setc al
movzx rax, al
ret
rcl_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
rcr_x64 PROC
; rcx = p1
; rdx = nSize
; r8 = nLowestBit
xor r10, r10
neg r8 ; CY set if r8 <> 0
ALIGN 16
loop1:
rcr qword ptr -8[rcx + rdx * 8], 1
dec rdx
jnz loop1
setc al
movzx rax, al
ret
rcr_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
div_x64 PROC
; rcx = &Hi
; rdx = &Lo
; r8 = nDiv
mov r11, rcx
mov r10, rdx
mov rdx, qword ptr [r11]
mov rax, qword ptr [r10]
div r8
mov qword ptr [r10], rdx ; remainder
mov qword ptr [r11], rax ; value
ret
div_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
rcl2_x64 PROC
; rcx = p1
; rdx = nSize
; r8 = bits
; r9 = c
push rbx
mov r10, rcx ; r10 = p1
xor rax, rax
mov rcx, 64
sub rcx, r8
mov r11, -1
shr r11, cl ; r11 = mask
mov rcx, r8 ; rcx = count of bits
mov rbx, rax ; rbx = old value = 0
or r9, r9
cmovnz rbx, r11 ; if (c) then old value = mask
mov r9, rax ; r9 = index (0..nSize-1)
ALIGN 16
loop1:
rol qword ptr [r10+r9*8], cl
mov rax, qword ptr [r10+r9*8]
and rax, r11
xor qword ptr [r10+r9*8], rax
or qword ptr [r10+r9*8], rbx
mov rbx, rax
lea r9, [r9+1]
dec rdx
jnz loop1
and rax, 1
pop rbx
ret
rcl2_x64 ENDP
;----------------------------------------
ALIGN 8
;----------------------------------------
rcr2_x64 PROC
; rcx = p1
; rdx = nSize
; r8 = bits
; r9 = c
push rbx
mov r10, rcx ; r10 = p1
xor rax, rax
mov rcx, 64
sub rcx, r8
mov r11, -1
shl r11, cl ; r11 = mask
mov rcx, r8 ; rcx = count of bits
mov rbx, rax ; rbx = old value = 0
or r9, r9
cmovnz rbx, r11 ; if (c) then old value = mask
mov r9, rdx ; r9 = index (0..nSize-1)
lea r9, [r9-1]
ALIGN 16
loop1:
ror qword ptr [r10+r9*8], cl
mov rax, qword ptr [r10+r9*8]
and rax, r11
xor qword ptr [r10+r9*8], rax
or qword ptr [r10+r9*8], rbx
mov rbx, rax
lea r9, [r9-1]
dec rdx
jnz loop1
rol rax, 1
and rax, 1
pop rbx
ret
rcr2_x64 ENDP
END