40 #ifndef headerfilettmathmathtt 41 #define headerfilettmathmathtt 50 #pragma warning( disable: 4127 ) 52 #pragma warning( disable: 4702 ) 54 #pragma warning( disable: 4800 ) 89 template<
class ValueType>
92 ValueType result( x );
93 result.SkipFraction();
108 template<
class ValueType>
114 *err = err_improper_argument;
119 ValueType result( x );
120 uint c = result.Round();
123 *err = c ? err_overflow : err_ok;
141 template<
class ValueType>
147 *err = err_improper_argument;
155 result.SkipFraction();
166 c += result.Add(one);
171 *err = c ? err_overflow : err_ok;
188 template<
class ValueType>
194 *err = err_improper_argument;
202 result.SkipFraction();
213 c += result.Sub(one);
218 *err = c ? err_overflow : err_ok;
236 template<
class ValueType>
242 *err = err_improper_argument;
248 uint state = result.Ln(x);
261 *err = err_improper_argument;
264 *err = err_internal_error;
277 template<
class ValueType>
278 ValueType
Log(
const ValueType & x,
const ValueType & base,
ErrorCode * err = 0)
282 if( err ) *err = err_improper_argument;
288 if( err ) *err = err_improper_argument;
293 uint state = result.Log(x, base);
307 *err = err_improper_argument;
310 *err = err_internal_error;
322 template<
class ValueType>
328 *err = err_improper_argument;
334 uint c = result.Exp(x);
337 *err = c ? err_overflow : err_ok;
357 namespace auxiliaryfunctions
364 template<
class ValueType>
365 uint PrepareSin(ValueType & x,
bool & change_sign)
374 change_sign = !change_sign;
394 change_sign = !change_sign;
429 template<
class ValueType>
430 ValueType Sin0pi05(
const ValueType & x)
433 ValueType numerator, denominator;
434 ValueType d_numerator, d_denominator;
435 ValueType one, temp, old_result;
439 temp.exponent.SubOne();
470 d_numerator.Mul( temp );
476 bool addition =
false;
482 c += numerator. Mul( d_numerator );
483 c += denominator. Mul( d_denominator );
484 c += d_denominator.Add( one );
485 c += denominator. Mul( d_denominator );
486 c += d_denominator.Add( one );
488 c += temp.Div(denominator);
502 addition = !addition;
508 if( result == old_result )
524 template<
class ValueType>
527 using namespace auxiliaryfunctions;
529 ValueType one, result;
535 *err = err_improper_argument;
543 if( PrepareSin( x, change_sign ) )
556 result = Sin0pi05( x );
564 if( result.IsSign() )
580 template<
class ValueType>
586 *err = err_improper_argument;
594 uint c = x.Add( pi05 );
618 template<
class ValueType>
621 ValueType result =
Cos(x, err);
623 if( err && *err != err_ok )
626 if( result.IsZero() )
629 *err = err_improper_argument;
636 return Sin(x, err) / result;
646 template<
class ValueType>
660 template<
class ValueType>
663 ValueType result =
Sin(x, err);
665 if( err && *err != err_ok )
668 if( result.IsZero() )
671 *err = err_improper_argument;
678 return Cos(x, err) / result;
688 template<
class ValueType>
702 namespace auxiliaryfunctions
714 template<
class ValueType>
715 ValueType ASin_0(
const ValueType & x)
717 ValueType nominator, denominator, nominator_add, nominator_x, denominator_add, denominator_x;
718 ValueType two, result(x), x2(x);
719 ValueType nominator_temp, denominator_temp, old_result = result;
727 nominator_add = nominator;
728 denominator_add = denominator;
734 c += nominator_x.Mul(x2);
735 nominator_temp = nominator_x;
736 c += nominator_temp.Mul(nominator);
737 denominator_temp = denominator;
738 c += denominator_temp.Mul(denominator_x);
739 c += nominator_temp.Div(denominator_temp);
746 result.Add(nominator_temp);
748 if( result == old_result )
755 c += nominator_add.Add(two);
756 c += denominator_add.Add(two);
757 c += nominator.Mul(nominator_add);
758 c += denominator.Mul(denominator_add);
759 c += denominator_x.Add(two);
778 template<
class ValueType>
779 ValueType ASin_1(
const ValueType & x)
781 ValueType nominator, denominator, nominator_add, nominator_x, nominator_x_add, denominator_add, denominator_x;
782 ValueType denominator2;
783 ValueType one, two, result;
784 ValueType nominator_temp, denominator_temp, old_result;
794 nominator_add = nominator;
795 denominator_add = denominator;
798 nominator_x_add = nominator_x;
805 nominator_temp = nominator_x;
806 c += nominator_temp.Mul(nominator);
807 denominator_temp = denominator;
808 c += denominator_temp.Mul(denominator_x);
809 c += denominator_temp.Mul(denominator2);
810 c += nominator_temp.Div(denominator_temp);
817 result.Add(nominator_temp);
819 if( result == old_result )
825 c += nominator_x.Mul(nominator_x_add);
826 c += nominator_add.Add(two);
827 c += denominator_add.Add(two);
828 c += nominator.Mul(nominator_add);
829 c += denominator.Mul(denominator_add);
830 c += denominator_x.Add(two);
831 c += denominator2.Mul(two);
835 nominator_x_add.exponent.AddOne();
836 one.exponent.SubOne();
837 nominator_x_add.Pow(one);
838 result.Mul(nominator_x_add);
854 template<
class ValueType>
857 using namespace auxiliaryfunctions;
859 ValueType result, one;
861 bool change_sign =
false;
866 *err = err_improper_argument;
871 if( x.GreaterWithoutSignThan(one) )
874 *err = err_improper_argument;
885 one.exponent.SubOne();
888 if( x.GreaterWithoutSignThan(one) )
909 template<
class ValueType>
915 temp.Sub(
ASin(x, err));
922 namespace auxiliaryfunctions
934 template<
class ValueType>
935 ValueType ATan0(
const ValueType & x)
937 ValueType nominator, denominator, nominator_add, denominator_add, temp;
938 ValueType result, old_result;
946 nominator_add.Mul(x);
948 denominator.SetOne();
953 c += nominator.Mul(nominator_add);
954 c += denominator.Add(denominator_add);
957 c += temp.Div(denominator);
968 if( result == old_result )
985 template<
class ValueType>
986 ValueType ATan01(
const ValueType & x)
1007 if( x.SmallerWithoutSignThan(half) )
1032 ValueType n(x),d(x),one,result;
1042 n.exponent.SubOne();
1056 template<
class ValueType>
1057 ValueType ATanGreaterThanPlusOne(
const ValueType & x)
1059 ValueType temp, atan;
1070 atan = ATan01(temp);
1084 template<
class ValueType>
1087 using namespace auxiliaryfunctions;
1089 ValueType one, result;
1091 bool change_sign =
false;
1104 if( x.GreaterWithoutSignThan(one) )
1105 result = ATanGreaterThanPlusOne(x);
1110 result.ChangeSign();
1122 template<
class ValueType>
1123 ValueType
ATg(
const ValueType & x)
1135 template<
class ValueType>
1136 ValueType
ACot(
const ValueType & x)
1141 result.Sub(
ATan(x));
1153 template<
class ValueType>
1154 ValueType
ACtg(
const ValueType & x)
1173 template<
class ValueType>
1179 *err = err_improper_argument;
1191 c += ex.exponent.SubOne();
1194 *err = c ? err_overflow : err_ok;
1205 template<
class ValueType>
1211 *err = err_improper_argument;
1223 c += ex.exponent.SubOne();
1226 *err = c ? err_overflow : err_ok;
1237 template<
class ValueType>
1243 *err = err_improper_argument;
1248 ValueType ex, emx, nominator, denominator;
1255 c += nominator.Sub(emx);
1257 c += denominator.Add(emx);
1259 c += nominator.Div(denominator);
1262 *err = c ? err_overflow : err_ok;
1274 template<
class ValueType>
1277 return Tanh(x, err);
1285 template<
class ValueType>
1291 *err = err_improper_argument;
1299 *err = err_improper_argument;
1304 ValueType ex, emx, nominator, denominator;
1311 c += nominator.Add(emx);
1313 c += denominator.Sub(emx);
1315 c += nominator.Div(denominator);
1318 *err = c ? err_overflow : err_ok;
1330 template<
class ValueType>
1333 return Coth(x, err);
1350 template<
class ValueType>
1356 *err = err_improper_argument;
1361 ValueType xx(x), one, result;
1367 one.exponent.SubOne();
1369 c += xx.PowFrac(one);
1375 *err = c ? err_overflow : err_ok;
1386 template<
class ValueType>
1392 *err = err_improper_argument;
1397 ValueType xx(x), one, result;
1404 *err = err_improper_argument;
1416 one.exponent.SubOne();
1417 c += xx.PowFrac(one);
1424 *err = c ? err_overflow : err_ok;
1435 template<
class ValueType>
1441 *err = err_improper_argument;
1446 ValueType nominator(x), denominator, one, result;
1450 if( !x.SmallerWithoutSignThan(one) )
1453 *err = err_improper_argument;
1458 c += nominator.Add(one);
1460 c += denominator.Sub(x);
1461 c += nominator.Div(denominator);
1462 c += result.Ln(nominator);
1463 c += result.exponent.SubOne();
1467 *err = c ? err_overflow : err_ok;
1476 template<
class ValueType>
1479 return ATanh(x, err);
1488 template<
class ValueType>
1494 *err = err_improper_argument;
1499 ValueType nominator(x), denominator(x), one, result;
1503 if( !x.GreaterWithoutSignThan(one) )
1506 *err = err_improper_argument;
1511 c += nominator.Add(one);
1512 c += denominator.Sub(one);
1513 c += nominator.Div(denominator);
1514 c += result.Ln(nominator);
1515 c += result.exponent.SubOne();
1519 *err = c ? err_overflow : err_ok;
1528 template<
class ValueType>
1531 return ACoth(x, err);
1551 template<
class ValueType>
1554 ValueType result, temp;
1560 *err = err_improper_argument;
1570 c += result.Div(temp);
1573 c += result.Mul(temp);
1576 *err = c ? err_overflow : err_ok;
1587 template<
class ValueType>
1590 ValueType result, delimiter;
1596 *err = err_improper_argument;
1605 c += result.Div(delimiter);
1608 *err = c ? err_overflow : err_ok;
1632 template<
class ValueType>
1633 ValueType
DegToDeg(
const ValueType & d,
const ValueType & m,
const ValueType & s,
1636 ValueType delimiter, multipler;
1639 if( d.IsNan() || m.IsNan() || s.IsNan() || m.IsSign() || s.IsSign() )
1642 *err = err_improper_argument;
1644 delimiter.SetZeroNan();
1652 c += multipler.Mul(m);
1653 c += multipler.Add(s);
1654 c += multipler.Div(delimiter);
1657 multipler.ChangeSign();
1659 c += multipler.Add(d);
1662 *err = c ? err_overflow : err_ok;
1671 template<
class ValueType>
1672 ValueType
DegToRad(
const ValueType & d,
const ValueType & m,
const ValueType & s,
1675 ValueType temp_deg =
DegToDeg(d,m,s,err);
1677 if( err && *err!=err_ok )
1689 template<
class ValueType>
1692 ValueType result, temp;
1698 *err = err_improper_argument;
1708 c += result.Div(temp);
1711 c += result.Mul(temp);
1714 *err = c ? err_overflow : err_ok;
1725 template<
class ValueType>
1728 ValueType result, delimiter;
1734 *err = err_improper_argument;
1743 c += result.Div(delimiter);
1746 *err = c ? err_overflow : err_ok;
1757 template<
class ValueType>
1760 ValueType result, temp;
1766 *err = err_improper_argument;
1774 c += result.Mul(temp);
1777 c += result.Div(temp);
1780 *err = c ? err_overflow : err_ok;
1789 template<
class ValueType>
1790 ValueType
DegToGrad(
const ValueType & d,
const ValueType & m,
const ValueType & s,
1793 ValueType temp_deg =
DegToDeg(d,m,s,err);
1795 if( err && *err!=err_ok )
1807 template<
class ValueType>
1810 ValueType result, temp;
1816 *err = err_improper_argument;
1824 c += result.Mul(temp);
1827 c += result.Div(temp);
1830 *err = c ? err_overflow : err_ok;
1851 template<
class ValueType>
1854 if( x.IsNan() || x.IsSign() )
1857 *err = err_improper_argument;
1867 *err = c ? err_overflow : err_ok;
1874 namespace auxiliaryfunctions
1877 template<
class ValueType>
1878 bool RootCheckIndexSign(ValueType & x,
const ValueType & index,
ErrorCode * err)
1880 if( index.IsSign() )
1884 *err = err_improper_argument;
1895 template<
class ValueType>
1896 bool RootCheckIndexZero(ValueType & x,
const ValueType & index,
ErrorCode * err)
1898 if( index.IsZero() )
1904 *err = err_improper_argument;
1924 template<
class ValueType>
1925 bool RootCheckIndexOne(
const ValueType & index,
ErrorCode * err)
1945 template<
class ValueType>
1946 bool RootCheckIndexTwo(ValueType & x,
const ValueType & index,
ErrorCode * err)
1959 template<
class ValueType>
1960 bool RootCheckIndexFrac(ValueType & x,
const ValueType & index,
ErrorCode * err)
1962 if( !index.IsInteger() )
1966 *err = err_improper_argument;
1977 template<
class ValueType>
1978 bool RootCheckXZero(ValueType & x,
ErrorCode * err)
1996 template<
class ValueType>
1997 bool RootCheckIndex(ValueType & x,
const ValueType & index,
ErrorCode * err,
bool * change_sign)
1999 *change_sign =
false;
2006 *change_sign =
true;
2017 *err = err_improper_argument;
2029 template<
class ValueType>
2030 uint RootCorrectInteger(ValueType & old_x, ValueType & x,
const ValueType & index)
2032 if( !old_x.IsInteger() || x.IsInteger() || !index.exponent.IsSign() )
2045 ValueType temp_round(temp);
2046 c += temp.PowUInt(index);
2051 return (c==0)? 0 : 1;
2075 template<
class ValueType>
2078 using namespace auxiliaryfunctions;
2080 if( x.IsNan() || index.IsNan() )
2083 *err = err_improper_argument;
2090 if( RootCheckIndexSign(x, index, err) )
return x;
2091 if( RootCheckIndexZero(x, index, err) )
return x;
2092 if( RootCheckIndexOne ( index, err) )
return x;
2093 if( RootCheckIndexTwo (x, index, err) )
return x;
2094 if( RootCheckIndexFrac(x, index, err) )
return x;
2095 if( RootCheckXZero (x, err) )
return x;
2103 if( RootCheckIndex(x, index, err, &change_sign ) )
return x;
2110 c += temp.Div(index);
2119 c += RootCorrectInteger(old_x, x, index);
2122 *err = c ? err_overflow : err_ok;
2136 template<
class ValueType>
2137 ValueType
Abs(
const ValueType & x)
2139 ValueType result( x );
2154 template<
class ValueType>
2172 template<
class ValueType>
2175 if( a.IsNan() || b.IsNan() )
2178 *err = err_improper_argument;
2188 *err = c ? err_overflow : err_ok;
2195 namespace auxiliaryfunctions
2211 template<
class ValueType>
2212 void SetFactorialSequence(std::vector<ValueType> & fact,
uint more = 20)
2217 uint start =
static_cast<uint>(fact.size());
2218 fact.resize(fact.size() + more);
2226 for(
uint i=start ; i<fact.size() ; ++i)
2228 fact[i] = fact[i-1];
2246 template<
class ValueType>
2250 ValueType k_, temp, temp2, temp3, sum;
2254 for(
uint k=0 ; k<m ; ++k)
2256 if( stop && (k & 15)==0 )
2257 if( stop->WasStopSignal() )
2260 if( k>1 && (k & 1) == 1 )
2269 temp2 = cgamma.
fact[m];
2270 temp3 = cgamma.
fact[k];
2271 temp3.Mul(cgamma.
fact[m-k]);
2276 temp.Mul(cgamma.
bern[k]);
2298 template<
class ValueType>
2301 ValueType denominator, temp, temp2, temp3, m_, sum, sum2, n_, k_;
2307 for(
uint m=start ; m<cgamma.
bern.size() ; ++m)
2311 cgamma.
bern[m].SetZero();
2321 denominator.SetOne();
2322 denominator.Sub(temp);
2323 if( denominator.exponent.AddOne() )
2324 denominator.SetNan();
2328 cgamma.
bern[m] = SetBernoulliNumbersSum(cgamma, n_, m, stop);
2330 if( stop && stop->WasStopSignal() )
2332 cgamma.
bern.resize(m);
2336 cgamma.
bern[m].Div(denominator);
2359 template<
class ValueType>
2366 cgamma.
bern.resize(cgamma.
bern.size() + more);
2370 cgamma.
bern[0].SetOne();
2374 if( cgamma.
bern.size() == 1 )
2379 cgamma.
bern[1].Set05();
2380 cgamma.
bern[1].ChangeSign();
2385 if( cgamma.
fact.size() < cgamma.
bern.size() )
2386 SetFactorialSequence(cgamma.
fact, static_cast<uint>(cgamma.
bern.size() - cgamma.
fact.size()));
2389 return SetBernoulliNumbersMore(cgamma, start, stop);
2403 template<
class ValueType>
2407 ValueType temp, temp2, denominator, sum, oldsum;
2413 if( stop && (m & 3)==0 )
2414 if( stop->WasStopSignal() )
2416 err = err_interrupt;
2422 denominator.Pow(temp);
2431 denominator.Mul(temp);
2434 if( m >= cgamma.
bern.size() )
2436 if( !SetBernoulliNumbers(cgamma, m - cgamma.
bern.size() + 1 + 3, stop) )
2439 err = err_interrupt;
2444 temp = cgamma.
bern[m];
2445 temp.Div(denominator);
2450 if( sum.IsNan() || oldsum==sum )
2468 template<
class ValueType>
2472 ValueType temp, temp2, temp3, denominator, sum;
2485 sum = GammaFactorialHighSum(n, cgamma, err, stop);
2501 template<
class ValueType>
2509 return GammaFactorialHigh(n, cgamma, err, stop);
2521 template<
class ValueType>
2524 TTMATH_ASSERT( n > 0 )
2526 if( n - 1 < static_cast<uint>(cgamma.
fact.size()) )
2527 return cgamma.
fact[n - 1];
2532 if( cgamma.
fact.size() < 2 )
2538 start =
static_cast<uint>(cgamma.
fact.size());
2539 res = cgamma.
fact[start-1];
2542 for(
uint i=start ; i<n ; ++i)
2554 template<
class ValueType>
2561 return GammaPlusLowIntegerInt(n_, cgamma);
2577 template<
class ValueType>
2580 ValueType one, denominator, temp, boundary;
2583 return GammaPlusLowInteger(n, cgamma);
2589 while( n < boundary )
2598 temp = GammaPlusHigh(n, cgamma, err, stop);
2599 temp.Div(denominator);
2608 template<
class ValueType>
2612 return GammaPlusHigh(n, cgamma, err, stop);
2614 return GammaPlusLow(n, cgamma, err, stop);
2627 template<
class ValueType>
2630 ValueType pi, denominator, temp, temp2;
2635 err = err_improper_argument;
2648 temp = GammaPlus(temp, cgamma, err, stop);
2678 template<
class ValueType>
2682 using namespace auxiliaryfunctions;
2690 *err = err_improper_argument;
2695 if( cgamma.
history.Get(n, result, err_tmp) )
2707 result = GammaMinus(n, cgamma, err_tmp, stop);
2712 err_tmp = err_improper_argument;
2717 result = GammaPlus(n, cgamma, err_tmp, stop);
2720 if( result.IsNan() && err_tmp==err_ok )
2721 err_tmp = err_overflow;
2726 if( stop && !stop->WasStopSignal() )
2727 cgamma.
history.Add(n, result, err_tmp);
2738 template<
class ValueType>
2744 return Gamma(n, cgamma, err);
2749 namespace auxiliaryfunctions
2758 template<
class ValueType>
2759 ValueType Factorial2(ValueType x,
2764 ValueType result, one;
2766 if( x.IsNan() || x.IsSign() || !x.IsInteger() )
2769 *err = err_improper_argument;
2780 return Gamma(x, *cgamma, err, stop);
2782 return Gamma(x, err);
2808 template<
class ValueType>
2812 return auxiliaryfunctions::Factorial2(x, &cgamma, err, stop);
2823 template<
class ValueType>
2839 template<
class ValueType>
2846 while( history.Remove(x) )
2873 #pragma warning( default: 4127 ) 2875 #pragma warning( default: 4702 ) 2877 #pragma warning( default: 4800 ) ValueType Sgn(ValueType x)
ValueType ACot(const ValueType &x)
ValueType ACoth(const ValueType &x, ErrorCode *err=0)
ValueType Tan(const ValueType &x, ErrorCode *err=0)
ValueType Log(const ValueType &x, const ValueType &base, ErrorCode *err=0)
ValueType Sin(ValueType x, ErrorCode *err=0)
ValueType ATg(const ValueType &x)
#define TTMATH_ARITHMETIC_MAX_LOOP
ValueType Exp(const ValueType &x, ErrorCode *err=0)
ValueType ACosh(const ValueType &x, ErrorCode *err=0)
ValueType RadToDeg(const ValueType &x, ErrorCode *err=0)
ValueType ASin(ValueType x, ErrorCode *err=0)
std::vector< ValueType > bern
ValueType ASinh(const ValueType &x, ErrorCode *err=0)
ValueType SkipFraction(const ValueType &x)
ValueType Tg(const ValueType &x, ErrorCode *err=0)
ValueType Cos(ValueType x, ErrorCode *err=0)
ValueType ATanh(const ValueType &x, ErrorCode *err=0)
ValueType Ln(const ValueType &x, ErrorCode *err=0)
ValueType RadToGrad(const ValueType &x, ErrorCode *err=0)
ValueType Abs(const ValueType &x)
History< ValueType > history
ValueType ACtgh(const ValueType &x, ErrorCode *err=0)
ValueType GradToDeg(const ValueType &x, ErrorCode *err=0)
ValueType Tgh(const ValueType &x, ErrorCode *err=0)
a namespace for the TTMath library
ValueType Root(ValueType x, const ValueType &index, ErrorCode *err=0)
ValueType DegToRad(const ValueType &x, ErrorCode *err=0)
ValueType GradToRad(const ValueType &x, ErrorCode *err=0)
ValueType Mod(ValueType a, const ValueType &b, ErrorCode *err=0)
ValueType Ctg(const ValueType &x, ErrorCode *err=0)
ValueType ATan(ValueType x)
ValueType Coth(const ValueType &x, ErrorCode *err=0)
ValueType Factorial(const ValueType &x, CGamma< ValueType > &cgamma, ErrorCode *err=0, const volatile StopCalculating *stop=0)
ValueType Floor(const ValueType &x, ErrorCode *err=0)
ValueType Tanh(const ValueType &x, ErrorCode *err=0)
ValueType Sinh(const ValueType &x, ErrorCode *err=0)
ValueType Cot(const ValueType &x, ErrorCode *err=0)
ValueType DegToGrad(const ValueType &x, ErrorCode *err=0)
ValueType Gamma(const ValueType &n, CGamma< ValueType > &cgamma, ErrorCode *err=0, const volatile StopCalculating *stop=0)
std::vector< ValueType > fact
ValueType Cosh(const ValueType &x, ErrorCode *err=0)
#define TTMATH_GAMMA_BOUNDARY
ValueType Round(const ValueType &x, ErrorCode *err=0)
ValueType ACtg(const ValueType &x)
ValueType DegToDeg(const ValueType &d, const ValueType &m, const ValueType &s, ErrorCode *err=0)
ValueType ATgh(const ValueType &x, ErrorCode *err=0)
A Class for representing floating point numbers.
ValueType Ctgh(const ValueType &x, ErrorCode *err=0)
ValueType Ceil(const ValueType &x, ErrorCode *err=0)
ValueType Sqrt(ValueType x, ErrorCode *err=0)
ValueType ACos(const ValueType &x, ErrorCode *err=0)