fixed: Big::Mod(x) didn't correctly return a carry
and the result was sometimes very big (even greater than x) fixed: global function Mod(x) didn't set an ErrorCode object fixed: global function Round() didn't test a carry now it sets ErrorCode object changed: function Sin(x) to Sin(x, ErrorCode * err=0) when x was very big the function returns zero now it sets ErrorCode object to err_overflow and the result is undefined the same is to Cos() function changed: PrepareSin(x) is using Big::Mod() now when reducing 2PI period should be a little accurate especially on a very big 'x' git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@143 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
05b67e7103
commit
939d0f7519
14
CHANGELOG
14
CHANGELOG
|
@ -1,3 +1,17 @@
|
||||||
|
Version 0.8.5 (2009.05.11):
|
||||||
|
* fixed: Big::Mod(x) didn't correctly return a carry
|
||||||
|
and the result was sometimes very big (even greater than x)
|
||||||
|
* fixed: global function Mod(x) didn't set an ErrorCode object
|
||||||
|
* fixed: global function Round() didn't test a carry
|
||||||
|
now it sets ErrorCode object
|
||||||
|
* changed: function Sin(x) to Sin(x, ErrorCode * err=0)
|
||||||
|
when x was very big the function returns zero
|
||||||
|
now it sets ErrorCode object to err_overflow
|
||||||
|
and the result is undefined
|
||||||
|
the same is to Cos() function
|
||||||
|
* changed: PrepareSin(x) is using Big::Mod() now when reducing 2PI period
|
||||||
|
should be a little accurate especially on a very big 'x'
|
||||||
|
|
||||||
Version 0.8.4 (2009.05.08):
|
Version 0.8.4 (2009.05.08):
|
||||||
* fixed: UInt::DivInt() didn't check whether the divisor is zero
|
* fixed: UInt::DivInt() didn't check whether the divisor is zero
|
||||||
there was a hardware interruption when the divisor was zero
|
there was a hardware interruption when the divisor was zero
|
||||||
|
|
|
@ -94,10 +94,13 @@ namespace ttmath
|
||||||
-2.7 = -3
|
-2.7 = -3
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Round(const ValueType & x)
|
ValueType Round(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
ValueType result( x );
|
ValueType result( x );
|
||||||
result.Round();
|
uint c = result.Round();
|
||||||
|
|
||||||
|
if( err )
|
||||||
|
*err = c ? err_overflow : err_ok;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -295,7 +298,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>
|
||||||
void PrepareSin(ValueType & x, bool & change_sign)
|
uint PrepareSin(ValueType & x, bool & change_sign)
|
||||||
{
|
{
|
||||||
ValueType temp;
|
ValueType temp;
|
||||||
|
|
||||||
|
@ -311,12 +314,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 > temp )
|
|
||||||
{
|
if( x.Mod(temp) )
|
||||||
x.Div( temp );
|
return 1;
|
||||||
x.RemainFraction();
|
|
||||||
x.Mul( temp );
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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>
|
||||||
|
|
||||||
|
@ -337,6 +338,8 @@ namespace ttmath
|
||||||
x.Sub( temp );
|
x.Sub( temp );
|
||||||
x = temp - x;
|
x = temp - x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -455,15 +458,28 @@ namespace ttmath
|
||||||
this function calculates the Sine
|
this function calculates the Sine
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Sin(ValueType x)
|
ValueType Sin(ValueType x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
using namespace auxiliaryfunctions;
|
using namespace auxiliaryfunctions;
|
||||||
|
|
||||||
ValueType one;
|
ValueType one, result;
|
||||||
bool change_sign;
|
bool change_sign;
|
||||||
|
|
||||||
PrepareSin( x, change_sign );
|
if( err )
|
||||||
ValueType result = Sin0pi05( x );
|
*err = err_ok;
|
||||||
|
|
||||||
|
if( PrepareSin( x, change_sign ) )
|
||||||
|
{
|
||||||
|
// x is too big, we cannnot reduce the 2*PI period
|
||||||
|
// prior to version 0.8.5 the result was zero
|
||||||
|
|
||||||
|
if( err )
|
||||||
|
*err = err_overflow; // maybe another error code?
|
||||||
|
|
||||||
|
return result; // result we remain as undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
result = Sin0pi05( x );
|
||||||
|
|
||||||
one.SetOne();
|
one.SetOne();
|
||||||
|
|
||||||
|
@ -488,14 +504,22 @@ 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)
|
ValueType Cos(ValueType x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
ValueType pi05;
|
ValueType pi05;
|
||||||
pi05.Set05Pi();
|
pi05.Set05Pi();
|
||||||
|
|
||||||
x.Add( pi05 );
|
uint c = x.Add( pi05 );
|
||||||
|
|
||||||
return Sin(x);
|
if( c )
|
||||||
|
{
|
||||||
|
if( err )
|
||||||
|
*err = err_overflow;
|
||||||
|
|
||||||
|
return ValueType(); // result is undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
return Sin(x, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -512,7 +536,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);
|
ValueType result = Cos(x, err);
|
||||||
|
|
||||||
|
if( err && *err != err_ok )
|
||||||
|
return result;
|
||||||
|
|
||||||
if( result.IsZero() )
|
if( result.IsZero() )
|
||||||
{
|
{
|
||||||
|
@ -522,10 +549,7 @@ namespace ttmath
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( err )
|
return Sin(x, err) / result;
|
||||||
*err = err_ok;
|
|
||||||
|
|
||||||
return Sin(x) / result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -552,7 +576,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);
|
ValueType result = Sin(x, err);
|
||||||
|
|
||||||
|
if( err && *err != err_ok )
|
||||||
|
return result;
|
||||||
|
|
||||||
if( result.IsZero() )
|
if( result.IsZero() )
|
||||||
{
|
{
|
||||||
|
@ -562,10 +589,7 @@ namespace ttmath
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( err )
|
return Cos(x, err) / result;
|
||||||
*err = err_ok;
|
|
||||||
|
|
||||||
return Cos(x) / result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2008,14 +2032,17 @@ 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
|
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)
|
ValueType Mod(ValueType a, const ValueType & b, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
a.Mod(b);
|
uint c = a.Mod(b);
|
||||||
|
|
||||||
|
if( err )
|
||||||
|
*err = c ? err_overflow : err_ok;
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
|
@ -952,7 +952,7 @@ public:
|
||||||
|
|
||||||
UInt<man*2> man1;
|
UInt<man*2> man1;
|
||||||
UInt<man*2> man2;
|
UInt<man*2> man2;
|
||||||
uint i,c;
|
uint i,c = 0;
|
||||||
|
|
||||||
if( ss2.IsZero() )
|
if( ss2.IsZero() )
|
||||||
{
|
{
|
||||||
|
@ -976,7 +976,9 @@ public:
|
||||||
|
|
||||||
i = man1.CompensationToLeft();
|
i = man1.CompensationToLeft();
|
||||||
|
|
||||||
c = exponent.Sub(i);
|
if( i )
|
||||||
|
c += exponent.Sub(i);
|
||||||
|
|
||||||
c += exponent.Sub(ss2.exponent);
|
c += exponent.Sub(ss2.exponent);
|
||||||
|
|
||||||
for(i=0 ; i<man ; ++i)
|
for(i=0 ; i<man ; ++i)
|
||||||
|
@ -998,7 +1000,7 @@ public:
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
12.6 mod 3 = 0.6 because 12.6 = 3*4 + 0.6
|
12.6 mod 3 = 0.6 because 12.6 = 3*4 + 0.6
|
||||||
-12.6 mod 3 = -0.6
|
-12.6 mod 3 = -0.6 bacause -12.6 = 3*(-4) + (-0.6)
|
||||||
12.6 mod -3 = 0.6
|
12.6 mod -3 = 0.6
|
||||||
-12.6 mod -3 = -0.6
|
-12.6 mod -3 = -0.6
|
||||||
|
|
||||||
|
@ -1011,18 +1013,25 @@ public:
|
||||||
|
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
|
if( !SmallerWithoutSignThan(ss2) )
|
||||||
|
{
|
||||||
Big<exp, man> temp(*this);
|
Big<exp, man> temp(*this);
|
||||||
|
|
||||||
c += temp.Div(ss2);
|
c = temp.Div(ss2);
|
||||||
temp.SkipFraction();
|
temp.SkipFraction();
|
||||||
c += temp.Mul(ss2);
|
c += temp.Mul(ss2);
|
||||||
c += Sub(temp);
|
c += Sub(temp);
|
||||||
|
|
||||||
|
if( !SmallerWithoutSignThan( ss2 ) )
|
||||||
|
c += 1;
|
||||||
|
}
|
||||||
|
|
||||||
return (c==0)? 0 : 1;
|
return (c==0)? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
power this = this ^ pow
|
power this = this ^ pow
|
||||||
(pow without a sign)
|
(pow without a sign)
|
||||||
|
|
|
@ -708,7 +708,11 @@ void Sin(int sindex, int amount_of_args, ValueType & result)
|
||||||
if( amount_of_args != 1 )
|
if( amount_of_args != 1 )
|
||||||
Error( err_improper_amount_of_arguments );
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
result = ttmath::Sin( ConvertAngleToRad(stack[sindex].value) );
|
ErrorCode err;
|
||||||
|
result = ttmath::Sin( ConvertAngleToRad(stack[sindex].value), &err );
|
||||||
|
|
||||||
|
if(err != err_ok)
|
||||||
|
Error( err );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cos(int sindex, int amount_of_args, ValueType & result)
|
void Cos(int sindex, int amount_of_args, ValueType & result)
|
||||||
|
@ -716,7 +720,11 @@ void Cos(int sindex, int amount_of_args, ValueType & result)
|
||||||
if( amount_of_args != 1 )
|
if( amount_of_args != 1 )
|
||||||
Error( err_improper_amount_of_arguments );
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
result = ttmath::Cos( ConvertAngleToRad(stack[sindex].value) );
|
ErrorCode err;
|
||||||
|
result = ttmath::Cos( ConvertAngleToRad(stack[sindex].value), &err );
|
||||||
|
|
||||||
|
if(err != err_ok)
|
||||||
|
Error( err );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tan(int sindex, int amount_of_args, ValueType & result)
|
void Tan(int sindex, int amount_of_args, ValueType & result)
|
||||||
|
@ -757,7 +765,10 @@ void Round(int sindex, int amount_of_args, ValueType & result)
|
||||||
if( amount_of_args != 1 )
|
if( amount_of_args != 1 )
|
||||||
Error( err_improper_amount_of_arguments );
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
result = ttmath::Round(stack[sindex].value);
|
result = stack[sindex].value;
|
||||||
|
|
||||||
|
if( result.Round() )
|
||||||
|
Error( err_overflow );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 4
|
#define TTMATH_REVISION_VER 5
|
||||||
#define TTMATH_PRERELEASE_VER 0
|
#define TTMATH_PRERELEASE_VER 1
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
Loading…
Reference in New Issue