fixed: Big::PowFrac(..) didn't return a correct error code
(when 'this' was negative) added: Root(x; index) (and to the parser as well) added: macro: TTMATH_PRERELEASE_VER (can be either zero or one) git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@32 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
837490e8b9
commit
c97ebf282f
2
README
2
README
|
@ -21,4 +21,4 @@ to do is to use 'include' directive of the preprocessor. How big the
|
|||
values can be is set directly in the source code by the programmer.
|
||||
|
||||
Author: Tomasz Sowa <t.sowa AnTispam slimaczek.pl>
|
||||
Home page: http://sourceforge.net/projects/ttmath
|
||||
Project page: http://sourceforge.net/projects/ttmath
|
||||
|
|
195
ttmath/ttmath.h
195
ttmath/ttmath.h
|
@ -1342,6 +1342,199 @@ namespace ttmath
|
|||
}
|
||||
|
||||
|
||||
|
||||
namespace auxiliaryfunctions
|
||||
{
|
||||
|
||||
template<class ValueType>
|
||||
bool RootCheckIndexSign(ValueType & x, const ValueType & index, ErrorCode * err)
|
||||
{
|
||||
if( index.IsSign() )
|
||||
{
|
||||
// index cannot be negative
|
||||
if( err )
|
||||
*err = err_improper_argument;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class ValueType>
|
||||
bool RootCheckIndexZero(ValueType & x, const ValueType & index, ErrorCode * err)
|
||||
{
|
||||
if( index.IsZero() )
|
||||
{
|
||||
if( x.IsZero() )
|
||||
{
|
||||
// there isn't root(0;0)
|
||||
if( err )
|
||||
*err = err_improper_argument;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// root(x;0) is 1 (if x!=0)
|
||||
x.SetOne();
|
||||
|
||||
if( err )
|
||||
*err = err_ok;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class ValueType>
|
||||
bool RootCheckIndexOne(ValueType & x, const ValueType & index, ErrorCode * err)
|
||||
{
|
||||
ValueType one;
|
||||
one.SetOne();
|
||||
|
||||
if( index == one )
|
||||
{
|
||||
//root(x;1) is x
|
||||
// we do it because if we used the PowFrac function
|
||||
// we would lose the precision
|
||||
if( err )
|
||||
*err = err_ok;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class ValueType>
|
||||
bool RootCheckIndexFrac(ValueType & x, const ValueType & index, ErrorCode * err)
|
||||
{
|
||||
ValueType indexfrac(index);
|
||||
indexfrac.RemainFraction();
|
||||
|
||||
if( !indexfrac.IsZero() )
|
||||
{
|
||||
// index must be integer
|
||||
if( err )
|
||||
*err = err_improper_argument;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class ValueType>
|
||||
bool RootCheckXZero(ValueType & x, const ValueType & index, ErrorCode * err)
|
||||
{
|
||||
if( x.IsZero() )
|
||||
{
|
||||
// root(0;index) is zero (if index!=0)
|
||||
x.SetZero();
|
||||
|
||||
if( err )
|
||||
*err = err_ok;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class ValueType>
|
||||
bool RootCheckIndex(ValueType & x, const ValueType & index, ErrorCode * err, bool * change_sign)
|
||||
{
|
||||
*change_sign = false;
|
||||
|
||||
if( index.Mod2() )
|
||||
{
|
||||
// index is odd (1,3,5...)
|
||||
if( x.IsSign() )
|
||||
{
|
||||
*change_sign = true;
|
||||
x.Abs();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// index is even
|
||||
// x cannot be negative
|
||||
if( x.IsSign() )
|
||||
{
|
||||
if( err )
|
||||
*err = err_improper_argument;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
indexth Root of x
|
||||
index must be integer and not negative <0;1;2;3....)
|
||||
|
||||
if index==0 the result is one
|
||||
if x==0 the result is zero and we assume root(0;0) is not defined
|
||||
|
||||
if index is even (2;4;6...) the result is x^(1/index) and x>0
|
||||
if index is odd (1;2;3;...) the result is either
|
||||
-(abs(x)^(1/index)) if x<0 or
|
||||
x^(1/index)) if x>0
|
||||
|
||||
(for index==1 the result is equal x)
|
||||
*/
|
||||
template<class ValueType>
|
||||
ValueType Root(ValueType x, const ValueType & index, ErrorCode * err = 0)
|
||||
{
|
||||
using namespace auxiliaryfunctions;
|
||||
|
||||
if( RootCheckIndexSign(x, index, err) ) return x;
|
||||
if( RootCheckIndexZero(x, index, err) ) return x;
|
||||
if( RootCheckIndexOne (x, index, err) ) return x;
|
||||
if( RootCheckIndexFrac(x, index, err) ) return x;
|
||||
if( RootCheckXZero(x, index, err) ) return x;
|
||||
|
||||
// index integer and index!=0
|
||||
// x!=0
|
||||
|
||||
uint c = 0;
|
||||
bool change_sign;
|
||||
if( RootCheckIndex(x, index, err, &change_sign ) ) return x;
|
||||
|
||||
ValueType newindex;
|
||||
newindex.SetOne();
|
||||
c += newindex.Div(index);
|
||||
c += x.PowFrac(newindex); // here can only be a carry
|
||||
|
||||
if( change_sign )
|
||||
x.SetSign();
|
||||
|
||||
if( err )
|
||||
*err = c ? err_overflow : err_ok;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
the factorial from given 'x'
|
||||
e.g.
|
||||
|
@ -1432,7 +1625,7 @@ namespace ttmath
|
|||
|
||||
/*!
|
||||
it returns the sign of the value
|
||||
e.g. -2 = 1
|
||||
e.g. -2 = -1
|
||||
0 = 0
|
||||
10 = 1
|
||||
*/
|
||||
|
|
|
@ -450,7 +450,7 @@ public:
|
|||
|
||||
/*!
|
||||
it remains the 'sign' of the value
|
||||
e.g. -2 = 1
|
||||
e.g. -2 = -1
|
||||
0 = 0
|
||||
10 = 1
|
||||
*/
|
||||
|
@ -883,6 +883,7 @@ public:
|
|||
pow can be negative and with fraction
|
||||
|
||||
return values:
|
||||
0 - ok
|
||||
1 - carry
|
||||
2 - incorrect argument ('this')
|
||||
*/
|
||||
|
@ -892,6 +893,10 @@ public:
|
|||
|
||||
Big<exp, man> temp;
|
||||
uint c = temp.Ln(*this);
|
||||
|
||||
if( c!= 0 )
|
||||
return c;
|
||||
|
||||
c += temp.Mul(pow);
|
||||
c += Exp(temp);
|
||||
|
||||
|
@ -904,6 +909,7 @@ public:
|
|||
pow can be negative and with fraction
|
||||
|
||||
return values:
|
||||
0 - ok
|
||||
1 - carry
|
||||
2 - incorrect argument ('this' or 'pow')
|
||||
*/
|
||||
|
|
|
@ -1030,6 +1030,18 @@ void Coth(int sindex, int amount_of_args, ValueType & result)
|
|||
}
|
||||
|
||||
|
||||
void Root(int sindex, int amount_of_args, ValueType & result)
|
||||
{
|
||||
if( amount_of_args != 2 )
|
||||
Error( err_improper_amount_of_arguments );
|
||||
|
||||
ErrorCode err;
|
||||
result = ttmath::Root(stack[sindex].value, stack[sindex+2].value, &err);
|
||||
|
||||
if( err != err_ok )
|
||||
Error( err );
|
||||
}
|
||||
|
||||
/*!
|
||||
this method returns the value from a user-defined function
|
||||
|
||||
|
@ -1178,6 +1190,7 @@ void CreateFunctionsTable()
|
|||
InsertFunctionToTable(std::string("tgh"), &Parser<ValueType>::Tanh);
|
||||
InsertFunctionToTable(std::string("coth"), &Parser<ValueType>::Coth);
|
||||
InsertFunctionToTable(std::string("ctgh"), &Parser<ValueType>::Coth);
|
||||
InsertFunctionToTable(std::string("root"), &Parser<ValueType>::Root);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,10 +58,14 @@
|
|||
|
||||
/*!
|
||||
the version of the library
|
||||
|
||||
TTMATH_PRERELEASE_VER is either zero or one
|
||||
if zero that means this is the release version of the library
|
||||
*/
|
||||
#define TTMATH_MAJOR_VER 0
|
||||
#define TTMATH_MINOR_VER 8
|
||||
#define TTMATH_REVISION_VER 0
|
||||
#define TTMATH_REVISION_VER 1
|
||||
#define TTMATH_PRERELEASE_VER 1
|
||||
|
||||
|
||||
/*!
|
||||
|
|
Loading…
Reference in New Issue