fixed: removed 'const' from some methods (operators: += -= *= /=) in the Big class
fixed: bad sizes in tables in some 'Set...' methods in the Big class fixed: Big::FromInt(Int<int_size> value) - the sign must be set at the end because SetSign checks whether there is zero and depends on it sets the sign or not (this was the stupid error which causes sometimes the errors 'overflow during printing') fixed: Big::SetMin - the sign must be set at the and changed: Big::Pow can use the reference now (the problem was actually with the Big::FromInt) added: a namespace 'auxiliaryfunctions' (in ttmath.h) added: ATan - arc tan, ACTan - arc ctan git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@17 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
d04632ea74
commit
e14e65002b
|
@ -1,3 +1,9 @@
|
||||||
|
Version 0.7.1 (2007.02.27):
|
||||||
|
* fixed the error 'overflow during printing' which was caused by Big::FromInt(Int<int_size> value)
|
||||||
|
(the sign has to be set at the end)
|
||||||
|
* fixed many small errors
|
||||||
|
* added ATan (arctan), ACTan (arc ctan) functions
|
||||||
|
|
||||||
Version 0.7.0 (2007.02.24):
|
Version 0.7.0 (2007.02.24):
|
||||||
* finished support for 64bit platforms
|
* finished support for 64bit platforms
|
||||||
* added ASin (arcsin), ACos (arccos) functions
|
* added ASin (arcsin), ACos (arccos) functions
|
||||||
|
|
1
TODO
1
TODO
|
@ -4,3 +4,4 @@ TODO TTMath Library
|
||||||
* to add the method Mod (a remainder from a division) for the Big type
|
* to add the method Mod (a remainder from a division) for the Big type
|
||||||
* to add operators (or functions) and, or, xor
|
* to add operators (or functions) and, or, xor
|
||||||
* to add functions for generating random values
|
* to add functions for generating random values
|
||||||
|
* to add constructors (UInt, Int) for 64bit platforms (constractors which take int and unsigned)
|
||||||
|
|
224
ttmath/ttmath.h
224
ttmath/ttmath.h
|
@ -261,7 +261,9 @@ namespace ttmath
|
||||||
* trigonometric functions
|
* trigonometric functions
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace auxiliaryfunctions
|
||||||
|
{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
an auxiliary function for calculating the Sin
|
an auxiliary function for calculating the Sin
|
||||||
|
@ -420,6 +422,7 @@ namespace ttmath
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace auxiliaryfunctions
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this function calulates the Sin
|
this function calulates the Sin
|
||||||
|
@ -427,6 +430,8 @@ namespace ttmath
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Sin(ValueType x)
|
ValueType Sin(ValueType x)
|
||||||
{
|
{
|
||||||
|
using namespace auxiliaryfunctions;
|
||||||
|
|
||||||
ValueType one;
|
ValueType one;
|
||||||
bool change_sign;
|
bool change_sign;
|
||||||
|
|
||||||
|
@ -531,6 +536,9 @@ namespace ttmath
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace auxiliaryfunctions
|
||||||
|
{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
arcus sin
|
arcus sin
|
||||||
|
|
||||||
|
@ -673,6 +681,9 @@ namespace ttmath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace auxiliaryfunctions
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
arc sin (x)
|
arc sin (x)
|
||||||
x is from <-1,1>
|
x is from <-1,1>
|
||||||
|
@ -680,6 +691,8 @@ namespace ttmath
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType ASin(ValueType x, ErrorCode * err = 0)
|
ValueType ASin(ValueType x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
|
using namespace auxiliaryfunctions;
|
||||||
|
|
||||||
ValueType one;
|
ValueType one;
|
||||||
one.SetOne();
|
one.SetOne();
|
||||||
bool change_sign = false;
|
bool change_sign = false;
|
||||||
|
@ -736,10 +749,213 @@ namespace ttmath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace auxiliaryfunctions
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
arc tan (x) where x is in <0; 0.5)
|
||||||
|
(x can be in (-0.5 ; 0.5) too)
|
||||||
|
|
||||||
|
we're using the Taylor series expanded in zero:
|
||||||
|
atan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 + ...
|
||||||
|
*/
|
||||||
|
template<class ValueType>
|
||||||
|
ValueType ATan0(const ValueType & x)
|
||||||
|
{
|
||||||
|
ValueType nominator, denominator, nominator_add, denominator_add, temp;
|
||||||
|
ValueType result, old_result;
|
||||||
|
bool adding = false;
|
||||||
|
uint c = 0;
|
||||||
|
|
||||||
|
result = x;
|
||||||
|
old_result = result;
|
||||||
|
nominator = x;
|
||||||
|
nominator_add = x;
|
||||||
|
nominator_add.Mul(x);
|
||||||
|
|
||||||
|
denominator.SetOne();
|
||||||
|
denominator_add = 2;
|
||||||
|
|
||||||
|
for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
|
||||||
|
{
|
||||||
|
c += nominator.Mul(nominator_add);
|
||||||
|
c += denominator.Add(denominator_add);
|
||||||
|
|
||||||
|
temp = nominator;
|
||||||
|
c += temp.Div(denominator);
|
||||||
|
|
||||||
|
if( c )
|
||||||
|
// the result should be ok
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( adding )
|
||||||
|
result.Add(temp);
|
||||||
|
else
|
||||||
|
result.Sub(temp);
|
||||||
|
|
||||||
|
if( result == old_result )
|
||||||
|
// there's no sense to calculate more
|
||||||
|
break;
|
||||||
|
|
||||||
|
old_result = result;
|
||||||
|
adding = !adding;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
arc tan (x) where x is in <0 ; 1>
|
||||||
|
*/
|
||||||
|
template<class ValueType>
|
||||||
|
ValueType ATan01(const ValueType & x)
|
||||||
|
{
|
||||||
|
ValueType half;
|
||||||
|
half.SetDotOne();
|
||||||
|
|
||||||
|
/*
|
||||||
|
it would be better if we chose about sqrt(2)-1=0.41... instead of 0.5 here
|
||||||
|
|
||||||
|
because as you can see below:
|
||||||
|
when x = sqrt(2)-1
|
||||||
|
abs(x) = abs( (x-1)/(1+x) )
|
||||||
|
so when we're calculating values around x
|
||||||
|
then they will be better converged to each other
|
||||||
|
|
||||||
|
for example if we have x=0.4999 then during calculating ATan0(0.4999)
|
||||||
|
we have to make about 141 iterations but when we have x=0.5
|
||||||
|
then during calculating ATan0( (x-1)/(1+x) ) we have to make
|
||||||
|
only about 89 iterations (both for Big<3,9>)
|
||||||
|
|
||||||
|
in the future this 0.5 can be changed
|
||||||
|
*/
|
||||||
|
if( x.SmallerWithoutSignThan(half) )
|
||||||
|
return ATan0(x);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
x>=0.5 and x<=1
|
||||||
|
(x can be even smaller than 0.5)
|
||||||
|
|
||||||
|
y = atac(x)
|
||||||
|
x = tan(y)
|
||||||
|
|
||||||
|
tan(y-b) = (tan(y)-tab(b)) / (1+tan(y)*tan(b))
|
||||||
|
y-b = atan( (tan(y)-tab(b)) / (1+tan(y)*tan(b)) )
|
||||||
|
y = b + atan( (x-tab(b)) / (1+x*tan(b)) )
|
||||||
|
|
||||||
|
let b = pi/4
|
||||||
|
tan(b) = tan(pi/4) = 1
|
||||||
|
y = pi/4 + atan( (x-1)/(1+x) )
|
||||||
|
|
||||||
|
so
|
||||||
|
atac(x) = pi/4 + atan( (x-1)/(1+x) )
|
||||||
|
when x->1 (x converges to 1) the (x-1)/(1+x) -> 0
|
||||||
|
and we can use ATan0() function here
|
||||||
|
*/
|
||||||
|
|
||||||
|
ValueType n(x),d(x),one,result;
|
||||||
|
|
||||||
|
one.SetOne();
|
||||||
|
n.Sub(one);
|
||||||
|
d.Add(one);
|
||||||
|
n.Div(d);
|
||||||
|
|
||||||
|
result = ATan0(n);
|
||||||
|
|
||||||
|
n.Set05Pi();
|
||||||
|
n.exponent.SubOne(); // =pi/4
|
||||||
|
result.Add(n);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
arc tan (x) where x > 1
|
||||||
|
|
||||||
|
we're using the formula:
|
||||||
|
atan(x) = pi/2 - atan(1/x) for x>0
|
||||||
|
*/
|
||||||
|
template<class ValueType>
|
||||||
|
ValueType ATanGreaterThanPlusOne(const ValueType & x)
|
||||||
|
{
|
||||||
|
ValueType temp, atan;
|
||||||
|
|
||||||
|
temp.SetOne();
|
||||||
|
|
||||||
|
if( temp.Div(x) )
|
||||||
|
{
|
||||||
|
// if there was a carry here that means x is very big
|
||||||
|
// and atan(1/x) fast converged to 0
|
||||||
|
atan.SetZero();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
atan = ATan01(temp);
|
||||||
|
|
||||||
|
temp.Set05Pi();
|
||||||
|
temp.Sub(atan);
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace auxiliaryfunctions
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
arc tan
|
||||||
|
*/
|
||||||
|
template<class ValueType>
|
||||||
|
ValueType ATan(ValueType x)
|
||||||
|
{
|
||||||
|
using namespace auxiliaryfunctions;
|
||||||
|
|
||||||
|
ValueType one, result;
|
||||||
|
one.SetOne();
|
||||||
|
bool change_sign = false;
|
||||||
|
|
||||||
|
// if x is negative we're using the formula:
|
||||||
|
// atan(-x) = -atan(x)
|
||||||
|
if( x.IsSign() )
|
||||||
|
{
|
||||||
|
change_sign = true;
|
||||||
|
x.Abs();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( x.GreaterWithoutSignThan(one) )
|
||||||
|
result = ATanGreaterThanPlusOne(x);
|
||||||
|
else
|
||||||
|
result = ATan01(x);
|
||||||
|
|
||||||
|
if( change_sign )
|
||||||
|
result.ChangeSign();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
arc ctan
|
||||||
|
|
||||||
|
we're using the formula:
|
||||||
|
actan(x) = pi/2 - atan(x)
|
||||||
|
*/
|
||||||
|
template<class ValueType>
|
||||||
|
ValueType ACTan(const ValueType & x)
|
||||||
|
{
|
||||||
|
ValueType result;
|
||||||
|
|
||||||
|
result.Set05Pi();
|
||||||
|
result.Sub(ATan(x));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
|
|
||||||
#include "ttmathint.h"
|
#include "ttmathint.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -59,8 +61,8 @@ class Big
|
||||||
/*
|
/*
|
||||||
value = mantissa * 2^exponent
|
value = mantissa * 2^exponent
|
||||||
|
|
||||||
exponent - integer value with a sign
|
exponent - an integer value with a sign
|
||||||
mantissa - integer value without a sing
|
mantissa - an integer value without a sing
|
||||||
|
|
||||||
mantissa must be pushed into the left side that is the highest bit from
|
mantissa must be pushed into the left side that is the highest bit from
|
||||||
mantissa must be one (of course if there's another value than zero) -- this job
|
mantissa must be one (of course if there's another value than zero) -- this job
|
||||||
|
@ -205,7 +207,7 @@ public:
|
||||||
// we must define this table as 'unsigned int' because
|
// we must define this table as 'unsigned int' because
|
||||||
// on 32bits and 64bits platforms this table is 32bits
|
// on 32bits and 64bits platforms this table is 32bits
|
||||||
|
|
||||||
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(uint));
|
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
|
||||||
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
|
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
|
||||||
info = 0;
|
info = 0;
|
||||||
}
|
}
|
||||||
|
@ -250,7 +252,7 @@ public:
|
||||||
0xb4130c93, 0xbc437944, 0xf4fd4452, 0xe2d74dd3, 0x645b2194, 0x41468794
|
0xb4130c93, 0xbc437944, 0xf4fd4452, 0xe2d74dd3, 0x645b2194, 0x41468794
|
||||||
};
|
};
|
||||||
|
|
||||||
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(uint));
|
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
|
||||||
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
|
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
|
||||||
info = 0;
|
info = 0;
|
||||||
}
|
}
|
||||||
|
@ -275,7 +277,7 @@ public:
|
||||||
0x44a02554, 0x731cdc8e, 0xa17293d1, 0x228a4ef8, 0x6e1adf84, 0x08689fa8
|
0x44a02554, 0x731cdc8e, 0xa17293d1, 0x228a4ef8, 0x6e1adf84, 0x08689fa8
|
||||||
};
|
};
|
||||||
|
|
||||||
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(uint));
|
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
|
||||||
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT);
|
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT);
|
||||||
info = 0;
|
info = 0;
|
||||||
}
|
}
|
||||||
|
@ -301,10 +303,10 @@ public:
|
||||||
void SetMin()
|
void SetMin()
|
||||||
{
|
{
|
||||||
info = 0;
|
info = 0;
|
||||||
SetSign();
|
|
||||||
|
|
||||||
mantissa.SetMaxValue();
|
mantissa.SetMaxValue();
|
||||||
exponent.SetMaxValue();
|
exponent.SetMaxValue();
|
||||||
|
SetSign();
|
||||||
|
|
||||||
// we don't have to use 'Standardizing()' because the last bit from
|
// we don't have to use 'Standardizing()' because the last bit from
|
||||||
// the mantissa is set
|
// the mantissa is set
|
||||||
|
@ -334,7 +336,7 @@ public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
it clears the sign
|
it clears the sign
|
||||||
(there'll be a absolute value)
|
(there'll be an absolute value)
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
-1 -> 1
|
-1 -> 1
|
||||||
|
@ -397,6 +399,7 @@ public:
|
||||||
{
|
{
|
||||||
Int<exp> exp_offset( exponent );
|
Int<exp> exp_offset( exponent );
|
||||||
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
|
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
|
||||||
|
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
exp_offset.Sub( ss2.exponent );
|
exp_offset.Sub( ss2.exponent );
|
||||||
|
@ -410,7 +413,8 @@ public:
|
||||||
ss2 = *this;
|
ss2 = *this;
|
||||||
*this = temp;
|
*this = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if( exp_offset > mantissa_size_in_bits )
|
if( exp_offset > mantissa_size_in_bits )
|
||||||
{
|
{
|
||||||
// the second value is too short for taking into consideration in the sum
|
// the second value is too short for taking into consideration in the sum
|
||||||
|
@ -729,29 +733,9 @@ public:
|
||||||
1 - carry
|
1 - carry
|
||||||
2 - incorrect argument ('this' or 'pow')
|
2 - incorrect argument ('this' or 'pow')
|
||||||
*/
|
*/
|
||||||
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
uint Pow(const Big<exp, man> & pow)
|
||||||
there should be 'sint Pow(const Big<exp, man> & pow)'
|
|
||||||
but vc2005express doesn't want to compile it perfect, that means
|
|
||||||
when using 'Maximize Speed /O2' the result of compilation doesn't work property
|
|
||||||
for example 10^(1/2) is a big value
|
|
||||||
i don't know where is the problem, with this source code or in the compilator
|
|
||||||
(it is when we're using 'Big<3,10>' or bigger values in parsing)
|
|
||||||
/gcc 3.4.2 works perfect (with -O3 optimalization flag)/
|
|
||||||
|
|
||||||
(we also can change 'Div' instead modifying this 'Pow' -- it'll be the same effect,
|
|
||||||
this error is only when we're using our mathematic parser)
|
|
||||||
|
|
||||||
gcc 3.4.6 (FreeBSD) with -O3 doesn't work perfect as well -- there must be
|
|
||||||
without the reference
|
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
|
|
||||||
|
|
||||||
//#ifdef __GNUC__
|
|
||||||
// uint Pow(const Big<exp, man> & pow)
|
|
||||||
//#else
|
|
||||||
uint Pow(Big<exp, man> pow)
|
|
||||||
//#endif
|
|
||||||
{
|
{
|
||||||
// TTMATH_REFERENCE_ASSERT( pow )
|
TTMATH_REFERENCE_ASSERT( pow )
|
||||||
|
|
||||||
if( IsZero() )
|
if( IsZero() )
|
||||||
{
|
{
|
||||||
|
@ -767,6 +751,7 @@ public:
|
||||||
Big<exp, man> pow_frac( pow );
|
Big<exp, man> pow_frac( pow );
|
||||||
pow_frac.RemainFraction();
|
pow_frac.RemainFraction();
|
||||||
|
|
||||||
|
|
||||||
if( pow_frac.IsZero() )
|
if( pow_frac.IsZero() )
|
||||||
return PowBInt( pow );
|
return PowBInt( pow );
|
||||||
|
|
||||||
|
@ -781,7 +766,7 @@ public:
|
||||||
uint c = temp.Ln(*this);
|
uint c = temp.Ln(*this);
|
||||||
c += temp.Mul(pow);
|
c += temp.Mul(pow);
|
||||||
c += Exp(temp);
|
c += Exp(temp);
|
||||||
|
|
||||||
return (c==0)? 0 : 1;
|
return (c==0)? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1038,6 +1023,7 @@ public:
|
||||||
// m will be the value of the mantissa in range <1,2)
|
// m will be the value of the mantissa in range <1,2)
|
||||||
Big<exp,man> m(x);
|
Big<exp,man> m(x);
|
||||||
m.exponent = -sint(man*TTMATH_BITS_PER_UINT - 1);
|
m.exponent = -sint(man*TTMATH_BITS_PER_UINT - 1);
|
||||||
|
|
||||||
LnSurrounding1(m);
|
LnSurrounding1(m);
|
||||||
|
|
||||||
Big<exp,man> exponent_temp;
|
Big<exp,man> exponent_temp;
|
||||||
|
@ -1048,7 +1034,6 @@ public:
|
||||||
|
|
||||||
Big<exp,man> ln2;
|
Big<exp,man> ln2;
|
||||||
ln2.SetLn2();
|
ln2.SetLn2();
|
||||||
|
|
||||||
c += exponent_temp.Mul(ln2);
|
c += exponent_temp.Mul(ln2);
|
||||||
c += Add(exponent_temp);
|
c += Add(exponent_temp);
|
||||||
|
|
||||||
|
@ -1282,6 +1267,7 @@ public:
|
||||||
FromInt( sint(value) );
|
FromInt( sint(value) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined _M_X64 || defined __x86_64__
|
#if defined _M_X64 || defined __x86_64__
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting 'int' to this class
|
a constructor for converting 'int' to this class
|
||||||
|
@ -1301,17 +1287,18 @@ public:
|
||||||
void FromInt(Int<int_size> value)
|
void FromInt(Int<int_size> value)
|
||||||
{
|
{
|
||||||
info = 0;
|
info = 0;
|
||||||
|
bool is_sign = false;
|
||||||
|
|
||||||
if( value.IsSign() )
|
if( value.IsSign() )
|
||||||
{
|
{
|
||||||
value.ChangeSign();
|
value.ChangeSign();
|
||||||
SetSign();
|
is_sign = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint minimum_size = (int_size < man)? int_size : man;
|
uint minimum_size = (int_size < man)? int_size : man;
|
||||||
sint compensation = (sint)value.CompensationToLeft();
|
sint compensation = (sint)value.CompensationToLeft();
|
||||||
exponent = (sint(int_size)-sint(man)) * sint(TTMATH_BITS_PER_UINT) - compensation;
|
exponent = (sint(int_size)-sint(man)) * sint(TTMATH_BITS_PER_UINT) - compensation;
|
||||||
|
|
||||||
// copying the highest words
|
// copying the highest words
|
||||||
uint i;
|
uint i;
|
||||||
for(i=1 ; i<=minimum_size ; ++i)
|
for(i=1 ; i<=minimum_size ; ++i)
|
||||||
|
@ -1321,6 +1308,9 @@ public:
|
||||||
for( ; i<=man ; ++i)
|
for( ; i<=man ; ++i)
|
||||||
mantissa.table[man-i] = 0;
|
mantissa.table[man-i] = 0;
|
||||||
|
|
||||||
|
if( is_sign )
|
||||||
|
SetSign();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1367,6 +1357,7 @@ public:
|
||||||
/*!
|
/*!
|
||||||
the default assignment operator
|
the default assignment operator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Big<exp,man> & operator=(const Big<exp,man> & value)
|
Big<exp,man> & operator=(const Big<exp,man> & value)
|
||||||
{
|
{
|
||||||
info = value.info;
|
info = value.info;
|
||||||
|
@ -1375,26 +1366,27 @@ public:
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a constructor for copying from another object of this class
|
a constructor for copying from another object of this class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Big(const Big<exp,man> & value)
|
Big(const Big<exp,man> & value)
|
||||||
{
|
{
|
||||||
operator=(value);
|
operator=(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a method for converting the value into the string with a base equal 'base'
|
a method for converting the value into the string with a base equal 'base'
|
||||||
|
|
||||||
input:
|
input:
|
||||||
base - the base on which the value will be showed
|
base - the base on which the value will be shown
|
||||||
|
|
||||||
if 'always_scientific' is true the result will be showed in 'scientific' mode
|
if 'always_scientific' is true the result will be shown in 'scientific' mode
|
||||||
|
|
||||||
if 'always_scientific' is false the result will be showed
|
if 'always_scientific' is false the result will be shown
|
||||||
either as 'scientific' or 'normal' mode, it depends whether the abs(exponent)
|
either as 'scientific' or 'normal' mode, it depends whether the abs(exponent)
|
||||||
is greater than 'when_scientific' or not, if it's greater the value
|
is greater than 'when_scientific' or not, if it's greater the value
|
||||||
will be printed as 'scientific'
|
will be printed as 'scientific'
|
||||||
|
@ -1407,8 +1399,8 @@ public:
|
||||||
(zero characters at the end -- after the comma operator)
|
(zero characters at the end -- after the comma operator)
|
||||||
|
|
||||||
if 'max_digit_after_comma' is equal or greater than zero
|
if 'max_digit_after_comma' is equal or greater than zero
|
||||||
that only 'max_digit_after_comma' after the comma operator will be showed
|
that only 'max_digit_after_comma' after the comma operator will be shown
|
||||||
(if 'max_digit_after_comma' is equal zero there'll be showed only
|
(if 'max_digit_after_comma' is equal zero there'll be shown only
|
||||||
integer value without the comma)
|
integer value without the comma)
|
||||||
for example when the value is:
|
for example when the value is:
|
||||||
12.345678 and max_digit_after_comma is 4
|
12.345678 and max_digit_after_comma is 4
|
||||||
|
@ -1431,7 +1423,7 @@ public:
|
||||||
{
|
{
|
||||||
static char error_overflow_msg[] = "overflow";
|
static char error_overflow_msg[] = "overflow";
|
||||||
result.erase();
|
result.erase();
|
||||||
|
|
||||||
if(base<2 || base>16)
|
if(base<2 || base>16)
|
||||||
{
|
{
|
||||||
result = error_overflow_msg;
|
result = error_overflow_msg;
|
||||||
|
@ -1612,19 +1604,17 @@ private:
|
||||||
// the sign don't interest us here
|
// the sign don't interest us here
|
||||||
temp.mantissa = mantissa;
|
temp.mantissa = mantissa;
|
||||||
temp.exponent = exponent;
|
temp.exponent = exponent;
|
||||||
|
|
||||||
c += temp.Div( base_ );
|
c += temp.Div( base_ );
|
||||||
|
|
||||||
// moving all bits of the mantissa into the right
|
// moving all bits of the mantissa into the right
|
||||||
// (how many times to move depend on the exponent)
|
// (how many times to move depend on the exponent)
|
||||||
c += temp.ToString_MoveMantissaIntoRight();
|
c += temp.ToString_MoveMantissaIntoRight();
|
||||||
|
|
||||||
// on account of we take 'new_exp' as small as it's
|
// because we took 'new_exp' as small as it was
|
||||||
// possible ([log base (2^exponent)] + 1) that after the division
|
// possible ([log base (2^exponent)] + 1) that after the division
|
||||||
// (temp.Div( base_ )) the value of exponent should be equal zero or
|
// (temp.Div( base_ )) the value of exponent should be equal zero or
|
||||||
// minimum smaller than zero then we've got the mantissa which has
|
// minimum smaller than zero then we've got the mantissa which has
|
||||||
// maximum valid bits
|
// maximum valid bits
|
||||||
|
|
||||||
temp.mantissa.ToString(new_man, base);
|
temp.mantissa.ToString(new_man, base);
|
||||||
|
|
||||||
// because we had used a bigger type for calculating I think we
|
// because we had used a bigger type for calculating I think we
|
||||||
|
@ -1651,6 +1641,7 @@ private:
|
||||||
uint ToString_Log(const Big<exp,man> & x, uint base)
|
uint ToString_Log(const Big<exp,man> & x, uint base)
|
||||||
{
|
{
|
||||||
TTMATH_REFERENCE_ASSERT( x )
|
TTMATH_REFERENCE_ASSERT( x )
|
||||||
|
TTMATH_ASSERT( base>=2 && base<=16 )
|
||||||
|
|
||||||
Big<exp,man> temp;
|
Big<exp,man> temp;
|
||||||
temp.SetOne();
|
temp.SetOne();
|
||||||
|
@ -1669,41 +1660,29 @@ private:
|
||||||
// (LnSurrounding1() will return one immediately)
|
// (LnSurrounding1() will return one immediately)
|
||||||
uint c = Ln(x);
|
uint c = Ln(x);
|
||||||
|
|
||||||
|
static Big<exp,man> log_history[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||||
|
uint index = base - 2;
|
||||||
|
|
||||||
|
if( log_history[index].IsZero() )
|
||||||
|
{
|
||||||
|
// we don't have 'base' in 'log_history' then we calculate it now
|
||||||
|
Big<exp,man> base_(base);
|
||||||
|
c += temp.Ln(base_);
|
||||||
|
c += Div(temp);
|
||||||
|
|
||||||
|
// the next time we'll get the 'Ln(base)' from the history,
|
||||||
|
// this 'log_history' can have (16-2+1) items max
|
||||||
|
log_history[index] = temp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we've calculated the 'Ln(base)' beforehand and we're getting it now
|
||||||
|
c += Div( log_history[index] );
|
||||||
|
}
|
||||||
|
|
||||||
|
return (c==0)? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* this is only temporarily (for testing)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// static Big<exp,man> log_history[15] = { 0l,0l,0l,0l,0l,0l,0l,0l,0l,0l,
|
|
||||||
// 0l,0l,0l,0l,0l };
|
|
||||||
static Big<exp,man> log_history[15] = { 0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0 };
|
|
||||||
|
|
||||||
Big<exp,man> * log_value = log_history + base - 2;
|
|
||||||
|
|
||||||
if( log_value->IsZero() )
|
|
||||||
{
|
|
||||||
// we don't have 'base' in 'log_history' then we calculate it now
|
|
||||||
Big<exp,man> base_(base);
|
|
||||||
c += temp.Ln(base_);
|
|
||||||
c += Div(temp);
|
|
||||||
|
|
||||||
// the next time we'll get the 'Ln(base)' from the history,
|
|
||||||
// this 'log_history' can have (16-2+1) items max
|
|
||||||
|
|
||||||
*log_value = temp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// we've calculated the 'Ln(base)' beforehand and we're using it now
|
|
||||||
|
|
||||||
c += Div( *log_value );
|
|
||||||
}
|
|
||||||
|
|
||||||
return (c==0)? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -1722,6 +1701,7 @@ private:
|
||||||
if( !exponent.IsSign() )
|
if( !exponent.IsSign() )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
||||||
if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
|
if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
|
||||||
// if 'exponent' is <= than '-sint(man*TTMATH_BITS_PER_UINT)'
|
// if 'exponent' is <= than '-sint(man*TTMATH_BITS_PER_UINT)'
|
||||||
// it means that we must cut the whole mantissa
|
// it means that we must cut the whole mantissa
|
||||||
|
@ -2613,7 +2593,7 @@ public:
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
Big<exp,man> & operator-=(const Big<exp,man> & ss2) const
|
Big<exp,man> & operator-=(const Big<exp,man> & ss2)
|
||||||
{
|
{
|
||||||
Sub(ss2);
|
Sub(ss2);
|
||||||
|
|
||||||
|
@ -2631,7 +2611,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Big<exp,man> & operator+=(const Big<exp,man> & ss2) const
|
Big<exp,man> & operator+=(const Big<exp,man> & ss2)
|
||||||
{
|
{
|
||||||
Add(ss2);
|
Add(ss2);
|
||||||
|
|
||||||
|
@ -2649,7 +2629,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Big<exp,man> & operator*=(const Big<exp,man> & ss2) const
|
Big<exp,man> & operator*=(const Big<exp,man> & ss2)
|
||||||
{
|
{
|
||||||
Mul(ss2);
|
Mul(ss2);
|
||||||
|
|
||||||
|
@ -2667,7 +2647,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Big<exp,man> & operator/=(const Big<exp,man> & ss2) const
|
Big<exp,man> & operator/=(const Big<exp,man> & ss2)
|
||||||
{
|
{
|
||||||
Div(ss2);
|
Div(ss2);
|
||||||
|
|
||||||
|
|
|
@ -493,8 +493,11 @@ public:
|
||||||
UInt<value_size>::table[i] = p.table[i];
|
UInt<value_size>::table[i] = p.table[i];
|
||||||
|
|
||||||
|
|
||||||
if( i < value_size )
|
// if( i < value_size )
|
||||||
|
|
||||||
|
if( value_size > argument_size )
|
||||||
{
|
{
|
||||||
|
// 'this' is longer than 'p'
|
||||||
uint fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)? TTMATH_UINT_MAX_VALUE : 0;
|
uint fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)? TTMATH_UINT_MAX_VALUE : 0;
|
||||||
|
|
||||||
for( ; i<value_size ; ++i)
|
for( ; i<value_size ; ++i)
|
||||||
|
@ -514,7 +517,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this operator convert an UInt<another_size> type to this class
|
this operator converts an UInt<another_size> type to this class
|
||||||
|
|
||||||
it doesn't return a carry
|
it doesn't return a carry
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -730,6 +730,24 @@ void ACos(int sindex, int amount_of_args, ValueType & result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ATan(int sindex, int amount_of_args, ValueType & result)
|
||||||
|
{
|
||||||
|
if( amount_of_args != 1 )
|
||||||
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
|
result = ttmath::ATan(stack[sindex].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ACTan(int sindex, int amount_of_args, ValueType & result)
|
||||||
|
{
|
||||||
|
if( amount_of_args != 1 )
|
||||||
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
|
result = ttmath::ACTan(stack[sindex].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns the value from a user-defined function
|
this method returns the value from a user-defined function
|
||||||
|
|
||||||
|
@ -854,6 +872,8 @@ void CreateFunctionsTable()
|
||||||
InsertFunctionToTable(std::string("min"), &Parser<ValueType>::Min);
|
InsertFunctionToTable(std::string("min"), &Parser<ValueType>::Min);
|
||||||
InsertFunctionToTable(std::string("asin"), &Parser<ValueType>::ASin);
|
InsertFunctionToTable(std::string("asin"), &Parser<ValueType>::ASin);
|
||||||
InsertFunctionToTable(std::string("acos"), &Parser<ValueType>::ACos);
|
InsertFunctionToTable(std::string("acos"), &Parser<ValueType>::ACos);
|
||||||
|
InsertFunctionToTable(std::string("atan"), &Parser<ValueType>::ATan);
|
||||||
|
InsertFunctionToTable(std::string("actan"), &Parser<ValueType>::ACTan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@
|
||||||
*/
|
*/
|
||||||
#define TTMATH_MAJOR_VER 0
|
#define TTMATH_MAJOR_VER 0
|
||||||
#define TTMATH_MINOR_VER 7
|
#define TTMATH_MINOR_VER 7
|
||||||
#define TTMATH_REVISION_VER 0
|
#define TTMATH_REVISION_VER 1
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -2519,7 +2519,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this operator convert an UInt<another_size> type to this class
|
this operator converts an UInt<another_size> type to this class
|
||||||
|
|
||||||
it doesn't return a carry
|
it doesn't return a carry
|
||||||
*/
|
*/
|
||||||
|
@ -2589,7 +2589,6 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a copy constructor
|
a copy constructor
|
||||||
*/
|
*/
|
||||||
|
@ -2599,6 +2598,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a template for producting constructors for copying from another types
|
a template for producting constructors for copying from another types
|
||||||
*/
|
*/
|
||||||
|
@ -2610,6 +2610,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a destructor
|
a destructor
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -109,7 +109,7 @@ namespace ttmath
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleaning the rest of the mantissa
|
// cleaning the rest of the mantissa
|
||||||
for( ; i>=0 ; --i)
|
for( ; i >= 0 ; --i)
|
||||||
table[i] = 0;
|
table[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue