added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),

RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
       Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
       change the names of user-defined variables or functions, and the names are 
       case-sensitive now
added: class History which is used in functions which take a lot of time
       during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x) 
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
       rewritten, now they have 128 32bit words (it's about 1232 valid
       decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
       not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
       platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
       this is for convenience for a programmer, he can only use #include
       with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
       it was using the method Big::FromInt(sint) which could produce wrong
       values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
       Big::Set05()
       (they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
       operators: Big::operator=(signed int) and Big::operator=(unsigned int)
       (these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
       (types in this library are not projected to be base-classes for
       another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
       Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
       Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
       UInt::operator=(signed int), UInt::UInt(signed int)
       (these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
       Int::operator=(unsigned int), Int::Int(unsigned int)
       (these operators and the constructors take a 32bit value)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2007-03-28 22:27:57 +00:00
parent abb8f292ab
commit 837490e8b9
16 changed files with 2126 additions and 576 deletions

View File

@ -1,9 +1,49 @@
Version 0.8.0 (2007.03.28):
* added: into the parser: SetFactorialMax()
* added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
* changed: class Objects in ttmathobjects.h has been completely rewritten,
we can change the names of user-defined variables or functions, and the
names are case-sensitive now
* added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
* added: Tg(x) a wrapper for Tan(x)
* changed: CTan(x) is Cot(x) now
* added: Ctg(x) a wrapper for Cot(x)
* added: ATg(x) a wrapper for ATan(x)
* changed: ACTan(x) is ACot(x) now
* added: ACtg(x) a wrapper for ACot(x)
* added: UInt::PrintTable() (for debugging etc.)
* changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have
been rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
* fixed: previous values from Big::SetPi() Big::SetE() and
Big::SetLn2() were not too much accurate (last 2-3 words were wrong)
* added: Big::SetLn10() (128 32bit words as well)
* added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on
32bit platforms and 64ul on 64bit platforms (128/2=64)
* added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
* changed: a small optimisation in UInt::Mul2Big()
* added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
* added: to samples: big.cpp, parser.cpp
* added/changes/fixed: in copy-constructors and operators= in Int,
Uint and Big (more info in the commit log)
* renamed Big::SetDotOne() into Big::Set05()
* changes: a few small optimisations in Big
* deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
* and more small changes (look at the commit log)
Version 0.7.2 (2007.03.09):
* added: Big::Mod - the remainder from a division
* added: Big::Sgn - the 'sign' from the value (-1,0,1)
* added: global functions Mod and Sgn too
* added: checking whether an user gives a correct value of a variable or function
(user-defined variables/functions in the mathematical parser)
* added: checking whether a user gives a correct value of a variable or function
(user-defined variables/functions in the mathematical parser)
* added: into the parser: logical operators: > < >= <= == != && ||
* added: into the parser: logical functions: and() or() not() if()
* added: ErrorCode::err_unknown_operator when the parser couldn't read an operator

22
README
View File

@ -1,2 +1,24 @@
TTMath - a bignum library for C++
TTMath is a small library which allows one to perform arithmetic operations
with big unsigned integer, big signed integer and big floating point
numbers. It provides standard mathematical operations like adding,
subtracting, multiplying, dividing etc. With the library also goes
a mathematical parser which helps you solving input formulas read directly
from a user.
TTMath is developed under the (new) BSD licence which means that it is free
for both personal and commercial use but the library has some technical
limitations: you can use it only on i386 and Amd64, another platforms are
not supported (Intel 64bit platforms were not tested but should work as
well), and you can use this library only with the C++ programming language.
The main goal of the library is to allow one to use big values in the same
way as the standard types like int, float, etc. It does not need to be
compiled first because the whole library is written as the C++ templates.
This means only C++ developers can use this library and one thing they have
to do is to use 'include' directive of the preprocessor. How big the
values can be is set directly in the source code by the programmer.
Author: Tomasz Sowa <t.sowa AnTispam slimaczek.pl>
Home page: http://sourceforge.net/projects/ttmath

8
TODO
View File

@ -1,7 +1,7 @@
TODO TTMath Library
===================
* to add operators (or functions) and, or, xor
* to add functions for generating random values
* to add constructors (UInt, Int) for 64bit platforms (constractors which take int and unsigned)
* to add 'history' for functions like 'factorial' which take a lot of time during calculating
* Add bitwise operators (or functions) and, or, xor
* Add functions for generating random values

View File

@ -8,7 +8,7 @@ CFLAGS = -Wall -pedantic -s -O2 -I..
$(CC) -c $(CFLAGS) $<
all: uint int
all: uint int big parser
uint: uint.o
@ -17,9 +17,17 @@ uint: uint.o
int: int.o
$(CC) -o int $(CFLAGS) int.o
big: big.o
$(CC) -o big $(CFLAGS) big.o
parser: parser.o
$(CC) -o parser $(CFLAGS) parser.o
uint.o: uint.cpp
int.o: int.cpp
big.o: big.cpp
parser.o: parser.cpp
clean:
@ -27,4 +35,7 @@ clean:
rm -f *.s
rm -f uint
rm -f int
rm -f big
rm -f parser
# on MS Windows can automatically be added suffixes .exe to the names of output programs
rm -f *.exe

97
samples/big.cpp Normal file
View File

@ -0,0 +1,97 @@
#include <ttmath/ttmath.h>
#include <iostream>
// for convenience we're defining MyBig type
// this type has 2 words for its mantissa and 1 word for its exponent
// (on a 32bit platform one word means a word of 32 bits,
// and on a 64bit platform one word means a word of 64 bits)
typedef ttmath::Big<1,2> MyBig;
void SimpleCalculating(const MyBig & a, const MyBig & b)
{
std::cout << "Simple calculating" << std::endl;
std::cout << "a = " << a << std::endl;
std::cout << "b = " << b << std::endl;
std::cout << "a + b = " << a+b << std::endl;
std::cout << "a - b = " << a-b << std::endl;
std::cout << "a * b = " << a*b << std::endl;
std::cout << "a / b = " << a/b << std::endl;
}
void CalculatingWithCarry(const MyBig & a, const MyBig & b)
{
MyBig atemp;
std::cout << "Calculating with a carry" << std::endl;
std::cout << "a = " << a << std::endl;
std::cout << "b = " << b << std::endl;
atemp = a;
if( !atemp.Add(b) )
std::cout << "a + b = " << atemp << std::endl;
else
std::cout << "a + b = (carry) " << atemp << std::endl;
atemp = a;
if( !atemp.Sub(b) )
std::cout << "a - b = " << atemp << std::endl;
else
std::cout << "a - b = (carry) " << atemp << std::endl;
atemp = a;
if( !atemp.Mul(b) )
std::cout << "a * b = " << atemp << std::endl;
else
std::cout << "a * b = (carry: the result is too big) " << std::endl;
// it have no sense to print 'atemp' (it's undefined)
atemp = a;
if( !atemp.Div(b) )
std::cout << "a / b = " << atemp << std::endl;
else
std::cout << "a / b = (carry or division by zero) " << std::endl;
}
int main()
{
MyBig a,b;
// conversion from 'const char *'
a = "123456.543456";
b = "98767878.124322";
SimpleCalculating(a,b);
// 'a' will have the max value which can be held in this type
a.SetMax();
// at the moment conversions from double (or float etc.) are not supported
// you cannot do that: b = 456.32f
b = "456.32";
// Look at the value 'a' and the product from a+b and a-b
// Don't worry this is the nature of floating point numbers
CalculatingWithCarry(a,b);
}
/*
the result (on 32 bit platform):
Simple calculating
a = 123456.543456
b = 98767878.124322
a + b = 98891334.667778
a - b = -98644421.580866
a * b = 12193540837712.2708
a / b = 0.0012499665458095765
Calculating with a carry
a = 1.624801256070839555e+646457012
b = 456.32
a + b = 1.624801256070839555e+646457012
a - b = 1.624801256070839555e+646457012
a * b = (carry: the result is too big)
a / b = 3.56066193914542329e+646457009
*/

View File

@ -1,4 +1,4 @@
#include <ttmath/ttmathint.h>
#include <ttmath/ttmath.h>
#include <iostream>
@ -18,7 +18,7 @@ void CalculatingWithCarry(const ttmath::Int<2> & a, const ttmath::Int<2> & b)
{
ttmath::Int<2> atemp;
std::cout << "Calculating with carry" << std::endl;
std::cout << "Calculating with a carry" << std::endl;
std::cout << "a = " << a << std::endl;
std::cout << "b = " << b << std::endl;
@ -26,13 +26,13 @@ ttmath::Int<2> atemp;
if( !atemp.Add(b) )
std::cout << "a + b = " << atemp << std::endl;
else
std::cout << "a + b = (carry: the result is too big) " << atemp << std::endl;
std::cout << "a + b = (carry) " << atemp << std::endl;
atemp = a;
if( !atemp.Sub(b) )
std::cout << "a - b = " << atemp << std::endl;
else
std::cout << "a - b = (carry: 'a' was smaller than 'b') " << atemp << std::endl;
std::cout << "a - b = (carry) " << atemp << std::endl;
atemp = a;
if( !atemp.Mul(b) )
@ -52,17 +52,19 @@ ttmath::Int<2> atemp;
int main()
{
// on 32bit platforms: 'a' and 'b' have 2-words (two 32bit words)
// in other words a,b are from <-2^63, 2^63 - 1>
// it means a,b are from <-2^63, 2^63 - 1>
ttmath::Int<2> a,b;
// conversion from int
a = 123456;
// conversion from 'const char *'
a = "123456";
b = "98767878";
SimpleCalculating(a,b);
// 'a' will have the max value which can be held in this type
a.SetMaxValue();
a.SetMax();
// conversion from 'int'
b = 10;
@ -71,7 +73,7 @@ ttmath::Int<2> a,b;
}
/*
the result:
the result (on 32 bit platform):
Simple calculating
a = 123456
@ -80,11 +82,11 @@ a + b = 98891334
a - b = -98644422
a * b = 12193487146368
a / b = 0
Calculating with carry
Calculating with a carry
a = 9223372036854775807
b = 10
a + b = (carry: the result is too big) -9223372036854775799
a + b = (carry) -9223372036854775799
a - b = 9223372036854775797
a * b = (carry: the result is too big)
a * b = (carry) the result is too big)
a / b = 922337203685477580
*/

34
samples/parser.cpp Normal file
View File

@ -0,0 +1,34 @@
#include <ttmath/ttmath.h>
#include <iostream>
// for convenience we're defining MyBig type
// this type has 2 words for its mantissa and 1 word for its exponent
// (on a 32bit platform one word means a word of 32 bits,
// and on a 64bit platform one word means a word of 64 bits)
typedef ttmath::Big<1,2> MyBig;
int main()
{
ttmath::Parser<MyBig> parser;
// the sine function takes its parameter as being in radians,
// the product from the arcus tangent will be in radians as well
const char equation[] = " (34 + 24) * 123 - 34.32 ^ 6 * sin(2.56) - atan(10)";
ttmath::ErrorCode err = parser.Parse(equation);
if( err == ttmath::err_ok )
std::cout << parser.stack[0].value << std::endl;
else
std::cout << "Error: "
<< static_cast<int>(err)
<< std::endl;
}
/*
the result (on 32 bit platform):
-897705014.52573107
*/

View File

@ -1,4 +1,4 @@
#include <ttmath/ttmathuint.h>
#include <ttmath/ttmath.h>
#include <iostream>
@ -18,7 +18,7 @@ void CalculatingWithCarry(const ttmath::UInt<2> & a, const ttmath::UInt<2> & b)
{
ttmath::UInt<2> atemp;
std::cout << "Calculating with carry" << std::endl;
std::cout << "Calculating with a carry" << std::endl;
std::cout << "a = " << a << std::endl;
std::cout << "b = " << b << std::endl;
@ -53,17 +53,19 @@ ttmath::UInt<2> atemp;
int main()
{
// on 32bit platforms: 'a' and 'b' have 2-words (two 32bit words)
// in other words a,b are from <0, 2^64 - 1>
// it means a,b are from <0, 2^64 - 1>
ttmath::UInt<2> a,b;
// conversion from 'const char *'
a = "123456";
b = "9876";
// conversion from int
b = 9876;
SimpleCalculating(a,b);
// 'a' will have the max value which can be held in this type
a.SetMaxValue();
a.SetMax();
// conversion from 'int'
b = 5;
@ -72,7 +74,7 @@ ttmath::UInt<2> a,b;
}
/*
the result:
the result (on 32 bit platform):
Simple calculating
a = 123456
@ -81,7 +83,7 @@ a + b = 133332
a - b = 113580
a * b = 1219251456
a / b = 12
Calculating with carry
Calculating with a carry
a = 18446744073709551615
b = 5
a + b = (carry: the result is too big) 4

View File

@ -46,126 +46,21 @@
*/
#include "ttmathbig.h"
#include "ttmathobjects.h"
#include <string>
namespace ttmath
{
/*!
the factorial from given 'x'
e.g.
Factorial(4) = 4! = 1*2*3*4
*/
template<class ValueType>
ValueType Factorial(const ValueType & x, ErrorCode * err = 0, const volatile StopCalculating * stop = 0)
{
ValueType result;
/*
*
* functions for rounding
*
*
*/
result.SetOne();
if( x.IsSign() )
{
if( err )
*err = err_improper_argument;
return result;
}
if( !x.exponent.IsSign() && !x.exponent.IsZero() )
{
// when x.exponent>0 there's no sense to calculate the formula
// (we can't add one into the x bacause
// we don't have enough bits in the mantissa)
if( err )
*err = err_overflow;
return result;
}
ValueType multipler;
ValueType one;
uint carry = 0;
one = result; // =1
multipler = result; // =1
while( !carry && multipler < x )
{
if( stop && stop->WasStopSignal() )
{
if( err )
*err = err_interrupt;
return result;
}
carry += multipler.Add(one);
carry += result.Mul(multipler);
}
if( err )
{
if( carry )
*err = err_overflow;
else
*err = err_ok;
}
return result;
}
/*!
absolute value of x
e.g. -2 = 2
2 = 2
*/
template<class ValueType>
ValueType Abs(const ValueType & x)
{
ValueType result( x );
result.Abs();
return result;
}
/*!
it returns the sign of the value
e.g. -2 = 1
0 = 0
10 = 1
*/
template<class ValueType>
ValueType Sgn(ValueType x)
{
x.Sgn();
return x;
}
/*!
the remainder from the division
e.g.
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
mod(-12.6 ; -3) = -0.6
*/
template<class ValueType>
ValueType Mod(ValueType a, const ValueType & b)
{
a.Mod(b);
return a;
}
/*!
this method skips the fraction from x
@ -200,6 +95,94 @@ namespace ttmath
return result;
}
/*!
this function returns a value representing the smallest integer
that is greater than or equal to x
Ceil(-3.7) = -3
Ceil(-3.1) = -3
Ceil(-3.0) = -3
Ceil(4.0) = 4
Ceil(4.2) = 5
Ceil(4.8) = 5
*/
template<class ValueType>
ValueType Ceil(const ValueType & x, ErrorCode * err = 0)
{
ValueType result(x);
uint c = 0;
result.SkipFraction();
if( result != x )
{
// x is with fraction
// if x is negative we don't have to do anything
if( !x.IsSign() )
{
ValueType one;
one.SetOne();
c += result.Add(one);
}
}
if( err )
*err = c ? err_overflow : err_ok;
return result;
}
/*!
this function returns a value representing the largest integer
that is less than or equal to x
Floor(-3.6) = -4
Floor(-3.1) = -4
Floor(-3) = -3
Floor(2) = 2
Floor(2.3) = 2
Floor(2.8) = 2
*/
template<class ValueType>
ValueType Floor(const ValueType & x, ErrorCode * err = 0)
{
ValueType result(x);
uint c = 0;
result.SkipFraction();
if( result != x )
{
// x is with fraction
// if x is positive we don't have to do anything
if( x.IsSign() )
{
ValueType one;
one.SetOne();
c += result.Sub(one);
}
}
if( err )
*err = c ? err_overflow : err_ok;
return result;
}
/*
*
* logarithms and the exponent
*
*
*/
/*!
this method calculates the natural logarithm (logarithm with the base 'e')
@ -277,13 +260,10 @@ namespace ttmath
{
ValueType result;
uint state = result.Exp(x);
uint c = result.Exp(x);
if( err )
if( state!=0 )
*err = err_overflow;
else
*err = err_ok;
*err = c ? err_overflow : err_ok;
return result;
}
@ -299,7 +279,7 @@ namespace ttmath
{
/*!
an auxiliary function for calculating the Sin
an auxiliary function for calculating the Sine
(you don't have to call this function)
*/
template<class ValueType>
@ -349,7 +329,7 @@ namespace ttmath
/*!
an auxiliary function for calculating the Sin
an auxiliary function for calculating the Sine
(you don't have to call this function)
it returns Sin(x) where 'x' is from <0, PI/2>
@ -457,8 +437,10 @@ namespace ttmath
} // namespace auxiliaryfunctions
/*!
this function calulates the Sin
this function calculates the Sine
*/
template<class ValueType>
ValueType Sin(ValueType x)
@ -490,7 +472,7 @@ namespace ttmath
/*!
this function calulates the Cos
this function calulates the Cosine
we're using the formula cos(x) = sin(x + PI/2)
*/
template<class ValueType>
@ -506,14 +488,14 @@ namespace ttmath
/*!
this function calulates the Tan
this function calulates the Tangent
we're using the formula tan(x) = sin(x) / cos(x)
it takes more time than calculating the Tan directly
from for example Taylor series but should be a bit preciser
because Tan receives its values from -infinity to +infinity
and when we calculate it from any series then we can make
a small mistake than calculating 'sin/cos'
a greater mistake than calculating 'sin/cos'
*/
template<class ValueType>
ValueType Tan(const ValueType & x, ErrorCode * err = 0)
@ -536,14 +518,27 @@ namespace ttmath
/*!
this function calulates the CTan
this function calulates the Tangent
look at the description of Tan(...)
(the abbreviation of Tangent can be 'tg' as well)
*/
template<class ValueType>
ValueType Tg(const ValueType & x, ErrorCode * err = 0)
{
return Tan(x, err);
}
/*!
this function calulates the Cotangent
we're using the formula tan(x) = cos(x) / sin(x)
(why do we make it in this way?
look at information in Tan() function)
*/
template<class ValueType>
ValueType CTan(const ValueType & x, ErrorCode * err = 0)
ValueType Cot(const ValueType & x, ErrorCode * err = 0)
{
ValueType result = Sin(x);
@ -562,6 +557,19 @@ namespace ttmath
}
/*!
this function calulates the Cotangent
look at the description of Cot(...)
(the abbreviation of Cotangent can be 'ctg' as well)
*/
template<class ValueType>
ValueType Ctg(const ValueType & x, ErrorCode * err = 0)
{
return Cot(x, err);
}
/*
*
* inverse trigonometric functions
@ -573,7 +581,7 @@ namespace ttmath
{
/*!
arcus sin
an auxiliary function for calculating the Arc Sine
we're calculating asin from the following formula:
asin(x) = x + (1*x^3)/(2*3) + (1*3*x^5)/(2*4*5) + (1*3*5*x^7)/(2*4*6*7) + ...
@ -635,7 +643,7 @@ namespace ttmath
/*!
arcus sin
an auxiliary function for calculating the Arc Sine
we're calculating asin from the following formula:
asin(x) = pi/2 - sqrt(2)*sqrt(1-x) * asin_temp
@ -718,7 +726,7 @@ namespace ttmath
/*!
arc sin (x)
this function calculates the Arc Sine
x is from <-1,1>
*/
template<class ValueType>
@ -765,7 +773,7 @@ namespace ttmath
/*!
arc cos (x)
this function calculates the Arc Cosine
we're using the formula:
acos(x) = pi/2 - asin(x)
@ -786,8 +794,9 @@ namespace ttmath
namespace auxiliaryfunctions
{
/*!
an auxiliary function for calculating the Arc Tangent
arc tan (x) where x is in <0; 0.5)
(x can be in (-0.5 ; 0.5) too)
@ -841,13 +850,15 @@ namespace ttmath
/*!
arc tan (x) where x is in <0 ; 1>
an auxiliary function for calculating the Arc Tangent
where x is in <0 ; 1>
*/
template<class ValueType>
ValueType ATan01(const ValueType & x)
{
ValueType half;
half.SetDotOne();
half.Set05();
/*
it would be better if we chose about sqrt(2)-1=0.41... instead of 0.5 here
@ -908,7 +919,8 @@ namespace ttmath
/*!
arc tan (x) where x > 1
an auxiliary function for calculating the Arc Tangent
where x > 1
we're using the formula:
atan(x) = pi/2 - atan(1/x) for x>0
@ -939,7 +951,7 @@ namespace ttmath
/*!
arc tan
this function calculates the Arc Tangent
*/
template<class ValueType>
ValueType ATan(ValueType x)
@ -971,13 +983,26 @@ namespace ttmath
/*!
arc ctan
this function calculates the Arc Tangent
look at the description of ATan(...)
(the abbreviation of Arc Tangent can be 'atg' as well)
*/
template<class ValueType>
ValueType ATg(const ValueType & x)
{
return ATan(x);
}
/*!
this function calculates the Arc Cotangent
we're using the formula:
actan(x) = pi/2 - atan(x)
*/
template<class ValueType>
ValueType ACTan(const ValueType & x)
ValueType ACot(const ValueType & x)
{
ValueType result;
@ -988,7 +1013,464 @@ namespace ttmath
}
/*!
this function calculates the Arc Cotangent
look at the description of ACot(...)
(the abbreviation of Arc Cotangent can be 'actg' as well)
*/
template<class ValueType>
ValueType ACtg(const ValueType & x)
{
return ACot(x);
}
/*
*
* hyperbolic functions
*
*
*/
/*!
this function calculates the Hyperbolic Sine
we're using the formula sinh(x)= ( e^x - e^(-x) ) / 2
*/
template<class ValueType>
ValueType Sinh(const ValueType & x, ErrorCode * err = 0)
{
ValueType ex, emx;
uint c = 0;
c += ex.Exp(x);
c += emx.Exp(-x);
c += ex.Sub(emx);
c += ex.exponent.SubOne();
if( err )
*err = c ? err_overflow : err_ok;
return ex;
}
/*!
this function calculates the Hyperbolic Cosine
we're using the formula cosh(x)= ( e^x + e^(-x) ) / 2
*/
template<class ValueType>
ValueType Cosh(const ValueType & x, ErrorCode * err = 0)
{
ValueType ex, emx;
uint c = 0;
c += ex.Exp(x);
c += emx.Exp(-x);
c += ex.Add(emx);
c += ex.exponent.SubOne();
if( err )
*err = c ? err_overflow : err_ok;
return ex;
}
/*!
this function calculates the Hyperbolic Tangent
we're using the formula tanh(x)= ( e^x - e^(-x) ) / ( e^x + e^(-x) )
*/
template<class ValueType>
ValueType Tanh(const ValueType & x, ErrorCode * err = 0)
{
ValueType ex, emx, nominator, denominator;
uint c = 0;
c += ex.Exp(x);
c += emx.Exp(-x);
nominator = ex;
c += nominator.Sub(emx);
denominator = ex;
c += denominator.Add(emx);
c += nominator.Div(denominator);
if( err )
*err = c ? err_overflow : err_ok;
return nominator;
}
/*!
this function calculates the Hyperbolic Tangent
look at the description of Tanh(...)
(the abbreviation of Hyperbolic Tangent can be 'tgh' as well)
*/
template<class ValueType>
ValueType Tgh(const ValueType & x, ErrorCode * err = 0)
{
return Tanh(x, err);
}
/*!
this function calculates the Hyperbolic Cotangent
we're using the formula coth(x)= ( e^x + e^(-x) ) / ( e^x - e^(-x) )
*/
template<class ValueType>
ValueType Coth(const ValueType & x, ErrorCode * err = 0)
{
if( x.IsZero() )
{
if( err )
*err = err_improper_argument;
return x;
}
ValueType ex, emx, nominator, denominator;
uint c = 0;
c += ex.Exp(x);
c += emx.Exp(-x);
nominator = ex;
c += nominator.Add(emx);
denominator = ex;
c += denominator.Sub(emx);
c += nominator.Div(denominator);
if( err )
*err = c ? err_overflow : err_ok;
return nominator;
}
/*!
this function calculates the Hyperbolic Cotangent
look at the description of Coth(...)
(the abbreviation of Hyperbolic Cotangent can be 'ctgh' as well)
*/
template<class ValueType>
ValueType Ctgh(const ValueType & x, ErrorCode * err = 0)
{
return Coth(x, err);
}
/*
*
* functions for converting between degrees and radians
*
*
*/
/*!
this function converts degrees to radians
it returns: x * pi / 180
*/
template<class ValueType>
ValueType DegToRad(const ValueType & x, ErrorCode * err = 0)
{
ValueType result, delimiter;
uint c = 0;
result.SetPi();
c += result.Mul(x);
delimiter = 180;
c += result.Div(delimiter);
if( err )
*err = c ? err_overflow : err_ok;
return result;
}
/*!
this function converts radians to degrees
it returns: x * 180 / pi
*/
template<class ValueType>
ValueType RadToDeg(const ValueType & x, ErrorCode * err = 0)
{
ValueType result, delimiter;
uint c = 0;
result = 180;
c += result.Mul(x);
delimiter.SetPi();
c += result.Div(delimiter);
if( err )
*err = c ? err_overflow : err_ok;
return result;
}
/*!
this function converts degrees in the long format into one value
long format: (degrees, minutes, seconds)
minutes and seconds must be greater than or equal zero
result:
if d>=0 : result= d + ((s/60)+m)/60
if d<0 : result= d - ((s/60)+m)/60
((s/60)+m)/60 = (s+60*m)/3600 (second version is faster because
there's only one division)
for example:
DegToDeg(10, 30, 0) = 10.5
DegToDeg(10, 24, 35.6)=10.4098(8)
*/
template<class ValueType>
ValueType DegToDeg( const ValueType & d, const ValueType & m, const ValueType & s,
ErrorCode * err = 0)
{
ValueType delimiter, multipler;
uint c = 0;
if( m.IsSign() || s.IsSign() )
{
if( err )
*err = err_improper_argument;
return delimiter;
}
multipler = 60;
delimiter = 3600;
c += multipler.Mul(m);
c += multipler.Add(s);
c += multipler.Div(delimiter);
if( d.IsSign() )
multipler.ChangeSign();
c += multipler.Add(d);
if( err )
*err = c ? err_overflow : err_ok;
return multipler;
}
/*!
this function converts degrees in the long format to radians
*/
template<class ValueType>
ValueType DegToRad( const ValueType & d, const ValueType & m, const ValueType & s,
ErrorCode * err = 0)
{
ValueType temp_deg = DegToDeg(d,m,s,err);
if( err && *err!=err_ok )
return temp_deg;
return DegToRad(temp_deg, err);
}
/*
*
* another functions
*
*
*/
/*!
this function calculates the square root
Sqrt(9) = 3
*/
template<class ValueType>
ValueType Sqrt(ValueType x, ErrorCode * err = 0)
{
if( x.IsSign() )
{
if( err )
*err = err_improper_argument;
return x;
}
if( x.IsZero() )
{
// Sqrt(0) = 0
if( err )
*err = err_ok;
return x;
}
ValueType pow;
pow.Set05();
// PowFrac can return only a carry because x is greater than zero
uint c = x.PowFrac(pow);
if( err )
*err = c ? err_overflow : err_ok;
return x;
}
/*!
the factorial from given 'x'
e.g.
Factorial(4) = 4! = 1*2*3*4
*/
template<class ValueType>
ValueType Factorial(const ValueType & x, ErrorCode * err = 0, const volatile StopCalculating * stop = 0)
{
static History<ValueType> history;
ValueType result;
result.SetOne();
if( x.IsSign() )
{
if( err )
*err = err_improper_argument;
return result;
}
if( !x.exponent.IsSign() && !x.exponent.IsZero() )
{
// when x.exponent>0 there's no sense to calculate the formula
// (we can't add one into the x bacause
// we don't have enough bits in the mantissa)
if( err )
*err = err_overflow;
return result;
}
ErrorCode err_tmp;
if( history.Get(x, result, err_tmp) )
{
if( err )
*err = err_tmp;
return result;
}
ValueType multipler;
ValueType one;
uint carry = 0;
one = result; // =1
multipler = result; // =1
while( !carry && multipler < x )
{
if( stop && stop->WasStopSignal() )
{
if( err )
*err = err_interrupt;
return result;
}
carry += multipler.Add(one);
carry += result.Mul(multipler);
}
err_tmp = carry ? err_overflow : err_ok;
history.Add(x, result, err_tmp);
if( err )
*err = carry ? err_overflow : err_ok;
return result;
}
/*!
absolute value of x
e.g. -2 = 2
2 = 2
*/
template<class ValueType>
ValueType Abs(const ValueType & x)
{
ValueType result( x );
result.Abs();
return result;
}
/*!
it returns the sign of the value
e.g. -2 = 1
0 = 0
10 = 1
*/
template<class ValueType>
ValueType Sgn(ValueType x)
{
x.Sgn();
return x;
}
/*!
the remainder from a division
e.g.
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
mod(-12.6 ; -3) = -0.6
*/
template<class ValueType>
ValueType Mod(ValueType a, const ValueType & b)
{
a.Mod(b);
return a;
}
} // namespace
/*!
this is for convenience for the user
he can only use '#include <ttmath/ttmath.h>' even if he uses the parser
*/
#include "ttmathparser.h"
#endif

View File

@ -40,19 +40,19 @@
/*!
\file ttmathbig.h
\brief A Class for representing big numbers
\brief A Class for representing floating point numbers
*/
#include "ttmathint.h"
#include <iostream>
namespace ttmath
{
/*!
\brief it implements the big value
\brief Big implements the floating point numbers
*/
template <uint exp,uint man>
class Big
@ -147,6 +147,7 @@ private:
public:
/*!
it sets value zero
*/
@ -167,19 +168,16 @@ public:
*/
void SetOne()
{
info = 0;
mantissa.SetOne();
exponent.SetZero();
Standardizing();
FromUInt(1);
}
/*!
it sets value 0.5
*/
void SetDotOne()
void Set05()
{
SetOne();
FromUInt(1);
exponent.SubOne();
}
@ -189,6 +187,10 @@ public:
*/
void SetPi()
{
// this is a static table which represents the value Pi (mantissa of it)
// (first is the highest word)
// we must define this table as 'unsigned int' because
// both on 32bit and 64bit platforms this table is 32bit
static const unsigned int temp_table[] = {
0xc90fdaa2, 0x2168c234, 0xc4c6628b, 0x80dc1cd1, 0x29024e08, 0x8a67cc74, 0x020bbea6, 0x3b139b22,
0x514a0879, 0x8e3404dd, 0xef9519b3, 0xcd3a431b, 0x302b0a6d, 0xf25f1437, 0x4fe1356d, 0x6d51c245,
@ -199,13 +201,26 @@ public:
0x9b2783a2, 0xec07a28f, 0xb5c55df0, 0x6f4c52c9, 0xde2bcbf6, 0x95581718, 0x3995497c, 0xea956ae5,
0x15d22618, 0x98fa0510, 0x15728e5a, 0x8aaac42d, 0xad33170d, 0x04507a33, 0xa85521ab, 0xdf1cba64,
0xecfb8504, 0x58dbef0a, 0x8aea7157, 0x5d060c7d, 0xb3970f85, 0xa6e1e4c7, 0xabf5ae8c, 0xdb0933d7,
0x1e8c94e0, 0x4a25619d, 0xcee3d226, 0x1ad2ee6b, 0xf0139f9d, 0x88e637cb
0x1e8c94e0, 0x4a25619d, 0xcee3d226, 0x1ad2ee6b, 0xf12ffa06, 0xd98a0864, 0xd8760273, 0x3ec86a64,
0x521f2b18, 0x177b200c, 0xbbe11757, 0x7a615d6c, 0x770988c0, 0xbad946e2, 0x08e24fa0, 0x74e5ab31,
0x43db5bfc, 0xe0fd108e, 0x4b82d120, 0xa9210801, 0x1a723c12, 0xa787e6d7, 0x88719a10, 0xbdba5b26,
0x99c32718, 0x6af4e23c, 0x1a946834, 0xb6150bda, 0x2583e9ca, 0x2ad44ce8, 0xdbbbc2db, 0x04de8ef9,
0x2e8efc14, 0x1fbecaa6, 0x287c5947, 0x4e6bc05d, 0x99b2964f, 0xa090c3a2, 0x233ba186, 0x515be7ed,
0x1f612970, 0xcee2d7af, 0xb81bdd76, 0x2170481c, 0xd0069127, 0xd5b05aa9, 0x93b4ea98, 0x8d8fddc1,
0x86ffb7dc, 0x90a6c08f, 0x4df435c9, 0x34028492, 0x36c3fab4, 0xd27c7026, 0xc1d4dcb2, 0x602646df // (last one was: 0x602646de)
// 0xc9751e76, ...
// (the last word was rounded up because the next one is 0xc9751e76 -- first bit is one 0xc..)
// 128 32bit words for the mantissa -- about 1232 valid digits (decimal)
};
// 78 unsigned 32bits words
// this is static table which represents the value Pi (mantissa of its)
// (first is the highest word)
// we must define this table as 'unsigned int' because
// on 32bits and 64bits platforms this table is 32bits
// the value of PI is comming from the website "Paul's 8192 Digits of Pi"
// http://www.escape.com/~paulg53/math/pi/8192.html
// 2999 digits were taken from this website
// (later they were compared with http://zenwerx.com/pi.php)
// and they were set into Big<1,300> type (using operator=(const char*) on 32bit platform)
// and then the first 128 words were taken into this table
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 128,
// and on 64bit platform value 64 (128/2=64))
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
@ -235,7 +250,7 @@ public:
/*!
it sets value e
(the base of natural logarithm)
(the base of the natural logarithm)
*/
void SetE()
{
@ -249,9 +264,24 @@ public:
0x8e4f1232, 0xeef28183, 0xc3fe3b1b, 0x4c6fad73, 0x3bb5fcbc, 0x2ec22005, 0xc58ef183, 0x7d1683b2,
0xc6f34a26, 0xc1b2effa, 0x886b4238, 0x611fcfdc, 0xde355b3b, 0x6519035b, 0xbc34f4de, 0xf99c0238,
0x61b46fc9, 0xd6e6c907, 0x7ad91d26, 0x91f7f7ee, 0x598cb0fa, 0xc186d91c, 0xaefe1309, 0x85139270,
0xb4130c93, 0xbc437944, 0xf4fd4452, 0xe2d74dd3, 0x645b2194, 0x41468794
0xb4130c93, 0xbc437944, 0xf4fd4452, 0xe2d74dd3, 0x64f2e21e, 0x71f54bff, 0x5cae82ab, 0x9c9df69e,
0xe86d2bc5, 0x22363a0d, 0xabc52197, 0x9b0deada, 0x1dbf9a42, 0xd5c4484e, 0x0abcd06b, 0xfa53ddef,
0x3c1b20ee, 0x3fd59d7c, 0x25e41d2b, 0x669e1ef1, 0x6e6f52c3, 0x164df4fb, 0x7930e9e4, 0xe58857b6,
0xac7d5f42, 0xd69f6d18, 0x7763cf1d, 0x55034004, 0x87f55ba5, 0x7e31cc7a, 0x7135c886, 0xefb4318a,
0xed6a1e01, 0x2d9e6832, 0xa907600a, 0x918130c4, 0x6dc778f9, 0x71ad0038, 0x092999a3, 0x33cb8b7a,
0x1a1db93d, 0x7140003c, 0x2a4ecea9, 0xf98d0acc, 0x0a8291cd, 0xcec97dcf, 0x8ec9b55a, 0x7f88a46b,
0x4db5a851, 0xf44182e1, 0xc68a007e, 0x5e0dd902, 0x0bfd64b6, 0x45036c7a, 0x4e677d2c, 0x38532a3a
//0x23ba4442,...
// 128 32bit words for the mantissa -- about 1232 valid digits (decimal)
};
// above value was calculated using Big<1,300> on 32bit platform
// and then the first 128 words were taken,
// the calculating was made by using ExpSurrounding0(1) method
// which took 1110 iterations
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 128,
// and on 64bit platform value 64 (128/2=64))
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
info = 0;
@ -274,23 +304,93 @@ public:
0x25669b33, 0x3564a337, 0x6a9c7f8a, 0x5e148e82, 0x074db601, 0x5cfe7aa3, 0x0c480a54, 0x17350d2c,
0x955d5179, 0xb1e17b9d, 0xae313cdb, 0x6c606cb1, 0x078f735d, 0x1b2db31b, 0x5f50b518, 0x5064c18b,
0x4d162db3, 0xb365853d, 0x7598a195, 0x1ae273ee, 0x5570b6c6, 0x8f969834, 0x96d4e6d3, 0x30af889b,
0x44a02554, 0x731cdc8e, 0xa17293d1, 0x228a4ef8, 0x6e1adf84, 0x08689fa8
0x44a02554, 0x731cdc8e, 0xa17293d1, 0x228a4ef9, 0x8d6f5177, 0xfbcf0755, 0x268a5c1f, 0x9538b982,
0x61affd44, 0x6b1ca3cf, 0x5e9222b8, 0x8c66d3c5, 0x422183ed, 0xc9942109, 0x0bbb16fa, 0xf3d949f2,
0x36e02b20, 0xcee886b9, 0x05c128d5, 0x3d0bd2f9, 0x62136319, 0x6af50302, 0x0060e499, 0x08391a0c,
0x57339ba2, 0xbeba7d05, 0x2ac5b61c, 0xc4e9207c, 0xef2f0ce2, 0xd7373958, 0xd7622658, 0x901e646a,
0x95184460, 0xdc4e7487, 0x156e0c29, 0x2413d5e3, 0x61c1696d, 0xd24aaebd, 0x473826fd, 0xa0c238b9,
0x0ab111bb, 0xbd67c724, 0x972cd18b, 0xfbbd9d42, 0x6c472096, 0xe76115c0, 0x5f6f7ceb, 0xac9f45ae,
0xcecb72f1, 0x9c38339d, 0x8f682625, 0x0dea891e, 0xf07afff3, 0xa892374e, 0x175eb4af, 0xc8daadd9 // (last one was: 0xc8daadd8)
// 0x85db6ab0, ...
// (the last word was rounded up because the next one is 0x85db6ab0 -- first bit is one 0x8..)
// 128 32bit words for the mantissa -- about 1232 valid digits (decimal)
};
// above value was calculated using Big<1,300> on 32bit platform
// and then the first 128 words were taken,
// the calculating was made by using LnSurrounding1(2) method
// which took 3030 iterations
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 128,
// and on 64bit platform value 64 (128/2=64))
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT);
info = 0;
}
/*!
it sets value ln(10)
the natural logarithm from value 10
I introduced this constant especially to make the conversion ToString()
being faster. In fact the method ToString() is keeping values of logarithms
it has calculated but it must calculate the logarithm at least once.
If a program, which uses this library, is running for a long time this
would be ok, but for programs which are running shorter, for example for
CGI applications which only once are printing values, this would be much
inconvenience. Then if we're printing with base (radix) 10 and the mantissa
of our value is smaller than or equal to TTMATH_BUILTIN_VARIABLES_SIZE
we don't calculate the logarithm but take it from this constant.
*/
void SetLn10()
{
static const unsigned int temp_table[] = {
0x935d8ddd, 0xaaa8ac16, 0xea56d62b, 0x82d30a28, 0xe28fecf9, 0xda5df90e, 0x83c61e82, 0x01f02d72,
0x962f02d7, 0xb1a8105c, 0xcc70cbc0, 0x2c5f0d68, 0x2c622418, 0x410be2da, 0xfb8f7884, 0x02e516d6,
0x782cf8a2, 0x8a8c911e, 0x765aa6c3, 0xb0d831fb, 0xef66ceb0, 0x4ab3c6fa, 0x5161bb49, 0xd219c7bb,
0xca67b35b, 0x23605085, 0x8e93368d, 0x44789c4f, 0x5b08b057, 0xd5ede20f, 0x469ea58e, 0x9305e981,
0xe2478fca, 0xad3aee98, 0x9cd5b42e, 0x6a271619, 0xa47ecb26, 0x978c5d4f, 0xdb1d28ea, 0x57d4fdc0,
0xe40bf3cc, 0x1e14126a, 0x45765cde, 0x268339db, 0xf47fa96d, 0xeb271060, 0xaf88486e, 0xa9b7401e,
0x3dfd3c51, 0x748e6d6e, 0x3848c8d2, 0x5faf1bca, 0xe88047f1, 0x7b0d9b50, 0xa949eaaa, 0xdf69e8a5,
0xf77e3760, 0x4e943960, 0xe38a5700, 0xffde2db1, 0xad6bfbff, 0xd821ba0a, 0x4cb0466d, 0x61ba648e,
0xef99c8e5, 0xf6974f36, 0x3982a78c, 0xa45ddfc8, 0x09426178, 0x19127a6e, 0x3b70fcda, 0x2d732d47,
0xb5e4b1c8, 0xc0e5a10a, 0xaa6604a5, 0x324ec3dc, 0xbc64ea80, 0x6e198566, 0x1f1d366c, 0x20663834,
0x4d5e843f, 0x20642b97, 0x0a62d18e, 0x478f7bd5, 0x8fcd0832, 0x4a7b32a6, 0xdef85a05, 0xeb56323a,
0x421ef5e0, 0xb00410a0, 0xa0d9c260, 0x794a976f, 0xf6ff363d, 0xb00b6b33, 0xf42c58de, 0xf8a3c52d,
0xed69b13d, 0xc1a03730, 0xb6524dc1, 0x8c167e86, 0x99d6d20e, 0xa2defd2b, 0xd006f8b4, 0xbe145a2a,
0xdf3ccbb3, 0x189da49d, 0xbc1261c8, 0xb3e4daad, 0x6a36cecc, 0xb2d5ae5b, 0x89bf752f, 0xb5dfb353,
0xff3065c4, 0x0cfceec8, 0x1be5a9a9, 0x67fddc57, 0xc4b83301, 0x006bf062, 0x4b40ed7a, 0x56c6cdcd,
0xa2d6fe91, 0x388e9e3e, 0x48a93f5f, 0x5e3b6eb4, 0xb81c4a5b, 0x53d49ea6, 0x8e668aea, 0xba83c7f9 // (last one was: 0xba83c7f8)
///0xfb5f06c3, ...
//(the last word was rounded up because the next one is 0xfb5f06c3 -- first bit is one 0xf..)
// 128 32bit words for the mantissa -- about 1232 valid digits (decimal)
};
// above value was calculated using Big<1,300> on 32bit platform
// and then the first 128 32bit words were taken,
// the calculating was made by using LnSurrounding1(10) method
// which took 16555 iterations
// (the formula used in LnSurrounding1(x) converges badly when
// the x is greater than one but in fact we can use it, only the
// number of iterations will be greater)
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 128,
// and on 64bit platform value 64 (128/2=64))
mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
info = 0;
}
/*!
it sets the maximum value which can be held in this type
*/
void SetMax()
{
info = 0;
mantissa.SetMaxValue();
exponent.SetMaxValue();
mantissa.SetMax();
exponent.SetMax();
// we don't have to use 'Standardizing()' because the last bit from
// the mantissa is set
@ -304,8 +404,8 @@ public:
{
info = 0;
mantissa.SetMaxValue();
exponent.SetMaxValue();
mantissa.SetMax();
exponent.SetMax();
SetSign();
// we don't have to use 'Standardizing()' because the last bit from
@ -775,7 +875,29 @@ public:
return 0;
}
/*!
power this = this ^ pow
this *must* be greater than zero (this > 0)
pow can be negative and with fraction
return values:
1 - carry
2 - incorrect argument ('this')
*/
uint PowFrac(const Big<exp, man> & pow)
{
TTMATH_REFERENCE_ASSERT( pow )
Big<exp, man> temp;
uint c = temp.Ln(*this);
c += temp.Mul(pow);
c += Exp(temp);
return (c==0)? 0 : 1;
}
/*!
power this = this ^ pow
@ -803,23 +925,13 @@ public:
Big<exp, man> pow_frac( pow );
pow_frac.RemainFraction();
if( pow_frac.IsZero() )
return PowBInt( pow );
// pow is with fraction (not integer)
// result = e^(pow * ln(this) ) where 'this' must be greater than 0
// IsZero() was tested before
if( IsSign() )
return 2;
Big<exp, man> temp;
uint c = temp.Ln(*this);
c += temp.Mul(pow);
c += Exp(temp);
return (c==0)? 0 : 1;
return PowFrac(pow);
}
@ -843,6 +955,10 @@ private:
denominator.SetOne();
denominator_i.SetOne();
// this is only to avoid getting a warning about an uninitialized object
// gcc 4.1.2 reports: 'old_value.info' may be used uninitialized in this function
// (in fact we will initialize it later when the condition 'testing' is fulfilled)
old_value.info = 0;
// every 'step_test' times we make a test
const uint step_test = 5;
@ -969,10 +1085,6 @@ private:
we're using the formula:
ln x = 2 * [ (x-1)/(x+1) + (1/3)((x-1)/(x+1))^3 + (1/5)((x-1)/(x+1))^5 + ... ]
parts - it's used for approximation, it means how many parts of the above formula
will be caltulated, when equals 0 then it is ommited
*/
void LnSurrounding1(const Big<exp,man> & x)
{
@ -998,9 +1110,13 @@ private:
denominator.SetOne();
SetZero();
// every 'step_test' times we make a test
// this is only to avoid getting a warning about an uninitialized object
// gcc 4.1.2 reports: 'old_value.info' may be used uninitialized in this function
// (in fact we will initialize it later when the condition 'testing' is fulfilled)
old_value.info = 0;
// every 'step_test' times we make a test
const uint step_test = 5;
// we begin from 1 in order to not testing at the beginning
@ -1253,7 +1369,7 @@ public:
if( IsSign() )
{
Int<int_size> min;
min.SetMinValue();
min.SetMin();
if( result == min )
return 0;
@ -1270,6 +1386,24 @@ public:
}
/*!
a method for converting 'uint' to this class
*/
void FromUInt(uint value)
{
info = 0;
for(uint i=0 ; i<man-1 ; ++i)
mantissa.table[i] = 0;
mantissa.table[man-1] = value;
exponent = -sint(man-1) * sint(TTMATH_BITS_PER_UINT);
// there shouldn't be a carry because 'value' has the 'uint' type
Standardizing();
}
/*!
a method for converting 'sint' to this class
*/
@ -1279,19 +1413,14 @@ public:
if( value < 0 )
{
value = -value;
value = -value;
is_sign = true;
}
info = 0;
mantissa = value;
exponent.SetZero();
FromUInt(uint(value));
if( is_sign )
SetSign();
// there shouldn't be a carry because 'value' has the type 'sint'
Standardizing();
}
@ -1307,31 +1436,101 @@ public:
/*!
a constructor for converting 'sint' and 'uint' to this class
an operator= for converting 'uint' to this class
*/
Big<exp, man> & operator=(uint value)
{
FromUInt(value);
return *this;
}
/*!
a constructor for converting 'sint' to this class
*/
Big(sint value)
{
FromInt(value);
}
/*!
a constructor for converting 'uint' to this class
*/
Big(uint value)
{
FromInt( sint(value) );
FromUInt(value);
}
#ifdef TTMATH_PLATFORM64
#if defined _M_X64 || defined __x86_64__
/*!
a constructor for converting 'int' to this class
(on 64bit platforms 'sint' has 64 bits and 'int' has 32 bits
in 64bit platforms we must define additional operators and contructors
in order to allow a user initializing the objects in this way:
Big<...> type = 20;
or
Big<...> type;
type = 30;
decimal constants such as 20, 30 etc. are integer literal of type int,
if the value is greater it can even be long int,
0 is an octal integer of type int
(ISO 14882 p2.13.1 Integer literals)
*/
Big(int value)
/*!
an operator= for converting 'signed int' to this class
***this operator is created only on a 64bit platform***
it takes one argument of 32bit
*/
Big<exp, man> & operator=(signed int value)
{
FromInt( sint(value) );
FromInt(sint(value));
return *this;
}
/*!
an operator= for converting 'unsigned int' to this class
***this operator is created only on a 64bit platform***
it takes one argument of 32bit
*/
Big<exp, man> & operator=(unsigned int value)
{
FromUInt(uint(value));
return *this;
}
/*!
a constructor for converting 'signed int' to this class
***this constructor is created only on a 64bit platform***
it takes one argument of 32bit
*/
Big(signed int value)
{
FromInt(sint(value));
}
/*!
a constructor for converting 'unsigned int' to this class
***this constructor is created only on a 64bit platform***
it takes one argument of 32bit
*/
Big(unsigned int value)
{
FromUInt(uint(value));
}
#endif
/*!
a method for converting from 'Int<int_size>' to this class
*/
@ -1401,7 +1600,7 @@ public:
/*!
a destructor
*/
virtual ~Big()
~Big()
{
}
@ -1712,28 +1911,44 @@ private:
// (LnSurrounding1() will return one immediately)
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;
}
static Big<exp,man> log_history[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/*
static Big<exp,man> log_history[15] = { sint(0),sint(0),sint(0),sint(0),sint(0),
sint(0),sint(0),sint(0),sint(0),sint(0),
sint(0),sint(0),sint(0),sint(0),sint(0) };
*/
uint index = base - 2;
if( log_history[index].IsZero() )
{
// we don't have 'base' in 'log_history' then we calculate it now
if( base==10 && man<=TTMATH_BUILTIN_VARIABLES_SIZE )
{
// for the base equal 10 we're using SelLn10() instead of calculating it
// (only if we have sufficient big the constant)
temp.SetLn10();
}
else
{
Big<exp,man> base_(base);
c += temp.Ln(base_);
}
// 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;
c += Div(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;
}
@ -2269,6 +2484,11 @@ private:
// we don't remove any white characters here
// this is only to avoid getting a warning about an uninitialized object
// gcc 4.1.2 reports: 'old_value.info' may be used uninitialized in this function
// (in fact we will initialize it later when the condition 'testing' is fulfilled)
old_value.info = 0;
power.SetOne();
for( ; (character=UInt<man>::CharToDigit(*source, base)) != -1 ; ++source, ++index )
@ -2804,7 +3024,7 @@ public:
Big<exp,man> half;
uint c;
half.SetDotOne();
half.Set05();
if( IsSign() )
{

View File

@ -52,7 +52,7 @@ namespace ttmath
/*!
\brief it implements a big integer value with a sign
\brief Int implements a big integer value with a sign
value_size - how many bytes specify our value
on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
@ -68,9 +68,9 @@ public:
this method sets the max value which this class can hold
(all bits will be one besides the last one)
*/
void SetMaxValue()
void SetMax()
{
UInt<value_size>::SetMaxValue();
UInt<value_size>::SetMax();
UInt<value_size>::table[value_size-1] = ~ TTMATH_UINT_HIGHEST_BIT;
}
@ -79,7 +79,7 @@ public:
this method sets the min value which this class can hold
(all bits will be zero besides the last one which is one)
*/
void SetMinValue()
void SetMin()
{
UInt<value_size>::SetZero();
UInt<value_size>::table[value_size-1] = TTMATH_UINT_HIGHEST_BIT;
@ -92,7 +92,7 @@ public:
*/
void SetSignOne()
{
UInt<value_size>::SetMaxValue();
UInt<value_size>::SetMax();
}
@ -106,10 +106,10 @@ public:
{
Int<value_size> temp;
temp.SetMinValue();
temp.SetMin();
/*
if the value is equal that one which has been returned from SetMinValue
if the value is equal that one which has been returned from SetMin
that means we can't change sign because the value is too big (bigger about one)
e.g. when value_size = 1 and value is -2147483648 we can't change it to the
@ -138,7 +138,8 @@ public:
e.g. 1 -> -1
-2 -> -2
from a positive value we always make a negative value
from a positive value we make a negative value,
if the value is negative we do nothing
*/
void SetSign()
{
@ -382,8 +383,8 @@ public:
1. if the signs were the same that means the result is too big
(the result must be without a sign)
2. if the signs were different that means if the result
is different from that one which has been returned from SetMinValue()
that is carry (result too big) but if the result is equal SetMinValue()
is different from that one which has been returned from SetMin()
that is carry (result too big) but if the result is equal SetMin()
there'll be ok (and the next SetSign will has no effect because
the value is actually negative -- look at description of that case
in ChangeSign())
@ -392,13 +393,13 @@ public:
{
/*
there can be one case where signs are different and
the result will be equal the value from SetMinValue()
the result will be equal the value from SetMin()
(this situation is ok)
*/
if( ss1_is_sign != ss2_is_sign )
{
Int<value_size> temp;
temp.SetMinValue();
temp.SetMin();
if( operator!=(temp) )
/*
@ -493,8 +494,6 @@ public:
UInt<value_size>::table[i] = p.table[i];
// if( i < value_size )
if( value_size > argument_size )
{
// 'this' is longer than 'p'
@ -516,6 +515,20 @@ public:
}
/*!
this method converts the sint type into this class
*/
void FromInt(sint value)
{
uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0;
for(uint i=1 ; i<value_size ; ++i)
UInt<value_size>::table[i] = fill;
UInt<value_size>::table[0] = uint(value);
}
/*!
this operator converts an UInt<another_size> type to this class
@ -542,32 +555,103 @@ public:
/*!
this method converts an sint type to this class
this method converts the sint type to this class
*/
Int<value_size> & operator=(sint i)
{
if(i<0)
SetSignOne();
else
UInt<value_size>::SetZero();
UInt<value_size>::table[0] = uint(i);
FromInt(i);
return *this;
}
/*!
a constructor for converting an uint to this class
a constructor for converting the uint to this class
*/
Int(sint i)
{
operator=(i);
FromInt(i);
}
/*!
a constructor for converting string to this class (with base=10)
this method converts the uint type to this class
*/
Int<value_size> & operator=(uint i)
{
UInt<value_size>::FromUInt(i);
return *this;
}
/*!
a constructor for converting the uint to this class
*/
Int(uint i)
{
UInt<value_size>::FromUInt(i);
}
#ifdef TTMATH_PLATFORM64
/*!
this method converts the signed int type to this class
***this operator is created only on a 64bit platform***
it takes one argument of 32bit
*/
Int<value_size> & operator=(signed int i)
{
FromInt(sint(i));
return *this;
}
/*!
a constructor for converting the signed int to this class
***this constructor is created only on a 64bit platform***
it takes one argument of 32bit
*/
Int(signed int i)
{
FromInt(sint(i));
}
/*!
this method converts the unsigned int type to this class
***this operator is created only on a 64bit platform***
it takes one argument of 32bit
*/
Int<value_size> & operator=(unsigned int i)
{
UInt<value_size>::FromUInt(uint(i));
return *this;
}
/*!
a constructor for converting the unsigned int to this class
***this constructor is created only on a 64bit platform***
it takes one argument of 32bit
*/
Int(unsigned int i)
{
UInt<value_size>::FromUInt(uint(i));
}
#endif
/*!
a constructor for converting string to this class (with the base=10)
*/
Int(const char * s)
{
@ -576,7 +660,7 @@ public:
/*!
a constructor for converting string to this class (with base=10)
a constructor for converting a string to this class (with the base=10)
*/
Int(const std::string & s)
{
@ -595,7 +679,7 @@ public:
/*!
a copy constructor
the copy constructor
*/
template<uint argument_size>
Int(const Int<argument_size> & u) : UInt<value_size>::size(value_size)
@ -607,9 +691,9 @@ public:
/*!
a destructor
the destructor
*/
virtual ~Int()
~Int()
{
}
@ -683,7 +767,7 @@ public:
{
Int<value_size> mmin;
mmin.SetMinValue();
mmin.SetMin();
/*
the reference to mmin will be automatically converted to the reference
@ -699,7 +783,7 @@ public:
{
Int<value_size> mmax;
mmax.SetMaxValue();
mmax.SetMax();
if( UInt<value_size>::operator>( mmax ) )
return 1;
@ -747,10 +831,19 @@ public:
*
* methods for comparing
*
* operators == and != will be the same as in the base class (UInt<value_size>)
*
*/
bool operator==(const Int<value_size> & l) const
{
return UInt<value_size>::operator==(l);
}
bool operator!=(const Int<value_size> & l) const
{
return UInt<value_size>::operator!=(l);
}
bool operator<(const Int<value_size> & l) const
{
sint i=value_size-1;

View File

@ -36,160 +36,83 @@
*/
#ifndef headerfilettmathobject
#define headerfilettmathobject
/*!
\file ttmathobjects.h
\brief Mathematic functions.
*/
#include "ttmathtypes.h"
#include <string>
#include <list>
#include <map>
#include <algorithm>
namespace ttmath
{
/*!
objects of this class are used with the mathematical parser
they hold variables or functions defined by a user
each object has its own table in which we're keeping variables or functions
*/
class Objects
{
public:
struct ObjectValue
/*!
one item (variable or function)
'items' will be on the table
*/
struct Item
{
// name of a variable of a function
std::string value;
// number of parameters required by the function
// (if there's a variable this 'param' is ignored)
int param;
ObjectValue() {}
ObjectValue(const std::string & v, int p) : value(v), param(p) {}
Item() {}
Item(const std::string & v, int p) : value(v), param(p) {}
};
typedef std::map<std::string, ObjectValue> Table;
// 'Table' is the type of our table
typedef std::map<std::string, Item> Table;
typedef Table::iterator Iterator;
typedef Table::const_iterator CIterator;
ErrorCode Add(const std::string & name, const std::string & value, int param = 0)
{
if( !CorrectCharacters(name) )
return err_incorrect_name;
if( AreBigLetters(name) )
{
std::string name_copy(name);
ToSmallLetters(name_copy);
return AddAfterChecking(name_copy, value, param);
}
else
return AddAfterChecking(name, value, param);
}
bool Empty() const
{
return table.empty();
}
void Clear()
{
return table.clear();
}
CIterator Begin() const
{
return table.begin();
}
CIterator End() const
{
return table.end();
}
ErrorCode Edit(const std::string & name, const std::string & value, int param = 0)
{
Table::iterator i = table.find(name);
if( i == table.end() )
// we don't have this variable in our table
return err_unknown_object;
i->second.value = value;
i->second.param = param;
return err_ok;
}
ErrorCode Delete(const std::string & name)
{
Table::iterator i = table.find(name);
if( i == table.end() )
// we don't have this variable in our table
return err_unknown_object;
table.erase( i );
return err_ok;
}
ErrorCode GetValue(const std::string & name, const char * * value) const
{
Table::const_iterator i = table.find(name);
if( i == table.end() )
{
// we don't have this variable in our table
*value = 0;
return err_unknown_object;
}
*value = i->second.value.c_str();
return err_ok;
}
ErrorCode GetValueParam(const std::string & name, const char * * value, int * param) const
{
Table::const_iterator i = table.find(name);
if( i == table.end() )
{
// we don't have this variable in our table
*value = 0;
return err_unknown_object;
}
*value = i->second.value.c_str();
*param = i->second.param;
return err_ok;
}
Table * GetTable()
{
return &table;
}
private:
Table table;
bool CorrectCharacter(int c, bool digit)
/*!
this method returns true if a character 'c' is a character
which can be in a name
if 'can_be_digit' is true that means when the 'c' is a digit this
method returns true otherwise it returns false
*/
static bool CorrectCharacter(int c, bool can_be_digit)
{
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
return true;
if( digit && (c>='0' && c<='9') )
if( can_be_digit && (c>='0' && c<='9') )
return true;
return false;
}
bool CorrectCharacters(const std::string & name)
/*!
this method returns true if the name can be as a name of an object
*/
static bool IsNameCorrect(const std::string & name)
{
if( name.empty() )
return false;
@ -205,52 +128,355 @@ private:
return true;
}
static int SmallLetter(int c)
/*!
this method adds one object (variable of function) into the table
*/
ErrorCode Add(const std::string & name, const std::string & value, int param = 0)
{
if( c>='A' && c<='Z' )
return c-'A'+'a';
if( !IsNameCorrect(name) )
return err_incorrect_name;
return c;
}
static bool AreBigLetters(const std::string & name)
{
std::string::const_iterator i;
for(i=name.begin() ; i!=name.end() ; ++i)
if( *i>='A' && *i<='Z' )
return true;
return false;
}
void ToSmallLetters(std::string & name)
{
std::string::iterator i;
for(i=name.begin() ; i!=name.end() ; ++i)
*i = SmallLetter(*i);
}
ErrorCode AddAfterChecking(const std::string & name, const std::string & value, int param)
{
Table::iterator i = table.find(name);
Iterator i = table.find(name);
if( i != table.end() )
// we have this object in our table
return err_object_exists;
table.insert( std::make_pair(name, ObjectValue(value, param)) );
table.insert( std::make_pair(name, Item(value, param)) );
return err_ok;
}
};
/*!
this method returns 'true' if the table is empty
*/
bool Empty() const
{
return table.empty();
}
/*!
this method clears the table
*/
void Clear()
{
return table.clear();
}
/*!
this method returns 'const_iterator' on the first item on the table
*/
CIterator Begin() const
{
return table.begin();
}
/*!
this method returns 'const_iterator' pointing at the space after last item
(returns table.end())
*/
CIterator End() const
{
return table.end();
}
/*!
this method changes the value and the number of parameters for a specific object
*/
ErrorCode EditValue(const std::string & name, const std::string & value, int param = 0)
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
Iterator i = table.find(name);
if( i == table.end() )
return err_unknown_object;
i->second.value = value;
i->second.param = param;
return err_ok;
}
/*!
this method changes the name of a specific object
*/
ErrorCode EditName(const std::string & old_name, const std::string & new_name)
{
if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
return err_incorrect_name;
Iterator old_i = table.find(old_name);
if( old_i == table.end() )
return err_unknown_object;
if( old_name == new_name )
// the new name is the same as the old one
// we treat it as a normal situation
return err_ok;
ErrorCode err = Add(new_name, old_i->second.value, old_i->second.param);
if( err == err_ok )
{
old_i = table.find(old_name);
TTMATH_ASSERT( old_i != table.end() )
table.erase(old_i);
}
return err;
}
/*!
this method deletes an object
*/
ErrorCode Delete(const std::string & name)
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
Iterator i = table.find(name);
if( i == table.end() )
return err_unknown_object;
table.erase( i );
return err_ok;
}
/*!
this method sets the value of a specific object
*/
ErrorCode GetValue(const std::string & name, std::string & value) const
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
CIterator i = table.find(name);
if( i == table.end() )
{
value.clear();
return err_unknown_object;
}
value = i->second.value;
return err_ok;
}
/*!
this method sets the value of a specific object
(this version is used for not copying the whole string)
*/
ErrorCode GetValue(const std::string & name, const char ** value) const
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
CIterator i = table.find(name);
if( i == table.end() )
{
*value = 0;
return err_unknown_object;
}
*value = i->second.value.c_str();
return err_ok;
}
/*!
this method sets the value and the number of parameters
of a specific object
*/
ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
CIterator i = table.find(name);
if( i == table.end() )
{
value.empty();
*param = 0;
return err_unknown_object;
}
value = i->second.value;
*param = i->second.param;
return err_ok;
}
/*!
this method sets the value and the number of parameters
of a specific object
(this version is used for not copying the whole string)
*/
ErrorCode GetValueAndParam(const std::string & name, const char ** value, int * param) const
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
CIterator i = table.find(name);
if( i == table.end() )
{
*value = 0;
*param = 0;
return err_unknown_object;
}
*value = i->second.value.c_str();
*param = i->second.param;
return err_ok;
}
/*!
this method returns a pointer into the table
*/
Table * GetTable()
{
return &table;
}
private:
Table table;
}; // end of class Objects
/*!
objects of the class History are used to keep values in functions
which take a lot of time during calculating, for instance in the
function Factorial(x)
it means that when we're calculating e.g. Factorial(1000) and the
Factorial finds that we have calculated it before, the value (result)
is taken from the history
*/
template<class ValueType>
class History
{
/*!
one item in the History's object holds a key, a value for the key
and a corresponding error code
*/
struct Item
{
ValueType key, value;
ErrorCode err;
};
/*!
we use std::list for simply deleting the first item
but because we're searching through the whole container
(in the method Get) the container should not be too big
(linear time of searching)
*/
typedef std::list<Item> buffer_type;
buffer_type buffer;
typename buffer_type::size_type buffer_max_size;
public:
/*!
default constructor
default max size of the History's container is 10 items
*/
History()
{
buffer_max_size = 10;
}
/*!
a constructor which takes another value of the max size
of the History's container
*/
History(typename buffer_type::size_type new_size)
{
buffer_max_size = new_size;
}
/*!
this method adds one item into the History
if the size of the container is greater than buffer_max_size
the first item will be removed
*/
void Add(const ValueType & key, const ValueType & value, ErrorCode err)
{
Item item;
item.key = key;
item.value = value;
item.err = err;
buffer.insert( buffer.end(), item );
if( buffer.size() > buffer_max_size )
buffer.erase(buffer.begin());
}
/*!
this method checks whether we have an item which has the key equal 'key'
if there's such item the method sets the 'value' and the 'err'
and returns true otherwise it returns false and 'value' and 'err'
remain unchanged
*/
bool Get(const ValueType & key, ValueType & value, ErrorCode & err)
{
typename buffer_type::iterator i = buffer.begin();
for( ; i != buffer.end() ; ++i )
{
if( i->key == key )
{
value = i->value;
err = i->err;
return true;
}
}
return false;
}
}; // end of class History
} // namespace

View File

@ -42,7 +42,7 @@
/*!
\file ttmathparser.h
\brief Mathematical parser
\brief A mathematical parser
*/
#include <fstream>
@ -654,13 +654,13 @@ void Tan(int sindex, int amount_of_args, ValueType & result)
Error( err );
}
void CTan(int sindex, int amount_of_args, ValueType & result)
void Cot(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::CTan(stack[sindex].value, &err);
result = ttmath::Cot(stack[sindex].value, &err);
if(err != err_ok)
Error( err );
@ -794,12 +794,12 @@ void ATan(int sindex, int amount_of_args, ValueType & result)
}
void ACTan(int sindex, int amount_of_args, ValueType & result)
void ACot(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);
result = ttmath::ACot(stack[sindex].value);
}
@ -889,6 +889,147 @@ void Not(int sindex, int amount_of_args, ValueType & result)
result.SetZero();
}
void DegToRad(int sindex, int amount_of_args, ValueType & result)
{
ErrorCode err;
if( amount_of_args == 1 )
{
result = ttmath::DegToRad(stack[sindex].value, &err);
}
else
if( amount_of_args == 3 )
{
result = ttmath::DegToRad( stack[sindex].value, stack[sindex+2].value,
stack[sindex+4].value, &err);
}
else
Error( err_improper_amount_of_arguments );
if( err != err_ok )
Error( err );
}
void RadToDeg(int sindex, int amount_of_args, ValueType & result)
{
ErrorCode err;
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
result = ttmath::RadToDeg(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void DegToDeg(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 3 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::DegToDeg( stack[sindex].value, stack[sindex+2].value,
stack[sindex+4].value, &err);
if( err != err_ok )
Error( err );
}
void Ceil(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::Ceil(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void Floor(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::Floor(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void Sqrt(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::Sqrt(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void Sinh(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::Sinh(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void Cosh(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::Cosh(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void Tanh(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::Tanh(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
void Coth(int sindex, int amount_of_args, ValueType & result)
{
if( amount_of_args != 1 )
Error( err_improper_amount_of_arguments );
ErrorCode err;
result = ttmath::Coth(stack[sindex].value, &err);
if( err != err_ok )
Error( err );
}
/*!
this method returns the value from a user-defined function
@ -902,7 +1043,7 @@ bool GetValueOfUserDefinedFunction(const std::string & function_name, int amount
const char * string_value;
int param;
if( puser_functions->GetValueParam(function_name, &string_value, &param) != err_ok )
if( puser_functions->GetValueAndParam(function_name, &string_value, &param) != err_ok )
return false;
if( param != amount_of_args )
@ -1003,7 +1144,9 @@ void CreateFunctionsTable()
InsertFunctionToTable(std::string("sin"), &Parser<ValueType>::Sin);
InsertFunctionToTable(std::string("cos"), &Parser<ValueType>::Cos);
InsertFunctionToTable(std::string("tan"), &Parser<ValueType>::Tan);
InsertFunctionToTable(std::string("ctan"), &Parser<ValueType>::CTan);
InsertFunctionToTable(std::string("tg"), &Parser<ValueType>::Tan);
InsertFunctionToTable(std::string("cot"), &Parser<ValueType>::Cot);
InsertFunctionToTable(std::string("ctg"), &Parser<ValueType>::Cot);
InsertFunctionToTable(std::string("int"), &Parser<ValueType>::Int);
InsertFunctionToTable(std::string("round"), &Parser<ValueType>::Round);
InsertFunctionToTable(std::string("ln"), &Parser<ValueType>::Ln);
@ -1014,13 +1157,27 @@ void CreateFunctionsTable()
InsertFunctionToTable(std::string("asin"), &Parser<ValueType>::ASin);
InsertFunctionToTable(std::string("acos"), &Parser<ValueType>::ACos);
InsertFunctionToTable(std::string("atan"), &Parser<ValueType>::ATan);
InsertFunctionToTable(std::string("actan"), &Parser<ValueType>::ACTan);
InsertFunctionToTable(std::string("atg"), &Parser<ValueType>::ATan);
InsertFunctionToTable(std::string("acot"), &Parser<ValueType>::ACot);
InsertFunctionToTable(std::string("actg"), &Parser<ValueType>::ACot);
InsertFunctionToTable(std::string("sgn"), &Parser<ValueType>::Sgn);
InsertFunctionToTable(std::string("mod"), &Parser<ValueType>::Mod);
InsertFunctionToTable(std::string("if"), &Parser<ValueType>::If);
InsertFunctionToTable(std::string("or"), &Parser<ValueType>::Or);
InsertFunctionToTable(std::string("and"), &Parser<ValueType>::And);
InsertFunctionToTable(std::string("not"), &Parser<ValueType>::Not);
InsertFunctionToTable(std::string("degtorad"), &Parser<ValueType>::DegToRad);
InsertFunctionToTable(std::string("radtodeg"), &Parser<ValueType>::RadToDeg);
InsertFunctionToTable(std::string("degtodeg"), &Parser<ValueType>::DegToDeg);
InsertFunctionToTable(std::string("ceil"), &Parser<ValueType>::Ceil);
InsertFunctionToTable(std::string("floor"), &Parser<ValueType>::Floor);
InsertFunctionToTable(std::string("sqrt"), &Parser<ValueType>::Sqrt);
InsertFunctionToTable(std::string("sinh"), &Parser<ValueType>::Sinh);
InsertFunctionToTable(std::string("cosh"), &Parser<ValueType>::Cosh);
InsertFunctionToTable(std::string("tanh"), &Parser<ValueType>::Tanh);
InsertFunctionToTable(std::string("tgh"), &Parser<ValueType>::Tanh);
InsertFunctionToTable(std::string("coth"), &Parser<ValueType>::Coth);
InsertFunctionToTable(std::string("ctgh"), &Parser<ValueType>::Coth);
}

View File

@ -41,14 +41,14 @@
/*!
\file ttmathtypes.h
\brief constants which are used in the library
\brief constants used in the library
As our library is written in header files (templates) we cannot use
constants like 'const int' etc. because we should have some source files
*.cpp to define this variables. Only what we can have are constants
defined by #define preprocessor macro.
defined by #define preprocessor macros.
All macros are preceded TTMATH_ part
All macros are preceded by TTMATH_ prefix
*/
@ -60,8 +60,8 @@
the version of the library
*/
#define TTMATH_MAJOR_VER 0
#define TTMATH_MINOR_VER 7
#define TTMATH_REVISION_VER 2
#define TTMATH_MINOR_VER 8
#define TTMATH_REVISION_VER 0
/*!
@ -74,7 +74,7 @@
is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
TTMATH_RELEASE
if you are confident that your code is without bugs you can define TTMATH_RELEASE
if you are confident that your code is perfect you can define TTMATH_RELEASE
macro for example by using -D option in gcc
gcc -DTTMATH_RELEASE -o myprogram myprogram.cpp
or by defining this macro in your code before using any header files of this library
@ -86,23 +86,33 @@
#endif
/*
VC doesn't have these macros
#if !defined(__i386__) && !defined(__amd64__)
#error "This code is designed only for x86/amd64 platforms (amd64 is very experimental now)"
#endif
*/
namespace ttmath
{
/*!
on 32bit platforms one word will be equal 32bits
on 64bit platforms one word will be 64bits
*/
#if !defined _M_X64 && !defined __x86_64__
/*!
we're using a 32bit platform
*/
#define TTMATH_PLATFORM32
#else
/*!
we're using a 64bit platform
*/
#define TTMATH_PLATFORM64
#endif
#ifdef TTMATH_PLATFORM32
/*!
on 32bit platforms one word (uint, sint) will be equal 32bits
*/
typedef unsigned int uint;
typedef signed int sint;
@ -116,16 +126,24 @@ namespace ttmath
*/
#define TTMATH_UINT_HIGHEST_BIT 2147483648u
/*!
the max value of the unsigned 32bit word (2^32 - 1)
(all bits equal one)
*/
#define TTMATH_UINT_MAX_VALUE 4294967295u
/*!
the number of words (32bit words on 32bit platform)
which are kept in built-in variables for a Big<> type
(these variables are defined in ttmathbig.h)
*/
#define TTMATH_BUILTIN_VARIABLES_SIZE 128u
#else
/*!
on 64bit platforms one word (uint, sint) will be equal 64bits
*/
typedef unsigned long uint;
typedef signed long sint;
@ -139,13 +157,18 @@ namespace ttmath
*/
#define TTMATH_UINT_HIGHEST_BIT 9223372036854775808ul
/*!
the max value of the unsigned 64bit word (2^64 - 1)
(all bits equal one)
*/
#define TTMATH_UINT_MAX_VALUE 18446744073709551615ul
/*!
the number of words (64bit words on 64bit platforms)
which are kept in built-in variables for a Big<> type
(these variables are defined in ttmathbig.h)
*/
#define TTMATH_BUILTIN_VARIABLES_SIZE 64ul
#endif
}
@ -159,12 +182,12 @@ namespace ttmath
TTMATH_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character
that means you can input values for example 1.2345 and 1,2345 as well
if you don't want it just put 0 there eg.
if you don't want it just put 0 there e.g.
#define TTMATH_COMMA_CHARACTER_2 0
then only TTMATH_COMMA_CHARACTER_1 will be used
don't put here any special character which is used by the parser
(for example a semicolon ';' shouldn't be here)
don't put there any special character which is used by the parser
(for example a semicolon ';' shouldn't be there)
*/
#define TTMATH_COMMA_CHARACTER_1 '.'
#define TTMATH_COMMA_CHARACTER_2 ','
@ -180,16 +203,16 @@ namespace ttmath
note! there'll not be so many iterations, iterations are stopped when
there is no sense to continue calculating (for example when the result
still remains unchanged after adding next series and we know that the next
series are smaller than previous)
series are smaller than previous ones)
*/
#define TTMATH_ARITHMETIC_MAX_LOOP 5000
#define TTMATH_ARITHMETIC_MAX_LOOP 10000
namespace ttmath
{
/*!
error codes
*/
@ -225,7 +248,14 @@ namespace ttmath
/*!
this simple class can be used in multithreading model
(you can write your own class derived from this one)
for example: in some functions like Factorial()
/at the moment only Factorial/ you can give a pointer to
the 'stop object', if the method WasStopSignal() of this
object returns true that means we should break the calculating
and return
*/
class StopCalculating
{
@ -274,7 +304,7 @@ namespace ttmath
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
was used)
What is it the 'reference' error?
What is the 'reference' error?
Some kind of methods use a reference as their argument to another object,
and the another object not always can be the same which is calling, e.g.
Big<1,2> foo(10);
@ -343,24 +373,28 @@ namespace ttmath
/*!
look at the description of macros TTMATH_RELEASE and TTMATH_DEBUG
*/
#ifdef TTMATH_DEBUG
#define TTMATH_REFERENCE_ASSERT(expression) \
if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__);
#if defined(__FILE__) && defined(__LINE__)
#define TTMATH_ASSERT(expression) \
if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__);
#define TTMATH_REFERENCE_ASSERT(expression) \
if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__);
/*
if your compiler doesn't support macros __FILE__ and __LINE__
you can above asserts change to:
#define TTMATH_ASSERT(expression) \
if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__);
#define TTMATH_REFERENCE_ASSERT(expression) \
if( &(expression) == this ) throw ReferenceError();
#else
#define TTMATH_REFERENCE_ASSERT(expression) \
if( &(expression) == this ) throw ReferenceError();
#define TTMATH_ASSERT(expression) \
if( !(expression) ) throw RuntimeError();
#endif
#define TTMATH_ASSERT(expression) \
if( !(expression) ) throw RuntimeError();
*/
#else
#define TTMATH_REFERENCE_ASSERT(expression)
#define TTMATH_ASSERT(expression)

View File

@ -45,6 +45,8 @@
\brief template class UInt<uint>
*/
#include <iostream>
#include <iomanip>
#include "ttmathtypes.h"
@ -54,7 +56,7 @@ namespace ttmath
{
/*!
\brief it implements a big integer value without a sign
\brief UInt implements a big integer value without a sign
value_size - how many bytes specify our value
on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
@ -73,6 +75,47 @@ public:
uint table[value_size];
/*!
this method is only for debugging purposes or when we want to make
a table of a variable (constant) in ttmathbig.h
it prints the table in a nice form of several columns
*/
void PrintTable(std::ostream & output) const
{
// how many columns there'll be
const int columns = 8;
int c = 1;
for(int i=value_size-1 ; i>=0 ; --i)
{
output << "0x" << std::setfill('0');
#ifdef TTMATH_PLATFORM32
output << std::setw(8);
#else
output << std::setw(16);
#endif
output << std::hex << table[i];
if( i>0 )
{
output << ", ";
if( ++c > columns )
{
output << std::endl;
c = 1;
}
}
}
output << std::endl;
}
/*!
it returns the size of the table
*/
@ -106,7 +149,7 @@ public:
this method sets the max value which this class can hold
(all bits will be one)
*/
void SetMaxValue()
void SetMax()
{
for(uint i=0 ; i<value_size ; ++i)
table[i] = TTMATH_UINT_MAX_VALUE;
@ -117,12 +160,14 @@ public:
this method sets the min value which this class can hold
(for an unsigned integer value the zero is the smallest value)
*/
void SetMinValue()
void SetMin()
{
SetZero();
}
#if !defined _M_X64 && !defined __x86_64__
#ifdef TTMATH_PLATFORM32
/*!
this method copies the value stored in an another table
@ -833,7 +878,7 @@ public:
}
#if !defined _M_X64 && !defined __x86_64__
#ifdef TTMATH_PLATFORM32
/*!
@ -1140,7 +1185,9 @@ public:
return moving;
}
#if !defined _M_X64 && !defined __x86_64__
#ifdef TTMATH_PLATFORM32
/*
this method returns the number of the highest set bit in one 32-bit word
@ -1218,7 +1265,8 @@ public:
}
#if !defined _M_X64 && !defined __x86_64__
#ifdef TTMATH_PLATFORM32
/*!
this method sets a special bit in the 'value'
@ -1291,7 +1339,9 @@ public:
public:
#if !defined _M_X64 && !defined __x86_64__
#ifdef TTMATH_PLATFORM32
/*!
@ -1534,18 +1584,26 @@ public:
*/
void Mul2Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
{
uint r2,r1,x1size,x2size,x1start,x2start;
uint r2,r1;
uint x1size=value_size, x2size=value_size;
uint x1start=0, x2start=0;
result.SetZero();
for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size);
for(x2size=value_size ; x2size>0 && ss2.table[x2size-1]==0 ; --x2size);
if( value_size > 2 )
{
// if the value_size is smaller than or equal to 2
// there is no sense to set x1size (and others) to another values
if( x1size==0 || x2size==0 )
return;
for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size);
for(x2size=value_size ; x2size>0 && ss2.table[x2size-1]==0 ; --x2size);
for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start);
for(x2start=0 ; x2start<x2size && ss2.table[x2start]==0 ; ++x2start);
if( x1size==0 || x2size==0 )
return;
for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start);
for(x2start=0 ; x2start<x2size && ss2.table[x2start]==0 ; ++x2start);
}
for(uint x1=x1start ; x1<x1size ; ++x1)
{
@ -1570,7 +1628,7 @@ public:
public:
#if !defined _M_X64 && !defined __x86_64__
#ifdef TTMATH_PLATFORM32
/*!
@ -2486,7 +2544,7 @@ public:
this method converts an UInt<another_size> type to this class
this operation has mainly sense if the value from p is
equal or smaller than that one which is returned from UInt<value_size>::SetMaxValue()
equal or smaller than that one which is returned from UInt<value_size>::SetMax()
it returns a carry if the value 'p' is too big
*/
@ -2518,6 +2576,18 @@ public:
}
/*!
this method converts the uint type to this class
*/
void FromUInt(uint value)
{
for(uint i=1 ; i<value_size ; ++i)
table[i] = 0;
table[0] = value;
}
/*!
this operator converts an UInt<another_size> type to this class
@ -2541,29 +2611,60 @@ public:
return *this;
}
/*!
this method convert an uint type to this class
this method converts the uint type to this class
*/
UInt<value_size> & operator=(uint i)
{
SetZero();
table[0] = i;
FromUInt(i);
return *this;
}
/*!
a constructor for converting an uint to this class
a constructor for converting the uint to this class
*/
UInt(uint i)
{
operator=(i);
FromUInt(i);
}
/*!
this method converts the sint type to this class
we provide operator(sint) and the constructor(sint) in order to allow
the programmer do that:
UInt<..> type = 10;
this constant 10 has the int type (signed int), if we don't give such
operators and constructors the compiler will not compile the program,
because it has to make a conversion and doesn't know into which type
(the UInt class has operator=(const char*), operator=(uint) etc.)
*/
UInt<value_size> & operator=(sint i)
{
FromUInt(uint(i));
return *this;
}
/*!
a constructor for converting string to this class (with base=10)
a constructor for converting the sint to this class
look at the description of UInt::operator=(sint)
*/
UInt(sint i)
{
FromUInt(uint(i));
}
/*!
a constructor for converting a string to this class (with the base=10)
*/
UInt(const char * s)
{
@ -2572,7 +2673,7 @@ public:
/*!
a constructor for converting string to this class (with base=10)
a constructor for converting a string to this class (with the base=10)
*/
UInt(const std::string & s)
{
@ -2615,12 +2716,11 @@ public:
/*!
a destructor
*/
virtual ~UInt()
~UInt()
{
}
/*!
this method returns the lowest value from table
@ -3081,10 +3181,13 @@ public:
}
#if defined _M_X64 || defined __x86_64__
// these methods for 64bit processors are defined in 'ttmathuint64.h'
#ifdef TTMATH_PLATFORM64
// these methods are for 64bit processors and are defined in 'ttmathuint64.h'
UInt<value_size> & operator=(unsigned int i);
UInt(unsigned int i);
UInt<value_size> & operator=(signed int i);
UInt(signed int i);
void SetFromTable(const unsigned int * temp_table, uint temp_table_len);
uint Add(const UInt<value_size> & ss2, uint c=0);
uint AddInt(uint value, uint index = 0);

View File

@ -52,7 +52,83 @@ namespace ttmath
*
*/
#if defined _M_X64 || defined __x86_64__
#ifdef TTMATH_PLATFORM64
/*!
in 64bit platforms we must define additional operators and contructors
in order to allow a user initializing the objects in this way:
UInt<...> type = 20;
or
UInt<...> type;
type = 30;
decimal constants such as 20, 30 etc. are integer literal of type int,
if the value is greater it can even be long int,
0 is an octal integer of type int
(ISO 14882 p2.13.1 Integer literals)
*/
/*!
this operator converts the unsigned int type to this class
***this operator is created only on a 64bit platform***
it takes one argument of 32bit
*/
template<uint value_size>
UInt<value_size> & UInt<value_size>::operator=(unsigned int i)
{
FromUInt(uint(i));
return *this;
}
/*!
a constructor for converting the unsigned int to this class
***this constructor is created only on a 64bit platform***
it takes one argument of 32bit
*/
template<uint value_size>
UInt<value_size>::UInt(unsigned int i)
{
FromUInt(uint(i));
}
/*!
an operator for converting the signed int to this class
***this constructor is created only on a 64bit platform***
it takes one argument of 32bit
look at the description of UInt::operator=(sint)
*/
template<uint value_size>
UInt<value_size> & UInt<value_size>::operator=(signed int i)
{
FromUInt(uint(i));
return *this;
}
/*!
a constructor for converting the signed int to this class
***this constructor is created only on a 64bit platform***
it takes one argument of 32bit
look at the description of UInt::operator=(sint)
*/
template<uint value_size>
UInt<value_size>::UInt(signed int i)
{
FromUInt(uint(i));
}
/*!
@ -60,6 +136,8 @@ namespace ttmath
(warning: first values in temp_table are the highest words -- it's different
from our table)
***this method is created only on a 64bit platform***
we copy as many words as it is possible
if temp_table_len is bigger than value_size we'll try to round
@ -119,6 +197,8 @@ namespace ttmath
this method adding ss2 to the this and adding carry if it's defined
(this = this + ss2 + c)
***this method is created only on a 64bit platform***
c must be zero or one (might be a bigger value than 1)
function returns carry (1) (if it was)
*/
@ -131,16 +211,8 @@ namespace ttmath
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
/*
this part might be compiled with for example visual c
*/
__asm
{
}
#endif
#endif
#ifdef __GNUC__
@ -206,7 +278,8 @@ namespace ttmath
this method adds one word (at a specific position)
and returns a carry (if it was)
e.g.
***this method is created only on a 64bit platform***
if we've got (value_size=3):
table[0] = 10;
@ -229,14 +302,8 @@ namespace ttmath
register uint c;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
__asm
{
}
#endif
#endif
#ifdef __GNUC__
__asm__ __volatile__(
@ -297,6 +364,8 @@ namespace ttmath
and these words begin on the 'index' position
(it's used in the multiplication algorithm 2)
***this method is created only on a 64bit platform***
index should be equal or smaller than value_size-2 (index <= value_size-2)
x1 - lower word, x2 - higher word
@ -330,14 +399,8 @@ namespace ttmath
register uint c;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
__asm
{
}
#endif
#endif
#ifdef __GNUC__
__asm__ __volatile__(
@ -420,6 +483,8 @@ namespace ttmath
carry if it has been defined
(this = this - ss2 - c)
***this method is created only on a 64bit platform***
c must be zero or one (might be a bigger value than 1)
function returns carry (1) (if it was)
*/
@ -431,16 +496,9 @@ namespace ttmath
register uint * p2 = const_cast<uint*>(ss2.table);
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
__asm
{
}
#error "another compiler than GCC is currently not supported in 64bit mode"
#endif
#ifdef __GNUC__
__asm__ __volatile__(
@ -499,7 +557,7 @@ namespace ttmath
this method subtracts one word (at a specific position)
and returns a carry (if it was)
e.g.
***this method is created only on a 64bit platform***
if we've got (value_size=3):
table[0] = 10;
@ -522,14 +580,8 @@ namespace ttmath
register uint c;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
__asm
{
}
#endif
#endif
#ifdef __GNUC__
__asm__ __volatile__(
@ -589,6 +641,8 @@ namespace ttmath
this method moving once all bits into the left side
return value <- this <- C
***this method is created only on a 64bit platform***
the lowest bit will hold value of 'c' and
function returns the highest bit
*/
@ -598,17 +652,10 @@ namespace ttmath
register sint b = value_size;
register uint * p1 = table;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
__asm
{
}
#endif
#ifdef __GNUC__
__asm__ __volatile__(
@ -653,6 +700,8 @@ namespace ttmath
this method moving once all bits into the right side
C -> *this -> return value
***this method is created only on a 64bit platform***
the highest bit will be held value of 'c' and
function returns the lowest bit
*/
@ -664,12 +713,7 @@ namespace ttmath
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
__asm
{
}
#endif
@ -718,6 +762,8 @@ namespace ttmath
/*
this method returns the number of the highest set bit in one 32-bit word
if the 'x' is zero this method returns '-1'
***this method is created only on a 64bit platform***
*/
template<uint value_size>
sint UInt<value_size>::FindLeadingBitInWord(uint x)
@ -725,15 +771,9 @@ namespace ttmath
register sint result;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
__asm
{
}
#endif
#ifdef __GNUC__
__asm__ __volatile__(
@ -758,6 +798,8 @@ namespace ttmath
this method sets a special bit in the 'value'
and returns the result
***this method is created only on a 64bit platform***
bit is from <0,31>
e.g.
@ -769,15 +811,9 @@ namespace ttmath
uint UInt<value_size>::SetBitInWord(uint value, uint bit)
{
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
__asm
{
}
#endif
#ifdef __GNUC__
__asm__ __volatile__(
@ -808,6 +844,8 @@ namespace ttmath
this methos never returns a carry
***this method is created only on a 64bit platform***
it is an auxiliary method for version two of the multiplication algorithm
*/
template<uint value_size>
@ -824,16 +862,9 @@ namespace ttmath
register uint result2_;
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
__asm
{
}
#endif
#ifdef __GNUC__
__asm__ __volatile__(
@ -865,6 +896,8 @@ namespace ttmath
/*!
this method calculates 64bits word a:b / 32bits c (a higher, b lower word)
r = a:b / c and rest - remainder
***this method is created only on a 64bit platform***
*
* WARNING:
@ -884,15 +917,9 @@ namespace ttmath
*/
#ifndef __GNUC__
#error "another compiler than GCC is currently not supported in 64bit mode"
__asm
{
}
#endif
#ifdef __GNUC__
__asm__ __volatile__(