- 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
This commit is contained in:
parent
cbc12db22f
commit
c91bd24e98
|
@ -45,6 +45,7 @@
|
||||||
\brief Mathematics functions.
|
\brief Mathematics functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "ttmathconfig.h"
|
||||||
#include "ttmathbig.h"
|
#include "ttmathbig.h"
|
||||||
#include "ttmathobjects.h"
|
#include "ttmathobjects.h"
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,10 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(disable:4127) // conditional expression is constant
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -79,9 +83,9 @@ class Big
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Int<exp> exponent;
|
Int<exp> exponent;
|
||||||
UInt<man> mantissa;
|
UInt<man> mantissa;
|
||||||
unsigned char info;
|
tchar_t info;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -237,7 +241,7 @@ private:
|
||||||
// 3101 digits were taken from this website
|
// 3101 digits were taken from this website
|
||||||
// (later the digits were compared with:
|
// (later the digits were compared with:
|
||||||
// http://www.eveandersson.com/pi/digits/1000000 and http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html )
|
// http://www.eveandersson.com/pi/digits/1000000 and http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html )
|
||||||
// and they were set into Big<1,400> type (using operator=(const char*) on a 32bit platform)
|
// and they were set into Big<1,400> type (using operator=(const tchar_t*) on a 32bit platform)
|
||||||
// and then the first 256 words were taken into this table
|
// and then the first 256 words were taken into this table
|
||||||
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
|
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
|
||||||
// and on 64bit platform value 128 (256/2=128))
|
// and on 64bit platform value 128 (256/2=128))
|
||||||
|
@ -655,9 +659,7 @@ public:
|
||||||
// there shouldn't be a carry here because
|
// there shouldn't be a carry here because
|
||||||
// (1) (2) guarantee that the mantissa of this
|
// (1) (2) guarantee that the mantissa of this
|
||||||
// is greater than or equal to the mantissa of the ss2
|
// is greater than or equal to the mantissa of the ss2
|
||||||
uint c_temp = mantissa.Sub(ss2.mantissa);
|
TTMATH_ASSERT( mantissa.Sub(ss2.mantissa) == 0 )
|
||||||
|
|
||||||
TTMATH_ASSERT( c_temp == 0 )
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c += Standardizing();
|
c += Standardizing();
|
||||||
|
@ -2037,7 +2039,7 @@ public:
|
||||||
// then V=(-1)**S * 2 ** (-1022) * (0.F)
|
// then V=(-1)**S * 2 ** (-1022) * (0.F)
|
||||||
// These are "unnormalized" values.
|
// These are "unnormalized" values.
|
||||||
|
|
||||||
FromDouble_SetExpAndMan(bool(temp.u & 0x8000000000000000ul),
|
FromDouble_SetExpAndMan((temp.u & 0x8000000000000000ul) != 0,
|
||||||
e - 1022 - man*TTMATH_BITS_PER_UINT + 1, 0, m);
|
e - 1022 - man*TTMATH_BITS_PER_UINT + 1, 0, m);
|
||||||
Standardizing();
|
Standardizing();
|
||||||
}
|
}
|
||||||
|
@ -2540,18 +2542,18 @@ public:
|
||||||
|
|
||||||
output:
|
output:
|
||||||
return value:
|
return value:
|
||||||
0 - ok and 'result' will be an object of type std::string which holds the value
|
0 - ok and 'result' will be an object of type tstr_t which holds the value
|
||||||
1 - if there was a carry
|
1 - if there was a carry
|
||||||
*/
|
*/
|
||||||
uint ToString( std::string & result,
|
uint ToString( tstr_t & result,
|
||||||
uint base = 10,
|
uint base = 10,
|
||||||
bool always_scientific = false,
|
bool always_scientific = false,
|
||||||
sint when_scientific = 15,
|
sint when_scientific = 15,
|
||||||
sint max_digit_after_comma = -1,
|
sint max_digit_after_comma = -1,
|
||||||
bool remove_trailing_zeroes = true,
|
bool remove_trailing_zeroes = true,
|
||||||
char decimal_point = TTMATH_COMMA_CHARACTER_1 ) const
|
tchar_t decimal_point = TTMATH_COMMA_CHARACTER_1 ) const
|
||||||
{
|
{
|
||||||
static char error_overflow_msg[] = "overflow";
|
static tchar_t error_overflow_msg[] = TTMATH_TEXT("overflow");
|
||||||
result.erase();
|
result.erase();
|
||||||
|
|
||||||
if(base<2 || base>16)
|
if(base<2 || base>16)
|
||||||
|
@ -2562,7 +2564,7 @@ public:
|
||||||
|
|
||||||
if( IsZero() )
|
if( IsZero() )
|
||||||
{
|
{
|
||||||
result = "0";
|
result = TTMATH_TEXT("0");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2687,7 +2689,7 @@ private:
|
||||||
but we need 'new'exp' as integer then we take:
|
but we need 'new'exp' as integer then we take:
|
||||||
new_exp = [log base (2^exponent)] + 1 <- where [x] means integer value from x
|
new_exp = [log base (2^exponent)] + 1 <- where [x] means integer value from x
|
||||||
*/
|
*/
|
||||||
uint ToString_CreateNewMantissaAndExponent( std::string & new_man, uint base,
|
uint ToString_CreateNewMantissaAndExponent( tstr_t & new_man, uint base,
|
||||||
Int<exp+1> & new_exp) const
|
Int<exp+1> & new_exp) const
|
||||||
{
|
{
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
@ -2870,7 +2872,7 @@ private:
|
||||||
(we can make that speciality when the base is 4,8 or 16 as well
|
(we can make that speciality when the base is 4,8 or 16 as well
|
||||||
but maybe in further time)
|
but maybe in further time)
|
||||||
*/
|
*/
|
||||||
uint ToString_CreateNewMantissaAndExponent_Base2( std::string & new_man,
|
uint ToString_CreateNewMantissaAndExponent_Base2( tstr_t & new_man,
|
||||||
Int<exp+1> & new_exp ) const
|
Int<exp+1> & new_exp ) const
|
||||||
{
|
{
|
||||||
for( sint i=man-1 ; i>=0 ; --i )
|
for( sint i=man-1 ; i>=0 ; --i )
|
||||||
|
@ -2900,13 +2902,13 @@ private:
|
||||||
this method roundes the last character from the new mantissa
|
this method roundes the last character from the new mantissa
|
||||||
(it's used in systems where the base is different from 2)
|
(it's used in systems where the base is different from 2)
|
||||||
*/
|
*/
|
||||||
uint ToString_RoundMantissa(std::string & new_man, uint base, Int<exp+1> & new_exp, char decimal_point) const
|
uint ToString_RoundMantissa(tstr_t & new_man, uint base, Int<exp+1> & new_exp, tchar_t decimal_point) const
|
||||||
{
|
{
|
||||||
// we must have minimum two characters
|
// we must have minimum two characters
|
||||||
if( new_man.length() < 2 )
|
if( new_man.length() < 2 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
std::string::size_type i = new_man.length() - 1;
|
tstr_t::size_type i = new_man.length() - 1;
|
||||||
|
|
||||||
// we're erasing the last character
|
// we're erasing the last character
|
||||||
uint digit = UInt<man>::CharToDigit( new_man[i] );
|
uint digit = UInt<man>::CharToDigit( new_man[i] );
|
||||||
|
@ -2927,7 +2929,7 @@ private:
|
||||||
|
|
||||||
this method addes one into the new mantissa
|
this method addes one into the new mantissa
|
||||||
*/
|
*/
|
||||||
void ToString_RoundMantissa_AddOneIntoMantissa(std::string & new_man, uint base, char decimal_point) const
|
void ToString_RoundMantissa_AddOneIntoMantissa(tstr_t & new_man, uint base, tchar_t decimal_point) const
|
||||||
{
|
{
|
||||||
if( new_man.empty() )
|
if( new_man.empty() )
|
||||||
return;
|
return;
|
||||||
|
@ -2965,13 +2967,13 @@ private:
|
||||||
this method sets the comma operator and/or puts the exponent
|
this method sets the comma operator and/or puts the exponent
|
||||||
into the string
|
into the string
|
||||||
*/
|
*/
|
||||||
uint ToString_SetCommaAndExponent( std::string & new_man, uint base,
|
uint ToString_SetCommaAndExponent( tstr_t & new_man, uint base,
|
||||||
Int<exp+1> & new_exp,
|
Int<exp+1> & new_exp,
|
||||||
bool always_scientific,
|
bool always_scientific,
|
||||||
sint when_scientific,
|
sint when_scientific,
|
||||||
sint max_digit_after_comma,
|
sint max_digit_after_comma,
|
||||||
bool remove_trailing_zeroes,
|
bool remove_trailing_zeroes,
|
||||||
char decimal_point) const
|
tchar_t decimal_point) const
|
||||||
{
|
{
|
||||||
uint carry = 0;
|
uint carry = 0;
|
||||||
|
|
||||||
|
@ -3011,12 +3013,12 @@ private:
|
||||||
an auxiliary method for converting into the string
|
an auxiliary method for converting into the string
|
||||||
*/
|
*/
|
||||||
void ToString_SetCommaAndExponent_Normal(
|
void ToString_SetCommaAndExponent_Normal(
|
||||||
std::string & new_man,
|
tstr_t & new_man,
|
||||||
uint base,
|
uint base,
|
||||||
Int<exp+1> & new_exp,
|
Int<exp+1> & new_exp,
|
||||||
sint max_digit_after_comma,
|
sint max_digit_after_comma,
|
||||||
bool remove_trailing_zeroes,
|
bool remove_trailing_zeroes,
|
||||||
char decimal_point) const
|
tchar_t decimal_point) const
|
||||||
{
|
{
|
||||||
if( !new_exp.IsSign() ) //if( new_exp >= 0 )
|
if( !new_exp.IsSign() ) //if( new_exp >= 0 )
|
||||||
return ToString_SetCommaAndExponent_Normal_AddingZero(new_man, new_exp);
|
return ToString_SetCommaAndExponent_Normal_AddingZero(new_man, new_exp);
|
||||||
|
@ -3028,7 +3030,7 @@ private:
|
||||||
/*!
|
/*!
|
||||||
an auxiliary method for converting into the string
|
an auxiliary method for converting into the string
|
||||||
*/
|
*/
|
||||||
void ToString_SetCommaAndExponent_Normal_AddingZero(std::string & new_man,
|
void ToString_SetCommaAndExponent_Normal_AddingZero(tstr_t & new_man,
|
||||||
Int<exp+1> & new_exp) const
|
Int<exp+1> & new_exp) const
|
||||||
{
|
{
|
||||||
// we're adding zero characters at the end
|
// we're adding zero characters at the end
|
||||||
|
@ -3048,12 +3050,12 @@ private:
|
||||||
an auxiliary method for converting into the string
|
an auxiliary method for converting into the string
|
||||||
*/
|
*/
|
||||||
void ToString_SetCommaAndExponent_Normal_SetCommaInside(
|
void ToString_SetCommaAndExponent_Normal_SetCommaInside(
|
||||||
std::string & new_man,
|
tstr_t & new_man,
|
||||||
uint base,
|
uint base,
|
||||||
Int<exp+1> & new_exp,
|
Int<exp+1> & new_exp,
|
||||||
sint max_digit_after_comma,
|
sint max_digit_after_comma,
|
||||||
bool remove_trailing_zeroes,
|
bool remove_trailing_zeroes,
|
||||||
char decimal_point) const
|
tchar_t decimal_point) const
|
||||||
{
|
{
|
||||||
// new_exp is < 0
|
// new_exp is < 0
|
||||||
|
|
||||||
|
@ -3072,7 +3074,7 @@ private:
|
||||||
// we're adding zero characters before the mantissa
|
// we're adding zero characters before the mantissa
|
||||||
|
|
||||||
uint how_many = e - new_man_len;
|
uint how_many = e - new_man_len;
|
||||||
std::string man_temp(how_many+1, '0');
|
tstr_t man_temp(how_many+1, '0');
|
||||||
|
|
||||||
man_temp.insert( man_temp.begin()+1, decimal_point);
|
man_temp.insert( man_temp.begin()+1, decimal_point);
|
||||||
new_man.insert(0, man_temp);
|
new_man.insert(0, man_temp);
|
||||||
|
@ -3085,12 +3087,12 @@ private:
|
||||||
/*!
|
/*!
|
||||||
an auxiliary method for converting into the string
|
an auxiliary method for converting into the string
|
||||||
*/
|
*/
|
||||||
void ToString_SetCommaAndExponent_Scientific( std::string & new_man,
|
void ToString_SetCommaAndExponent_Scientific( tstr_t & new_man,
|
||||||
uint base,
|
uint base,
|
||||||
Int<exp+1> & scientific_exp,
|
Int<exp+1> & scientific_exp,
|
||||||
sint max_digit_after_comma,
|
sint max_digit_after_comma,
|
||||||
bool remove_trailing_zeroes,
|
bool remove_trailing_zeroes,
|
||||||
char decimal_point) const
|
tchar_t decimal_point) const
|
||||||
{
|
{
|
||||||
if( new_man.empty() )
|
if( new_man.empty() )
|
||||||
return;
|
return;
|
||||||
|
@ -3104,16 +3106,16 @@ private:
|
||||||
new_man += 'e';
|
new_man += 'e';
|
||||||
|
|
||||||
if( !scientific_exp.IsSign() )
|
if( !scientific_exp.IsSign() )
|
||||||
new_man += "+";
|
new_man += TTMATH_TEXT("+");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// the 10 here is meant as the base 'base'
|
// the 10 here is meant as the base 'base'
|
||||||
// (no matter which 'base' we're using there'll always be 10 here)
|
// (no matter which 'base' we're using there'll always be 10 here)
|
||||||
new_man += "*10^";
|
new_man += TTMATH_TEXT("*10^");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string temp_exp;
|
tstr_t temp_exp;
|
||||||
scientific_exp.ToString( temp_exp, base );
|
scientific_exp.ToString( temp_exp, base );
|
||||||
|
|
||||||
new_man += temp_exp;
|
new_man += temp_exp;
|
||||||
|
@ -3123,11 +3125,11 @@ private:
|
||||||
/*!
|
/*!
|
||||||
an auxiliary method for converting into the string
|
an auxiliary method for converting into the string
|
||||||
*/
|
*/
|
||||||
void ToString_CorrectDigitsAfterComma( std::string & new_man,
|
void ToString_CorrectDigitsAfterComma( tstr_t & new_man,
|
||||||
uint base,
|
uint base,
|
||||||
sint max_digit_after_comma,
|
sint max_digit_after_comma,
|
||||||
bool remove_trailing_zeroes,
|
bool remove_trailing_zeroes,
|
||||||
char decimal_point) const
|
tchar_t decimal_point) const
|
||||||
{
|
{
|
||||||
if( max_digit_after_comma >= 0 )
|
if( max_digit_after_comma >= 0 )
|
||||||
ToString_CorrectDigitsAfterComma_Round(new_man, base, max_digit_after_comma, decimal_point);
|
ToString_CorrectDigitsAfterComma_Round(new_man, base, max_digit_after_comma, decimal_point);
|
||||||
|
@ -3141,8 +3143,8 @@ private:
|
||||||
an auxiliary method for converting into the string
|
an auxiliary method for converting into the string
|
||||||
*/
|
*/
|
||||||
void ToString_CorrectDigitsAfterComma_CutOffZeroCharacters(
|
void ToString_CorrectDigitsAfterComma_CutOffZeroCharacters(
|
||||||
std::string & new_man,
|
tstr_t & new_man,
|
||||||
char decimal_point) const
|
tchar_t decimal_point) const
|
||||||
{
|
{
|
||||||
// minimum two characters
|
// minimum two characters
|
||||||
if( new_man.length() < 2 )
|
if( new_man.length() < 2 )
|
||||||
|
@ -3160,7 +3162,7 @@ private:
|
||||||
// we must have a comma
|
// we must have a comma
|
||||||
// (the comma can be removed by ToString_CorrectDigitsAfterComma_Round
|
// (the comma can be removed by ToString_CorrectDigitsAfterComma_Round
|
||||||
// which is called before)
|
// which is called before)
|
||||||
if( new_man.find_last_of(decimal_point, i) == std::string::npos )
|
if( new_man.find_last_of(decimal_point, i) == tstr_t::npos )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// if directly before the first zero is the comma operator
|
// if directly before the first zero is the comma operator
|
||||||
|
@ -3176,26 +3178,26 @@ private:
|
||||||
an auxiliary method for converting into the string
|
an auxiliary method for converting into the string
|
||||||
*/
|
*/
|
||||||
void ToString_CorrectDigitsAfterComma_Round(
|
void ToString_CorrectDigitsAfterComma_Round(
|
||||||
std::string & new_man,
|
tstr_t & new_man,
|
||||||
uint base,
|
uint base,
|
||||||
sint max_digit_after_comma,
|
sint max_digit_after_comma,
|
||||||
char decimal_point) const
|
tchar_t decimal_point) const
|
||||||
{
|
{
|
||||||
// first we're looking for the comma operator
|
// first we're looking for the comma operator
|
||||||
std::string::size_type index = new_man.find(decimal_point, 0);
|
tstr_t::size_type index = new_man.find(decimal_point, 0);
|
||||||
|
|
||||||
if( index == std::string::npos )
|
if( index == tstr_t::npos )
|
||||||
// nothing was found (actually there can't be this situation)
|
// nothing was found (actually there can't be this situation)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// we're calculating how many digits there are at the end (after the comma)
|
// we're calculating how many digits there are at the end (after the comma)
|
||||||
// 'after_comma' will be greater than zero because at the end
|
// 'after_comma' will be greater than zero because at the end
|
||||||
// we have at least one digit
|
// we have at least one digit
|
||||||
std::string::size_type after_comma = new_man.length() - index - 1;
|
tstr_t::size_type after_comma = new_man.length() - index - 1;
|
||||||
|
|
||||||
// if 'max_digit_after_comma' is greater than 'after_comma' (or equal)
|
// if 'max_digit_after_comma' is greater than 'after_comma' (or equal)
|
||||||
// we don't have anything for cutting
|
// we don't have anything for cutting
|
||||||
if( std::string::size_type(max_digit_after_comma) >= after_comma )
|
if( tstr_t::size_type(max_digit_after_comma) >= after_comma )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint last_digit = UInt<man>::CharToDigit( new_man[ index + max_digit_after_comma + 1 ], base );
|
uint last_digit = UInt<man>::CharToDigit( new_man[ index + max_digit_after_comma + 1 ], base );
|
||||||
|
@ -3241,7 +3243,7 @@ public:
|
||||||
no value has been read (there are no digits)
|
no value has been read (there are no digits)
|
||||||
on other words if 'value_read' is true -- there is at least one digit in the string
|
on other words if 'value_read' is true -- there is at least one digit in the string
|
||||||
*/
|
*/
|
||||||
uint FromString(const char * source, uint base = 10, const char ** after_source = 0, bool * value_read = 0)
|
uint FromString(const tchar_t * source, uint base = 10, const tchar_t ** after_source = 0, bool * value_read = 0)
|
||||||
{
|
{
|
||||||
bool is_sign;
|
bool is_sign;
|
||||||
bool value_read_temp = false;
|
bool value_read_temp = false;
|
||||||
|
@ -3290,7 +3292,7 @@ private:
|
||||||
|
|
||||||
(this method is used from 'FromString_ReadPartScientific' too)
|
(this method is used from 'FromString_ReadPartScientific' too)
|
||||||
*/
|
*/
|
||||||
void FromString_TestSign( const char * & source, bool & is_sign )
|
void FromString_TestSign( const tchar_t * & source, bool & is_sign )
|
||||||
{
|
{
|
||||||
UInt<man>::SkipWhiteCharacters(source);
|
UInt<man>::SkipWhiteCharacters(source);
|
||||||
|
|
||||||
|
@ -3312,7 +3314,7 @@ private:
|
||||||
/*!
|
/*!
|
||||||
we're testing whether there's a comma operator
|
we're testing whether there's a comma operator
|
||||||
*/
|
*/
|
||||||
bool FromString_TestCommaOperator(const char * & source)
|
bool FromString_TestCommaOperator(const tchar_t * & source)
|
||||||
{
|
{
|
||||||
if( (*source == TTMATH_COMMA_CHARACTER_1) ||
|
if( (*source == TTMATH_COMMA_CHARACTER_1) ||
|
||||||
(*source == TTMATH_COMMA_CHARACTER_2 && TTMATH_COMMA_CHARACTER_2 != 0 ) )
|
(*source == TTMATH_COMMA_CHARACTER_2 && TTMATH_COMMA_CHARACTER_2 != 0 ) )
|
||||||
|
@ -3330,7 +3332,7 @@ private:
|
||||||
this method reads the first part of a string
|
this method reads the first part of a string
|
||||||
(before the comma operator)
|
(before the comma operator)
|
||||||
*/
|
*/
|
||||||
uint FromString_ReadPartBeforeComma( const char * & source, uint base, bool & value_read )
|
uint FromString_ReadPartBeforeComma( const tchar_t * & source, uint base, bool & value_read )
|
||||||
{
|
{
|
||||||
sint character;
|
sint character;
|
||||||
Big<exp, man> temp;
|
Big<exp, man> temp;
|
||||||
|
@ -3359,7 +3361,7 @@ private:
|
||||||
this method reads the second part of a string
|
this method reads the second part of a string
|
||||||
(after the comma operator)
|
(after the comma operator)
|
||||||
*/
|
*/
|
||||||
uint FromString_ReadPartAfterComma( const char * & source, uint base, bool & value_read )
|
uint FromString_ReadPartAfterComma( const tchar_t * & source, uint base, bool & value_read )
|
||||||
{
|
{
|
||||||
sint character;
|
sint character;
|
||||||
uint c = 0, index = 1;
|
uint c = 0, index = 1;
|
||||||
|
@ -3417,12 +3419,12 @@ private:
|
||||||
|
|
||||||
it is called when the base is 10 and some digits were read before
|
it is called when the base is 10 and some digits were read before
|
||||||
*/
|
*/
|
||||||
int FromString_ReadScientificIfExists(const char * & source)
|
int FromString_ReadScientificIfExists(const tchar_t * & source)
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
|
||||||
bool scientific_read = false;
|
bool scientific_read = false;
|
||||||
const char * before_scientific = source;
|
const tchar_t * before_scientific = source;
|
||||||
|
|
||||||
if( FromString_TestScientific(source) )
|
if( FromString_TestScientific(source) )
|
||||||
c += FromString_ReadPartScientific( source, scientific_read );
|
c += FromString_ReadPartScientific( source, scientific_read );
|
||||||
|
@ -3440,7 +3442,7 @@ private:
|
||||||
|
|
||||||
this character is only allowed when we're using the base equals 10
|
this character is only allowed when we're using the base equals 10
|
||||||
*/
|
*/
|
||||||
bool FromString_TestScientific(const char * & source)
|
bool FromString_TestScientific(const tchar_t * & source)
|
||||||
{
|
{
|
||||||
UInt<man>::SkipWhiteCharacters(source);
|
UInt<man>::SkipWhiteCharacters(source);
|
||||||
|
|
||||||
|
@ -3459,7 +3461,7 @@ private:
|
||||||
this method reads the exponent (after 'e' character) when there's a scientific
|
this method reads the exponent (after 'e' character) when there's a scientific
|
||||||
format of value and only when we're using the base equals 10
|
format of value and only when we're using the base equals 10
|
||||||
*/
|
*/
|
||||||
uint FromString_ReadPartScientific( const char * & source, bool & scientific_read )
|
uint FromString_ReadPartScientific( const tchar_t * & source, bool & scientific_read )
|
||||||
{
|
{
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
Big<exp, man> new_exponent, temp;
|
Big<exp, man> new_exponent, temp;
|
||||||
|
@ -3486,7 +3488,7 @@ private:
|
||||||
this method reads the value of the extra exponent when scientific format is used
|
this method reads the value of the extra exponent when scientific format is used
|
||||||
(only when base == 10)
|
(only when base == 10)
|
||||||
*/
|
*/
|
||||||
uint FromString_ReadPartScientific_ReadExponent( const char * & source, Big<exp, man> & new_exponent, bool & scientific_read )
|
uint FromString_ReadPartScientific_ReadExponent( const tchar_t * & source, Big<exp, man> & new_exponent, bool & scientific_read )
|
||||||
{
|
{
|
||||||
sint character;
|
sint character;
|
||||||
Big<exp, man> base, temp;
|
Big<exp, man> base, temp;
|
||||||
|
@ -3519,7 +3521,7 @@ public:
|
||||||
/*!
|
/*!
|
||||||
a method for converting a string into its value
|
a method for converting a string into its value
|
||||||
*/
|
*/
|
||||||
uint FromString(const std::string & string, uint base = 10)
|
uint FromString(const tstr_t & string, uint base = 10)
|
||||||
{
|
{
|
||||||
return FromString( string.c_str(), base );
|
return FromString( string.c_str(), base );
|
||||||
}
|
}
|
||||||
|
@ -3528,7 +3530,7 @@ public:
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting a string into this class
|
a constructor for converting a string into this class
|
||||||
*/
|
*/
|
||||||
Big(const char * string)
|
Big(const tchar_t * string)
|
||||||
{
|
{
|
||||||
FromString( string );
|
FromString( string );
|
||||||
}
|
}
|
||||||
|
@ -3537,7 +3539,7 @@ public:
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting a string into this class
|
a constructor for converting a string into this class
|
||||||
*/
|
*/
|
||||||
Big(const std::string & string)
|
Big(const tstr_t & string)
|
||||||
{
|
{
|
||||||
FromString( string.c_str() );
|
FromString( string.c_str() );
|
||||||
}
|
}
|
||||||
|
@ -3546,7 +3548,7 @@ public:
|
||||||
/*!
|
/*!
|
||||||
an operator= for converting a string into its value
|
an operator= for converting a string into its value
|
||||||
*/
|
*/
|
||||||
Big<exp, man> & operator=(const char * string)
|
Big<exp, man> & operator=(const tchar_t * string)
|
||||||
{
|
{
|
||||||
FromString( string );
|
FromString( string );
|
||||||
|
|
||||||
|
@ -3557,7 +3559,7 @@ public:
|
||||||
/*!
|
/*!
|
||||||
an operator= for converting a string into its value
|
an operator= for converting a string into its value
|
||||||
*/
|
*/
|
||||||
Big<exp, man> & operator=(const std::string & string)
|
Big<exp, man> & operator=(const tstr_t & string)
|
||||||
{
|
{
|
||||||
FromString( string.c_str() );
|
FromString( string.c_str() );
|
||||||
|
|
||||||
|
@ -3964,9 +3966,9 @@ public:
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
friend std::ostream & operator<<(std::ostream & s, const Big<exp,man> & l)
|
friend tostrm_t & operator<<(tostrm_t & s, const Big<exp,man> & l)
|
||||||
{
|
{
|
||||||
std::string ss;
|
tstr_t ss;
|
||||||
|
|
||||||
l.ToString(ss);
|
l.ToString(ss);
|
||||||
s << ss;
|
s << ss;
|
||||||
|
@ -3975,12 +3977,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
friend std::istream & operator>>(std::istream & s, Big<exp,man> & l)
|
friend tistrm_t & operator>>(tistrm_t & s, Big<exp,man> & l)
|
||||||
{
|
{
|
||||||
std::string ss;
|
tstr_t ss;
|
||||||
|
|
||||||
// 'char' for operator>>
|
// 'tchar_t' for operator>>
|
||||||
unsigned char z;
|
unsigned tchar_t z;
|
||||||
bool was_comma = false;
|
bool was_comma = false;
|
||||||
|
|
||||||
// operator>> omits white characters if they're set for ommiting
|
// operator>> omits white characters if they're set for ommiting
|
||||||
|
@ -4023,6 +4025,9 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(default:4127) // conditional expression is constant
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* 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 headerfilettmathmathttconfig
|
||||||
|
#define headerfilettmathmathttconfig
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace ttmath
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#if defined(_UNICODE)
|
||||||
|
typedef wchar_t tchar_t;
|
||||||
|
typedef std::wstring tstr_t;
|
||||||
|
typedef std::wostringstream tostrstrm_t;
|
||||||
|
typedef std::wostream tostrm_t;
|
||||||
|
typedef std::wistream tistrm_t;
|
||||||
|
#else
|
||||||
|
typedef unsigned char tchar_t;
|
||||||
|
typedef std::string tstr_t;
|
||||||
|
typedef std::ostringstream tostrstrm_t;
|
||||||
|
typedef std::ostream tostrm_t;
|
||||||
|
typedef std::istream tistrm_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_UNICODE)
|
||||||
|
#define __TEXT(quote) L ## quote
|
||||||
|
#else
|
||||||
|
#define __TEXT(quote) quote
|
||||||
|
#endif
|
||||||
|
#define TTMATH_TEXT(quote) __TEXT(quote)
|
||||||
|
#else
|
||||||
|
typedef unsigned char tchar_t;
|
||||||
|
typedef std::string tstr_t;
|
||||||
|
typedef std::ostringstream tostrstrm_t;
|
||||||
|
typedef std::ostream tostrm_t;
|
||||||
|
typedef std::istream tistrm_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif // headerfilettmathmathttconfig
|
|
@ -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 tchar_t * 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 tstr_t & 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(tstr_t & result, uint b = 10) const
|
||||||
{
|
{
|
||||||
if( IsSign() )
|
if( IsSign() )
|
||||||
{
|
{
|
||||||
|
@ -904,7 +914,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 tchar_t * s, uint b = 10, const tchar_t ** after_source = 0, bool * value_read = 0)
|
||||||
{
|
{
|
||||||
bool is_sign = false;
|
bool is_sign = false;
|
||||||
|
|
||||||
|
@ -961,7 +971,7 @@ 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 tstr_t & s, uint b = 10)
|
||||||
{
|
{
|
||||||
return FromString( s.c_str() );
|
return FromString( s.c_str() );
|
||||||
}
|
}
|
||||||
|
@ -970,7 +980,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 char * s)
|
Int<value_size> & operator=(const tchar_t * s)
|
||||||
{
|
{
|
||||||
FromString(s);
|
FromString(s);
|
||||||
|
|
||||||
|
@ -981,7 +991,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 tstr_t & s)
|
||||||
{
|
{
|
||||||
FromString( s.c_str() );
|
FromString( s.c_str() );
|
||||||
|
|
||||||
|
@ -1268,9 +1278,9 @@ public:
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
friend std::ostream & operator<<(std::ostream & s, const Int<value_size> & l)
|
friend tostrm_t & operator<<(tostrm_t & s, const Int<value_size> & l)
|
||||||
{
|
{
|
||||||
std::string ss;
|
tstr_t ss;
|
||||||
|
|
||||||
l.ToString(ss);
|
l.ToString(ss);
|
||||||
s << ss;
|
s << ss;
|
||||||
|
@ -1280,12 +1290,12 @@ public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
friend std::istream & operator>>(std::istream & s, Int<value_size> & l)
|
friend tistrm_t & operator>>(tistrm_t & s, Int<value_size> & l)
|
||||||
{
|
{
|
||||||
std::string ss;
|
tstr_t ss;
|
||||||
|
|
||||||
// char for operator>>
|
// tchar_t for operator>>
|
||||||
unsigned char z;
|
unsigned tchar_t 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;
|
||||||
|
@ -1316,5 +1326,9 @@ public:
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(default:4127) // conditional expression is constant
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -73,18 +73,18 @@ public:
|
||||||
struct Item
|
struct Item
|
||||||
{
|
{
|
||||||
// name of a variable of a function
|
// name of a variable of a function
|
||||||
std::string value;
|
tstr_t 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 tstr_t & 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<tstr_t, Item> Table;
|
||||||
typedef Table::iterator Iterator;
|
typedef Table::iterator Iterator;
|
||||||
typedef Table::const_iterator CIterator;
|
typedef Table::const_iterator CIterator;
|
||||||
|
|
||||||
|
@ -112,7 +112,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 tstr_t & name)
|
||||||
{
|
{
|
||||||
if( name.empty() )
|
if( name.empty() )
|
||||||
return false;
|
return false;
|
||||||
|
@ -120,7 +120,7 @@ public:
|
||||||
if( !CorrectCharacter(name[0], false) )
|
if( !CorrectCharacter(name[0], false) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::string::const_iterator i=name.begin();
|
tstr_t::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 +133,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 tstr_t & name)
|
||||||
{
|
{
|
||||||
Iterator i = table.find(name);
|
Iterator i = table.find(name);
|
||||||
|
|
||||||
|
@ -148,7 +148,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 tstr_t & name, const tstr_t & value, int param = 0)
|
||||||
{
|
{
|
||||||
if( !IsNameCorrect(name) )
|
if( !IsNameCorrect(name) )
|
||||||
return err_incorrect_name;
|
return err_incorrect_name;
|
||||||
|
@ -205,7 +205,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 tstr_t & name, const tstr_t & value, int param = 0)
|
||||||
{
|
{
|
||||||
if( !IsNameCorrect(name) )
|
if( !IsNameCorrect(name) )
|
||||||
return err_incorrect_name;
|
return err_incorrect_name;
|
||||||
|
@ -225,7 +225,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 tstr_t & old_name, const tstr_t & 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 +256,7 @@ public:
|
||||||
/*!
|
/*!
|
||||||
this method deletes an object
|
this method deletes an object
|
||||||
*/
|
*/
|
||||||
ErrorCode Delete(const std::string & name)
|
ErrorCode Delete(const tstr_t & name)
|
||||||
{
|
{
|
||||||
if( !IsNameCorrect(name) )
|
if( !IsNameCorrect(name) )
|
||||||
return err_incorrect_name;
|
return err_incorrect_name;
|
||||||
|
@ -275,7 +275,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 tstr_t & name, tstr_t & value) const
|
||||||
{
|
{
|
||||||
if( !IsNameCorrect(name) )
|
if( !IsNameCorrect(name) )
|
||||||
return err_incorrect_name;
|
return err_incorrect_name;
|
||||||
|
@ -298,7 +298,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 tstr_t & name, const tchar_t ** value) const
|
||||||
{
|
{
|
||||||
if( !IsNameCorrect(name) )
|
if( !IsNameCorrect(name) )
|
||||||
return err_incorrect_name;
|
return err_incorrect_name;
|
||||||
|
@ -321,7 +321,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 tstr_t & name, tstr_t & value, int * param) const
|
||||||
{
|
{
|
||||||
if( !IsNameCorrect(name) )
|
if( !IsNameCorrect(name) )
|
||||||
return err_incorrect_name;
|
return err_incorrect_name;
|
||||||
|
@ -347,7 +347,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 tstr_t & name, const tchar_t ** value, int * param) const
|
||||||
{
|
{
|
||||||
if( !IsNameCorrect(name) )
|
if( !IsNameCorrect(name) )
|
||||||
return err_incorrect_name;
|
return err_incorrect_name;
|
||||||
|
|
|
@ -256,7 +256,7 @@ public:
|
||||||
bool function;
|
bool function;
|
||||||
|
|
||||||
// if function is true
|
// if function is true
|
||||||
std::string function_name;
|
tstr_t function_name;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
the sign of value
|
the sign of value
|
||||||
|
@ -310,11 +310,11 @@ ErrorCode error;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
pointer to the currently reading char
|
pointer to the currently reading tchar_t
|
||||||
|
|
||||||
when an error has occured it may be used to count the index of the wrong character
|
when an error has occured it may be used to count the index of the wrong character
|
||||||
*/
|
*/
|
||||||
const char * pstring;
|
const tchar_t * pstring;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -351,7 +351,7 @@ const Objects * puser_variables;
|
||||||
const Objects * puser_functions;
|
const Objects * puser_functions;
|
||||||
|
|
||||||
|
|
||||||
typedef std::map<std::string, ValueType> FunctionLocalVariables;
|
typedef std::map<tstr_t, ValueType> FunctionLocalVariables;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a pointer to the local variables of a function
|
a pointer to the local variables of a function
|
||||||
|
@ -362,13 +362,13 @@ const FunctionLocalVariables * pfunction_local_variables;
|
||||||
/*!
|
/*!
|
||||||
a temporary set using during parsing user defined variables
|
a temporary set using during parsing user defined variables
|
||||||
*/
|
*/
|
||||||
std::set<std::string> visited_variables;
|
std::set<tstr_t> visited_variables;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a temporary set using during parsing user defined functions
|
a temporary set using during parsing user defined functions
|
||||||
*/
|
*/
|
||||||
std::set<std::string> visited_functions;
|
std::set<tstr_t> visited_functions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -396,10 +396,10 @@ typedef void (ValueType::*pfunction_var)();
|
||||||
table of mathematic functions
|
table of mathematic functions
|
||||||
|
|
||||||
this map consists of:
|
this map consists of:
|
||||||
std::string - function's name
|
tstr_t - function's name
|
||||||
pfunction - pointer to specific function
|
pfunction - pointer to specific function
|
||||||
*/
|
*/
|
||||||
typedef std::map<std::string, pfunction> FunctionsTable;
|
typedef std::map<tstr_t, pfunction> FunctionsTable;
|
||||||
FunctionsTable functions_table;
|
FunctionsTable functions_table;
|
||||||
|
|
||||||
|
|
||||||
|
@ -407,10 +407,10 @@ FunctionsTable functions_table;
|
||||||
table of mathematic operators
|
table of mathematic operators
|
||||||
|
|
||||||
this map consists of:
|
this map consists of:
|
||||||
std::string - operators's name
|
tstr_t - operators's name
|
||||||
MatOperator::Type - type of the operator
|
MatOperator::Type - type of the operator
|
||||||
*/
|
*/
|
||||||
typedef std::map<std::string, typename MatOperator::Type> OperatorsTable;
|
typedef std::map<tstr_t, typename MatOperator::Type> OperatorsTable;
|
||||||
OperatorsTable operators_table;
|
OperatorsTable operators_table;
|
||||||
|
|
||||||
|
|
||||||
|
@ -418,10 +418,10 @@ OperatorsTable operators_table;
|
||||||
table of mathematic variables
|
table of mathematic variables
|
||||||
|
|
||||||
this map consists of:
|
this map consists of:
|
||||||
std::string - variable's name
|
tstr_t - variable's name
|
||||||
pfunction_var - pointer to specific function which returns value of variable
|
pfunction_var - pointer to specific function which returns value of variable
|
||||||
*/
|
*/
|
||||||
typedef std::map<std::string, pfunction_var> VariablesTable;
|
typedef std::map<tstr_t, pfunction_var> VariablesTable;
|
||||||
VariablesTable variables_table;
|
VariablesTable variables_table;
|
||||||
|
|
||||||
|
|
||||||
|
@ -456,7 +456,7 @@ void SkipWhiteCharacters()
|
||||||
/*!
|
/*!
|
||||||
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
|
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
|
||||||
*/
|
*/
|
||||||
void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const std::string & name)
|
void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const tstr_t & name)
|
||||||
{
|
{
|
||||||
if( variable )
|
if( variable )
|
||||||
{
|
{
|
||||||
|
@ -474,7 +474,7 @@ void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, cons
|
||||||
/*!
|
/*!
|
||||||
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
|
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
|
||||||
*/
|
*/
|
||||||
void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::string & name)
|
void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const tstr_t & name)
|
||||||
{
|
{
|
||||||
if( variable )
|
if( variable )
|
||||||
visited_variables.insert( name );
|
visited_variables.insert( name );
|
||||||
|
@ -486,7 +486,7 @@ void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::stri
|
||||||
/*!
|
/*!
|
||||||
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
|
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
|
||||||
*/
|
*/
|
||||||
void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::string & name)
|
void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const tstr_t & name)
|
||||||
{
|
{
|
||||||
if( variable )
|
if( variable )
|
||||||
visited_variables.erase( name );
|
visited_variables.erase( name );
|
||||||
|
@ -505,7 +505,7 @@ void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::s
|
||||||
(there can be a recurrence here therefore we're using 'visited_variables'
|
(there can be a recurrence here therefore we're using 'visited_variables'
|
||||||
and 'visited_functions' sets to make a stop condition)
|
and 'visited_functions' sets to make a stop condition)
|
||||||
*/
|
*/
|
||||||
ValueType RecurrenceParsingVariablesOrFunction(bool variable, const std::string & name, const char * new_string, FunctionLocalVariables * local_variables = 0)
|
ValueType RecurrenceParsingVariablesOrFunction(bool variable, const tstr_t & name, const tchar_t * new_string, FunctionLocalVariables * local_variables = 0)
|
||||||
{
|
{
|
||||||
RecurrenceParsingVariablesOrFunction_CheckStopCondition(variable, name);
|
RecurrenceParsingVariablesOrFunction_CheckStopCondition(variable, name);
|
||||||
RecurrenceParsingVariablesOrFunction_AddName(variable, name);
|
RecurrenceParsingVariablesOrFunction_AddName(variable, name);
|
||||||
|
@ -548,12 +548,12 @@ public:
|
||||||
/*!
|
/*!
|
||||||
this method returns the user-defined value of a variable
|
this method returns the user-defined value of a variable
|
||||||
*/
|
*/
|
||||||
bool GetValueOfUserDefinedVariable(const std::string & variable_name,ValueType & result)
|
bool GetValueOfUserDefinedVariable(const tstr_t & variable_name,ValueType & result)
|
||||||
{
|
{
|
||||||
if( !puser_variables )
|
if( !puser_variables )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const char * string_value;
|
const tchar_t * string_value;
|
||||||
|
|
||||||
if( puser_variables->GetValue(variable_name, &string_value) != err_ok )
|
if( puser_variables->GetValue(variable_name, &string_value) != err_ok )
|
||||||
return false;
|
return false;
|
||||||
|
@ -567,7 +567,7 @@ return true;
|
||||||
/*!
|
/*!
|
||||||
this method returns the value of a local variable of a function
|
this method returns the value of a local variable of a function
|
||||||
*/
|
*/
|
||||||
bool GetValueOfFunctionLocalVariable(const std::string & variable_name, ValueType & result)
|
bool GetValueOfFunctionLocalVariable(const tstr_t & variable_name, ValueType & result)
|
||||||
{
|
{
|
||||||
if( !pfunction_local_variables )
|
if( !pfunction_local_variables )
|
||||||
return false;
|
return false;
|
||||||
|
@ -589,7 +589,7 @@ return true;
|
||||||
we make an object of type ValueType then call a method which
|
we make an object of type ValueType then call a method which
|
||||||
sets the correct value in it and finally we'll return the object
|
sets the correct value in it and finally we'll return the object
|
||||||
*/
|
*/
|
||||||
ValueType GetValueOfVariable(const std::string & variable_name)
|
ValueType GetValueOfVariable(const tstr_t & variable_name)
|
||||||
{
|
{
|
||||||
ValueType result;
|
ValueType result;
|
||||||
|
|
||||||
|
@ -600,7 +600,7 @@ ValueType result;
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
||||||
typename std::map<std::string, pfunction_var>::iterator i =
|
typename std::map<tstr_t, pfunction_var>::iterator i =
|
||||||
variables_table.find(variable_name);
|
variables_table.find(variable_name);
|
||||||
|
|
||||||
if( i == variables_table.end() )
|
if( i == variables_table.end() )
|
||||||
|
@ -1338,12 +1338,12 @@ void Avg(int sindex, int amount_of_args, ValueType & result)
|
||||||
|
|
||||||
(look at the description in 'CallFunction(...)')
|
(look at the description in 'CallFunction(...)')
|
||||||
*/
|
*/
|
||||||
bool GetValueOfUserDefinedFunction(const std::string & function_name, int amount_of_args, int sindex)
|
bool GetValueOfUserDefinedFunction(const tstr_t & function_name, int amount_of_args, int sindex)
|
||||||
{
|
{
|
||||||
if( !puser_functions )
|
if( !puser_functions )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const char * string_value;
|
const tchar_t * string_value;
|
||||||
int param;
|
int param;
|
||||||
|
|
||||||
if( puser_functions->GetValueAndParam(function_name, &string_value, ¶m) != err_ok )
|
if( puser_functions->GetValueAndParam(function_name, &string_value, ¶m) != err_ok )
|
||||||
|
@ -1357,7 +1357,7 @@ bool GetValueOfUserDefinedFunction(const std::string & function_name, int amount
|
||||||
|
|
||||||
if( amount_of_args > 0 )
|
if( amount_of_args > 0 )
|
||||||
{
|
{
|
||||||
char buffer[20];
|
tchar_t buffer[20];
|
||||||
|
|
||||||
// x = x1
|
// x = x1
|
||||||
sprintf(buffer,"x");
|
sprintf(buffer,"x");
|
||||||
|
@ -1389,7 +1389,7 @@ return true;
|
||||||
result will be stored in 'stack[sindex-1].value'
|
result will be stored in 'stack[sindex-1].value'
|
||||||
(we don't have to set the correct type of this element, it'll be set later)
|
(we don't have to set the correct type of this element, it'll be set later)
|
||||||
*/
|
*/
|
||||||
void CallFunction(const std::string & function_name, int amount_of_args, int sindex)
|
void CallFunction(const tstr_t & function_name, int amount_of_args, int sindex)
|
||||||
{
|
{
|
||||||
if( GetValueOfUserDefinedFunction(function_name, amount_of_args, sindex) )
|
if( GetValueOfUserDefinedFunction(function_name, amount_of_args, sindex) )
|
||||||
return;
|
return;
|
||||||
|
@ -1415,9 +1415,9 @@ void CallFunction(const std::string & function_name, int amount_of_args, int sin
|
||||||
function_name - name of the function
|
function_name - name of the function
|
||||||
pf - pointer to the function (to the wrapper)
|
pf - pointer to the function (to the wrapper)
|
||||||
*/
|
*/
|
||||||
void InsertFunctionToTable(const char * function_name, pfunction pf)
|
void InsertFunctionToTable(const tchar_t * function_name, pfunction pf)
|
||||||
{
|
{
|
||||||
functions_table.insert( std::make_pair(std::string(function_name), pf));
|
functions_table.insert( std::make_pair(tstr_t(function_name), pf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1428,9 +1428,9 @@ void InsertFunctionToTable(const char * function_name, pfunction pf)
|
||||||
variable_name - name of the function
|
variable_name - name of the function
|
||||||
pf - pointer to the function
|
pf - pointer to the function
|
||||||
*/
|
*/
|
||||||
void InsertVariableToTable(const char * variable_name, pfunction_var pf)
|
void InsertVariableToTable(const tchar_t * variable_name, pfunction_var pf)
|
||||||
{
|
{
|
||||||
variables_table.insert( std::make_pair(std::string(variable_name), pf));
|
variables_table.insert( std::make_pair(tstr_t(variable_name), pf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1538,7 +1538,7 @@ return c;
|
||||||
what should be returned is tested just by a '(' character that means if there's
|
what should be returned is tested just by a '(' character that means if there's
|
||||||
a '(' character after a name that function returns 'true'
|
a '(' character after a name that function returns 'true'
|
||||||
*/
|
*/
|
||||||
bool ReadName(std::string & result)
|
bool ReadName(tstr_t & result)
|
||||||
{
|
{
|
||||||
int character;
|
int character;
|
||||||
|
|
||||||
|
@ -1610,7 +1610,7 @@ return false;
|
||||||
*/
|
*/
|
||||||
bool ReadVariableOrFunction(Item & result)
|
bool ReadVariableOrFunction(Item & result)
|
||||||
{
|
{
|
||||||
std::string name;
|
tstr_t name;
|
||||||
bool is_it_name_of_function = ReadName(name);
|
bool is_it_name_of_function = ReadName(name);
|
||||||
|
|
||||||
if( is_it_name_of_function )
|
if( is_it_name_of_function )
|
||||||
|
@ -1639,7 +1639,7 @@ return is_it_name_of_function;
|
||||||
*/
|
*/
|
||||||
void ReadValue(Item & result, int reading_base)
|
void ReadValue(Item & result, int reading_base)
|
||||||
{
|
{
|
||||||
const char * new_stack_pointer;
|
const tchar_t * new_stack_pointer;
|
||||||
bool value_read;
|
bool value_read;
|
||||||
|
|
||||||
int carry = result.value.FromString(pstring, reading_base, &new_stack_pointer, &value_read);
|
int carry = result.value.FromString(pstring, reading_base, &new_stack_pointer, &value_read);
|
||||||
|
@ -1812,7 +1812,7 @@ return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsertOperatorToTable(const std::string & name, typename MatOperator::Type type)
|
void InsertOperatorToTable(const tstr_t & name, typename MatOperator::Type type)
|
||||||
{
|
{
|
||||||
operators_table.insert( std::make_pair(name, type) );
|
operators_table.insert( std::make_pair(name, type) );
|
||||||
}
|
}
|
||||||
|
@ -1823,19 +1823,19 @@ void InsertOperatorToTable(const std::string & name, typename MatOperator::Type
|
||||||
*/
|
*/
|
||||||
void CreateMathematicalOperatorsTable()
|
void CreateMathematicalOperatorsTable()
|
||||||
{
|
{
|
||||||
InsertOperatorToTable(std::string("||"), MatOperator::lor);
|
InsertOperatorToTable(tstr_t("||"), MatOperator::lor);
|
||||||
InsertOperatorToTable(std::string("&&"), MatOperator::land);
|
InsertOperatorToTable(tstr_t("&&"), MatOperator::land);
|
||||||
InsertOperatorToTable(std::string("!="), MatOperator::neq);
|
InsertOperatorToTable(tstr_t("!="), MatOperator::neq);
|
||||||
InsertOperatorToTable(std::string("=="), MatOperator::eq);
|
InsertOperatorToTable(tstr_t("=="), MatOperator::eq);
|
||||||
InsertOperatorToTable(std::string(">="), MatOperator::get);
|
InsertOperatorToTable(tstr_t(">="), MatOperator::get);
|
||||||
InsertOperatorToTable(std::string("<="), MatOperator::let);
|
InsertOperatorToTable(tstr_t("<="), MatOperator::let);
|
||||||
InsertOperatorToTable(std::string(">"), MatOperator::gt);
|
InsertOperatorToTable(tstr_t(">"), MatOperator::gt);
|
||||||
InsertOperatorToTable(std::string("<"), MatOperator::lt);
|
InsertOperatorToTable(tstr_t("<"), MatOperator::lt);
|
||||||
InsertOperatorToTable(std::string("-"), MatOperator::sub);
|
InsertOperatorToTable(tstr_t("-"), MatOperator::sub);
|
||||||
InsertOperatorToTable(std::string("+"), MatOperator::add);
|
InsertOperatorToTable(tstr_t("+"), MatOperator::add);
|
||||||
InsertOperatorToTable(std::string("/"), MatOperator::div);
|
InsertOperatorToTable(tstr_t("/"), MatOperator::div);
|
||||||
InsertOperatorToTable(std::string("*"), MatOperator::mul);
|
InsertOperatorToTable(tstr_t("*"), MatOperator::mul);
|
||||||
InsertOperatorToTable(std::string("^"), MatOperator::pow);
|
InsertOperatorToTable(tstr_t("^"), MatOperator::pow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1845,12 +1845,12 @@ void CreateMathematicalOperatorsTable()
|
||||||
e.g.
|
e.g.
|
||||||
true when str1="test" and str2="te"
|
true when str1="test" and str2="te"
|
||||||
*/
|
*/
|
||||||
bool IsSubstring(const std::string & str1, const std::string & str2)
|
bool IsSubstring(const tstr_t & str1, const tstr_t & str2)
|
||||||
{
|
{
|
||||||
if( str2.length() > str1.length() )
|
if( str2.length() > str1.length() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for(std::string::size_type i=0 ; i<str2.length() ; ++i)
|
for(tstr_t::size_type i=0 ; i<str2.length() ; ++i)
|
||||||
if( str1[i] != str2[i] )
|
if( str1[i] != str2[i] )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1863,7 +1863,7 @@ return true;
|
||||||
*/
|
*/
|
||||||
void ReadMathematicalOperator(Item & result)
|
void ReadMathematicalOperator(Item & result)
|
||||||
{
|
{
|
||||||
std::string oper;
|
tstr_t oper;
|
||||||
typename OperatorsTable::iterator iter_old, iter_new;
|
typename OperatorsTable::iterator iter_old, iter_new;
|
||||||
|
|
||||||
iter_old = operators_table.end();
|
iter_old = operators_table.end();
|
||||||
|
@ -2510,7 +2510,7 @@ void SetFactorialMax(const ValueType & m)
|
||||||
/*!
|
/*!
|
||||||
the main method using for parsing string
|
the main method using for parsing string
|
||||||
*/
|
*/
|
||||||
ErrorCode Parse(const char * str)
|
ErrorCode Parse(const tchar_t * str)
|
||||||
{
|
{
|
||||||
stack_index = 0;
|
stack_index = 0;
|
||||||
pstring = str;
|
pstring = str;
|
||||||
|
|
|
@ -1,447 +1,451 @@
|
||||||
/*
|
/*
|
||||||
* 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@slimaczek.pl>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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>
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
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 8
|
||||||
#define TTMATH_REVISION_VER 4
|
#define TTMATH_REVISION_VER 4
|
||||||
#define TTMATH_PRERELEASE_VER 1
|
#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
|
this type is twice bigger than uint
|
||||||
(64bit on a 32bit platforms)
|
(64bit on a 32bit platforms)
|
||||||
|
|
||||||
although C++ Standard - ANSI ISO IEC 14882:2003 doesn't define such a type (long long)
|
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
|
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
|
this type is used in UInt::MulTwoWords and UInt::DivTwoWords when macro TTMATH_NOASM is defined
|
||||||
*/
|
*/
|
||||||
typedef unsigned long long int ulint;
|
typedef unsigned long long int ulint;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
how many bits there are in the uint type
|
how many bits there are in the uint type
|
||||||
*/
|
*/
|
||||||
#define TTMATH_BITS_PER_UINT 32u
|
#define TTMATH_BITS_PER_UINT 32u
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the mask for the highest bit in the unsigned 32bit word (2^31)
|
the mask for the highest bit in the unsigned 32bit word (2^31)
|
||||||
*/
|
*/
|
||||||
#define TTMATH_UINT_HIGHEST_BIT 2147483648u
|
#define TTMATH_UINT_HIGHEST_BIT 2147483648u
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the max value of the unsigned 32bit word (2^32 - 1)
|
the max value of the unsigned 32bit word (2^32 - 1)
|
||||||
(all bits equal one)
|
(all bits equal one)
|
||||||
*/
|
*/
|
||||||
#define TTMATH_UINT_MAX_VALUE 4294967295u
|
#define TTMATH_UINT_MAX_VALUE 4294967295u
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the number of words (32bit words on 32bit platform)
|
the number of words (32bit words on 32bit platform)
|
||||||
which are kept in built-in variables for a Big<> type
|
which are kept in built-in variables for a Big<> type
|
||||||
(these variables are defined in ttmathbig.h)
|
(these variables are defined in ttmathbig.h)
|
||||||
*/
|
*/
|
||||||
#define TTMATH_BUILTIN_VARIABLES_SIZE 256u
|
#define TTMATH_BUILTIN_VARIABLES_SIZE 256u
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
on 64bit platforms one word (uint, sint) will be equal 64bits
|
on 64bit platforms one word (uint, sint) will be equal 64bits
|
||||||
*/
|
*/
|
||||||
typedef unsigned long uint;
|
#if defined(_MSC_VER)
|
||||||
typedef signed long sint;
|
typedef unsigned __int64 uint;
|
||||||
|
typedef signed __int64 sint;
|
||||||
/*!
|
#else
|
||||||
on 64bit platform we do not define ulint
|
typedef unsigned long long uint;
|
||||||
sizeof(long long) is 8 (64bit) but we need 128bit
|
typedef signed long long sint;
|
||||||
|
#endif
|
||||||
on 64 bit platform (when there is defined TTMATH_NOASM macro)
|
/*!
|
||||||
methods UInt::MulTwoWords and UInt::DivTwoWords are using other algorithms than those on 32 bit
|
on 64bit platform we do not define ulint
|
||||||
*/
|
sizeof(long long) is 8 (64bit) but we need 128bit
|
||||||
//typedef unsigned long long int ulint;
|
|
||||||
|
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
|
||||||
how many bits there are in the uint type
|
*/
|
||||||
*/
|
//typedef unsigned long long int ulint;
|
||||||
#define TTMATH_BITS_PER_UINT 64ul
|
|
||||||
|
/*!
|
||||||
/*!
|
how many bits there are in the uint type
|
||||||
the mask for the highest bit in the unsigned 64bit word (2^63)
|
*/
|
||||||
*/
|
#define TTMATH_BITS_PER_UINT 64ul
|
||||||
#define TTMATH_UINT_HIGHEST_BIT 9223372036854775808ul
|
|
||||||
|
/*!
|
||||||
/*!
|
the mask for the highest bit in the unsigned 64bit word (2^63)
|
||||||
the max value of the unsigned 64bit word (2^64 - 1)
|
*/
|
||||||
(all bits equal one)
|
#define TTMATH_UINT_HIGHEST_BIT 0x8000000000000000ul
|
||||||
*/
|
|
||||||
#define TTMATH_UINT_MAX_VALUE 18446744073709551615ul
|
/*!
|
||||||
|
the max value of the unsigned 64bit word (2^64 - 1)
|
||||||
/*!
|
(all bits equal one)
|
||||||
the number of words (64bit words on 64bit platforms)
|
*/
|
||||||
which are kept in built-in variables for a Big<> type
|
#define TTMATH_UINT_MAX_VALUE 0xfffffffffffffffful
|
||||||
(these variables are defined in ttmathbig.h)
|
|
||||||
*/
|
/*!
|
||||||
#define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
|
the number of words (64bit words on 64bit platforms)
|
||||||
|
which are kept in built-in variables for a Big<> type
|
||||||
#endif
|
(these variables are defined in ttmathbig.h)
|
||||||
}
|
*/
|
||||||
|
#define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
|
||||||
|
|
||||||
|
#endif
|
||||||
/*!
|
}
|
||||||
characters which represent the comma operator
|
|
||||||
|
|
||||||
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing (default, can be overwritten in ToString() function)
|
|
||||||
TTMATH_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character
|
/*!
|
||||||
that means you can input values for example 1.2345 and 1,2345 as well
|
characters which represent the comma operator
|
||||||
|
|
||||||
if you don't want it just put 0 there e.g.
|
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing (default, can be overwritten in ToString() function)
|
||||||
#define TTMATH_COMMA_CHARACTER_2 0
|
TTMATH_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character
|
||||||
then only TTMATH_COMMA_CHARACTER_1 will be used
|
that means you can input values for example 1.2345 and 1,2345 as well
|
||||||
|
|
||||||
don't put there any special character which is used by the parser
|
if you don't want it just put 0 there e.g.
|
||||||
(for example a semicolon ';' shouldn't be there)
|
#define TTMATH_COMMA_CHARACTER_2 0
|
||||||
*/
|
then only TTMATH_COMMA_CHARACTER_1 will be used
|
||||||
#define TTMATH_COMMA_CHARACTER_1 '.'
|
|
||||||
#define TTMATH_COMMA_CHARACTER_2 ','
|
don't put there any special character which is used by the parser
|
||||||
|
(for example a semicolon ';' shouldn't be there)
|
||||||
|
*/
|
||||||
|
#define TTMATH_COMMA_CHARACTER_1 '.'
|
||||||
/*!
|
#define TTMATH_COMMA_CHARACTER_2 ','
|
||||||
this variable defines how many iterations are performed
|
|
||||||
during some kind of calculating when we're making any long formulas
|
|
||||||
(for example Taylor series)
|
|
||||||
|
/*!
|
||||||
it's used in ExpSurrounding0(...), LnSurrounding1(...), Sin0pi05(...), etc.
|
this variable defines how many iterations are performed
|
||||||
|
during some kind of calculating when we're making any long formulas
|
||||||
note! there'll not be so many iterations, iterations are stopped when
|
(for example Taylor series)
|
||||||
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
|
it's used in ExpSurrounding0(...), LnSurrounding1(...), Sin0pi05(...), etc.
|
||||||
series are smaller than previous ones)
|
|
||||||
*/
|
note! there'll not be so many iterations, iterations are stopped when
|
||||||
#define TTMATH_ARITHMETIC_MAX_LOOP 10000
|
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
|
||||||
namespace ttmath
|
|
||||||
{
|
|
||||||
|
|
||||||
/*!
|
|
||||||
error codes
|
namespace ttmath
|
||||||
*/
|
{
|
||||||
enum ErrorCode
|
|
||||||
{
|
/*!
|
||||||
err_ok = 0,
|
error codes
|
||||||
err_nothing_has_read,
|
*/
|
||||||
err_unknown_character,
|
enum ErrorCode
|
||||||
err_unexpected_final_bracket,
|
{
|
||||||
err_stack_not_clear,
|
err_ok = 0,
|
||||||
err_unknown_variable,
|
err_nothing_has_read,
|
||||||
err_division_by_zero,
|
err_unknown_character,
|
||||||
err_interrupt,
|
err_unexpected_final_bracket,
|
||||||
err_overflow,
|
err_stack_not_clear,
|
||||||
err_unknown_function,
|
err_unknown_variable,
|
||||||
err_unknown_operator,
|
err_division_by_zero,
|
||||||
err_unexpected_semicolon_operator,
|
err_interrupt,
|
||||||
err_improper_amount_of_arguments,
|
err_overflow,
|
||||||
err_improper_argument,
|
err_unknown_function,
|
||||||
err_unexpected_end,
|
err_unknown_operator,
|
||||||
err_internal_error,
|
err_unexpected_semicolon_operator,
|
||||||
err_incorrect_name,
|
err_improper_amount_of_arguments,
|
||||||
err_incorrect_value,
|
err_improper_argument,
|
||||||
err_variable_exists,
|
err_unexpected_end,
|
||||||
err_variable_loop,
|
err_internal_error,
|
||||||
err_functions_loop,
|
err_incorrect_name,
|
||||||
err_must_be_only_one_value,
|
err_incorrect_value,
|
||||||
err_object_exists,
|
err_variable_exists,
|
||||||
err_unknown_object,
|
err_variable_loop,
|
||||||
err_still_calculating,
|
err_functions_loop,
|
||||||
err_too_big_factorial,
|
err_must_be_only_one_value,
|
||||||
err_in_short_form_used_function
|
err_object_exists,
|
||||||
};
|
err_unknown_object,
|
||||||
|
err_still_calculating,
|
||||||
|
err_too_big_factorial,
|
||||||
/*!
|
err_in_short_form_used_function
|
||||||
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
|
this simple class can be used in multithreading model
|
||||||
the 'stop object', if the method WasStopSignal() of this
|
(you can write your own class derived from this one)
|
||||||
object returns true that means we should break the calculating
|
|
||||||
and return
|
for example: in some functions like Factorial()
|
||||||
*/
|
/at the moment only Factorial/ you can give a pointer to
|
||||||
class StopCalculating
|
the 'stop object', if the method WasStopSignal() of this
|
||||||
{
|
object returns true that means we should break the calculating
|
||||||
public:
|
and return
|
||||||
virtual bool WasStopSignal() const volatile { return false; }
|
*/
|
||||||
virtual ~StopCalculating(){}
|
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
|
/*!
|
||||||
*/
|
a small class which is useful when compiling with gcc
|
||||||
class ExceptionInfo
|
|
||||||
{
|
object of this type holds the name and the line of a file
|
||||||
const char * file;
|
in which the macro TTMATH_ASSERT or TTMATH_REFERENCE_ASSERT was used
|
||||||
int line;
|
*/
|
||||||
|
class ExceptionInfo
|
||||||
public:
|
{
|
||||||
ExceptionInfo() : file(0), line(0) {}
|
const tchar_t * file;
|
||||||
ExceptionInfo(const char * f, int l) : file(f), line(l) {}
|
int line;
|
||||||
|
|
||||||
std::string Where() const
|
public:
|
||||||
{
|
ExceptionInfo() : file(0), line(0) {}
|
||||||
if( !file )
|
ExceptionInfo(const tchar_t * f, int l) : file(f), line(l) {}
|
||||||
return "unknown";
|
|
||||||
|
tstr_t Where() const
|
||||||
std::ostringstream result;
|
{
|
||||||
result << file << ":" << line;
|
if( !file )
|
||||||
|
return(TTMATH_TEXT("unknown"));
|
||||||
return result.str();
|
|
||||||
}
|
tostrstrm_t result;
|
||||||
};
|
result << file << TTMATH_TEXT(":") << 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
|
/*!
|
||||||
|
A small class used for reporting 'reference' errors
|
||||||
If you compile with gcc you can get a small benefit
|
|
||||||
from using method Where() (it returns std::string with
|
In the library is used macro TTMATH_REFERENCE_ASSERT which
|
||||||
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
|
can throw an exception of this type
|
||||||
was used)
|
|
||||||
|
If you compile with gcc you can get a small benefit
|
||||||
What is the 'reference' error?
|
from using method Where() (it returns tstr_t with
|
||||||
Some kind of methods use a reference as their argument to another object,
|
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
|
||||||
and the another object not always can be the same which is calling, e.g.
|
was used)
|
||||||
Big<1,2> foo(10);
|
|
||||||
foo.Mul(foo); // this is incorrect
|
What is the 'reference' error?
|
||||||
above method Mul is making something more with 'this' object and
|
Some kind of methods use a reference as their argument to another object,
|
||||||
'this' cannot be passed as the argument because the result will be undefined
|
and the another object not always can be the same which is calling, e.g.
|
||||||
|
Big<1,2> foo(10);
|
||||||
macro TTMATH_REFERENCE_ASSERT helps us to solve the above problem
|
foo.Mul(foo); // this is incorrect
|
||||||
|
above method Mul is making something more with 'this' object and
|
||||||
note! some methods can use 'this' object as the argument
|
'this' cannot be passed as the argument because the result will be undefined
|
||||||
for example this code is correct:
|
|
||||||
UInt<2> foo(10);
|
macro TTMATH_REFERENCE_ASSERT helps us to solve the above problem
|
||||||
foo.Add(foo);
|
|
||||||
but there are only few methods which can do that
|
note! some methods can use 'this' object as the argument
|
||||||
*/
|
for example this code is correct:
|
||||||
class ReferenceError : public std::logic_error, ExceptionInfo
|
UInt<2> foo(10);
|
||||||
{
|
foo.Add(foo);
|
||||||
public:
|
but there are only few methods which can do that
|
||||||
|
*/
|
||||||
ReferenceError() : std::logic_error ("reference error")
|
class ReferenceError : public std::logic_error, ExceptionInfo
|
||||||
{
|
{
|
||||||
}
|
public:
|
||||||
|
|
||||||
ReferenceError(const char * f, int l) :
|
ReferenceError() : std::logic_error ("reference error")
|
||||||
std::logic_error ("reference error"), ExceptionInfo(f,l)
|
{
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
ReferenceError(const tchar_t * f, int l) :
|
||||||
std::string Where() const
|
std::logic_error ("reference error"), ExceptionInfo(f,l)
|
||||||
{
|
{
|
||||||
return ExceptionInfo::Where();
|
}
|
||||||
}
|
|
||||||
};
|
tstr_t 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
|
a small class used for reporting errors
|
||||||
|
|
||||||
if you compile with gcc you can get a small benefit
|
in the library is used macro TTMATH_ASSERT which
|
||||||
from using method Where() (it returns std::string with
|
(if the condition in it is false) throw an exception
|
||||||
the name and the line of a file where the macro TTMATH_ASSERT
|
of this type
|
||||||
was used)
|
|
||||||
*/
|
if you compile with gcc you can get a small benefit
|
||||||
class RuntimeError : public std::runtime_error, ExceptionInfo
|
from using method Where() (it returns tstr_t with
|
||||||
{
|
the name and the line of a file where the macro TTMATH_ASSERT
|
||||||
public:
|
was used)
|
||||||
|
*/
|
||||||
RuntimeError() : std::runtime_error ("internal error")
|
class RuntimeError : public std::runtime_error, ExceptionInfo
|
||||||
{
|
{
|
||||||
}
|
public:
|
||||||
|
|
||||||
RuntimeError(const char * f, int l) :
|
RuntimeError() : std::runtime_error ("internal error")
|
||||||
std::runtime_error ("internal error"), ExceptionInfo(f,l)
|
{
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
RuntimeError(const tchar_t * f, int l) :
|
||||||
std::string Where() const
|
std::runtime_error ("internal error"), ExceptionInfo(f,l)
|
||||||
{
|
{
|
||||||
return ExceptionInfo::Where();
|
}
|
||||||
}
|
|
||||||
};
|
tstr_t Where() const
|
||||||
|
{
|
||||||
|
return ExceptionInfo::Where();
|
||||||
|
}
|
||||||
/*!
|
};
|
||||||
look at the description of macros TTMATH_RELEASE and TTMATH_DEBUG
|
|
||||||
*/
|
|
||||||
#ifdef TTMATH_DEBUG
|
|
||||||
|
/*!
|
||||||
#if defined(__FILE__) && defined(__LINE__)
|
look at the description of macros TTMATH_RELEASE and TTMATH_DEBUG
|
||||||
|
*/
|
||||||
#define TTMATH_REFERENCE_ASSERT(expression) \
|
#ifdef TTMATH_DEBUG
|
||||||
if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__);
|
|
||||||
|
#if defined(__FILE__) && defined(__LINE__)
|
||||||
#define TTMATH_ASSERT(expression) \
|
|
||||||
if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__);
|
#define TTMATH_REFERENCE_ASSERT(expression) \
|
||||||
|
if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__);
|
||||||
#else
|
|
||||||
|
#define TTMATH_ASSERT(expression) \
|
||||||
#define TTMATH_REFERENCE_ASSERT(expression) \
|
if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__);
|
||||||
if( &(expression) == this ) throw ReferenceError();
|
|
||||||
|
#else
|
||||||
#define TTMATH_ASSERT(expression) \
|
|
||||||
if( !(expression) ) throw RuntimeError();
|
#define TTMATH_REFERENCE_ASSERT(expression) \
|
||||||
#endif
|
if( &(expression) == this ) throw ReferenceError();
|
||||||
|
|
||||||
#else
|
#define TTMATH_ASSERT(expression) \
|
||||||
#define TTMATH_REFERENCE_ASSERT(expression)
|
if( !(expression) ) throw RuntimeError();
|
||||||
#define TTMATH_ASSERT(expression)
|
#endif
|
||||||
#endif
|
|
||||||
|
#else
|
||||||
|
#define TTMATH_REFERENCE_ASSERT(expression)
|
||||||
|
#define TTMATH_ASSERT(expression)
|
||||||
#ifdef TTMATH_DEBUG_LOG
|
#endif
|
||||||
|
|
||||||
#define TTMATH_LOG(msg) \
|
|
||||||
PrintLog(msg, std::cout);
|
|
||||||
|
#ifdef TTMATH_DEBUG_LOG
|
||||||
#else
|
|
||||||
|
#define TTMATH_LOG(msg) \
|
||||||
#define TTMATH_LOG(msg)
|
PrintLog(msg, std::cout);
|
||||||
|
|
||||||
#endif
|
#else
|
||||||
|
|
||||||
|
#define TTMATH_LOG(msg)
|
||||||
} // namespace
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -50,7 +50,9 @@
|
||||||
|
|
||||||
#include "ttmathtypes.h"
|
#include "ttmathtypes.h"
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(disable:4127) // conditional expression is constant
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief a namespace for the TTMath library
|
\brief a namespace for the TTMath library
|
||||||
|
@ -84,7 +86,7 @@ public:
|
||||||
|
|
||||||
it prints the table in a nice form of several columns
|
it prints the table in a nice form of several columns
|
||||||
*/
|
*/
|
||||||
void PrintTable(std::ostream & output) const
|
void PrintTable(tostrm_t & output) const
|
||||||
{
|
{
|
||||||
// how many columns there'll be
|
// how many columns there'll be
|
||||||
const int columns = 8;
|
const int columns = 8;
|
||||||
|
@ -118,7 +120,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PrintLog(const char * msg, std::ostream & output) const
|
void PrintLog(const tchar_t * msg, tostrm_t & output) const
|
||||||
{
|
{
|
||||||
output << msg << std::endl;
|
output << msg << std::endl;
|
||||||
|
|
||||||
|
@ -1473,7 +1475,7 @@ private:
|
||||||
bool Div2_DivisorGreaterOrEqual( const UInt<value_size> & divisor,
|
bool Div2_DivisorGreaterOrEqual( const UInt<value_size> & divisor,
|
||||||
UInt<value_size> * remainder,
|
UInt<value_size> * remainder,
|
||||||
uint table_id, uint index,
|
uint table_id, uint index,
|
||||||
uint divisor_table_id, uint divisor_index )
|
uint /*divisor_table_id*/, uint divisor_index )
|
||||||
{
|
{
|
||||||
if( divisor_index > index )
|
if( divisor_index > index )
|
||||||
{
|
{
|
||||||
|
@ -1604,7 +1606,7 @@ private:
|
||||||
for(uint i = j+1 ; i<value_size ; ++i)
|
for(uint i = j+1 ; i<value_size ; ++i)
|
||||||
q.table[i] = 0;
|
q.table[i] = 0;
|
||||||
|
|
||||||
while( true )
|
for (;;)
|
||||||
{
|
{
|
||||||
u1 = table[j+n-1];
|
u1 = table[j+n-1];
|
||||||
u0 = table[j+n-2];
|
u0 = table[j+n-2];
|
||||||
|
@ -2005,7 +2007,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts a digit into a char
|
this method converts a digit into a tchar_t
|
||||||
digit should be from <0,F>
|
digit should be from <0,F>
|
||||||
(we don't have to get a base)
|
(we don't have to get a base)
|
||||||
|
|
||||||
|
@ -2141,7 +2143,7 @@ public:
|
||||||
this constant 10 has the int type (signed int), if we don't give such
|
this constant 10 has the int type (signed int), if we don't give such
|
||||||
operators and constructors the compiler will not compile the program,
|
operators and constructors the compiler will not compile the program,
|
||||||
because it has to make a conversion and doesn't know into which type
|
because it has to make a conversion and doesn't know into which type
|
||||||
(the UInt class has operator=(const char*), operator=(uint) etc.)
|
(the UInt class has operator=(const tchar_t*), operator=(uint) etc.)
|
||||||
*/
|
*/
|
||||||
UInt<value_size> & operator=(sint i)
|
UInt<value_size> & operator=(sint i)
|
||||||
{
|
{
|
||||||
|
@ -2256,18 +2258,18 @@ 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)
|
||||||
*/
|
*/
|
||||||
UInt(const char * s)
|
UInt(const tchar_t * s)
|
||||||
{
|
{
|
||||||
FromString(s);
|
FromString(s);
|
||||||
|
|
||||||
TTMATH_LOG("UInt::UInt(const char *)")
|
TTMATH_LOG("UInt::UInt(const tchar_t *)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
UInt(const std::string & s)
|
UInt(const tstr_t & s)
|
||||||
{
|
{
|
||||||
FromString( s.c_str() );
|
FromString( s.c_str() );
|
||||||
}
|
}
|
||||||
|
@ -2332,10 +2334,10 @@ 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(tstr_t & result, uint b = 10) const
|
||||||
{
|
{
|
||||||
UInt<value_size> temp( *this );
|
UInt<value_size> temp( *this );
|
||||||
char character;
|
tchar_t character;
|
||||||
uint rem;
|
uint rem;
|
||||||
|
|
||||||
result.clear();
|
result.clear();
|
||||||
|
@ -2360,7 +2362,7 @@ public:
|
||||||
/*
|
/*
|
||||||
this method's ommiting any white characters from the string
|
this method's ommiting any white characters from the string
|
||||||
*/
|
*/
|
||||||
static void SkipWhiteCharacters(const char * & c)
|
static void SkipWhiteCharacters(const tchar_t * & c)
|
||||||
{
|
{
|
||||||
while( (*c==' ' ) || (*c=='\t') || (*c==13 ) || (*c=='\n') )
|
while( (*c==' ' ) || (*c=='\t') || (*c==13 ) || (*c=='\n') )
|
||||||
++c;
|
++c;
|
||||||
|
@ -2384,7 +2386,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 tchar_t * s, uint b = 10, const tchar_t ** after_source = 0, bool * value_read = 0)
|
||||||
{
|
{
|
||||||
UInt<value_size> base( b );
|
UInt<value_size> base( b );
|
||||||
UInt<value_size> temp;
|
UInt<value_size> temp;
|
||||||
|
@ -2434,7 +2436,7 @@ public:
|
||||||
|
|
||||||
(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 tstr_t & s, uint b = 10)
|
||||||
{
|
{
|
||||||
return FromString( s.c_str(), b );
|
return FromString( s.c_str(), b );
|
||||||
}
|
}
|
||||||
|
@ -2444,11 +2446,11 @@ public:
|
||||||
/*!
|
/*!
|
||||||
this operator converts a string into its value (with base = 10)
|
this operator converts a string into its value (with base = 10)
|
||||||
*/
|
*/
|
||||||
UInt<value_size> & operator=(const char * s)
|
UInt<value_size> & operator=(const tchar_t * s)
|
||||||
{
|
{
|
||||||
FromString(s);
|
FromString(s);
|
||||||
|
|
||||||
TTMATH_LOG("UInt::operator=(const char *)")
|
TTMATH_LOG("UInt::operator=(const tchar_t *)")
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -2457,7 +2459,7 @@ public:
|
||||||
/*!
|
/*!
|
||||||
this operator converts a string into its value (with base = 10)
|
this operator converts a string into its value (with base = 10)
|
||||||
*/
|
*/
|
||||||
UInt<value_size> & operator=(const std::string & s)
|
UInt<value_size> & operator=(const tstr_t & s)
|
||||||
{
|
{
|
||||||
FromString( s.c_str() );
|
FromString( s.c_str() );
|
||||||
|
|
||||||
|
@ -2825,9 +2827,9 @@ public:
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
friend std::ostream & operator<<(std::ostream & s, const UInt<value_size> & l)
|
friend tostrm_t & operator<<(tostrm_t & s, const UInt<value_size> & l)
|
||||||
{
|
{
|
||||||
std::string ss;
|
tstr_t ss;
|
||||||
|
|
||||||
l.ToString(ss);
|
l.ToString(ss);
|
||||||
s << ss;
|
s << ss;
|
||||||
|
@ -2837,12 +2839,12 @@ public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
friend std::istream & operator>>(std::istream & s, UInt<value_size> & l)
|
friend tistrm_t & operator>>(tistrm_t & s, UInt<value_size> & l)
|
||||||
{
|
{
|
||||||
std::string ss;
|
tstr_t ss;
|
||||||
|
|
||||||
// char for operator>>
|
// tchar_t for operator>>
|
||||||
unsigned char z;
|
tchar_t 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;
|
||||||
|
@ -2925,6 +2927,10 @@ public:
|
||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(default:4127) // conditional expression is constant
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "ttmathuint_x86.h"
|
#include "ttmathuint_x86.h"
|
||||||
#include "ttmathuint_x86_64.h"
|
#include "ttmathuint_x86_64.h"
|
||||||
|
|
|
@ -41,9 +41,9 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef TTMATH_NOASM
|
#ifndef TTMATH_NOASM
|
||||||
|
#pragma message("ASM code included")
|
||||||
#ifdef TTMATH_PLATFORM64
|
#ifdef TTMATH_PLATFORM64
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\file ttmathuint_x86_64.h
|
\file ttmathuint_x86_64.h
|
||||||
\brief template class UInt<uint> with assembler code for 64bit x86_64 processors
|
\brief template class UInt<uint> with assembler code for 64bit x86_64 processors
|
||||||
|
@ -55,6 +55,24 @@
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if defined(_M_IX64)
|
||||||
|
#include <intrin.h>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
uint __fastcall adc_x64(uint* p1, const uint* p2, uint nSize, uint c);
|
||||||
|
uint __fastcall addindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue);
|
||||||
|
uint __fastcall addindexed2_x64(uint* p1, uint nSize, uint nPos, uint nValue1, uint nValue2);
|
||||||
|
uint __fastcall sbb_x64(uint* p1, const uint* p2, uint nSize, uint c);
|
||||||
|
uint __fastcall subindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue);
|
||||||
|
uint __fastcall rcl_x64(uint* p1, uint nSize, uint nLowestBit);
|
||||||
|
uint __fastcall rcr_x64(uint* p1, uint nSize, uint nLowestBit);
|
||||||
|
uint __fastcall div_x64(uint* pnValHi, uint* pnValLo, uint nDiv);
|
||||||
|
uint __fastcall rcl2_x64(uint* p1, uint nSize, uint nBits, uint c);
|
||||||
|
uint __fastcall rcr2_x64(uint* p1, uint nSize, uint nBits, uint c);
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* basic mathematic functions
|
* basic mathematic functions
|
||||||
|
@ -78,16 +96,20 @@ namespace ttmath
|
||||||
uint b = value_size;
|
uint b = value_size;
|
||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
const uint * p2 = ss2.table;
|
const uint * p2 = ss2.table;
|
||||||
uint dummy, dummy2;
|
|
||||||
|
|
||||||
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
||||||
// this algorithm doesn't require it
|
// this algorithm doesn't require it
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#if defined(_M_IX64)
|
||||||
|
c = adc_x64(p1,p2,b,c);
|
||||||
|
#else
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
uint dummy, dummy2;
|
||||||
/*
|
/*
|
||||||
this part should be compiled with gcc
|
this part should be compiled with gcc
|
||||||
*/
|
*/
|
||||||
|
@ -145,15 +167,19 @@ namespace ttmath
|
||||||
uint b = value_size;
|
uint b = value_size;
|
||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
uint c;
|
uint c;
|
||||||
uint dummy, dummy2;
|
|
||||||
|
|
||||||
TTMATH_ASSERT( index < value_size )
|
TTMATH_ASSERT( index < value_size )
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#if defined(_M_IX64)
|
||||||
|
c = addindexed_x64(p1,b,index,value);
|
||||||
|
#else
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
uint dummy, dummy2;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
|
@ -223,15 +249,20 @@ namespace ttmath
|
||||||
uint b = value_size;
|
uint b = value_size;
|
||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
uint c;
|
uint c;
|
||||||
uint dummy, dummy2;
|
|
||||||
|
|
||||||
TTMATH_ASSERT( index < value_size - 1 )
|
TTMATH_ASSERT( index < value_size - 1 )
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#if defined(_M_IX64)
|
||||||
|
c = addindexed2_x64(p1,b,index,x2,x1);
|
||||||
|
#else
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
uint dummy, dummy2;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"subq %%rdx, %%rcx \n"
|
"subq %%rdx, %%rcx \n"
|
||||||
|
@ -284,16 +315,21 @@ namespace ttmath
|
||||||
uint b = value_size;
|
uint b = value_size;
|
||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
const uint * p2 = ss2.table;
|
const uint * p2 = ss2.table;
|
||||||
uint dummy, dummy2;
|
|
||||||
|
|
||||||
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
||||||
// this algorithm doesn't require it
|
// this algorithm doesn't require it
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#if defined(_M_IX64)
|
||||||
|
c = sbb_x64(p1,p2,b,c);
|
||||||
|
#else
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
uint dummy, dummy2;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"xorq %%rdx, %%rdx \n"
|
"xorq %%rdx, %%rdx \n"
|
||||||
|
@ -347,15 +383,20 @@ namespace ttmath
|
||||||
uint b = value_size;
|
uint b = value_size;
|
||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
uint c;
|
uint c;
|
||||||
uint dummy, dummy2;
|
|
||||||
|
|
||||||
TTMATH_ASSERT( index < value_size )
|
TTMATH_ASSERT( index < value_size )
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#if defined(_M_IX64)
|
||||||
|
c = subindexed_x64(p1,b,index,value);
|
||||||
|
#else
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
uint dummy, dummy2;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"subq %%rdx, %%rcx \n"
|
"subq %%rdx, %%rcx \n"
|
||||||
|
@ -404,13 +445,18 @@ namespace ttmath
|
||||||
{
|
{
|
||||||
sint b = value_size;
|
sint b = value_size;
|
||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
uint dummy, dummy2;
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#if defined(_M_IX64)
|
||||||
|
c = rcl_x64(p1,b,c);
|
||||||
|
#else
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
uint dummy, dummy2;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"xorq %%rdx, %%rdx \n" // rdx=0
|
"xorq %%rdx, %%rdx \n" // rdx=0
|
||||||
|
@ -456,13 +502,18 @@ namespace ttmath
|
||||||
{
|
{
|
||||||
sint b = value_size;
|
sint b = value_size;
|
||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
uint dummy;
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#if defined(_M_IX64)
|
||||||
|
c = rcr_x64(p1,b,c);
|
||||||
|
#else
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
uint dummy;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"neg %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
|
"neg %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
|
||||||
|
@ -509,13 +560,18 @@ namespace ttmath
|
||||||
|
|
||||||
uint b = value_size;
|
uint b = value_size;
|
||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
uint dummy, dummy2, dummy3;
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#if defined(_M_IX64)
|
||||||
|
c = rcl2_x64(p1,b,bits,c);
|
||||||
|
#else
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
uint dummy, dummy2, dummy3;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"movq %%rcx, %%rsi \n"
|
"movq %%rcx, %%rsi \n"
|
||||||
|
@ -580,14 +636,19 @@ namespace ttmath
|
||||||
|
|
||||||
sint b = value_size;
|
sint b = value_size;
|
||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
uint dummy, dummy2, dummy3;
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#if defined(_M_IX64)
|
||||||
|
c = rcr2_x64(p1,b,bits,c);
|
||||||
|
#else
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
uint dummy, dummy2, dummy3;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"movq %%rcx, %%rsi \n"
|
"movq %%rcx, %%rsi \n"
|
||||||
|
@ -646,7 +707,16 @@ namespace ttmath
|
||||||
register sint result;
|
register sint result;
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#if defined(_MSC_VER)
|
||||||
|
unsigned long nIndex(0);
|
||||||
|
|
||||||
|
if (_BitScanReverse64(&nIndex,x) == 0)
|
||||||
|
result = -1;
|
||||||
|
else
|
||||||
|
result = nIndex;
|
||||||
|
#else
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
@ -691,7 +761,11 @@ namespace ttmath
|
||||||
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#if defined(_MSC_VER)
|
||||||
|
old_bit = _bittestandset((long*)&value,bit) != 0;
|
||||||
|
#else
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
@ -747,7 +821,11 @@ namespace ttmath
|
||||||
register uint result2_;
|
register uint result2_;
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#if defined(_MSC_VER)
|
||||||
|
result1_ = _umul128(a,b,&result2_);
|
||||||
|
#else
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
@ -804,7 +882,13 @@ namespace ttmath
|
||||||
TTMATH_ASSERT( c != 0 )
|
TTMATH_ASSERT( c != 0 )
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#if defined(_MSC_VER)
|
||||||
|
div_x64(&a,&b,c);
|
||||||
|
r_ = a;
|
||||||
|
rest_ = b;
|
||||||
|
#else
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
|
@ -0,0 +1,358 @@
|
||||||
|
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
|
||||||
|
mov r11, 0
|
||||||
|
sub rax, r9 ; sets CARRY if r9 != 0
|
||||||
|
|
||||||
|
loop1:
|
||||||
|
mov rax,qword ptr [rdx + r11 * 8]
|
||||||
|
adc qword ptr [rcx + r11 * 8], rax
|
||||||
|
inc r11
|
||||||
|
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
|
||||||
|
|
||||||
|
sub rdx, r8 ; rdx = remaining count of uints
|
||||||
|
loop1:
|
||||||
|
add qword ptr [rcx + r8 * 8], r9
|
||||||
|
jnc done
|
||||||
|
|
||||||
|
inc r8
|
||||||
|
mov r9, 1
|
||||||
|
dec rdx
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
done:
|
||||||
|
setc al
|
||||||
|
movzx rax, al
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
addindexed_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
addindexed2_x64 PROC
|
||||||
|
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = b
|
||||||
|
; r8 = nPos
|
||||||
|
; r9 = nValue1
|
||||||
|
; [esp+0x28] = nValue2
|
||||||
|
|
||||||
|
mov r11, rcx ; table
|
||||||
|
sub rdx, r8 ; rdx = remaining count of uints
|
||||||
|
mov r10, [esp+028h] ; r10 = nValue2
|
||||||
|
|
||||||
|
add qword ptr [r11 + r8 * 8], r10
|
||||||
|
inc r8
|
||||||
|
loop1:
|
||||||
|
adc qword ptr [r11 + r8 * 8], r9
|
||||||
|
jnc done
|
||||||
|
|
||||||
|
inc r8
|
||||||
|
mov r9, 0 ; set to 0 -> cy still set!
|
||||||
|
dec rdx
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
done:
|
||||||
|
setc al
|
||||||
|
movzx rax, al
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
addindexed2_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
sbb_x64 PROC
|
||||||
|
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = p2
|
||||||
|
; r8 = nCount
|
||||||
|
; r9 = nCarry
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
mov r11, 0
|
||||||
|
sub rax, r9 ; sets CARRY if r9 != 0
|
||||||
|
|
||||||
|
loop1:
|
||||||
|
mov rax,qword ptr [rdx + r11 * 8]
|
||||||
|
sbb qword ptr [rcx + r11 * 8], rax
|
||||||
|
inc r11
|
||||||
|
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
|
||||||
|
loop1:
|
||||||
|
sub qword ptr [rcx + r8 * 8], r9
|
||||||
|
jnc done
|
||||||
|
|
||||||
|
inc r8
|
||||||
|
mov r9, 1
|
||||||
|
dec rdx
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
done:
|
||||||
|
setc al
|
||||||
|
movzx rax, al
|
||||||
|
|
||||||
|
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
|
||||||
|
loop1:
|
||||||
|
rcl qword ptr [r11 + r10 * 8], 1
|
||||||
|
inc r10
|
||||||
|
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
|
||||||
|
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
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
inc r9
|
||||||
|
dec rdx
|
||||||
|
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
and rax, 1
|
||||||
|
ret
|
||||||
|
|
||||||
|
rcl2_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
rcr2_x64 PROC
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = nSize
|
||||||
|
; r8 = bits
|
||||||
|
; r9 = c
|
||||||
|
|
||||||
|
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)
|
||||||
|
dec r9
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
dec r9
|
||||||
|
dec rdx
|
||||||
|
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
rol rax, 1
|
||||||
|
and rax, 1
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
rcr2_x64 ENDP
|
||||||
|
|
||||||
|
END
|
Loading…
Reference in New Issue