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:
Tomasz Sowa 2007-04-05 19:08:15 +00:00
parent 837490e8b9
commit c97ebf282f
5 changed files with 220 additions and 4 deletions

2
README
View File

@ -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

View File

@ -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
*/

View File

@ -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')
*/

View File

@ -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);
}

View File

@ -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
/*!