- added AboutEqualWithoutSign() to big<> to allow 'suppression' of some unexpected results (that are perfectly logical though, given the possibly unrepresentable nature of binary representation of decimals) like
big<>("10.456466") * 2 == big<>("20.912932") resulting in FALSE result. git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@171 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
548
ttmath/ttmath.h
548
ttmath/ttmath.h
@@ -45,7 +45,7 @@
|
|||||||
\brief Mathematics functions.
|
\brief Mathematics functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ttmathconfig.h"
|
#include "ttmathconfig.h"
|
||||||
#include "ttmathbig.h"
|
#include "ttmathbig.h"
|
||||||
#include "ttmathobjects.h"
|
#include "ttmathobjects.h"
|
||||||
|
|
||||||
@@ -96,21 +96,21 @@ namespace ttmath
|
|||||||
-2.7 = -3
|
-2.7 = -3
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Round(const ValueType & x, ErrorCode * err = 0)
|
ValueType Round(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType result( x );
|
ValueType result( x );
|
||||||
uint c = result.Round();
|
uint c = result.Round();
|
||||||
|
|
||||||
if( err )
|
if( err )
|
||||||
*err = c ? err_overflow : err_ok;
|
*err = c ? err_overflow : err_ok;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -131,14 +131,14 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Ceil(const ValueType & x, ErrorCode * err = 0)
|
ValueType Ceil(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType result(x);
|
ValueType result(x);
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
@@ -178,14 +178,14 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Floor(const ValueType & x, ErrorCode * err = 0)
|
ValueType Floor(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType result(x);
|
ValueType result(x);
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
@@ -226,14 +226,14 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Ln(const ValueType & x, ErrorCode * err = 0)
|
ValueType Ln(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType result;
|
ValueType result;
|
||||||
uint state = result.Ln(x);
|
uint state = result.Ln(x);
|
||||||
|
|
||||||
@@ -267,14 +267,14 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Log(const ValueType & x, const ValueType & base, ErrorCode * err = 0)
|
ValueType Log(const ValueType & x, const ValueType & base, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() || base.IsNan() )
|
if( x.IsNan() || base.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return ValueType(); // default NaN
|
return ValueType(); // default NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType result;
|
ValueType result;
|
||||||
uint state = result.Log(x, base);
|
uint state = result.Log(x, base);
|
||||||
|
|
||||||
@@ -308,14 +308,14 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Exp(const ValueType & x, ErrorCode * err = 0)
|
ValueType Exp(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType result;
|
ValueType result;
|
||||||
uint c = result.Exp(x);
|
uint c = result.Exp(x);
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ namespace ttmath
|
|||||||
(you don't have to call this function)
|
(you don't have to call this function)
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
uint PrepareSin(ValueType & x, bool & change_sign)
|
uint PrepareSin(ValueType & x, bool & change_sign)
|
||||||
{
|
{
|
||||||
ValueType temp;
|
ValueType temp;
|
||||||
|
|
||||||
@@ -361,10 +361,10 @@ namespace ttmath
|
|||||||
// we're reducing the period 2*PI
|
// we're reducing the period 2*PI
|
||||||
// (for big values there'll always be zero)
|
// (for big values there'll always be zero)
|
||||||
temp.Set2Pi();
|
temp.Set2Pi();
|
||||||
|
|
||||||
if( x.Mod(temp) )
|
if( x.Mod(temp) )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
||||||
// we're setting 'x' as being in the range of <0, 0.5PI>
|
// we're setting 'x' as being in the range of <0, 0.5PI>
|
||||||
|
|
||||||
@@ -385,8 +385,8 @@ namespace ttmath
|
|||||||
x.Sub( temp );
|
x.Sub( temp );
|
||||||
x = temp - x;
|
x = temp - x;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -473,7 +473,7 @@ namespace ttmath
|
|||||||
if( c )
|
if( c )
|
||||||
// Sin is from <-1,1> and cannot make an overflow
|
// Sin is from <-1,1> and cannot make an overflow
|
||||||
// but the carry can be from the Taylor series
|
// but the carry can be from the Taylor series
|
||||||
// (then we only break our calculations)
|
// (then we only break our calculations)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if( addition )
|
if( addition )
|
||||||
@@ -505,23 +505,23 @@ namespace ttmath
|
|||||||
this function calculates the Sine
|
this function calculates the Sine
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Sin(ValueType x, ErrorCode * err = 0)
|
ValueType Sin(ValueType x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
using namespace auxiliaryfunctions;
|
using namespace auxiliaryfunctions;
|
||||||
|
|
||||||
ValueType one, result;
|
ValueType one, result;
|
||||||
bool change_sign;
|
bool change_sign;
|
||||||
|
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return result; // NaN is set by default
|
||||||
}
|
}
|
||||||
|
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_ok;
|
*err = err_ok;
|
||||||
|
|
||||||
if( PrepareSin( x, change_sign ) )
|
if( PrepareSin( x, change_sign ) )
|
||||||
{
|
{
|
||||||
@@ -531,7 +531,7 @@ namespace ttmath
|
|||||||
// result has NaN flag set by default
|
// result has NaN flag set by default
|
||||||
|
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_overflow; // maybe another error code? err_improper_argument?
|
*err = err_overflow; // maybe another error code? err_improper_argument?
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return result; // NaN is set by default
|
||||||
}
|
}
|
||||||
@@ -561,20 +561,20 @@ namespace ttmath
|
|||||||
we're using the formula cos(x) = sin(x + PI/2)
|
we're using the formula cos(x) = sin(x + PI/2)
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Cos(ValueType x, ErrorCode * err = 0)
|
ValueType Cos(ValueType x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType pi05;
|
ValueType pi05;
|
||||||
pi05.Set05Pi();
|
pi05.Set05Pi();
|
||||||
|
|
||||||
uint c = x.Add( pi05 );
|
uint c = x.Add( pi05 );
|
||||||
|
|
||||||
if( c )
|
if( c )
|
||||||
{
|
{
|
||||||
@@ -584,9 +584,9 @@ namespace ttmath
|
|||||||
return ValueType(); // result is undefined (NaN is set by default)
|
return ValueType(); // result is undefined (NaN is set by default)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Sin(x, err);
|
return Sin(x, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this function calulates the Tangent
|
this function calulates the Tangent
|
||||||
@@ -601,10 +601,10 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Tan(const ValueType & x, ErrorCode * err = 0)
|
ValueType Tan(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
ValueType result = Cos(x, err);
|
ValueType result = Cos(x, err);
|
||||||
|
|
||||||
if( err && *err != err_ok )
|
if( err && *err != err_ok )
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if( result.IsZero() )
|
if( result.IsZero() )
|
||||||
{
|
{
|
||||||
@@ -616,7 +616,7 @@ namespace ttmath
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Sin(x, err) / result;
|
return Sin(x, err) / result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -643,10 +643,10 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Cot(const ValueType & x, ErrorCode * err = 0)
|
ValueType Cot(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
ValueType result = Sin(x, err);
|
ValueType result = Sin(x, err);
|
||||||
|
|
||||||
if( err && *err != err_ok )
|
if( err && *err != err_ok )
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if( result.IsZero() )
|
if( result.IsZero() )
|
||||||
{
|
{
|
||||||
@@ -658,7 +658,7 @@ namespace ttmath
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Cos(x, err) / result;
|
return Cos(x, err) / result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -843,14 +843,14 @@ namespace ttmath
|
|||||||
one.SetOne();
|
one.SetOne();
|
||||||
bool change_sign = false;
|
bool change_sign = false;
|
||||||
|
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return result; // NaN is set by default
|
||||||
}
|
}
|
||||||
|
|
||||||
if( x.GreaterWithoutSignThan(one) )
|
if( x.GreaterWithoutSignThan(one) )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
@@ -1073,9 +1073,9 @@ namespace ttmath
|
|||||||
one.SetOne();
|
one.SetOne();
|
||||||
bool change_sign = false;
|
bool change_sign = false;
|
||||||
|
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
return result; // NaN is set by default
|
return result; // NaN is set by default
|
||||||
|
|
||||||
// if x is negative we're using the formula:
|
// if x is negative we're using the formula:
|
||||||
// atan(-x) = -atan(x)
|
// atan(-x) = -atan(x)
|
||||||
if( x.IsSign() )
|
if( x.IsSign() )
|
||||||
@@ -1156,14 +1156,14 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Sinh(const ValueType & x, ErrorCode * err = 0)
|
ValueType Sinh(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType ex, emx;
|
ValueType ex, emx;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
@@ -1188,14 +1188,14 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Cosh(const ValueType & x, ErrorCode * err = 0)
|
ValueType Cosh(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType ex, emx;
|
ValueType ex, emx;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
@@ -1220,14 +1220,14 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Tanh(const ValueType & x, ErrorCode * err = 0)
|
ValueType Tanh(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType ex, emx, nominator, denominator;
|
ValueType ex, emx, nominator, denominator;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
@@ -1268,14 +1268,14 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Coth(const ValueType & x, ErrorCode * err = 0)
|
ValueType Coth(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
if( x.IsZero() )
|
if( x.IsZero() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
@@ -1333,14 +1333,14 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType ASinh(const ValueType & x, ErrorCode * err = 0)
|
ValueType ASinh(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType xx(x), one, result;
|
ValueType xx(x), one, result;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
one.SetOne();
|
one.SetOne();
|
||||||
@@ -1369,14 +1369,14 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType ACosh(const ValueType & x, ErrorCode * err = 0)
|
ValueType ACosh(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType xx(x), one, result;
|
ValueType xx(x), one, result;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
one.SetOne();
|
one.SetOne();
|
||||||
@@ -1418,14 +1418,14 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType ATanh(const ValueType & x, ErrorCode * err = 0)
|
ValueType ATanh(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType nominator(x), denominator, one, result;
|
ValueType nominator(x), denominator, one, result;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
one.SetOne();
|
one.SetOne();
|
||||||
@@ -1471,14 +1471,14 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType ACoth(const ValueType & x, ErrorCode * err = 0)
|
ValueType ACoth(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return x; // NaN
|
return x; // NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType nominator(x), denominator(x), one, result;
|
ValueType nominator(x), denominator(x), one, result;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
one.SetOne();
|
one.SetOne();
|
||||||
@@ -1537,14 +1537,14 @@ namespace ttmath
|
|||||||
ValueType result, temp;
|
ValueType result, temp;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return result; // NaN is set by default
|
||||||
}
|
}
|
||||||
|
|
||||||
result = x;
|
result = x;
|
||||||
|
|
||||||
// it is better to make division first and then multiplication
|
// it is better to make division first and then multiplication
|
||||||
@@ -1573,14 +1573,14 @@ namespace ttmath
|
|||||||
ValueType result, delimiter;
|
ValueType result, delimiter;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return result; // NaN is set by default
|
||||||
}
|
}
|
||||||
|
|
||||||
result = 180;
|
result = 180;
|
||||||
c += result.Mul(x);
|
c += result.Mul(x);
|
||||||
|
|
||||||
@@ -1618,7 +1618,7 @@ namespace ttmath
|
|||||||
ValueType delimiter, multipler;
|
ValueType delimiter, multipler;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
if( d.IsNan() || m.IsNan() || s.IsNan() || m.IsSign() || s.IsSign() )
|
if( d.IsNan() || m.IsNan() || s.IsNan() || m.IsSign() || s.IsSign() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
@@ -1672,14 +1672,14 @@ namespace ttmath
|
|||||||
ValueType result, temp;
|
ValueType result, temp;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return result; // NaN is set by default
|
||||||
}
|
}
|
||||||
|
|
||||||
result = x;
|
result = x;
|
||||||
|
|
||||||
// it is better to make division first and then multiplication
|
// it is better to make division first and then multiplication
|
||||||
@@ -1708,14 +1708,14 @@ namespace ttmath
|
|||||||
ValueType result, delimiter;
|
ValueType result, delimiter;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return result; // NaN is set by default
|
||||||
}
|
}
|
||||||
|
|
||||||
result = 200;
|
result = 200;
|
||||||
c += result.Mul(x);
|
c += result.Mul(x);
|
||||||
|
|
||||||
@@ -1740,14 +1740,14 @@ namespace ttmath
|
|||||||
ValueType result, temp;
|
ValueType result, temp;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return result; // NaN is set by default
|
||||||
}
|
}
|
||||||
|
|
||||||
result = x;
|
result = x;
|
||||||
|
|
||||||
temp = 200;
|
temp = 200;
|
||||||
@@ -1790,14 +1790,14 @@ namespace ttmath
|
|||||||
ValueType result, temp;
|
ValueType result, temp;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return result; // NaN is set by default
|
||||||
}
|
}
|
||||||
|
|
||||||
result = x;
|
result = x;
|
||||||
|
|
||||||
temp = 180;
|
temp = 180;
|
||||||
@@ -1831,7 +1831,7 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Sqrt(ValueType x, ErrorCode * err = 0)
|
ValueType Sqrt(ValueType x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() || x.IsSign() )
|
if( x.IsNan() || x.IsSign() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
@@ -1913,7 +1913,7 @@ namespace ttmath
|
|||||||
|
|
||||||
|
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
bool RootCheckIndexOne(const ValueType & index, ErrorCode * err)
|
bool RootCheckIndexOne(const ValueType & index, ErrorCode * err)
|
||||||
{
|
{
|
||||||
ValueType one;
|
ValueType one;
|
||||||
one.SetOne();
|
one.SetOne();
|
||||||
@@ -1955,12 +1955,12 @@ namespace ttmath
|
|||||||
|
|
||||||
|
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
bool RootCheckXZero(ValueType & x, ErrorCode * err)
|
bool RootCheckXZero(ValueType & x, ErrorCode * err)
|
||||||
{
|
{
|
||||||
if( x.IsZero() )
|
if( x.IsZero() )
|
||||||
{
|
{
|
||||||
// root(0;index) is zero (if index!=0)
|
// root(0;index) is zero (if index!=0)
|
||||||
// RootCheckIndexZero() must be called beforehand
|
// RootCheckIndexZero() must be called beforehand
|
||||||
x.SetZero();
|
x.SetZero();
|
||||||
|
|
||||||
if( err )
|
if( err )
|
||||||
@@ -2027,19 +2027,19 @@ namespace ttmath
|
|||||||
{
|
{
|
||||||
using namespace auxiliaryfunctions;
|
using namespace auxiliaryfunctions;
|
||||||
|
|
||||||
if( x.IsNan() || index.IsNan() )
|
if( x.IsNan() || index.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return ValueType(); // NaN is set by default
|
return ValueType(); // NaN is set by default
|
||||||
}
|
}
|
||||||
|
|
||||||
if( RootCheckIndexSign(x, index, err) ) return x;
|
if( RootCheckIndexSign(x, index, err) ) return x;
|
||||||
if( RootCheckIndexZero(x, index, err) ) return x;
|
if( RootCheckIndexZero(x, index, err) ) return x;
|
||||||
if( RootCheckIndexOne ( index, err) ) return x;
|
if( RootCheckIndexOne ( index, err) ) return x;
|
||||||
if( RootCheckIndexFrac(x, index, err) ) return x;
|
if( RootCheckIndexFrac(x, index, err) ) return x;
|
||||||
if( RootCheckXZero (x, err) ) return x;
|
if( RootCheckXZero (x, err) ) return x;
|
||||||
|
|
||||||
// index integer and index!=0
|
// index integer and index!=0
|
||||||
// x!=0
|
// x!=0
|
||||||
@@ -2090,17 +2090,17 @@ namespace ttmath
|
|||||||
|
|
||||||
while( !carry && multipler<maxvalue )
|
while( !carry && multipler<maxvalue )
|
||||||
{
|
{
|
||||||
if( stop && (multipler & 127)==0 ) // it means 'stop && (multipler % 128)==0'
|
if( stop && (multipler & 127)==0 ) // it means 'stop && (multipler % 128)==0'
|
||||||
{
|
{
|
||||||
// after each 128 iterations we make a test
|
// after each 128 iterations we make a test
|
||||||
if( stop->WasStopSignal() )
|
if( stop->WasStopSignal() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_interrupt;
|
*err = err_interrupt;
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++multipler;
|
++multipler;
|
||||||
carry += result.MulUInt(multipler);
|
carry += result.MulUInt(multipler);
|
||||||
@@ -2123,25 +2123,25 @@ namespace ttmath
|
|||||||
|
|
||||||
one.SetOne();
|
one.SetOne();
|
||||||
uint carry = 0;
|
uint carry = 0;
|
||||||
uint iter = 1; // only for testing the stop object
|
uint iter = 1; // only for testing the stop object
|
||||||
|
|
||||||
while( !carry && multipler < x )
|
while( !carry && multipler < x )
|
||||||
{
|
{
|
||||||
if( stop && (iter & 31)==0 ) // it means 'stop && (iter % 32)==0'
|
if( stop && (iter & 31)==0 ) // it means 'stop && (iter % 32)==0'
|
||||||
{
|
{
|
||||||
// after each 32 iterations we make a test
|
// after each 32 iterations we make a test
|
||||||
if( stop->WasStopSignal() )
|
if( stop->WasStopSignal() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_interrupt;
|
*err = err_interrupt;
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
carry += multipler.Add(one);
|
carry += multipler.Add(one);
|
||||||
carry += result.Mul(multipler);
|
carry += result.Mul(multipler);
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( err )
|
if( err )
|
||||||
@@ -2168,16 +2168,16 @@ namespace ttmath
|
|||||||
static History<ValueType> history;
|
static History<ValueType> history;
|
||||||
ValueType result;
|
ValueType result;
|
||||||
|
|
||||||
if( x.IsNan() || x.IsSign() )
|
if( x.IsNan() || x.IsSign() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN set by default
|
return result; // NaN set by default
|
||||||
}
|
}
|
||||||
|
|
||||||
result.SetOne();
|
result.SetOne();
|
||||||
|
|
||||||
if( !x.exponent.IsSign() && !x.exponent.IsZero() )
|
if( !x.exponent.IsSign() && !x.exponent.IsZero() )
|
||||||
{
|
{
|
||||||
// when x.exponent>0 there's no sense to calculate the formula
|
// when x.exponent>0 there's no sense to calculate the formula
|
||||||
@@ -2256,25 +2256,25 @@ namespace ttmath
|
|||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
mod( 12.6 ; 3) = 0.6 because 12.6 = 3*4 + 0.6
|
mod( 12.6 ; 3) = 0.6 because 12.6 = 3*4 + 0.6
|
||||||
mod(-12.6 ; 3) = -0.6 bacause -12.6 = 3*(-4) + (-0.6)
|
mod(-12.6 ; 3) = -0.6 bacause -12.6 = 3*(-4) + (-0.6)
|
||||||
mod( 12.6 ; -3) = 0.6
|
mod( 12.6 ; -3) = 0.6
|
||||||
mod(-12.6 ; -3) = -0.6
|
mod(-12.6 ; -3) = -0.6
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Mod(ValueType a, const ValueType & b, ErrorCode * err = 0)
|
ValueType Mod(ValueType a, const ValueType & b, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( a.IsNan() || b.IsNan() )
|
if( a.IsNan() || b.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return ValueType(); // NaN is set by default
|
return ValueType(); // NaN is set by default
|
||||||
}
|
}
|
||||||
|
|
||||||
uint c = a.Mod(b);
|
uint c = a.Mod(b);
|
||||||
|
|
||||||
if( err )
|
if( err )
|
||||||
*err = c ? err_overflow : err_ok;
|
*err = c ? err_overflow : err_ok;
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
@@ -2290,11 +2290,11 @@ namespace ttmath
|
|||||||
*/
|
*/
|
||||||
#include "ttmathparser.h"
|
#include "ttmathparser.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning( default: 4127 )
|
#pragma warning( default: 4127 )
|
||||||
//warning C4127: conditional expression is constant
|
//warning C4127: conditional expression is constant
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@@ -3864,26 +3864,36 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsNearZero() const
|
bool AboutEqualWithoutSign(const Big<exp,man> & ss2, int nBitsToIgnore = 4) const
|
||||||
{
|
{
|
||||||
// we should check the mantissas beforehand because sometimes we can have
|
// we should check the mantissas beforehand because sometimes we can have
|
||||||
// a mantissa set to zero but in the exponent something another value
|
// a mantissa set to zero but in the exponent something another value
|
||||||
// (maybe we've forgotten about calling CorrectZero() ?)
|
// (maybe we've forgotten about calling CorrectZero() ?)
|
||||||
if( mantissa.IsZero() )
|
if( mantissa.IsZero() && ss2.mantissa.IsZero())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt<man> m(mantissa);
|
if( exponent==ss2.exponent )
|
||||||
|
{
|
||||||
m.Rcr(man*3); // pi * thumb rule...
|
if (mantissa == ss2.mantissa)
|
||||||
|
{
|
||||||
return(m.IsZero());
|
return(true);
|
||||||
|
}
|
||||||
|
ASSERT(nBitsToIgnore < TTMATH_BITS_PER_UINT);
|
||||||
|
|
||||||
|
for (int n = man-1; n > 0; --n)
|
||||||
|
{
|
||||||
|
if (mantissa.table[n] != ss2.mantissa.table[n])
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
uint nMask = ~((1 << nBitsToIgnore) - 1);
|
||||||
|
return((mantissa.table[0] & nMask) == (ss2.mantissa.table[0] & nMask));
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool operator<(const Big<exp,man> & ss2) const
|
bool operator<(const Big<exp,man> & ss2) const
|
||||||
{
|
{
|
||||||
if( IsSign() && !ss2.IsSign() )
|
if( IsSign() && !ss2.IsSign() )
|
||||||
@@ -3914,16 +3924,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool operator^=(const Big<exp,man> & ss2) const
|
|
||||||
{
|
|
||||||
if( IsSign() != ss2.IsSign() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return AboutEqualWithoutSign( ss2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool operator>(const Big<exp,man> & ss2) const
|
bool operator>(const Big<exp,man> & ss2) const
|
||||||
{
|
{
|
||||||
if( IsSign() && !ss2.IsSign() )
|
if( IsSign() && !ss2.IsSign() )
|
||||||
|
@@ -64,8 +64,8 @@
|
|||||||
*/
|
*/
|
||||||
#define TTMATH_MAJOR_VER 0
|
#define TTMATH_MAJOR_VER 0
|
||||||
#define TTMATH_MINOR_VER 8
|
#define TTMATH_MINOR_VER 8
|
||||||
#define TTMATH_REVISION_VER 5
|
#define TTMATH_REVISION_VER 5
|
||||||
#define TTMATH_PRERELEASE_VER 0
|
#define TTMATH_PRERELEASE_VER 0
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -232,16 +232,16 @@ namespace ttmath
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this is a limit when calculating Karatsuba multiplication
|
this is a limit when calculating Karatsuba multiplication
|
||||||
if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
|
if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
|
||||||
the Karatsuba algorithm will use standard schoolbook multiplication
|
the Karatsuba algorithm will use standard schoolbook multiplication
|
||||||
*/
|
*/
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
|
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
|
||||||
#else
|
#else
|
||||||
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
|
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user