mirror of
https://github.com/dashr9230/SA-MP.git
synced 2026-10-10 03:33:04 +08:00
Add ttmath 0.9.1 library
This commit is contained in:
@@ -230,6 +230,16 @@
|
|||||||
RelativePath=".\archive\TinyEncrypt.h">
|
RelativePath=".\archive\TinyEncrypt.h">
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="ttmath"
|
||||||
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath="..\ttmath\ttmathuint.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ttmath\ttmathuint_x86.h">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\audiostream.cpp">
|
RelativePath=".\audiostream.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
|||||||
@@ -108,6 +108,16 @@
|
|||||||
<References>
|
<References>
|
||||||
</References>
|
</References>
|
||||||
<Files>
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="ttmath"
|
||||||
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath="..\ttmath\ttmathuint.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ttmath\ttmathuint_x86.h">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\actorpool.cpp">
|
RelativePath=".\actorpool.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
|||||||
+2835
File diff suppressed because it is too large
Load Diff
+5236
File diff suppressed because it is too large
Load Diff
+1547
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,243 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the (new) BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||||
|
* project may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfilettmathmisc
|
||||||
|
#define headerfilettmathmisc
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\file ttmathmisc.h
|
||||||
|
\brief some helpful functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace ttmath
|
||||||
|
{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
some helpful functions
|
||||||
|
*/
|
||||||
|
class Misc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* AssignString(result, str)
|
||||||
|
* result = str
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result = str
|
||||||
|
*/
|
||||||
|
static void AssignString(std::string & result, const char * str)
|
||||||
|
{
|
||||||
|
result = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result = str
|
||||||
|
*/
|
||||||
|
static void AssignString(std::wstring & result, const char * str)
|
||||||
|
{
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
for( ; *str ; ++str )
|
||||||
|
result += *str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result = str
|
||||||
|
*/
|
||||||
|
static void AssignString(std::wstring & result, const std::string & str)
|
||||||
|
{
|
||||||
|
return AssignString(result, str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result = str
|
||||||
|
*/
|
||||||
|
static void AssignString(std::string & result, const wchar_t * str)
|
||||||
|
{
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
for( ; *str ; ++str )
|
||||||
|
result += static_cast<char>(*str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result = str
|
||||||
|
*/
|
||||||
|
static void AssignString(std::string & result, const std::wstring & str)
|
||||||
|
{
|
||||||
|
return AssignString(result, str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* AddString(result, str)
|
||||||
|
* result += str
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result += str
|
||||||
|
*/
|
||||||
|
static void AddString(std::string & result, const char * str)
|
||||||
|
{
|
||||||
|
result += str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result += str
|
||||||
|
*/
|
||||||
|
static void AddString(std::wstring & result, const char * str)
|
||||||
|
{
|
||||||
|
for( ; *str ; ++str )
|
||||||
|
result += *str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
this method omits any white characters from the string
|
||||||
|
char_type is char or wchar_t
|
||||||
|
*/
|
||||||
|
template<class char_type>
|
||||||
|
static void SkipWhiteCharacters(const char_type * & c)
|
||||||
|
{
|
||||||
|
// 13 is at the end in a DOS text file (\r\n)
|
||||||
|
while( (*c==' ' ) || (*c=='\t') || (*c==13 ) || (*c=='\n') )
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this static method converts one character into its value
|
||||||
|
|
||||||
|
for example:
|
||||||
|
1 -> 1
|
||||||
|
8 -> 8
|
||||||
|
A -> 10
|
||||||
|
f -> 15
|
||||||
|
|
||||||
|
this method don't check whether c is correct or not
|
||||||
|
*/
|
||||||
|
static uint CharToDigit(uint c)
|
||||||
|
{
|
||||||
|
if(c>='0' && c<='9')
|
||||||
|
return c-'0';
|
||||||
|
|
||||||
|
if(c>='a' && c<='z')
|
||||||
|
return c-'a'+10;
|
||||||
|
|
||||||
|
return c-'A'+10;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method changes a character 'c' into its value
|
||||||
|
(if there can't be a correct value it returns -1)
|
||||||
|
|
||||||
|
for example:
|
||||||
|
c=2, base=10 -> function returns 2
|
||||||
|
c=A, base=10 -> function returns -1
|
||||||
|
c=A, base=16 -> function returns 10
|
||||||
|
*/
|
||||||
|
static sint CharToDigit(uint c, uint base)
|
||||||
|
{
|
||||||
|
if( c>='0' && c<='9' )
|
||||||
|
c=c-'0';
|
||||||
|
else
|
||||||
|
if( c>='a' && c<='z' )
|
||||||
|
c=c-'a'+10;
|
||||||
|
else
|
||||||
|
if( c>='A' && c<='Z' )
|
||||||
|
c=c-'A'+10;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
|
if( c >= base )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
|
return sint(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts a digit into a char
|
||||||
|
digit should be from <0,F>
|
||||||
|
(we don't have to get a base)
|
||||||
|
|
||||||
|
for example:
|
||||||
|
1 -> 1
|
||||||
|
8 -> 8
|
||||||
|
10 -> A
|
||||||
|
15 -> F
|
||||||
|
*/
|
||||||
|
static uint DigitToChar(uint digit)
|
||||||
|
{
|
||||||
|
if( digit < 10 )
|
||||||
|
return digit + '0';
|
||||||
|
|
||||||
|
return digit - 10 + 'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}; // struct Misc
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,766 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of TTMath Mathematical Library
|
||||||
|
* and is distributed under the (new) BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||||
|
* project may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef headerfilettmathobject
|
||||||
|
#define headerfilettmathobject
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\file ttmathobjects.h
|
||||||
|
\brief Mathematic functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "ttmathtypes.h"
|
||||||
|
#include "ttmathmisc.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace ttmath
|
||||||
|
{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
objects of this class are used with the mathematical parser
|
||||||
|
they hold variables or functions defined by a user
|
||||||
|
|
||||||
|
each object has its own table in which we're keeping variables or functions
|
||||||
|
*/
|
||||||
|
class Objects
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
one item (variable or function)
|
||||||
|
'items' will be on the table
|
||||||
|
*/
|
||||||
|
struct Item
|
||||||
|
{
|
||||||
|
// name of a variable of a function
|
||||||
|
// internally we store variables and funcions as std::string (not std::wstring even when wide characters are used)
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
// number of parameters required by the function
|
||||||
|
// (if there's a variable this 'param' is ignored)
|
||||||
|
int param;
|
||||||
|
|
||||||
|
Item() {}
|
||||||
|
Item(const std::string & v, int p) : value(v), param(p) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 'Table' is the type of our table
|
||||||
|
typedef std::map<std::string, Item> Table;
|
||||||
|
typedef Table::iterator Iterator;
|
||||||
|
typedef Table::const_iterator CIterator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns true if a character 'c' is a character
|
||||||
|
which can be in a name
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if( can_be_digit && ((c>='0' && c<='9') || c=='_') )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns true if the name can be as a name of an object
|
||||||
|
*/
|
||||||
|
template<class string_type>
|
||||||
|
static bool IsNameCorrect(const string_type & name)
|
||||||
|
{
|
||||||
|
if( name.empty() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( !CorrectCharacter(name[0], false) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
typename string_type::const_iterator i = name.begin();
|
||||||
|
|
||||||
|
for(++i ; i!=name.end() ; ++i)
|
||||||
|
if( !CorrectCharacter(*i, true) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns true if such an object is defined (name exists)
|
||||||
|
*/
|
||||||
|
bool IsDefined(const std::string & name)
|
||||||
|
{
|
||||||
|
Iterator i = table.find(name);
|
||||||
|
|
||||||
|
if( i != table.end() )
|
||||||
|
// we have this object in our table
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns true if such an object is defined (name exists)
|
||||||
|
*/
|
||||||
|
bool IsDefined(const std::wstring & name)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
|
||||||
|
return IsDefined(str_tmp1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method adds one object (variable of function) into the table
|
||||||
|
*/
|
||||||
|
ErrorCode Add(const std::string & name, const std::string & value, int param = 0)
|
||||||
|
{
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Iterator i = table.find(name);
|
||||||
|
|
||||||
|
if( i != table.end() )
|
||||||
|
// we have this object in our table
|
||||||
|
return err_object_exists;
|
||||||
|
|
||||||
|
table.insert( std::make_pair(name, Item(value, param)) );
|
||||||
|
|
||||||
|
return err_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method adds one object (variable of function) into the table
|
||||||
|
*/
|
||||||
|
ErrorCode Add(const std::wstring & name, const std::wstring & value, int param = 0)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
Misc::AssignString(str_tmp2, value);
|
||||||
|
|
||||||
|
return Add(str_tmp1, str_tmp2, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns 'true' if the table is empty
|
||||||
|
*/
|
||||||
|
bool Empty() const
|
||||||
|
{
|
||||||
|
return table.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method clears the table
|
||||||
|
*/
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
return table.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns 'const_iterator' on the first item on the table
|
||||||
|
*/
|
||||||
|
CIterator Begin() const
|
||||||
|
{
|
||||||
|
return table.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns 'const_iterator' pointing at the space after last item
|
||||||
|
(returns table.end())
|
||||||
|
*/
|
||||||
|
CIterator End() const
|
||||||
|
{
|
||||||
|
return table.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Iterator i = table.find(name);
|
||||||
|
|
||||||
|
if( i == table.end() )
|
||||||
|
return err_unknown_object;
|
||||||
|
|
||||||
|
i->second.value = value;
|
||||||
|
i->second.param = param;
|
||||||
|
|
||||||
|
return err_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method changes the value and the number of parameters for a specific object
|
||||||
|
*/
|
||||||
|
ErrorCode EditValue(const std::wstring & name, const std::wstring & value, int param = 0)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
Misc::AssignString(str_tmp2, value);
|
||||||
|
|
||||||
|
return EditValue(str_tmp1, str_tmp2, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method changes the name of a specific object
|
||||||
|
*/
|
||||||
|
ErrorCode EditName(const std::string & old_name, const std::string & new_name)
|
||||||
|
{
|
||||||
|
if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Iterator old_i = table.find(old_name);
|
||||||
|
if( old_i == table.end() )
|
||||||
|
return err_unknown_object;
|
||||||
|
|
||||||
|
if( old_name == new_name )
|
||||||
|
// the new name is the same as the old one
|
||||||
|
// we treat it as a normal situation
|
||||||
|
return err_ok;
|
||||||
|
|
||||||
|
ErrorCode err = Add(new_name, old_i->second.value, old_i->second.param);
|
||||||
|
|
||||||
|
if( err == err_ok )
|
||||||
|
{
|
||||||
|
old_i = table.find(old_name);
|
||||||
|
TTMATH_ASSERT( old_i != table.end() )
|
||||||
|
|
||||||
|
table.erase(old_i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method changes the name of a specific object
|
||||||
|
*/
|
||||||
|
ErrorCode EditName(const std::wstring & old_name, const std::wstring & new_name)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, old_name);
|
||||||
|
Misc::AssignString(str_tmp2, new_name);
|
||||||
|
|
||||||
|
return EditName(str_tmp1, str_tmp2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method deletes an object
|
||||||
|
*/
|
||||||
|
ErrorCode Delete(const std::string & name)
|
||||||
|
{
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Iterator i = table.find(name);
|
||||||
|
|
||||||
|
if( i == table.end() )
|
||||||
|
return err_unknown_object;
|
||||||
|
|
||||||
|
table.erase( i );
|
||||||
|
|
||||||
|
return err_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method deletes an object
|
||||||
|
*/
|
||||||
|
ErrorCode Delete(const std::wstring & name)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
|
||||||
|
return Delete(str_tmp1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method gets the value of a specific object
|
||||||
|
*/
|
||||||
|
ErrorCode GetValue(const std::string & name, std::string & value) const
|
||||||
|
{
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
CIterator i = table.find(name);
|
||||||
|
|
||||||
|
if( i == table.end() )
|
||||||
|
{
|
||||||
|
value.clear();
|
||||||
|
return err_unknown_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = i->second.value;
|
||||||
|
|
||||||
|
return err_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method gets the value of a specific object
|
||||||
|
*/
|
||||||
|
ErrorCode GetValue(const std::wstring & name, std::wstring & value)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
ErrorCode err = GetValue(str_tmp1, str_tmp2);
|
||||||
|
Misc::AssignString(value, str_tmp2);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method gets the value of a specific object
|
||||||
|
(this version is used for not copying the whole string)
|
||||||
|
*/
|
||||||
|
ErrorCode GetValue(const std::string & name, const char ** value) const
|
||||||
|
{
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
CIterator i = table.find(name);
|
||||||
|
|
||||||
|
if( i == table.end() )
|
||||||
|
{
|
||||||
|
*value = 0;
|
||||||
|
return err_unknown_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
*value = i->second.value.c_str();
|
||||||
|
|
||||||
|
return err_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method gets the value of a specific object
|
||||||
|
(this version is used for not copying the whole string)
|
||||||
|
*/
|
||||||
|
ErrorCode GetValue(const std::wstring & name, const char ** value)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
|
||||||
|
return GetValue(str_tmp1, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method gets the value and the number of parameters
|
||||||
|
of a specific object
|
||||||
|
*/
|
||||||
|
ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const
|
||||||
|
{
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
CIterator i = table.find(name);
|
||||||
|
|
||||||
|
if( i == table.end() )
|
||||||
|
{
|
||||||
|
value.empty();
|
||||||
|
*param = 0;
|
||||||
|
return err_unknown_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = i->second.value;
|
||||||
|
*param = i->second.param;
|
||||||
|
|
||||||
|
return err_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method gets the value and the number of parameters
|
||||||
|
of a specific object
|
||||||
|
*/
|
||||||
|
ErrorCode GetValueAndParam(const std::wstring & name, std::wstring & value, int * param)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
ErrorCode err = GetValueAndParam(str_tmp1, str_tmp2, param);
|
||||||
|
Misc::AssignString(value, str_tmp2);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method sets the value and the number of parameters
|
||||||
|
of a specific object
|
||||||
|
(this version is used for not copying the whole string)
|
||||||
|
*/
|
||||||
|
ErrorCode GetValueAndParam(const std::string & name, const char ** value, int * param) const
|
||||||
|
{
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
CIterator i = table.find(name);
|
||||||
|
|
||||||
|
if( i == table.end() )
|
||||||
|
{
|
||||||
|
*value = 0;
|
||||||
|
*param = 0;
|
||||||
|
return err_unknown_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
*value = i->second.value.c_str();
|
||||||
|
*param = i->second.param;
|
||||||
|
|
||||||
|
return err_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method sets the value and the number of parameters
|
||||||
|
of a specific object
|
||||||
|
(this version is used for not copying the whole string
|
||||||
|
but in fact we make one copying during AssignString())
|
||||||
|
*/
|
||||||
|
ErrorCode GetValueAndParam(const std::wstring & name, const char ** value, int * param)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
|
||||||
|
return GetValueAndParam(str_tmp1, value, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns a pointer into the table
|
||||||
|
*/
|
||||||
|
Table * GetTable()
|
||||||
|
{
|
||||||
|
return &table;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Table table;
|
||||||
|
std::string str_tmp1, str_tmp2;
|
||||||
|
|
||||||
|
}; // end of class Objects
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
objects of the class History are used to keep values in functions
|
||||||
|
which take a lot of time during calculating, for instance in the
|
||||||
|
function Factorial(x)
|
||||||
|
|
||||||
|
it means that when we're calculating e.g. Factorial(1000) and the
|
||||||
|
Factorial finds that we have calculated it before, the value (result)
|
||||||
|
is taken from the history
|
||||||
|
*/
|
||||||
|
template<class ValueType>
|
||||||
|
class History
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
one item in the History's object holds a key, a value for the key
|
||||||
|
and a corresponding error code
|
||||||
|
*/
|
||||||
|
struct Item
|
||||||
|
{
|
||||||
|
ValueType key, value;
|
||||||
|
ErrorCode err;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
we use std::list for simply deleting the first item
|
||||||
|
but because we're searching through the whole container
|
||||||
|
(in the method Get) the container should not be too big
|
||||||
|
(linear time of searching)
|
||||||
|
*/
|
||||||
|
typedef std::list<Item> buffer_type;
|
||||||
|
buffer_type buffer;
|
||||||
|
typename buffer_type::size_type buffer_max_size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/*!
|
||||||
|
default constructor
|
||||||
|
default max size of the History's container is 15 items
|
||||||
|
*/
|
||||||
|
History()
|
||||||
|
{
|
||||||
|
buffer_max_size = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
a constructor which takes another value of the max size
|
||||||
|
of the History's container
|
||||||
|
*/
|
||||||
|
History(typename buffer_type::size_type new_size)
|
||||||
|
{
|
||||||
|
buffer_max_size = new_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method adds one item into the History
|
||||||
|
if the size of the container is greater than buffer_max_size
|
||||||
|
the first item will be removed
|
||||||
|
*/
|
||||||
|
void Add(const ValueType & key, const ValueType & value, ErrorCode err)
|
||||||
|
{
|
||||||
|
Item item;
|
||||||
|
item.key = key;
|
||||||
|
item.value = value;
|
||||||
|
item.err = err;
|
||||||
|
|
||||||
|
buffer.insert( buffer.end(), item );
|
||||||
|
|
||||||
|
if( buffer.size() > buffer_max_size )
|
||||||
|
buffer.erase(buffer.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method checks whether we have an item which has the key equal 'key'
|
||||||
|
|
||||||
|
if there's such item the method sets the 'value' and the 'err'
|
||||||
|
and returns true otherwise it returns false and 'value' and 'err'
|
||||||
|
remain unchanged
|
||||||
|
*/
|
||||||
|
bool Get(const ValueType & key, ValueType & value, ErrorCode & err)
|
||||||
|
{
|
||||||
|
typename buffer_type::iterator i = buffer.begin();
|
||||||
|
|
||||||
|
for( ; i != buffer.end() ; ++i )
|
||||||
|
{
|
||||||
|
if( i->key == key )
|
||||||
|
{
|
||||||
|
value = i->value;
|
||||||
|
err = i->err;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this methods deletes an item
|
||||||
|
|
||||||
|
we assume that there is only one item with the 'key'
|
||||||
|
(this methods removes the first one)
|
||||||
|
*/
|
||||||
|
bool Remove(const ValueType & key)
|
||||||
|
{
|
||||||
|
typename buffer_type::iterator i = buffer.begin();
|
||||||
|
|
||||||
|
for( ; i != buffer.end() ; ++i )
|
||||||
|
{
|
||||||
|
if( i->key == key )
|
||||||
|
{
|
||||||
|
buffer.erase(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}; // end of class History
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this is an auxiliary class used when calculating Gamma() or Factorial()
|
||||||
|
|
||||||
|
in multithreaded environment you can provide an object of this class to
|
||||||
|
the Gamma() or Factorial() function, e.g;
|
||||||
|
typedef Big<1, 3> MyBig;
|
||||||
|
MyBig x = 123456;
|
||||||
|
CGamma<MyBig> cgamma;
|
||||||
|
std::cout << Gamma(x, cgamma);
|
||||||
|
each thread should have its own CGamma<> object
|
||||||
|
|
||||||
|
in a single-thread environment a CGamma<> object is a static variable
|
||||||
|
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 these coefficients is a little time-consuming operation,
|
||||||
|
(especially when the mantissa is large) and first call to Gamma() or Factorial()
|
||||||
|
can take more time than next calls, and in the end this is the point when InitAll()
|
||||||
|
comes in handy: you can call this method somewhere at the beginning of your program
|
||||||
|
*/
|
||||||
|
void InitAll();
|
||||||
|
// definition is in ttmath.h
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,250 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the (new) BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||||
|
* project may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef headerfilettmaththreads
|
||||||
|
#define headerfilettmaththreads
|
||||||
|
|
||||||
|
#include "ttmathtypes.h"
|
||||||
|
|
||||||
|
#ifdef TTMATH_WIN32_THREADS
|
||||||
|
#include <windows.h>
|
||||||
|
#include <cstdio>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TTMATH_POSIX_THREADS
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\file ttmaththreads.h
|
||||||
|
\brief Some objects used in multithreads environment
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
this is a simple skeleton of a program in multithreads environment:
|
||||||
|
|
||||||
|
#define TTMATH_MULTITHREADS
|
||||||
|
#include<ttmath/ttmath.h>
|
||||||
|
|
||||||
|
TTMATH_MULTITHREADS_HELPER
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
[...]
|
||||||
|
}
|
||||||
|
|
||||||
|
make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file)
|
||||||
|
use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace ttmath
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TTMATH_WIN32_THREADS
|
||||||
|
|
||||||
|
/*
|
||||||
|
we use win32 threads
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
|
||||||
|
somewhere in *.cpp file
|
||||||
|
|
||||||
|
(at the moment in win32 this macro does nothing)
|
||||||
|
*/
|
||||||
|
#define TTMATH_MULTITHREADS_HELPER
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
objects of this class are used to synchronize
|
||||||
|
*/
|
||||||
|
class ThreadLock
|
||||||
|
{
|
||||||
|
HANDLE mutex_handle;
|
||||||
|
|
||||||
|
|
||||||
|
void CreateName(char * buffer) const
|
||||||
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning (disable : 4996)
|
||||||
|
// warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sprintf(buffer, "TTMATH_LOCK_%ul", (unsigned long)GetCurrentProcessId());
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning (default : 4996)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool Lock()
|
||||||
|
{
|
||||||
|
char buffer[50];
|
||||||
|
|
||||||
|
CreateName(buffer);
|
||||||
|
mutex_handle = CreateMutexA(0, false, buffer);
|
||||||
|
|
||||||
|
if( mutex_handle == 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
WaitForSingleObject(mutex_handle, INFINITE);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ThreadLock()
|
||||||
|
{
|
||||||
|
mutex_handle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
~ThreadLock()
|
||||||
|
{
|
||||||
|
if( mutex_handle != 0 )
|
||||||
|
{
|
||||||
|
ReleaseMutex(mutex_handle);
|
||||||
|
CloseHandle(mutex_handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // #ifdef TTMATH_WIN32_THREADS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TTMATH_POSIX_THREADS
|
||||||
|
|
||||||
|
/*
|
||||||
|
we use posix threads
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
|
||||||
|
somewhere in *.cpp file
|
||||||
|
(this macro defines a pthread_mutex_t object used by TTMath library)
|
||||||
|
*/
|
||||||
|
#define TTMATH_MULTITHREADS_HELPER \
|
||||||
|
namespace ttmath \
|
||||||
|
{ \
|
||||||
|
pthread_mutex_t ttmath_mutex = PTHREAD_MUTEX_INITIALIZER; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
ttmath_mutex will be defined by TTMATH_MULTITHREADS_HELPER macro
|
||||||
|
*/
|
||||||
|
extern pthread_mutex_t ttmath_mutex;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
objects of this class are used to synchronize
|
||||||
|
*/
|
||||||
|
class ThreadLock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool Lock()
|
||||||
|
{
|
||||||
|
if( pthread_mutex_lock(&ttmath_mutex) != 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
~ThreadLock()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&ttmath_mutex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // #ifdef TTMATH_POSIX_THREADS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
we don't use win32 and pthreads
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*/
|
||||||
|
#define TTMATH_MULTITHREADS_HELPER
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
objects of this class are used to synchronize
|
||||||
|
actually we don't synchronize, the method Lock() returns always 'false'
|
||||||
|
*/
|
||||||
|
class ThreadLock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool Lock()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // #if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,646 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the (new) BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2010, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||||
|
* project may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef headerfilettmathtypes
|
||||||
|
#define headerfilettmathtypes
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\file ttmathtypes.h
|
||||||
|
\brief constants used in the library
|
||||||
|
|
||||||
|
As our library is written in header files (templates) we cannot use
|
||||||
|
constants like 'const int' etc. because we should have some source files
|
||||||
|
*.cpp to define this variables. Only what we can have are constants
|
||||||
|
defined by #define preprocessor macros.
|
||||||
|
|
||||||
|
All macros are preceded by TTMATH_ prefix
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the version of the library
|
||||||
|
|
||||||
|
TTMATH_PRERELEASE_VER is either zero or one
|
||||||
|
if zero that means this is the release version of the library
|
||||||
|
*/
|
||||||
|
#define TTMATH_MAJOR_VER 0
|
||||||
|
#define TTMATH_MINOR_VER 9
|
||||||
|
#define TTMATH_REVISION_VER 1
|
||||||
|
#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
|
||||||
|
*/
|
||||||
|
#ifndef TTMATH_RELEASE
|
||||||
|
#define TTMATH_DEBUG
|
||||||
|
#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
|
||||||
|
|
||||||
|
/*!
|
||||||
|
on 32bit platforms one word (uint, sint) will be equal 32bits
|
||||||
|
*/
|
||||||
|
typedef unsigned int uint;
|
||||||
|
typedef signed int sint;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this type is twice bigger than uint
|
||||||
|
(64bit on a 32bit platforms)
|
||||||
|
|
||||||
|
although C++ Standard - ANSI ISO IEC 14882:2003 doesn't define such a type (long long)
|
||||||
|
but it is defined in C99 and in upcoming C++0x /3.9.1 (2)/ and many compilers support it
|
||||||
|
|
||||||
|
this type is used in UInt::MulTwoWords and UInt::DivTwoWords when macro TTMATH_NOASM is defined
|
||||||
|
but only on a 32bit platform
|
||||||
|
*/
|
||||||
|
#ifdef TTMATH_NOASM
|
||||||
|
typedef unsigned long long int ulint;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
how many bits there are in the uint type
|
||||||
|
*/
|
||||||
|
#define TTMATH_BITS_PER_UINT 32u
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the mask for the highest bit in the unsigned 32bit word (2^31)
|
||||||
|
*/
|
||||||
|
#define TTMATH_UINT_HIGHEST_BIT 2147483648u
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the max value of the unsigned 32bit word (2^32 - 1)
|
||||||
|
(all bits equal one)
|
||||||
|
*/
|
||||||
|
#define TTMATH_UINT_MAX_VALUE 4294967295u
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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)
|
||||||
|
*/
|
||||||
|
#define TTMATH_BUILTIN_VARIABLES_SIZE 256u
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this macro returns the number of machine words
|
||||||
|
capable to hold min_bits bits
|
||||||
|
e.g. TTMATH_BITS(128) returns 4
|
||||||
|
*/
|
||||||
|
#define TTMATH_BITS(min_bits) ((min_bits-1)/32 + 1)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*!
|
||||||
|
on 64bit platforms one word (uint, sint) will be equal 64bits
|
||||||
|
*/
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
/* in VC 'long' type has 32 bits, __int64 is VC extension */
|
||||||
|
typedef unsigned __int64 uint;
|
||||||
|
typedef signed __int64 sint;
|
||||||
|
#else
|
||||||
|
typedef unsigned long uint;
|
||||||
|
typedef signed long sint;
|
||||||
|
#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
|
||||||
|
*/
|
||||||
|
//typedef unsigned long long int ulint;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
how many bits there are in the uint type
|
||||||
|
*/
|
||||||
|
#define TTMATH_BITS_PER_UINT 64ul
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the mask for the highest bit in the unsigned 64bit word (2^63)
|
||||||
|
*/
|
||||||
|
#define TTMATH_UINT_HIGHEST_BIT 9223372036854775808ul
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the max value of the unsigned 64bit word (2^64 - 1)
|
||||||
|
(all bits equal one)
|
||||||
|
*/
|
||||||
|
#define TTMATH_UINT_MAX_VALUE 18446744073709551615ul
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the number of words (64bit words on 64bit platforms)
|
||||||
|
which are kept in built-in variables for a Big<> type
|
||||||
|
(these variables are defined in ttmathbig.h)
|
||||||
|
*/
|
||||||
|
#define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this macro returns the number of machine words
|
||||||
|
capable to hold min_bits bits
|
||||||
|
e.g. TTMATH_BITS(128) returns 2
|
||||||
|
*/
|
||||||
|
#define TTMATH_BITS(min_bits) ((min_bits-1)/64 + 1)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(TTMATH_MULTITHREADS) && !defined(TTMATH_MULTITHREADS_NOSYNC)
|
||||||
|
#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#define TTMATH_WIN32_THREADS
|
||||||
|
#elif defined(unix) || defined(__unix__) || defined(__unix)
|
||||||
|
#define TTMATH_POSIX_THREADS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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
|
||||||
|
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
|
||||||
|
series are smaller than previous ones)
|
||||||
|
*/
|
||||||
|
#define TTMATH_ARITHMETIC_MAX_LOOP 10000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this is a limit when calculating Karatsuba multiplication
|
||||||
|
if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
|
||||||
|
the Karatsuba algorithm will use standard schoolbook multiplication
|
||||||
|
*/
|
||||||
|
#ifdef TTMATH_DEBUG_LOG
|
||||||
|
// if TTMATH_DEBUG_LOG is defined then we should use the same size regardless of the compiler
|
||||||
|
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
|
||||||
|
#else
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
|
||||||
|
#else
|
||||||
|
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this is a special value used when calculating the Gamma(x) function
|
||||||
|
if x is greater than this value then the Gamma(x) will be calculated using
|
||||||
|
some kind of series
|
||||||
|
|
||||||
|
don't use smaller values than about 100
|
||||||
|
*/
|
||||||
|
#define TTMATH_GAMMA_BOUNDARY 2000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace ttmath
|
||||||
|
{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
lib type codes:
|
||||||
|
asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
||||||
|
asm_gcc_32 - with asm code designed for GCC (32 bits)
|
||||||
|
asm_vc_64 - with asm for VC (64 bit)
|
||||||
|
asm_gcc_64 - with asm for GCC (64 bit)
|
||||||
|
no_asm_32 - pure C++ version (32 bit) - without any asm code
|
||||||
|
no_asm_64 - pure C++ version (64 bit) - without any asm code
|
||||||
|
*/
|
||||||
|
enum LibTypeCode
|
||||||
|
{
|
||||||
|
asm_vc_32 = 0,
|
||||||
|
asm_gcc_32,
|
||||||
|
asm_vc_64,
|
||||||
|
asm_gcc_64,
|
||||||
|
no_asm_32,
|
||||||
|
no_asm_64
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
error codes
|
||||||
|
*/
|
||||||
|
enum ErrorCode
|
||||||
|
{
|
||||||
|
err_ok = 0,
|
||||||
|
err_nothing_has_read,
|
||||||
|
err_unknown_character,
|
||||||
|
err_unexpected_final_bracket,
|
||||||
|
err_stack_not_clear,
|
||||||
|
err_unknown_variable,
|
||||||
|
err_division_by_zero,
|
||||||
|
err_interrupt,
|
||||||
|
err_overflow,
|
||||||
|
err_unknown_function,
|
||||||
|
err_unknown_operator,
|
||||||
|
err_unexpected_semicolon_operator,
|
||||||
|
err_improper_amount_of_arguments,
|
||||||
|
err_improper_argument,
|
||||||
|
err_unexpected_end,
|
||||||
|
err_internal_error,
|
||||||
|
err_incorrect_name,
|
||||||
|
err_incorrect_value,
|
||||||
|
err_variable_exists,
|
||||||
|
err_variable_loop,
|
||||||
|
err_functions_loop,
|
||||||
|
err_must_be_only_one_value,
|
||||||
|
err_object_exists,
|
||||||
|
err_unknown_object,
|
||||||
|
err_still_calculating,
|
||||||
|
err_in_short_form_used_function,
|
||||||
|
err_percent_from
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this struct is used when converting to/from a string
|
||||||
|
/temporarily only in Big::ToString() and Big::FromString()/
|
||||||
|
*/
|
||||||
|
struct Conv
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
base (radix) on which the value will be shown (or read)
|
||||||
|
default: 10
|
||||||
|
*/
|
||||||
|
uint base;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
used only in Big::ToString()
|
||||||
|
if true the value will be always shown in the scientific mode, e.g: 123e+30
|
||||||
|
default: false
|
||||||
|
*/
|
||||||
|
bool scient;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
used only in Big::ToString()
|
||||||
|
if scient is false then the value will be print in the scientific mode
|
||||||
|
only if the exponent is greater than scien_from
|
||||||
|
default: 15
|
||||||
|
*/
|
||||||
|
sint scient_from;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
if 'base_round' is true and 'base' is different from 2, 4, 8, or 16
|
||||||
|
and the result value is not an integer then we make an additional rounding
|
||||||
|
(after converting the last digit from the result is skipped)
|
||||||
|
default: true
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
Conv c;
|
||||||
|
c.base_round = false;
|
||||||
|
Big<1, 1> a = "0.1"; // decimal input
|
||||||
|
std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999
|
||||||
|
*/
|
||||||
|
bool base_round;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
used only in Big::ToString()
|
||||||
|
tells how many digits after comma are possible
|
||||||
|
default: -1 which means all digits are printed
|
||||||
|
|
||||||
|
set it to zero if you want integer value only
|
||||||
|
|
||||||
|
for example when the value is:
|
||||||
|
12.345678 and 'round' is 4
|
||||||
|
then the result will be
|
||||||
|
12.3457 (the last digit was rounded)
|
||||||
|
*/
|
||||||
|
sint round;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
if true that not mattered digits in the mantissa will be cut off
|
||||||
|
(zero characters at the end -- after the comma operator)
|
||||||
|
e.g. 1234,78000 will be: 1234,78
|
||||||
|
default: true
|
||||||
|
*/
|
||||||
|
bool trim_zeroes;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the main comma operator (used when reading and writing)
|
||||||
|
default is a dot '.'
|
||||||
|
*/
|
||||||
|
uint comma;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
additional comma operator (used only when reading)
|
||||||
|
if you don't want it just set it to zero
|
||||||
|
default is a comma ','
|
||||||
|
|
||||||
|
this allowes you to convert from a value:
|
||||||
|
123.45 as well as from 123,45
|
||||||
|
*/
|
||||||
|
uint comma2;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
it sets the character which is used for grouping
|
||||||
|
if group=' ' then: 1234,56789 will be printed as: 1 234,567 89
|
||||||
|
|
||||||
|
if you don't want grouping just set it to zero (which is default)
|
||||||
|
*/
|
||||||
|
uint group;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*/
|
||||||
|
uint group_exp; // not implemented yet
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Conv()
|
||||||
|
{
|
||||||
|
// default values
|
||||||
|
base = 10;
|
||||||
|
scient = false;
|
||||||
|
scient_from = 15;
|
||||||
|
base_round = true;
|
||||||
|
round = -1;
|
||||||
|
trim_zeroes = true;
|
||||||
|
comma = '.';
|
||||||
|
comma2 = ',';
|
||||||
|
group = 0;
|
||||||
|
group_exp = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this simple class can be used in multithreading model
|
||||||
|
(you can write your own class derived from this one)
|
||||||
|
|
||||||
|
for example: in some functions like Factorial()
|
||||||
|
/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
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool WasStopSignal() const volatile { return false; }
|
||||||
|
virtual ~StopCalculating(){}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
a small class which is useful when compiling with gcc
|
||||||
|
|
||||||
|
object of this type holds the name and the line of a file
|
||||||
|
in which the macro TTMATH_ASSERT or TTMATH_REFERENCE_ASSERT was used
|
||||||
|
*/
|
||||||
|
class ExceptionInfo
|
||||||
|
{
|
||||||
|
const char * file;
|
||||||
|
int line;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ExceptionInfo() : file(0), line(0) {}
|
||||||
|
ExceptionInfo(const char * f, int l) : file(f), line(l) {}
|
||||||
|
|
||||||
|
std::string Where() const
|
||||||
|
{
|
||||||
|
if( !file )
|
||||||
|
return "unknown";
|
||||||
|
|
||||||
|
std::ostringstream result;
|
||||||
|
result << file << ":" << line;
|
||||||
|
|
||||||
|
return result.str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
A small class used for reporting 'reference' errors
|
||||||
|
|
||||||
|
In the library is used macro TTMATH_REFERENCE_ASSERT which
|
||||||
|
can throw an exception of this type
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ReferenceError() : std::logic_error("reference error")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ReferenceError(const char * f, int l) :
|
||||||
|
std::logic_error("reference error"), ExceptionInfo(f,l)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Where() const
|
||||||
|
{
|
||||||
|
return ExceptionInfo::Where();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
a small class used for reporting errors
|
||||||
|
|
||||||
|
in the library is used macro TTMATH_ASSERT which
|
||||||
|
(if the condition in it is false) throw an exception
|
||||||
|
of this type
|
||||||
|
|
||||||
|
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_ASSERT
|
||||||
|
was used)
|
||||||
|
*/
|
||||||
|
class RuntimeError : public std::runtime_error, public ExceptionInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
RuntimeError() : std::runtime_error("internal error")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RuntimeError(const char * f, int l) :
|
||||||
|
std::runtime_error("internal error"), ExceptionInfo(f,l)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Where() const
|
||||||
|
{
|
||||||
|
return ExceptionInfo::Where();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
look at the description of macros TTMATH_RELEASE and TTMATH_DEBUG
|
||||||
|
*/
|
||||||
|
#ifdef TTMATH_DEBUG
|
||||||
|
|
||||||
|
#if defined(__FILE__) && defined(__LINE__)
|
||||||
|
|
||||||
|
#define TTMATH_REFERENCE_ASSERT(expression) \
|
||||||
|
if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__);
|
||||||
|
|
||||||
|
#define TTMATH_ASSERT(expression) \
|
||||||
|
if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define TTMATH_REFERENCE_ASSERT(expression) \
|
||||||
|
if( &(expression) == this ) throw ReferenceError();
|
||||||
|
|
||||||
|
#define TTMATH_ASSERT(expression) \
|
||||||
|
if( !(expression) ) throw RuntimeError();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define TTMATH_REFERENCE_ASSERT(expression)
|
||||||
|
#define TTMATH_ASSERT(expression)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TTMATH_DEBUG_LOG
|
||||||
|
#define TTMATH_LOG(msg) PrintLog(msg, std::cout);
|
||||||
|
#define TTMATH_LOGC(msg, carry) PrintLog(msg, carry, std::cout);
|
||||||
|
#define TTMATH_VECTOR_LOG(msg, vector, len) PrintVectorLog(msg, std::cout, vector, len);
|
||||||
|
#define TTMATH_VECTOR_LOGC(msg, carry, vector, len) PrintVectorLog(msg, carry, std::cout, vector, len);
|
||||||
|
#else
|
||||||
|
#define TTMATH_LOG(msg)
|
||||||
|
#define TTMATH_LOGC(msg, carry)
|
||||||
|
#define TTMATH_VECTOR_LOG(msg, vector, len)
|
||||||
|
#define TTMATH_VECTOR_LOGC(msg, carry, vector, len)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
+3520
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,548 @@
|
|||||||
|
;
|
||||||
|
; This file is a part of TTMath Bignum Library
|
||||||
|
; and is distributed under the (new) BSD licence.
|
||||||
|
; Author: Christian Kaiser <chk@online.de>
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
; Copyright (c) 2009, Christian Kaiser
|
||||||
|
; All rights reserved.
|
||||||
|
;
|
||||||
|
; Redistribution and use in source and binary forms, with or without
|
||||||
|
; modification, are permitted provided that the following conditions are met:
|
||||||
|
;
|
||||||
|
; * Redistributions of source code must retain the above copyright notice,
|
||||||
|
; this list of conditions and the following disclaimer.
|
||||||
|
;
|
||||||
|
; * Redistributions in binary form must reproduce the above copyright
|
||||||
|
; notice, this list of conditions and the following disclaimer in the
|
||||||
|
; documentation and/or other materials provided with the distribution.
|
||||||
|
;
|
||||||
|
; * Neither the name Christian Kaiser nor the names of contributors to this
|
||||||
|
; project may be used to endorse or promote products derived
|
||||||
|
; from this software without specific prior written permission.
|
||||||
|
;
|
||||||
|
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
|
; THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
; compile with debug info: ml64.exe /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
|
||||||
|
;
|
||||||
|
|
||||||
|
PUBLIC ttmath_adc_x64
|
||||||
|
PUBLIC ttmath_addindexed_x64
|
||||||
|
PUBLIC ttmath_addindexed2_x64
|
||||||
|
PUBLIC ttmath_addvector_x64
|
||||||
|
|
||||||
|
PUBLIC ttmath_sbb_x64
|
||||||
|
PUBLIC ttmath_subindexed_x64
|
||||||
|
PUBLIC ttmath_subvector_x64
|
||||||
|
|
||||||
|
PUBLIC ttmath_rcl_x64
|
||||||
|
PUBLIC ttmath_rcr_x64
|
||||||
|
|
||||||
|
PUBLIC ttmath_rcl2_x64
|
||||||
|
PUBLIC ttmath_rcr2_x64
|
||||||
|
|
||||||
|
PUBLIC ttmath_div_x64
|
||||||
|
|
||||||
|
;
|
||||||
|
; Microsoft x86_64 convention: http://msdn.microsoft.com/en-us/library/9b372w95.aspx
|
||||||
|
;
|
||||||
|
; "rax, rcx, rdx, r8-r11 are volatile."
|
||||||
|
; "rbx, rbp, rdi, rsi, r12-r15 are nonvolatile."
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
.CODE
|
||||||
|
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_adc_x64 PROC
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = p2
|
||||||
|
; r8 = nSize
|
||||||
|
; r9 = nCarry
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
xor r11, r11
|
||||||
|
sub rax, r9 ; sets CARRY if r9 != 0
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
mov rax,qword ptr [rdx + r11 * 8]
|
||||||
|
adc qword ptr [rcx + r11 * 8], rax
|
||||||
|
lea r11, [r11+1]
|
||||||
|
dec r8
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
setc al
|
||||||
|
movzx rax, al
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_adc_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_addindexed_x64 PROC
|
||||||
|
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = nSize
|
||||||
|
; r8 = nPos
|
||||||
|
; r9 = nValue
|
||||||
|
|
||||||
|
xor rax, rax ; rax = result
|
||||||
|
sub rdx, r8 ; rdx = remaining count of uints
|
||||||
|
|
||||||
|
add qword ptr [rcx + r8 * 8], r9
|
||||||
|
jc next1
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
next1:
|
||||||
|
mov r9, 1
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
dec rdx
|
||||||
|
jz done_with_cy
|
||||||
|
lea r8, [r8+1]
|
||||||
|
add qword ptr [rcx + r8 * 8], r9
|
||||||
|
jc loop1
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
done_with_cy:
|
||||||
|
lea rax, [rax+1] ; rax = 1
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_addindexed_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_addindexed2_x64 PROC
|
||||||
|
|
||||||
|
; rcx = p1 (pointer)
|
||||||
|
; rdx = b (value size)
|
||||||
|
; r8 = nPos
|
||||||
|
; r9 = nValue1
|
||||||
|
; [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
|
||||||
|
|
||||||
|
ttmath_addindexed2_x64 ENDP
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
ttmath_addvector_x64 PROC
|
||||||
|
; rcx = ss1
|
||||||
|
; rdx = ss2
|
||||||
|
; r8 = ss1_size
|
||||||
|
; r9 = ss2_size
|
||||||
|
; [esp+0x28] = result
|
||||||
|
|
||||||
|
mov r10, [esp+028h]
|
||||||
|
sub r8, r9
|
||||||
|
xor r11, r11 ; r11=0, cf=0
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
mov rax, qword ptr [rcx + r11 * 8]
|
||||||
|
adc rax, qword ptr [rdx + r11 * 8]
|
||||||
|
mov qword ptr [r10 + r11 * 8], rax
|
||||||
|
inc r11
|
||||||
|
dec r9
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
adc r9, r9 ; r9 has the cf state
|
||||||
|
|
||||||
|
or r8, r8
|
||||||
|
jz done
|
||||||
|
|
||||||
|
neg r9 ; setting cf from r9
|
||||||
|
mov r9, 0 ; don't use xor here (cf is used)
|
||||||
|
loop2:
|
||||||
|
mov rax, qword ptr [rcx + r11 * 8]
|
||||||
|
adc rax, r9
|
||||||
|
mov qword ptr [r10 + r11 * 8], rax
|
||||||
|
inc r11
|
||||||
|
dec r8
|
||||||
|
jnz loop2
|
||||||
|
|
||||||
|
adc r8, r8
|
||||||
|
mov rax, r8
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
done:
|
||||||
|
mov rax, r9
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_addvector_x64 ENDP
|
||||||
|
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_sbb_x64 PROC
|
||||||
|
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = p2
|
||||||
|
; r8 = nCount
|
||||||
|
; r9 = nCarry
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
xor r11, r11
|
||||||
|
sub rax, r9 ; sets CARRY if r9 != 0
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
mov rax,qword ptr [rdx + r11 * 8]
|
||||||
|
sbb qword ptr [rcx + r11 * 8], rax
|
||||||
|
lea r11, [r11+1]
|
||||||
|
dec r8
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
setc al
|
||||||
|
movzx rax, al
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_sbb_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_subindexed_x64 PROC
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = nSize
|
||||||
|
; r8 = nPos
|
||||||
|
; r9 = nValue
|
||||||
|
|
||||||
|
sub rdx, r8 ; rdx = remaining count of uints
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
sub qword ptr [rcx + r8 * 8], r9
|
||||||
|
jnc done
|
||||||
|
|
||||||
|
lea r8, [r8+1]
|
||||||
|
mov r9, 1
|
||||||
|
dec rdx
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
mov rax, 1
|
||||||
|
ret
|
||||||
|
|
||||||
|
done:
|
||||||
|
xor rax, rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_subindexed_x64 ENDP
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
; the same asm code as in addvector_x64 only two instructions 'adc' changed to 'sbb'
|
||||||
|
|
||||||
|
ttmath_subvector_x64 PROC
|
||||||
|
; rcx = ss1
|
||||||
|
; rdx = ss2
|
||||||
|
; r8 = ss1_size
|
||||||
|
; r9 = ss2_size
|
||||||
|
; [esp+0x28] = result
|
||||||
|
|
||||||
|
mov r10, [esp+028h]
|
||||||
|
sub r8, r9
|
||||||
|
xor r11, r11 ; r11=0, cf=0
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
mov rax, qword ptr [rcx + r11 * 8]
|
||||||
|
sbb rax, qword ptr [rdx + r11 * 8]
|
||||||
|
mov qword ptr [r10 + r11 * 8], rax
|
||||||
|
inc r11
|
||||||
|
dec r9
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
adc r9, r9 ; r9 has the cf state
|
||||||
|
|
||||||
|
or r8, r8
|
||||||
|
jz done
|
||||||
|
|
||||||
|
neg r9 ; setting cf from r9
|
||||||
|
mov r9, 0 ; don't use xor here (cf is used)
|
||||||
|
loop2:
|
||||||
|
mov rax, qword ptr [rcx + r11 * 8]
|
||||||
|
sbb rax, r9
|
||||||
|
mov qword ptr [r10 + r11 * 8], rax
|
||||||
|
inc r11
|
||||||
|
dec r8
|
||||||
|
jnz loop2
|
||||||
|
|
||||||
|
adc r8, r8
|
||||||
|
mov rax, r8
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
done:
|
||||||
|
mov rax, r9
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_subvector_x64 ENDP
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_rcl_x64 PROC
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = b
|
||||||
|
; r8 = nLowestBit
|
||||||
|
|
||||||
|
mov r11, rcx ; table
|
||||||
|
xor r10, r10
|
||||||
|
neg r8 ; CY set if r8 <> 0
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
rcl qword ptr [r11 + r10 * 8], 1
|
||||||
|
lea r10, [r10+1]
|
||||||
|
dec rdx
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
setc al
|
||||||
|
movzx rax, al
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_rcl_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_rcr_x64 PROC
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = nSize
|
||||||
|
; r8 = nLowestBit
|
||||||
|
|
||||||
|
xor r10, r10
|
||||||
|
neg r8 ; CY set if r8 <> 0
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
rcr qword ptr -8[rcx + rdx * 8], 1
|
||||||
|
dec rdx
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
setc al
|
||||||
|
movzx rax, al
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_rcr_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_div_x64 PROC
|
||||||
|
|
||||||
|
; rcx = &Hi
|
||||||
|
; rdx = &Lo
|
||||||
|
; r8 = nDiv
|
||||||
|
|
||||||
|
mov r11, rcx
|
||||||
|
mov r10, rdx
|
||||||
|
|
||||||
|
mov rdx, qword ptr [r11]
|
||||||
|
mov rax, qword ptr [r10]
|
||||||
|
div r8
|
||||||
|
mov qword ptr [r10], rdx ; remainder
|
||||||
|
mov qword ptr [r11], rax ; value
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_div_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_rcl2_x64 PROC
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = nSize
|
||||||
|
; r8 = bits
|
||||||
|
; r9 = c
|
||||||
|
|
||||||
|
push rbx
|
||||||
|
|
||||||
|
mov r10, rcx ; r10 = p1
|
||||||
|
xor rax, rax
|
||||||
|
|
||||||
|
mov rcx, 64
|
||||||
|
sub rcx, r8
|
||||||
|
|
||||||
|
mov r11, -1
|
||||||
|
shr r11, cl ; r11 = mask
|
||||||
|
|
||||||
|
mov rcx, r8 ; rcx = count of bits
|
||||||
|
|
||||||
|
mov rbx, rax ; rbx = old value = 0
|
||||||
|
or r9, r9
|
||||||
|
cmovnz rbx, r11 ; if (c) then old value = mask
|
||||||
|
|
||||||
|
mov r9, rax ; r9 = index (0..nSize-1)
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
rol qword ptr [r10+r9*8], cl
|
||||||
|
mov rax, qword ptr [r10+r9*8]
|
||||||
|
and rax, r11
|
||||||
|
xor qword ptr [r10+r9*8], rax
|
||||||
|
or qword ptr [r10+r9*8], rbx
|
||||||
|
mov rbx, rax
|
||||||
|
|
||||||
|
lea r9, [r9+1]
|
||||||
|
dec rdx
|
||||||
|
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
and rax, 1
|
||||||
|
pop rbx
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_rcl2_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_rcr2_x64 PROC
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = nSize
|
||||||
|
; r8 = bits
|
||||||
|
; r9 = c
|
||||||
|
|
||||||
|
push rbx
|
||||||
|
mov r10, rcx ; r10 = p1
|
||||||
|
xor rax, rax
|
||||||
|
|
||||||
|
mov rcx, 64
|
||||||
|
sub rcx, r8
|
||||||
|
|
||||||
|
mov r11, -1
|
||||||
|
shl r11, cl ; r11 = mask
|
||||||
|
|
||||||
|
mov rcx, r8 ; rcx = count of bits
|
||||||
|
|
||||||
|
mov rbx, rax ; rbx = old value = 0
|
||||||
|
or r9, r9
|
||||||
|
cmovnz rbx, r11 ; if (c) then old value = mask
|
||||||
|
|
||||||
|
mov r9, rdx ; r9 = index (0..nSize-1)
|
||||||
|
lea r9, [r9-1]
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
ror qword ptr [r10+r9*8], cl
|
||||||
|
mov rax, qword ptr [r10+r9*8]
|
||||||
|
and rax, r11
|
||||||
|
xor qword ptr [r10+r9*8], rax
|
||||||
|
or qword ptr [r10+r9*8], rbx
|
||||||
|
mov rbx, rax
|
||||||
|
|
||||||
|
lea r9, [r9-1]
|
||||||
|
dec rdx
|
||||||
|
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
rol rax, 1
|
||||||
|
and rax, 1
|
||||||
|
pop rbx
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_rcr2_x64 ENDP
|
||||||
|
|
||||||
|
END
|
||||||
Reference in New Issue
Block a user