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:
Tomasz Sowa 2009-05-11 01:50:00 +00:00
parent 05b67e7103
commit 939d0f7519
5 changed files with 106 additions and 45 deletions

View File

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

View File

@ -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,13 +314,11 @@ 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>
temp.SetPi(); temp.SetPi();
@ -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 );
if( c )
{
if( err )
*err = err_overflow;
return Sin(x); 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;
} }
@ -2007,15 +2031,18 @@ namespace ttmath
the remainder from a division the remainder from a division
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;
} }

View File

@ -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)
@ -997,8 +999,8 @@ public:
the remainder from a division the remainder from a division
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;
Big<exp, man> temp(*this); if( !SmallerWithoutSignThan(ss2) )
{
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)

View File

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

View File

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