Compare commits
40 Commits
Author | SHA1 | Date | |
---|---|---|---|
d8b829f4c5 | |||
fca1bc1a33 | |||
c65857297b | |||
f530635262 | |||
9327b4ebd4 | |||
d695785cbb | |||
85d1b87ac0 | |||
bfdc6d3df3 | |||
5668fbecf5 | |||
3899b8631c | |||
460608859c | |||
978815f12d | |||
404727f3de | |||
4aebe9aa18 | |||
e18201ba35 | |||
5b24101a83 | |||
6da0386a2d | |||
c7c859fc76 | |||
1d81dc75ff | |||
712bfc9c3b | |||
91e7badb62 | |||
cfd719cca2 | |||
f1115a2ce9 | |||
ca51020fe6 | |||
f8f324f98f | |||
cdd95f602c | |||
98c2379182 | |||
2933213a02 | |||
4d0241c9c9 | |||
4f3f05fa9d | |||
f139e6457c | |||
29bb4fb3f7 | |||
5002f435ae | |||
61886fc829 | |||
25f876762a | |||
692ff5406e | |||
669698c6d7 | |||
93ba8ce17d | |||
d27cabec93 | |||
bc9d528a75 |
384
CHANGELOG
384
CHANGELOG
@@ -1,122 +1,262 @@
|
|||||||
Version 0.8.1 (2007.04.17):
|
Version 0.8.3 (2009.04.06):
|
||||||
* fixed: Big::PowFrac(..) didn't return a correct error code
|
* fixed: RclMoveAllWords() and RcrMoveAllWords() sometimes didn't return
|
||||||
(when 'this' was negative)
|
the proper carry, (when 'bits' was greater than or equal to 'value_size')
|
||||||
* added: Root(x; index) (and to the parser as well)
|
this had impact on Rcl() and Rcr(), they also returned the wrong carry
|
||||||
* added: macro: TTMATH_PRERELEASE_VER (can be either zero or one)
|
* fixed: UInt::Div() didn't return a correct result when the divisor was equal 1
|
||||||
* added: UInt::MulInt(int, UInt<int another_size>::&)
|
there was an error in UInt::DivInt() - when the divisor was 1 it returned
|
||||||
* added: Big::MulUInt(uint)
|
zero and the carry was set
|
||||||
* changed: Big::MulInt(sint)
|
* fixed: there was a TTMATH_REREFENCE_ASSERT error in Big::PowUInt() caused by: start.Mul(start)
|
||||||
* added: Big::ToUInt(uint &)
|
* fixed: Big::Add incorrectly rounded 'this' when both exponents were equal
|
||||||
* changed: Big::ToInt(sint&)
|
it caused that sometimes when adding a zero the result has changed
|
||||||
* changed: Factorial() it uses Big::MulUInt() at the beginning
|
this had impact among other things on FromString() method
|
||||||
(faster now especially more on a 32bit platform)
|
"0,8" had different binary representation from "0,80"
|
||||||
* added: doxygen.cfg for generating a documentation from the doxygen
|
* fixed: template Big::FromBig(const Big<another_exp, another_man> & another)
|
||||||
* changed: UInt::Rcl(uint c=0) and UInt::Rcr(uint c=0) into
|
didn't correctly set the exponent (when the mantisses had different size -
|
||||||
UInt::Rcl2(uint bits, uint c) and UInt::Rcr2(uint bits, uint c)
|
when 'man' was different from 'another_man')
|
||||||
now they can move more than one bit and they are only private
|
this had impact on operator= too
|
||||||
* fixed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c)
|
sample:
|
||||||
didn't correctly return a carry if the 'bits' were equal
|
Big<2,3> a = 100;
|
||||||
to 'value_size*TTMATH_BITS_PER_UINT'
|
Big<3,5> b;
|
||||||
* changed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c)
|
b = a; // b had a wrong value
|
||||||
into UInt::Rcl(uint bits, uint c=0) and
|
* fixed: Big::Pow(const Big<exp, man> & pow)
|
||||||
UInt::Rcr(uint bits, uint c=0)
|
it's using PowInt() only when pow.exponent is in range (-man*TTMATH_BITS_PER_UINT; 0]
|
||||||
they are faster now when the bits is greater than a half of
|
previously the powering 'hung' on an input like this: "(1+ 1e-10000) ^ 10e100000000"
|
||||||
the TTMATH_BITS_PER_UINT
|
(there was 10e100000000 iterations in PowInt())
|
||||||
* changed: UInt::CompensationToLeft() it's faster now
|
* fixed: in function DegToRad(const ValueType & x, ErrorCode * err = 0) it is better
|
||||||
* changed: more small changes where there were UInt::Rcl(uint c=0) and
|
to make division first and then mutliplication -- the result is more
|
||||||
UInt::Rcr(uint c=0) used
|
accurate especially when x is: 90,180,270 or 360
|
||||||
* changed: as the Big type uses UInt::Rcl() and UInt::Rcr() a lot then
|
* fixed: the parser didn't correctly treat operators for changing the base
|
||||||
it is much faster now (about 5-25%)
|
(radix) -- operators '#' and '&', e.g.:
|
||||||
* added: ASinh(), ACosh(), ATanh() /ATgh()/, ACoth() /ACtgh()/
|
'#sin(1)' was equal '0' -- there was a zero from '#' and then
|
||||||
and to the parser as well
|
it was multipied by 'sin(1)'
|
||||||
* added: UInt::BitAnd(), UInt::BitOr(), UInt::BitXor(), UInt::BitNot(),
|
the parser didn't check whether Big::FromString() has actually
|
||||||
Big::BitAnd(), Big::BitOr(), Big::BitXor()
|
read a proper value -- the method Big::FromString() didn't have
|
||||||
* added: to the parser: bitand(), bitor(), bitxor()
|
something to report such a situation
|
||||||
/band(), bor(), bxor()/
|
* fixed: Big::FromString() when the base is 10, the method reads the scientific
|
||||||
* changed: the way of parsing operators in the mathematical parser
|
part only if such a part it correctly supplied, e.g:
|
||||||
(the parser is not too much greedy now)
|
'1234e10', '1234e+10', '1234e-5'
|
||||||
|
previous '1234e' was treated as: '1234e0' (now parsing stops on 'e' and
|
||||||
Version 0.8.0 (2007.03.28):
|
the 'e' can be parsed by other parsers, e.g. the mathematical
|
||||||
* added: into the parser: SetFactorialMax()
|
parser -- now in the parser would be: '1234e' = '1234 * e' = '3354,3597...' )
|
||||||
* added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
|
* changed: renamed: Big::PowUInt(UInt<pow_size> pow) -> Big::Pow(UInt<pow_size> pow)
|
||||||
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
|
it returns 2 when there is: 0^0
|
||||||
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
|
* changed: renamed: Big::PowInt(Int<pow_size> pow) -> Big::Pow(Int<pow_size> pow)
|
||||||
* changed: class Objects in ttmathobjects.h has been completely rewritten,
|
it returns 2 when there is: 0^0 or 0^(-something)
|
||||||
we can change the names of user-defined variables or functions, and the
|
* changed: renamed: Big::PowBUInt() -> PowUInt(), Big::PowBInt() -> Big::PowInt()
|
||||||
names are case-sensitive now
|
they return 2 when the arguments are incorrect (like above)
|
||||||
* added: class History which is used in functions which take a lot of time
|
* changed: UInt::SetBitInWord(uint & value, uint bit) is taking the first argument by a reference now,
|
||||||
during calculating e.g. Factorial(x)
|
the specific bit is set in the 'value' and the method returns the last state of the bit (zero or one)
|
||||||
* added: Tg(x) a wrapper for Tan(x)
|
* changed: UInt::SetBit(uint bit_index) - it's using TTMATH_ASSERT now
|
||||||
* changed: CTan(x) is Cot(x) now
|
* changed: the size of built-in variables (constants) in ttmathbig.h
|
||||||
* added: Ctg(x) a wrapper for Cot(x)
|
now they consist of 256 32bit words
|
||||||
* added: ATg(x) a wrapper for ATan(x)
|
macro TTMATH_BUILTIN_VARIABLES_SIZE is equal: 256u on a 32bit platform and 128ul on a 64bit platform
|
||||||
* changed: ACTan(x) is ACot(x) now
|
* changed: the asm code in ttmathuint.h and ttmathuint64.h has been completely rewritten
|
||||||
* added: ACtg(x) a wrapper for ACot(x)
|
now UInt<> is faster about 15-30% than UInt<> from 0.8.2
|
||||||
* added: UInt::PrintTable() (for debugging etc.)
|
this has impact on Big<> too - it's faster about 10% now
|
||||||
* changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have
|
* changed: in the parser: the form with operators '#' and '&' is as follows:
|
||||||
been rewritten, now they have 128 32bit words (it's about 1232 valid
|
[-|+][#|&]numeric_value
|
||||||
decimal digits)
|
previous was: [-|+][#|&][-|+]numeric_value
|
||||||
* fixed: previous values from Big::SetPi() Big::SetE() and
|
* changed: in the parser: the short form of multiplication has the same
|
||||||
Big::SetLn2() were not too much accurate (last 2-3 words were wrong)
|
priority as the normal multiplication, e.g.:
|
||||||
* added: Big::SetLn10() (128 32bit words as well)
|
'2x^3' = 2 * (x^3)
|
||||||
* added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on
|
previous the priority was greater than powering priority
|
||||||
32bit platforms and 64ul on 64bit platforms (128/2=64)
|
previous: '2x^3' = (2*x) ^ 3
|
||||||
* added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
|
* added: UInt::GetBit(uint bit_index) - returning the state of the specific bit
|
||||||
* changed: a small optimisation in UInt::Mul2Big()
|
* added: Big::operator=(double) and Big::Big(double)
|
||||||
* added: at the end of ttmath.h: #include "ttmathparser.h"
|
* added: UInt::Pow(UInt<value_size> pow) and Int::Pow(Int<value_size> pow)
|
||||||
this is for convenience for a programmer, he can only use #include
|
* added: global template functions in ttmath.h:
|
||||||
with ttmath.h even if he uses the parser
|
ValueType GradToRad(const ValueType & x, ErrorCode * err = 0)
|
||||||
* added: to samples: big.cpp, parser.cpp
|
ValueType RadToGrad(const ValueType & x, ErrorCode * err = 0)
|
||||||
* added/changes/fixed: in copy-constructors and operators= in Int,
|
ValueType DegToGrad(const ValueType & x, ErrorCode * err = 0)
|
||||||
Uint and Big (more info in the commit log)
|
ValueType DegToGrad(const ValueType & d, const ValueType & m,
|
||||||
* renamed Big::SetDotOne() into Big::Set05()
|
const ValueType & s, ErrorCode * err = 0)
|
||||||
* changes: a few small optimisations in Big
|
ValueType GradToDeg(const ValueType & x, ErrorCode * err = 0)
|
||||||
* deleted: the word 'virtual' from destructors: UInt, Int, Big
|
* added: Parser::SetDegRadGrad(int angle) - 0 deg, 1 rad (default), 2 grad
|
||||||
(types in this library are not projected to be base-classes for
|
this affects following functions (in the parser only): sin, cos, tan, cot,
|
||||||
another ones derived from them)
|
asin, acos, atan, acot
|
||||||
* and more small changes (look at the commit log)
|
* added: functions to the parser: gradtorad(grad), radtograd(rad), degtograd(deg),
|
||||||
|
degtograd(d,m,s), gradtodeg(grad)
|
||||||
Version 0.7.2 (2007.03.09):
|
* added: UInt::FromString, added a parametr 'after_source'
|
||||||
* added: Big::Mod - the remainder from a division
|
which is pointing at the end of the parsed string
|
||||||
* added: Big::Sgn - the 'sign' from the value (-1,0,1)
|
* added: Int::FromString(): parameter 'const char ** after_source = 0'
|
||||||
* added: global functions Mod and Sgn too
|
if exists it's pointing at the end of the parsed string
|
||||||
* added: checking whether a user gives a correct value of a variable or function
|
* added: to UInt::FromString(), Int::FromString(), Big::FromString():
|
||||||
(user-defined variables/functions in the mathematical parser)
|
parameter 'bool * value_read = 0' - (if exists) tells
|
||||||
* added: into the parser: logical operators: > < >= <= == != && ||
|
whether something has actually been read (at least one digit)
|
||||||
* added: into the parser: logical functions: and() or() not() if()
|
* added: Objects::IsDefined(const std::string & name)
|
||||||
* added: ErrorCode::err_unknown_operator when the parser couldn't read an operator
|
returning true if such an object is defined
|
||||||
|
* removed: Big::FromString() this method doesn't longer recognize operators
|
||||||
Version 0.7.1 (2007.02.27):
|
for changing the base ('#' and '&')
|
||||||
* fixed the error 'overflow during printing' which was caused
|
|
||||||
by Big::FromInt(Int<int_size> value) (the sign has to be set at the end)
|
|
||||||
* fixed many small errors
|
Version 0.8.2 (2008.06.18):
|
||||||
* added ATan (arctan), ACTan (arc ctan) functions
|
* added: UInt::BitNot2() this method has been proposed by
|
||||||
|
Arek <kmicicc AnTispam users.sourceforge.net>
|
||||||
Version 0.7.0 (2007.02.24):
|
* changed: Int::FromInt(const Int<argument_size> & p),
|
||||||
* finished support for 64bit platforms
|
Int::FromInt(sint value) (it returns zero now)
|
||||||
* added ASin (arcsin), ACos (arccos) functions
|
Int::operator=(uint i)
|
||||||
|
Int::Int(uint i)
|
||||||
Version 0.6.4 (2007.01.29):
|
* added: Int::FromUInt(const UInt<argument_size> & p),
|
||||||
* fixed the problem with a sign in the mathematical parser /-(1) was 1/
|
Int::FromUInt(uint value)
|
||||||
* added UInt::AddInt and UInt::SubInt
|
and appropriate constructors and assignment
|
||||||
* changed UInt::AddOne and UInt::SubOne (much faster now)
|
operators as well
|
||||||
* added UInt::SetBitInWord
|
* changed: Big::FromInt(Int<int_size> value),
|
||||||
* changed UInt::SetBit (much faster now)
|
* added: Big::FromUInt(UInt<int_size> value),
|
||||||
* UInt::AddTwoUints renamed to UInt::AddTwoInts
|
Big::operator=(const UInt<int_size> & value)
|
||||||
* UInt::FindLeadingBit32 renamed to UInt::FindLeadingBitInWord
|
Big::Big(const UInt<int_size> & value)
|
||||||
* added UInt::SetBitInWord
|
* changed: the parser is allowed to recognize values which
|
||||||
* UInt::Mul64 renamed to UInt::MulTwoWords
|
begin with a dot, e.g '.5' is treated as '0.5'
|
||||||
* UInt::Div64 renamed to UInt::DivTwoWords
|
* added: a method Big::FromDouble(double) which converts from
|
||||||
* and more small changes in UInt type
|
standard double into a Big
|
||||||
* start adding support for Amd64 (not finished yet) (added ttmathuint64.h)
|
* added: uint Big::ToDouble(double&) - converting into double
|
||||||
|
* added: Big::FromBig() and an operator= and a contructor
|
||||||
Version 0.6.3 (2007.01.22):
|
for converting from another kind of a Big class
|
||||||
* position of arguments (x and base) in logarithm functions are swapped
|
* added: to the parser: avg(), sum()
|
||||||
* it's possible to use any multiplication algorithms in the same time
|
* added: 'decimal_point' parameter into Big::ToString(...)
|
||||||
(macros UINT_MUL_VERSION_'X' have gone)
|
* fixed: Big::operator>> didn't use TTMATH_COMMA_CHARACTER_2 macro
|
||||||
* added ExceptionInfo, ReferenceError and RuntimeError classes
|
* added: a short form of multiplication (without the '*' character)
|
||||||
* the mess in macros has been cleaned up
|
e.g. '5y', (it's used only if the second parameter
|
||||||
* added TTMATH_RELEASE macro
|
is a variable or function)
|
||||||
|
* changed: variables and functions are case-sensitive now
|
||||||
Version 0.6.2 (2007.01.10):
|
* added: variables and functions can have underline characters
|
||||||
* New division algorithm (radix b) where b is 2^32
|
in their names
|
||||||
|
* changed: 'max_digit_after_comma' in Big::ToString()
|
||||||
|
remove the -2 state
|
||||||
|
* added: 'remove_trailing_zeroes' in Big::ToString()
|
||||||
|
it's either true or false
|
||||||
|
* fixed/changed: the way of using Big::SetSign()
|
||||||
|
the method do not check whether there is a zero or not now
|
||||||
|
(even if there's a zero the method can set a sign bit)
|
||||||
|
I changed this due to some prior errors
|
||||||
|
(errors corrected in revision 17, 49 and 58)
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.8.1 (2007.04.17):
|
||||||
|
* fixed: Big::PowFrac(..) didn't return a correct error code
|
||||||
|
(when 'this' was negative)
|
||||||
|
* added: Root(x; index) (and to the parser as well)
|
||||||
|
* added: macro: TTMATH_PRERELEASE_VER (can be either zero or one)
|
||||||
|
* added: UInt::MulInt(int, UInt<int another_size>::&)
|
||||||
|
* added: Big::MulUInt(uint)
|
||||||
|
* changed: Big::MulInt(sint)
|
||||||
|
* added: Big::ToUInt(uint &)
|
||||||
|
* changed: Big::ToInt(sint&)
|
||||||
|
* changed: Factorial() it uses Big::MulUInt() at the beginning
|
||||||
|
(faster now especially more on a 32bit platform)
|
||||||
|
* added: doxygen.cfg for generating a documentation from the doxygen
|
||||||
|
* changed: UInt::Rcl(uint c=0) and UInt::Rcr(uint c=0) into
|
||||||
|
UInt::Rcl2(uint bits, uint c) and UInt::Rcr2(uint bits, uint c)
|
||||||
|
now they can move more than one bit and they are only private
|
||||||
|
* fixed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c)
|
||||||
|
didn't correctly return a carry if the 'bits' were equal
|
||||||
|
to 'value_size*TTMATH_BITS_PER_UINT'
|
||||||
|
* changed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c)
|
||||||
|
into UInt::Rcl(uint bits, uint c=0) and
|
||||||
|
UInt::Rcr(uint bits, uint c=0)
|
||||||
|
they are faster now when the bits is greater than a half of
|
||||||
|
the TTMATH_BITS_PER_UINT
|
||||||
|
* changed: UInt::CompensationToLeft() it's faster now
|
||||||
|
* changed: more small changes where there were UInt::Rcl(uint c=0) and
|
||||||
|
UInt::Rcr(uint c=0) used
|
||||||
|
* changed: as the Big type uses UInt::Rcl() and UInt::Rcr() a lot then
|
||||||
|
it is much faster now (about 5-25%)
|
||||||
|
* added: ASinh(), ACosh(), ATanh() /ATgh()/, ACoth() /ACtgh()/
|
||||||
|
and to the parser as well
|
||||||
|
* added: UInt::BitAnd(), UInt::BitOr(), UInt::BitXor(), UInt::BitNot(),
|
||||||
|
Big::BitAnd(), Big::BitOr(), Big::BitXor()
|
||||||
|
* added: to the parser: bitand(), bitor(), bitxor()
|
||||||
|
/band(), bor(), bxor()/
|
||||||
|
* changed: the way of parsing operators in the mathematical parser
|
||||||
|
(the parser is not too much greedy now)
|
||||||
|
|
||||||
|
|
||||||
|
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 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
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.7.1 (2007.02.27):
|
||||||
|
* fixed: the error 'overflow during printing' which was caused
|
||||||
|
by Big::FromInt(Int<int_size> value) (the sign has to be set at the end)
|
||||||
|
* fixed: many small errors
|
||||||
|
* added: ATan (arctan), ACTan (arc ctan) functions
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.7.0 (2007.02.24):
|
||||||
|
* finished: support for 64bit platforms
|
||||||
|
* added: ASin (arcsin), ACos (arccos) functions
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.6.4 (2007.01.29):
|
||||||
|
* fixed: the problem with a sign in the mathematical parser /-(1) was 1/
|
||||||
|
* added: UInt::AddInt and UInt::SubInt
|
||||||
|
* changed: UInt::AddOne and UInt::SubOne (much faster now)
|
||||||
|
* added: UInt::SetBitInWord
|
||||||
|
* changed: UInt::SetBit (much faster now)
|
||||||
|
UInt::AddTwoUints renamed to UInt::AddTwoInts
|
||||||
|
UInt::FindLeadingBit32 renamed to UInt::FindLeadingBitInWord
|
||||||
|
UInt::Mul64 renamed to UInt::MulTwoWords
|
||||||
|
UInt::Div64 renamed to UInt::DivTwoWords
|
||||||
|
* added: UInt::SetBitInWord
|
||||||
|
* and more small changes in UInt type
|
||||||
|
* start adding support for Amd64 (not finished yet) (added ttmathuint64.h)
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.6.3 (2007.01.22):
|
||||||
|
* changed: position of arguments (x and base) in logarithm functions are swapped
|
||||||
|
* changed: it's possible to use any multiplication algorithms in the same time
|
||||||
|
(macros UINT_MUL_VERSION_'X' have gone)
|
||||||
|
* added: ExceptionInfo, ReferenceError and RuntimeError classes
|
||||||
|
* changed: the mess in macros has been cleaned up
|
||||||
|
* added: TTMATH_RELEASE macro
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.6.2 (2007.01.10):
|
||||||
|
* added: New division algorithm (radix b) where b is 2^32
|
||||||
|
56
COPYRIGHT
56
COPYRIGHT
@@ -1,28 +1,28 @@
|
|||||||
Copyright (c) 2006-2007, Tomasz Sowa
|
Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice,
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
this list of conditions and the following disclaimer.
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
* Neither the name Tomasz Sowa nor the names of contributors to this
|
* Neither the name Tomasz Sowa nor the names of contributors to this
|
||||||
project may be used to endorse or promote products derived
|
project may be used to endorse or promote products derived
|
||||||
from this software without specific prior written permission.
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
THE POSSIBILITY OF SUCH DAMAGE.
|
THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
50
README
50
README
@@ -1,24 +1,26 @@
|
|||||||
TTMath - a bignum library for C++
|
TTMath - a bignum library for C++
|
||||||
|
|
||||||
TTMath is a small library which allows one to perform arithmetic operations
|
TTMath is a small library which allows one to perform arithmetic operations
|
||||||
with big unsigned integer, big signed integer and big floating point
|
with big unsigned integer, big signed integer and big floating point
|
||||||
numbers. It provides standard mathematical operations like adding,
|
numbers. It provides standard mathematical operations like adding,
|
||||||
subtracting, multiplying, dividing etc. With the library also goes
|
subtracting, multiplying, dividing etc. With the library also goes
|
||||||
a mathematical parser which helps you solving input formulas read directly
|
a mathematical parser which helps you solving input formulas read directly
|
||||||
from a user.
|
from a user.
|
||||||
|
|
||||||
TTMath is developed under the (new) BSD licence which means that it is free
|
TTMath is developed under the BSD licence which means that it is free
|
||||||
for both personal and commercial use but the library has some technical
|
for both personal and commercial use.
|
||||||
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
|
The library has some technical limitations:
|
||||||
well), and you can use this library only with the C++ programming language.
|
* there are only two platforms that are supported: x86 and x86_64,
|
||||||
|
* 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
|
The main goal of the library is to allow one to use big values in the same
|
||||||
compiled first because the whole library is written as the C++ templates.
|
way as the standard types like int, float, etc. It does not need to be
|
||||||
This means only C++ developers can use this library and one thing they have
|
compiled first because the whole library is written as the C++ templates.
|
||||||
to do is to use 'include' directive of the preprocessor. How big the
|
This means only C++ developers can use this library and one thing they have
|
||||||
values can be is set directly in the source code by the programmer.
|
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>
|
|
||||||
Project page: http://sourceforge.net/projects/ttmath
|
Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
|
Project pages: http://ttmath.slimaczek.pl
|
||||||
|
http://sourceforge.net/projects/ttmath
|
||||||
|
5
TODO
5
TODO
@@ -1,5 +0,0 @@
|
|||||||
TODO TTMath Library
|
|
||||||
===================
|
|
||||||
|
|
||||||
* Add functions for generating random values
|
|
||||||
* Add something like NaN to the Big<> type
|
|
27
constgen/Makefile
Normal file
27
constgen/Makefile
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
o = main.o
|
||||||
|
CC = g++
|
||||||
|
CFLAGS = -s -O2 -DCONSTANTSGENERATOR
|
||||||
|
name = gen
|
||||||
|
|
||||||
|
|
||||||
|
.SUFFIXES: .cpp .o
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
|
||||||
|
|
||||||
|
all: $(name)
|
||||||
|
|
||||||
|
$(name): $(o)
|
||||||
|
$(CC) -o $(name) $(CFLAGS) $(o)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
main.o: main.cpp
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o
|
||||||
|
rm -f *.s
|
||||||
|
rm -f $(name)
|
||||||
|
rm -f $(name).exe
|
126
constgen/main.cpp
Normal file
126
constgen/main.cpp
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the (new) BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||||
|
* project may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
this simple program is used to make constants which then are put into ttmathbig.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "../ttmath/ttmath.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
void CalcPi()
|
||||||
|
{
|
||||||
|
ttmath::Big<1,400> pi;
|
||||||
|
|
||||||
|
// 3100 digits after commna, taken from: http://zenwerx.com/pi.php
|
||||||
|
pi = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
|
||||||
|
"8214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196"
|
||||||
|
"4428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273"
|
||||||
|
"7245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094"
|
||||||
|
"3305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912"
|
||||||
|
"9833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132"
|
||||||
|
"0005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235"
|
||||||
|
"4201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859"
|
||||||
|
"5024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303"
|
||||||
|
"5982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989"
|
||||||
|
"3809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151"
|
||||||
|
"5574857242454150695950829533116861727855889075098381754637464939319255060400927701671139009848824012"
|
||||||
|
"8583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912"
|
||||||
|
"9331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279"
|
||||||
|
"6782354781636009341721641219924586315030286182974555706749838505494588586926995690927210797509302955"
|
||||||
|
"3211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000"
|
||||||
|
"8164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333"
|
||||||
|
"4547762416862518983569485562099219222184272550254256887671790494601653466804988627232791786085784383"
|
||||||
|
"8279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863"
|
||||||
|
"0674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759009"
|
||||||
|
"9465764078951269468398352595709825822620522489407726719478268482601476990902640136394437455305068203"
|
||||||
|
"4962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382"
|
||||||
|
"6868386894277415599185592524595395943104997252468084598727364469584865383673622262609912460805124388"
|
||||||
|
"4390451244136549762780797715691435997700129616089441694868555848406353422072225828488648158456028506"
|
||||||
|
"0168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125"
|
||||||
|
"1507606947945109659609402522887971089314566913686722874894056010150330861792868092087476091782493858"
|
||||||
|
"9009714909675985261365549781893129784821682998948722658804857564014270477555132379641451523746234364"
|
||||||
|
"5428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344"
|
||||||
|
"0374200731057853906219838744780847848968332144571386875194350643021845319104848100537061468067491927"
|
||||||
|
"8191197939952061419663428754440643745123718192179998391015919561814675142691239748940907186494231961"
|
||||||
|
"5679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215";
|
||||||
|
|
||||||
|
std::cout << "---------------- PI ----------------" << std::endl;
|
||||||
|
pi.mantissa.PrintTable(std::cout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CalcE()
|
||||||
|
{
|
||||||
|
ttmath::Big<1,400> e;
|
||||||
|
ttmath::uint steps;
|
||||||
|
|
||||||
|
// macro CONSTANTSGENERATOR has to be defined
|
||||||
|
e.ExpSurrounding0(1, &steps);
|
||||||
|
std::cout << "---------------- e ----------------" << std::endl;
|
||||||
|
e.mantissa.PrintTable(std::cout);
|
||||||
|
|
||||||
|
std::cout << "ExpSurrounding0(1): " << steps << " iterations" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CalcLn(int x)
|
||||||
|
{
|
||||||
|
ttmath::Big<1,400> ln;
|
||||||
|
ttmath::uint steps;
|
||||||
|
|
||||||
|
// macro CONSTANTSGENERATOR has to be defined
|
||||||
|
ln.LnSurrounding1(x, &steps);
|
||||||
|
std::cout << "---------------- ln(" << x << ") ----------------" << std::endl;
|
||||||
|
ln.mantissa.PrintTable(std::cout);
|
||||||
|
|
||||||
|
std::cout << "LnSurrounding1(" << x << "): " << steps << " iterations" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
CalcPi();
|
||||||
|
CalcE();
|
||||||
|
CalcLn(2);
|
||||||
|
CalcLn(10);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -31,7 +31,7 @@ PROJECT_NAME = TTMath
|
|||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# if some version control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 0.8.0
|
PROJECT_NUMBER = 0.8.2
|
||||||
|
|
||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||||
# base path where the generated documentation will be put.
|
# base path where the generated documentation will be put.
|
||||||
|
@@ -32,20 +32,21 @@ MyBig atemp;
|
|||||||
if( !atemp.Add(b) )
|
if( !atemp.Add(b) )
|
||||||
std::cout << "a + b = " << atemp << std::endl;
|
std::cout << "a + b = " << atemp << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "a + b = (carry) " << atemp << std::endl;
|
std::cout << "a + b = (carry)" << std::endl;
|
||||||
|
// it have no sense to print 'atemp' (it's undefined)
|
||||||
|
|
||||||
atemp = a;
|
atemp = a;
|
||||||
if( !atemp.Sub(b) )
|
if( !atemp.Sub(b) )
|
||||||
std::cout << "a - b = " << atemp << std::endl;
|
std::cout << "a - b = " << atemp << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "a - b = (carry) " << atemp << std::endl;
|
std::cout << "a - b = (carry)" << std::endl;
|
||||||
|
|
||||||
atemp = a;
|
atemp = a;
|
||||||
if( !atemp.Mul(b) )
|
if( !atemp.Mul(b) )
|
||||||
std::cout << "a * b = " << atemp << std::endl;
|
std::cout << "a * b = " << atemp << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "a * b = (carry: the result is too big) " << std::endl;
|
std::cout << "a * b = (carry)" << std::endl;
|
||||||
// it have no sense to print 'atemp' (it's undefined)
|
|
||||||
|
|
||||||
atemp = a;
|
atemp = a;
|
||||||
if( !atemp.Div(b) )
|
if( !atemp.Div(b) )
|
||||||
@@ -68,9 +69,8 @@ MyBig a,b;
|
|||||||
// 'a' will have the max value which can be held in this type
|
// 'a' will have the max value which can be held in this type
|
||||||
a.SetMax();
|
a.SetMax();
|
||||||
|
|
||||||
// at the moment conversions from double (or float etc.) are not supported
|
// conversion from double
|
||||||
// you cannot do that: b = 456.32f
|
b = 456.32;
|
||||||
b = "456.32";
|
|
||||||
|
|
||||||
// Look at the value 'a' and the product from a+b and a-b
|
// 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
|
// Don't worry this is the nature of floating point numbers
|
||||||
@@ -89,9 +89,9 @@ a * b = 12193540837712.2708
|
|||||||
a / b = 0.0012499665458095765
|
a / b = 0.0012499665458095765
|
||||||
Calculating with a carry
|
Calculating with a carry
|
||||||
a = 1.624801256070839555e+646457012
|
a = 1.624801256070839555e+646457012
|
||||||
b = 456.32
|
b = 456.31999999999999
|
||||||
a + b = 1.624801256070839555e+646457012
|
a + b = 1.624801256070839555e+646457012
|
||||||
a - b = 1.624801256070839555e+646457012
|
a - b = 1.624801256070839555e+646457012
|
||||||
a * b = (carry: the result is too big)
|
a * b = (carry)
|
||||||
a / b = 3.56066193914542329e+646457009
|
a / b = 3.56066193914542334e+646457009
|
||||||
*/
|
*/
|
||||||
|
31
tests/Makefile
Normal file
31
tests/Makefile
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
CC = g++
|
||||||
|
o = main.o uinttest.o
|
||||||
|
CFLAGS = -Wall -O2 -s
|
||||||
|
ttmath = ..
|
||||||
|
name = tests
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.SUFFIXES: .cpp .o
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CC) -c $(CFLAGS) -I$(ttmath) $<
|
||||||
|
|
||||||
|
|
||||||
|
all: $(name)
|
||||||
|
|
||||||
|
|
||||||
|
$(name): $(o)
|
||||||
|
$(CC) -o $(name) $(CFLAGS) -I$(ttmath) $(o)
|
||||||
|
|
||||||
|
|
||||||
|
main.o: main.cpp uinttest.h
|
||||||
|
uinttest.o: uinttest.cpp uinttest.h
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o
|
||||||
|
rm -f $(name)
|
||||||
|
rm -f $(name).exe
|
||||||
|
|
||||||
|
|
68
tests/main.cpp
Normal file
68
tests/main.cpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the (new) BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||||
|
* project may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <ttmath/ttmath.h>
|
||||||
|
#include "uinttest.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char uint_tests_file[] = "tests.uint32";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_uint()
|
||||||
|
{
|
||||||
|
UIntTest test;
|
||||||
|
|
||||||
|
test.set_file_name(uint_tests_file);
|
||||||
|
test.go();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
using namespace ttmath;
|
||||||
|
|
||||||
|
|
||||||
|
test_uint();
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
92
tests/tests.uint32
Normal file
92
tests/tests.uint32
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
# Add
|
||||||
|
|
||||||
|
# min_bits max_bits a b result carry
|
||||||
|
add 32 0 0 0 0 0
|
||||||
|
add 32 0 1 1 2 0
|
||||||
|
add 32 0 2342234 3563456 5905690 0
|
||||||
|
add 32 0 254455 3453435 3707890 0
|
||||||
|
add 32 0 4294967295 0 4294967295 0
|
||||||
|
add 32 32 4294967295 1 0 1
|
||||||
|
add 32 32 4294967295 0 4294967295 0
|
||||||
|
add 64 64 18446744073709551615 1 0 1
|
||||||
|
add 64 64 18446744073709551615 0 18446744073709551615 0
|
||||||
|
add 96 96 79228162514264337593543950335 1 0 1
|
||||||
|
add 96 96 79228162514264337593543950335 0 79228162514264337593543950335 0
|
||||||
|
add 128 128 340282366920938463463374607431768211455 1 0 1
|
||||||
|
add 128 128 340282366920938463463374607431768211455 0 340282366920938463463374607431768211455 0
|
||||||
|
add 160 160 1461501637330902918203684832716283019655932542975 1 0 1
|
||||||
|
add 160 160 1461501637330902918203684832716283019655932542975 0 1461501637330902918203684832716283019655932542975 0
|
||||||
|
add 192 192 6277101735386680763835789423207666416102355444464034512895 1 0 1
|
||||||
|
add 192 192 6277101735386680763835789423207666416102355444464034512895 0 6277101735386680763835789423207666416102355444464034512895 0
|
||||||
|
|
||||||
|
|
||||||
|
# AddInt
|
||||||
|
|
||||||
|
# min_bits max_bits bits_per_int a b(int) index result carry
|
||||||
|
addint 32 0 32 0 0 0 0 0
|
||||||
|
addint 32 0 32 1000 2000 0 3000 0
|
||||||
|
addint 64 0 32 562342345 1423445 1 6113650284997065 0
|
||||||
|
addint 64 0 32 5342342455 3423553423 0 8765895878 0
|
||||||
|
addint 96 0 32 478895734 46756734 2 862509505820513898647477878 0
|
||||||
|
addint 128 0 32 27370506140054471803784984408165997441 24543 3 27372450636847059393422542757339093889 0
|
||||||
|
addint 128 128 32 340282366841711102552375003685868034945 2234543 3 177038656721750864719686733515479937 1
|
||||||
|
addint 160 160 32 1461501637330902918124457471805283415910032366465 3 3 158457126631793409034731674497 1
|
||||||
|
addint 192 0 32 6277101735386680763835789423128439055191355840718134336385 3354 1 6277101735386680763835789423128439055191355855123454647169 0
|
||||||
|
addint 192 192 32 6277101735386680763835789423128439055191355840718134336385 3354 5 4901876491607848387655079701569502248322251848964993 1
|
||||||
|
|
||||||
|
addint 64 0 64 0 0 0 0 0
|
||||||
|
addint 64 0 64 5342342 345534234 0 350876576 0
|
||||||
|
addint 64 0 64 5342342455 34235534234 0 39577876689 0
|
||||||
|
addint 64 64 64 18446744073709550615 2000 0 999 1
|
||||||
|
addint 128 0 64 42895062544824211012058135 3453234 0 42895062544824211015511369 0
|
||||||
|
addint 128 0 64 42895062544824211012058135 456234234 1 8458931214807741031021280279 0
|
||||||
|
addint 128 128 64 340282366920938426569886460012664978455 45623 1 804702316727431770143767 1
|
||||||
|
addint 192 192 64 6277101735386680763835789423207666379208867297044931279895 45623234 1 841563227924816702308613143 1
|
||||||
|
addint 192 192 64 6277101735386679588840776445207152040176347835149297122327 45623234 2 15523607057094857017675614218510090830281178135 1
|
||||||
|
addint 192 192 64 6277101735386680763835789423207666416102355444464034512895 1 0 0 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# AddTwoInts
|
||||||
|
# a the value
|
||||||
|
# c lower word
|
||||||
|
# b higher word
|
||||||
|
# index - index of the lower (c) word
|
||||||
|
# if there is a carry the result is skipped
|
||||||
|
|
||||||
|
# min_bits max_bits bits_per_int a b(int) c(int) index result carry
|
||||||
|
addtwoints 64 0 32 0 0 0 0 0 0
|
||||||
|
addtwoints 64 0 32 23542345 3453245 2356252356 0 14831576719870221 0
|
||||||
|
addtwoints 64 64 32 4563456879824345332 3453245255 3673623543 0 0 1
|
||||||
|
addtwoints 96 0 32 345345634564352344231 1231354534 345324551 1 22714482299528678798871855271 0
|
||||||
|
addtwoints 96 96 32 33333336690445123453645645123 4241542514 145235414 1 0 1
|
||||||
|
addtwoints 128 0 32 921345787234870984751756 2356245656 3423623455 2 186681013820253010515426931265335245452 0
|
||||||
|
addtwoints 128 128 32 259817508127340892734075234234345345346 3452345324 452354345 2 0 1
|
||||||
|
addtwoints 160 0 32 458674036702857083457018457034 435236456 1451234242 1 466702732224470435083940719562 0
|
||||||
|
addtwoints 160 0 32 258672084570198475012875019876674534523452543562 935245345 736765636 3 576919584276960743542382023227664277469907669578 0
|
||||||
|
addtwoints 192 0 32 2398670187501982374012837086745045 3253453245 234567536 4 4754927244626858434362642830810490464530603685767816794581 0
|
||||||
|
addtwoints 192 192 32 1734564564356435667546738087098769876387468736123143453646 3456345245 3256347435 4 0 1
|
||||||
|
|
||||||
|
|
||||||
|
addtwoints 128 0 64 0 0 0 0 0 0
|
||||||
|
addtwoints 128 0 64 14513452345 234512412345 8473567534 0 4325990452636459442359440119399 0
|
||||||
|
addtwoints 128 128 64 325434534534536347567567356714513452345 4324546234512412345 8473567534 0 0 1
|
||||||
|
addtwoints 192 0 64 8786356223462562562561234 4356879827345 34745638455 1 1482569380039046311960318103044992688410168990618834 0
|
||||||
|
addtwoints 192 0 64 875687458745872039847234234048572306857602 12341234356 3472568734534 1 4199505313073142510985676024483326499863441546882 0
|
||||||
|
addtwoints 192 192 64 6234554767823878635622346242564564564564564564562562561234 457644356879827345 34844576655 1 0 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
424
tests/uinttest.cpp
Normal file
424
tests/uinttest.cpp
Normal file
@@ -0,0 +1,424 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the (new) BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||||
|
* project may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "uinttest.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void UIntTest::set_file_name(const std::string & f)
|
||||||
|
{
|
||||||
|
file_name = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool UIntTest::read_uint(uuint & result)
|
||||||
|
{
|
||||||
|
UInt<1> temp;
|
||||||
|
|
||||||
|
int c = temp.FromString(pline, 10, &pline);
|
||||||
|
|
||||||
|
result = temp.ToUInt();
|
||||||
|
|
||||||
|
if( c )
|
||||||
|
{
|
||||||
|
std::cerr << " carry from reading uint" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<uuint type_size>
|
||||||
|
bool UIntTest::read_uint(UInt<type_size> & result)
|
||||||
|
{
|
||||||
|
int c = result.FromString(pline, 10, &pline);
|
||||||
|
|
||||||
|
if( c )
|
||||||
|
{
|
||||||
|
std::cerr << " carry from UInt<>::FromString()" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool UIntTest::check_minmax_bits(int type_size)
|
||||||
|
{
|
||||||
|
uuint min_bits;
|
||||||
|
uuint max_bits;
|
||||||
|
|
||||||
|
read_uint(min_bits);
|
||||||
|
read_uint(max_bits);
|
||||||
|
|
||||||
|
if( min_bits != 0 && type_size * TTMATH_BITS_PER_UINT < (unsigned int)min_bits )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( max_bits != 0 && type_size * TTMATH_BITS_PER_UINT > (unsigned int)max_bits )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool UIntTest::check_minmax_bits_bitperint(int type_size)
|
||||||
|
{
|
||||||
|
if( !check_minmax_bits(type_size) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uuint bits;
|
||||||
|
|
||||||
|
read_uint(bits);
|
||||||
|
|
||||||
|
if( TTMATH_BITS_PER_UINT != bits )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool UIntTest::check_end()
|
||||||
|
{
|
||||||
|
skip_white_characters();
|
||||||
|
|
||||||
|
if( *pline!='#' && *pline!= 0 )
|
||||||
|
{
|
||||||
|
std::cerr << "syntax error" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<uuint type_size>
|
||||||
|
bool UIntTest::check_result_carry(const ttmath::UInt<type_size> & result, const ttmath::UInt<type_size> & new_result,
|
||||||
|
int carry, int new_carry)
|
||||||
|
{
|
||||||
|
bool ok = true;
|
||||||
|
|
||||||
|
if( new_carry != carry )
|
||||||
|
{
|
||||||
|
std::cerr << "Incorrect carry: " << new_carry << " (expected: " << carry << ")" << std::endl;
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( new_result != result )
|
||||||
|
{
|
||||||
|
std::cerr << "Incorrect result: " << new_result << " (expected: " << result << ")" << std::endl;
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<uuint type_size>
|
||||||
|
bool UIntTest::check_result_or_carry(const ttmath::UInt<type_size> & result, const ttmath::UInt<type_size> & new_result,
|
||||||
|
int carry, int new_carry)
|
||||||
|
{
|
||||||
|
if( new_carry != carry )
|
||||||
|
{
|
||||||
|
std::cerr << "Incorrect carry: " << new_carry << " (expected: " << carry << ")" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( new_carry == 1 )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if( new_result != result )
|
||||||
|
{
|
||||||
|
std::cerr << "Incorrect result: " << new_result << " (expected: " << result << ")" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<uuint type_size>
|
||||||
|
void UIntTest::test_add()
|
||||||
|
{
|
||||||
|
UInt<type_size> a,b,result, new_result;
|
||||||
|
|
||||||
|
if( !check_minmax_bits(type_size) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
read_uint(a);
|
||||||
|
read_uint(b);
|
||||||
|
read_uint(result);
|
||||||
|
|
||||||
|
uuint carry;
|
||||||
|
read_uint(carry);
|
||||||
|
|
||||||
|
std::cerr << '[' << row << "] Add<" << type_size << ">: ";
|
||||||
|
|
||||||
|
if( !check_end() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
new_result = a;
|
||||||
|
int new_carry = new_result.Add(b);
|
||||||
|
|
||||||
|
if( check_result_carry(result, new_result, carry, new_carry) )
|
||||||
|
std::cerr << "ok" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<uuint type_size>
|
||||||
|
void UIntTest::test_addint()
|
||||||
|
{
|
||||||
|
UInt<type_size> a, result, new_result;
|
||||||
|
|
||||||
|
if( !check_minmax_bits_bitperint(type_size) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
uuint b, index, carry;
|
||||||
|
|
||||||
|
read_uint(a);
|
||||||
|
read_uint(b);
|
||||||
|
read_uint(index);
|
||||||
|
read_uint(result);
|
||||||
|
|
||||||
|
read_uint(carry);
|
||||||
|
|
||||||
|
std::cerr << '[' << row << "] AddInt<" << type_size << ">: ";
|
||||||
|
|
||||||
|
if( !check_end() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
new_result = a;
|
||||||
|
int new_carry = new_result.AddInt(b, index);
|
||||||
|
|
||||||
|
if( check_result_carry(result, new_result, carry, new_carry) )
|
||||||
|
std::cerr << "ok" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uuint type_size>
|
||||||
|
void UIntTest::test_addtwoints()
|
||||||
|
{
|
||||||
|
UInt<type_size> a, result, new_result;
|
||||||
|
|
||||||
|
if( !check_minmax_bits_bitperint(type_size) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::cerr << '[' << row << "] AddTwoInts<" << type_size << ">: ";
|
||||||
|
|
||||||
|
uuint b, c, index, carry;
|
||||||
|
|
||||||
|
read_uint(a);
|
||||||
|
read_uint(b);
|
||||||
|
read_uint(c);
|
||||||
|
read_uint(index);
|
||||||
|
read_uint(result);
|
||||||
|
|
||||||
|
read_uint(carry);
|
||||||
|
|
||||||
|
|
||||||
|
if( !check_end() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( index >= type_size - 1 )
|
||||||
|
{
|
||||||
|
std::cerr << "index too large" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
new_result = a;
|
||||||
|
int new_carry = new_result.AddTwoInts(b, c, index);
|
||||||
|
|
||||||
|
if( check_result_or_carry(result, new_result, carry, new_carry) )
|
||||||
|
std::cerr << "ok" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int UIntTest::upper_char(int c)
|
||||||
|
{
|
||||||
|
if( c>='a' && c<='z' )
|
||||||
|
return c - 'a' + 'A';
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool UIntTest::is_white(int c)
|
||||||
|
{
|
||||||
|
if( c==' ' || c=='\t' || c==13 )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UIntTest::skip_white_characters()
|
||||||
|
{
|
||||||
|
while( is_white(*pline) )
|
||||||
|
++pline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool UIntTest::read_method()
|
||||||
|
{
|
||||||
|
skip_white_characters();
|
||||||
|
|
||||||
|
if( *pline == '#' )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
method.clear();
|
||||||
|
|
||||||
|
for(int c = upper_char(*pline) ; c>='A'&& c<='Z' ; c = upper_char(*pline) )
|
||||||
|
{
|
||||||
|
method += c;
|
||||||
|
++pline;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( method.empty() )
|
||||||
|
{
|
||||||
|
skip_white_characters();
|
||||||
|
if( *pline == 0 )
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << '[' << row << "] ";
|
||||||
|
std::cerr << "syntax error" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void UIntTest::test_method()
|
||||||
|
{
|
||||||
|
const char * p = pline;
|
||||||
|
|
||||||
|
if( method == "ADD" )
|
||||||
|
{
|
||||||
|
pline = p; test_add<1>();
|
||||||
|
pline = p; test_add<2>();
|
||||||
|
pline = p; test_add<3>();
|
||||||
|
pline = p; test_add<4>();
|
||||||
|
pline = p; test_add<5>();
|
||||||
|
pline = p; test_add<6>();
|
||||||
|
pline = p; test_add<7>();
|
||||||
|
pline = p; test_add<8>();
|
||||||
|
pline = p; test_add<9>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( method == "ADDINT" )
|
||||||
|
{
|
||||||
|
pline = p; test_addint<1>();
|
||||||
|
pline = p; test_addint<2>();
|
||||||
|
pline = p; test_addint<3>();
|
||||||
|
pline = p; test_addint<4>();
|
||||||
|
pline = p; test_addint<5>();
|
||||||
|
pline = p; test_addint<6>();
|
||||||
|
pline = p; test_addint<7>();
|
||||||
|
pline = p; test_addint<8>();
|
||||||
|
pline = p; test_addint<9>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( method == "ADDTWOINTS" )
|
||||||
|
{
|
||||||
|
pline = p; test_addtwoints<1>();
|
||||||
|
pline = p; test_addtwoints<2>();
|
||||||
|
pline = p; test_addtwoints<3>();
|
||||||
|
pline = p; test_addtwoints<4>();
|
||||||
|
pline = p; test_addtwoints<5>();
|
||||||
|
pline = p; test_addtwoints<6>();
|
||||||
|
pline = p; test_addtwoints<7>();
|
||||||
|
pline = p; test_addtwoints<8>();
|
||||||
|
pline = p; test_addtwoints<9>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << '[' << row << "] ";
|
||||||
|
std::cerr << "method " << method << " is not supported" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool UIntTest::check_line()
|
||||||
|
{
|
||||||
|
std::getline(file, line);
|
||||||
|
|
||||||
|
pline = line.c_str();
|
||||||
|
|
||||||
|
if( read_method() )
|
||||||
|
test_method();
|
||||||
|
|
||||||
|
|
||||||
|
if( file.eof() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void UIntTest::go()
|
||||||
|
{
|
||||||
|
file.open(file_name.c_str());
|
||||||
|
|
||||||
|
|
||||||
|
if( !file )
|
||||||
|
{
|
||||||
|
std::cerr << "I can't open the input file" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
row = 1;
|
||||||
|
|
||||||
|
while( check_line() )
|
||||||
|
++row;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
105
tests/uinttest.h
Normal file
105
tests/uinttest.h
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the (new) BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||||
|
* project may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef headerfileuinttest
|
||||||
|
#define headerfileuinttest
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <ttmath/ttmath.h>
|
||||||
|
|
||||||
|
using namespace ttmath;
|
||||||
|
typedef ttmath::uint uuint;
|
||||||
|
|
||||||
|
|
||||||
|
class UIntTest
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string file_name;
|
||||||
|
|
||||||
|
// current line from the file
|
||||||
|
std::string line;
|
||||||
|
const char * pline;
|
||||||
|
|
||||||
|
std::ifstream file;
|
||||||
|
|
||||||
|
|
||||||
|
std::string method;
|
||||||
|
|
||||||
|
int row;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void set_file_name(const std::string & f);
|
||||||
|
|
||||||
|
void go();
|
||||||
|
|
||||||
|
bool read_uint(uuint & result);
|
||||||
|
|
||||||
|
template<uuint type_size>
|
||||||
|
bool read_uint(UInt<type_size> & result);
|
||||||
|
|
||||||
|
|
||||||
|
template<uuint type_size> void test_add();
|
||||||
|
template<uuint type_size> void test_addint();
|
||||||
|
template<uuint type_size> void test_addtwoints();
|
||||||
|
|
||||||
|
template<uuint type_size> bool check_result_carry(const ttmath::UInt<type_size> & result, const ttmath::UInt<type_size> & new_result,
|
||||||
|
int carry, int new_carry);
|
||||||
|
|
||||||
|
template<uuint type_size> bool check_result_or_carry(const ttmath::UInt<type_size> & result, const ttmath::UInt<type_size> & new_result,
|
||||||
|
int carry, int new_carry);
|
||||||
|
|
||||||
|
int upper_char(int c);
|
||||||
|
bool is_white(int c);
|
||||||
|
void skip_white_characters();
|
||||||
|
bool read_method();
|
||||||
|
void test_method();
|
||||||
|
bool check_line();
|
||||||
|
|
||||||
|
bool check_minmax_bits(int type_size);
|
||||||
|
bool check_minmax_bits_bitperint(int type_size);
|
||||||
|
bool check_end();
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
156
ttmath/ttmath.h
156
ttmath/ttmath.h
@@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Mathematical Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the (new) BSD licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2007, Tomasz Sowa
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -275,6 +275,11 @@ namespace ttmath
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
this namespace consists of auxiliary functions
|
||||||
|
(something like 'private' in a class)
|
||||||
|
*/
|
||||||
namespace auxiliaryfunctions
|
namespace auxiliaryfunctions
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -1342,7 +1347,7 @@ namespace ttmath
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* functions for converting between degrees and radians
|
* functions for converting between degrees, radians and gradians
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -1356,14 +1361,18 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType DegToRad(const ValueType & x, ErrorCode * err = 0)
|
ValueType DegToRad(const ValueType & x, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
ValueType result, delimiter;
|
ValueType result, temp;
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
result.SetPi();
|
result = x;
|
||||||
c += result.Mul(x);
|
|
||||||
|
|
||||||
delimiter = 180;
|
// it is better to make division first and then multiplication
|
||||||
c += result.Div(delimiter);
|
// the result is more accurate especially when x is: 90,180,270 or 360
|
||||||
|
temp = 180;
|
||||||
|
c += result.Div(temp);
|
||||||
|
|
||||||
|
temp.SetPi();
|
||||||
|
c += result.Mul(temp);
|
||||||
|
|
||||||
if( err )
|
if( err )
|
||||||
*err = c ? err_overflow : err_ok;
|
*err = c ? err_overflow : err_ok;
|
||||||
@@ -1463,6 +1472,128 @@ namespace ttmath
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this function converts gradians to radians
|
||||||
|
|
||||||
|
it returns: x * pi / 200
|
||||||
|
*/
|
||||||
|
template<class ValueType>
|
||||||
|
ValueType GradToRad(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
{
|
||||||
|
ValueType result, temp;
|
||||||
|
uint c = 0;
|
||||||
|
|
||||||
|
result = x;
|
||||||
|
|
||||||
|
// it is better to make division first and then multiplication
|
||||||
|
// the result is more accurate especially when x is: 100,200,300 or 400
|
||||||
|
temp = 200;
|
||||||
|
c += result.Div(temp);
|
||||||
|
|
||||||
|
temp.SetPi();
|
||||||
|
c += result.Mul(temp);
|
||||||
|
|
||||||
|
if( err )
|
||||||
|
*err = c ? err_overflow : err_ok;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this function converts radians to gradians
|
||||||
|
|
||||||
|
it returns: x * 200 / pi
|
||||||
|
*/
|
||||||
|
template<class ValueType>
|
||||||
|
ValueType RadToGrad(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
{
|
||||||
|
ValueType result, delimiter;
|
||||||
|
uint c = 0;
|
||||||
|
|
||||||
|
result = 200;
|
||||||
|
c += result.Mul(x);
|
||||||
|
|
||||||
|
delimiter.SetPi();
|
||||||
|
c += result.Div(delimiter);
|
||||||
|
|
||||||
|
if( err )
|
||||||
|
*err = c ? err_overflow : err_ok;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this function converts degrees to gradians
|
||||||
|
|
||||||
|
it returns: x * 200 / 180
|
||||||
|
*/
|
||||||
|
template<class ValueType>
|
||||||
|
ValueType DegToGrad(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
{
|
||||||
|
ValueType result, temp;
|
||||||
|
uint c = 0;
|
||||||
|
|
||||||
|
result = x;
|
||||||
|
|
||||||
|
temp = 200;
|
||||||
|
c += result.Mul(temp);
|
||||||
|
|
||||||
|
temp = 180;
|
||||||
|
c += result.Div(temp);
|
||||||
|
|
||||||
|
if( err )
|
||||||
|
*err = c ? err_overflow : err_ok;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this function converts degrees in the long format to gradians
|
||||||
|
*/
|
||||||
|
template<class ValueType>
|
||||||
|
ValueType DegToGrad( 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 DegToGrad(temp_deg, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this function converts degrees to gradians
|
||||||
|
|
||||||
|
it returns: x * 180 / 200
|
||||||
|
*/
|
||||||
|
template<class ValueType>
|
||||||
|
ValueType GradToDeg(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
{
|
||||||
|
ValueType result, temp;
|
||||||
|
uint c = 0;
|
||||||
|
|
||||||
|
result = x;
|
||||||
|
|
||||||
|
temp = 180;
|
||||||
|
c += result.Mul(temp);
|
||||||
|
|
||||||
|
temp = 200;
|
||||||
|
c += result.Div(temp);
|
||||||
|
|
||||||
|
if( err )
|
||||||
|
*err = c ? err_overflow : err_ok;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* another functions
|
* another functions
|
||||||
@@ -1536,7 +1667,7 @@ namespace ttmath
|
|||||||
{
|
{
|
||||||
if( x.IsZero() )
|
if( x.IsZero() )
|
||||||
{
|
{
|
||||||
// there isn't root(0;0)
|
// there isn't root(0;0) - we assume it's not defined
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
@@ -1685,7 +1816,14 @@ namespace ttmath
|
|||||||
c += x.PowFrac(newindex); // here can only be a carry
|
c += x.PowFrac(newindex); // here can only be a carry
|
||||||
|
|
||||||
if( change_sign )
|
if( change_sign )
|
||||||
|
{
|
||||||
|
// the value of x should be different from zero
|
||||||
|
// (x is actually tested by RootCheckXZero)
|
||||||
|
TTMATH_ASSERT( x.IsZero() == false )
|
||||||
|
|
||||||
x.SetSign();
|
x.SetSign();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if( err )
|
if( err )
|
||||||
*err = c ? err_overflow : err_ok;
|
*err = c ? err_overflow : err_ok;
|
||||||
|
1259
ttmath/ttmathbig.h
1259
ttmath/ttmathbig.h
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Mathematical Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the (new) BSD licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2007, Tomasz Sowa
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -208,7 +208,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method adds two value with a sign and returns carry
|
this method adds two value with a sign and returns a carry
|
||||||
|
|
||||||
we're using methods from the base class because values are stored with U2
|
we're using methods from the base class because values are stored with U2
|
||||||
we must only make the carry correction
|
we must only make the carry correction
|
||||||
@@ -469,23 +469,84 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
power this = this ^ pow
|
||||||
|
this can be negative
|
||||||
|
pow is >= 0
|
||||||
|
*/
|
||||||
|
uint Pow2(const Int<value_size> & pow)
|
||||||
|
{
|
||||||
|
bool was_sign = IsSign();
|
||||||
|
uint c = 0;
|
||||||
|
|
||||||
|
if( was_sign )
|
||||||
|
c += Abs();
|
||||||
|
|
||||||
|
uint c_temp = UInt<value_size>::Pow(pow);
|
||||||
|
if( c_temp > 0 )
|
||||||
|
return c_temp; // c_temp can be: 0, 1 or 2
|
||||||
|
|
||||||
|
if( was_sign && (pow.table[0] & 1) == 1 )
|
||||||
|
// negative value to the power of odd number is negative
|
||||||
|
c += ChangeSign();
|
||||||
|
|
||||||
|
return (c==0)? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
power this = this ^ pow
|
||||||
|
|
||||||
|
return values:
|
||||||
|
0 - ok
|
||||||
|
1 - carry
|
||||||
|
2 - incorrect arguments 0^0 or 0^(-something)
|
||||||
|
*/
|
||||||
|
uint Pow(Int<value_size> pow)
|
||||||
|
{
|
||||||
|
if( !pow.IsSign() )
|
||||||
|
return Pow2(pow);
|
||||||
|
|
||||||
|
if( UInt<value_size>::IsZero() )
|
||||||
|
// if 'p' is negative then
|
||||||
|
// 'this' must be different from zero
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
if( pow.ChangeSign() )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
Int<value_size> t(*this);
|
||||||
|
uint c_temp = t.Pow2(pow);
|
||||||
|
if( c_temp > 0 )
|
||||||
|
return c_temp;
|
||||||
|
|
||||||
|
UInt<value_size>::SetOne();
|
||||||
|
if( Div(t) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* convertion methods
|
* convertion methods
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method convert an UInt<another_size> type to this class
|
an auxiliary method for converting both from UInt and Int
|
||||||
|
|
||||||
this operation has mainly sense if the value from p
|
|
||||||
can be held in this type
|
|
||||||
|
|
||||||
it returns a carry if the value 'p' is too big
|
|
||||||
*/
|
*/
|
||||||
template<uint argument_size>
|
template<uint argument_size>
|
||||||
uint FromInt(const Int<argument_size> & p)
|
uint FromUIntOrInt(const UInt<argument_size> & p, bool UInt_type)
|
||||||
{
|
{
|
||||||
uint min_size = (value_size < argument_size)? value_size : argument_size;
|
uint min_size = (value_size < argument_size)? value_size : argument_size;
|
||||||
uint i;
|
uint i;
|
||||||
@@ -496,15 +557,25 @@ public:
|
|||||||
|
|
||||||
if( value_size > argument_size )
|
if( value_size > argument_size )
|
||||||
{
|
{
|
||||||
// 'this' is longer than 'p'
|
uint fill;
|
||||||
uint fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)? TTMATH_UINT_MAX_VALUE : 0;
|
|
||||||
|
|
||||||
|
if( UInt_type )
|
||||||
|
fill = 0;
|
||||||
|
else
|
||||||
|
fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)?
|
||||||
|
TTMATH_UINT_MAX_VALUE : 0;
|
||||||
|
|
||||||
|
// 'this' is longer than 'p'
|
||||||
for( ; i<value_size ; ++i)
|
for( ; i<value_size ; ++i)
|
||||||
UInt<value_size>::table[i] = fill;
|
UInt<value_size>::table[i] = fill;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)? TTMATH_UINT_MAX_VALUE : 0;
|
uint test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)?
|
||||||
|
TTMATH_UINT_MAX_VALUE : 0;
|
||||||
|
|
||||||
|
if( UInt_type && test!=0 )
|
||||||
|
return 1;
|
||||||
|
|
||||||
for( ; i<argument_size ; ++i)
|
for( ; i<argument_size ; ++i)
|
||||||
if( p.table[i] != test )
|
if( p.table[i] != test )
|
||||||
@@ -514,11 +585,27 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts an Int<another_size> type into this class
|
||||||
|
|
||||||
|
this operation has mainly sense if the value from p
|
||||||
|
can be held in this type
|
||||||
|
|
||||||
|
it returns a carry if the value 'p' is too big
|
||||||
|
*/
|
||||||
|
template<uint argument_size>
|
||||||
|
uint FromInt(const Int<argument_size> & p)
|
||||||
|
{
|
||||||
|
return FromUIntOrInt(p, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts the sint type into this class
|
this method converts the sint type into this class
|
||||||
*/
|
*/
|
||||||
void FromInt(sint value)
|
uint FromInt(sint value)
|
||||||
{
|
{
|
||||||
uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0;
|
uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0;
|
||||||
|
|
||||||
@@ -526,16 +613,46 @@ public:
|
|||||||
UInt<value_size>::table[i] = fill;
|
UInt<value_size>::table[i] = fill;
|
||||||
|
|
||||||
UInt<value_size>::table[0] = uint(value);
|
UInt<value_size>::table[0] = uint(value);
|
||||||
|
|
||||||
|
// there'll never be a carry here
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this operator converts an UInt<another_size> type to this class
|
this method converts UInt<another_size> into this class
|
||||||
|
|
||||||
it doesn't return a carry
|
|
||||||
*/
|
*/
|
||||||
template<uint argument_size>
|
template<uint argument_size>
|
||||||
Int<value_size> & operator=(const Int<argument_size> & p)
|
uint FromUInt(const UInt<argument_size> & p)
|
||||||
|
{
|
||||||
|
return FromUIntOrInt(p, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the uint type into this class
|
||||||
|
*/
|
||||||
|
uint FromUInt(uint value)
|
||||||
|
{
|
||||||
|
for(uint i=1 ; i<value_size ; ++i)
|
||||||
|
UInt<value_size>::table[i] = 0;
|
||||||
|
|
||||||
|
UInt<value_size>::table[0] = value;
|
||||||
|
|
||||||
|
// there can be a carry here when the size of this value is equal one word
|
||||||
|
// and the 'value' has the highest bit set
|
||||||
|
if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// converting from Int
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the default assignment operator
|
||||||
|
*/
|
||||||
|
Int<value_size> & operator=(const Int<value_size> & p)
|
||||||
{
|
{
|
||||||
FromInt(p);
|
FromInt(p);
|
||||||
|
|
||||||
@@ -544,9 +661,12 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the default assignment operator
|
this operator converts an Int<another_size> type to this class
|
||||||
|
|
||||||
|
it doesn't return a carry
|
||||||
*/
|
*/
|
||||||
Int<value_size> & operator=(const Int<value_size> & p)
|
template<uint argument_size>
|
||||||
|
Int<value_size> & operator=(const Int<argument_size> & p)
|
||||||
{
|
{
|
||||||
FromInt(p);
|
FromInt(p);
|
||||||
|
|
||||||
@@ -575,11 +695,47 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts the uint type to this class
|
a copy constructor
|
||||||
|
*/
|
||||||
|
Int(const Int<value_size> & u)
|
||||||
|
{
|
||||||
|
FromInt(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
a constructor for copying from another types
|
||||||
|
*/
|
||||||
|
template<uint argument_size>
|
||||||
|
Int(const Int<argument_size> & u)
|
||||||
|
{
|
||||||
|
// look that 'size' we still set as 'value_size' and not as u.value_size
|
||||||
|
FromInt(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// converting from UInt
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this operator converts an UInt<another_size> type to this class
|
||||||
|
|
||||||
|
it doesn't return a carry
|
||||||
|
*/
|
||||||
|
template<uint argument_size>
|
||||||
|
Int<value_size> & operator=(const UInt<argument_size> & p)
|
||||||
|
{
|
||||||
|
FromUInt(p);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the Uint type to this class
|
||||||
*/
|
*/
|
||||||
Int<value_size> & operator=(uint i)
|
Int<value_size> & operator=(uint i)
|
||||||
{
|
{
|
||||||
UInt<value_size>::FromUInt(i);
|
FromUInt(i);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -590,10 +746,23 @@ public:
|
|||||||
*/
|
*/
|
||||||
Int(uint i)
|
Int(uint i)
|
||||||
{
|
{
|
||||||
UInt<value_size>::FromUInt(i);
|
FromUInt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
a constructor for copying from another types
|
||||||
|
*/
|
||||||
|
template<uint argument_size>
|
||||||
|
Int(const UInt<argument_size> & u)
|
||||||
|
{
|
||||||
|
// look that 'size' we still set as 'value_size' and not as u.value_size
|
||||||
|
FromUInt(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
#ifdef TTMATH_PLATFORM64
|
#ifdef TTMATH_PLATFORM64
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -630,7 +799,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
Int<value_size> & operator=(unsigned int i)
|
Int<value_size> & operator=(unsigned int i)
|
||||||
{
|
{
|
||||||
UInt<value_size>::FromUInt(uint(i));
|
FromUInt(uint(i));
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -644,7 +813,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
Int(unsigned int i)
|
Int(unsigned int i)
|
||||||
{
|
{
|
||||||
UInt<value_size>::FromUInt(uint(i));
|
FromUInt(uint(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -678,18 +847,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
the copy constructor
|
|
||||||
*/
|
|
||||||
template<uint argument_size>
|
|
||||||
Int(const Int<argument_size> & u) : UInt<value_size>::size(value_size)
|
|
||||||
{
|
|
||||||
// look that 'size' we still set as 'value_size' and not as u.value_size
|
|
||||||
|
|
||||||
operator=(u);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the destructor
|
the destructor
|
||||||
*/
|
*/
|
||||||
@@ -697,6 +854,7 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns the lowest value from table with a sign
|
this method returns the lowest value from table with a sign
|
||||||
|
|
||||||
@@ -742,8 +900,12 @@ public:
|
|||||||
|
|
||||||
existing first white characters will be ommited
|
existing first white characters will be ommited
|
||||||
(between '-' and a first digit can be white characters too)
|
(between '-' and a first digit can be white characters too)
|
||||||
|
|
||||||
|
after_source (if exists) is pointing at the end of the parsed string
|
||||||
|
|
||||||
|
value_read (if exists) tells whether something has actually been read (at least one digit)
|
||||||
*/
|
*/
|
||||||
uint FromString(const char * s, uint b = 10)
|
uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
|
||||||
{
|
{
|
||||||
bool is_sign = false;
|
bool is_sign = false;
|
||||||
|
|
||||||
@@ -760,7 +922,7 @@ public:
|
|||||||
UInt<value_size>::SkipWhiteCharacters(++s);
|
UInt<value_size>::SkipWhiteCharacters(++s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( UInt<value_size>::FromString(s,b) )
|
if( UInt<value_size>::FromString(s,b,after_source,value_read) )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if( is_sign )
|
if( is_sign )
|
||||||
@@ -771,12 +933,15 @@ public:
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
the reference to mmin will be automatically converted to the reference
|
the reference to mmin will be automatically converted to the reference
|
||||||
to a UInt type
|
to UInt type
|
||||||
(this value can be equal mmin -- look at a description in ChangeSign())
|
(this value can be equal mmin -- look at a description in ChangeSign())
|
||||||
*/
|
*/
|
||||||
if( UInt<value_size>::operator>( mmin ) )
|
if( UInt<value_size>::operator>( mmin ) )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
if the value is equal mmin the method ChangeSign() does nothing (only returns 1 but we ignore it)
|
||||||
|
*/
|
||||||
ChangeSign();
|
ChangeSign();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2007, Tomasz Sowa
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -102,7 +102,7 @@ public:
|
|||||||
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
|
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if( can_be_digit && (c>='0' && c<='9') )
|
if( can_be_digit && ((c>='0' && c<='9') || c=='_') )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -130,6 +130,21 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns true if such an object is defined (name exists)
|
||||||
|
*/
|
||||||
|
bool IsDefined(const std::string & name)
|
||||||
|
{
|
||||||
|
Iterator i = table.find(name);
|
||||||
|
|
||||||
|
if( i != table.end() )
|
||||||
|
// we have this object in our table
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method adds one object (variable of function) into the table
|
this method adds one object (variable of function) into the table
|
||||||
*/
|
*/
|
||||||
@@ -258,7 +273,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets the value of a specific object
|
this method gets the value of a specific object
|
||||||
*/
|
*/
|
||||||
ErrorCode GetValue(const std::string & name, std::string & value) const
|
ErrorCode GetValue(const std::string & name, std::string & value) const
|
||||||
{
|
{
|
||||||
@@ -280,7 +295,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets the value of a specific object
|
this method gets the value of a specific object
|
||||||
(this version is used for not copying the whole string)
|
(this version is used for not copying the whole string)
|
||||||
*/
|
*/
|
||||||
ErrorCode GetValue(const std::string & name, const char ** value) const
|
ErrorCode GetValue(const std::string & name, const char ** value) const
|
||||||
@@ -303,7 +318,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets the value and the number of parameters
|
this method gets the value and the number of parameters
|
||||||
of a specific object
|
of a specific object
|
||||||
*/
|
*/
|
||||||
ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const
|
ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2007, Tomasz Sowa
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -61,14 +61,14 @@ namespace ttmath
|
|||||||
/*!
|
/*!
|
||||||
\brief Mathematical parser
|
\brief Mathematical parser
|
||||||
|
|
||||||
let x will be an input string means an expression for converting:
|
let x will be an input string meaning an expression for converting:
|
||||||
|
|
||||||
x = [+|-]Value[operator[+|-]Value][operator[+|-]Value]...
|
x = [+|-]Value[operator[+|-]Value][operator[+|-]Value]...
|
||||||
where:
|
where:
|
||||||
an operator can be:
|
an operator can be:
|
||||||
^ (pow) (the highest priority)
|
^ (pow) (the heighest priority)
|
||||||
|
|
||||||
* (mul)
|
* (mul) (or multiplication without an operator -- short mul)
|
||||||
/ (div) (* and / have the same priority)
|
/ (div) (* and / have the same priority)
|
||||||
|
|
||||||
+ (add)
|
+ (add)
|
||||||
@@ -85,9 +85,23 @@ namespace ttmath
|
|||||||
|
|
||||||
|| (logical or) (the lowest priority)
|
|| (logical or) (the lowest priority)
|
||||||
|
|
||||||
|
short mul:
|
||||||
|
if the second Value (Var below) is either a variable or function there might not be
|
||||||
|
an operator between them, e.g.
|
||||||
|
"[+|-]Value Var" is treated as "[+|-]Value * Var" and the multiplication
|
||||||
|
has the same priority as a normal multiplication:
|
||||||
|
4x = 4 * x
|
||||||
|
2^3m = (2^3)* m
|
||||||
|
6h^3 = 6 * (h^3)
|
||||||
|
2sin(pi) = 2 * sin(pi)
|
||||||
|
etc.
|
||||||
|
|
||||||
and Value can be:
|
Value can be:
|
||||||
constant e.g. 100
|
constant e.g. 100, can be preceded by operators for changing the base (radix): [#|&]
|
||||||
|
# - hex
|
||||||
|
& - bin
|
||||||
|
sample: #10 = 16
|
||||||
|
&10 = 2
|
||||||
variable e.g. pi
|
variable e.g. pi
|
||||||
another expression between brackets e.g (x)
|
another expression between brackets e.g (x)
|
||||||
function e.g. sin(x)
|
function e.g. sin(x)
|
||||||
@@ -106,6 +120,11 @@ namespace ttmath
|
|||||||
for separating parameters
|
for separating parameters
|
||||||
"1 < 2" (the result will be: 1)
|
"1 < 2" (the result will be: 1)
|
||||||
"4 < 3" (the result will be: 0)
|
"4 < 3" (the result will be: 0)
|
||||||
|
"2+x" (of course if the variable 'x' is defined)
|
||||||
|
"4x+10"
|
||||||
|
"#20+10" = 32 + 10 = 42
|
||||||
|
"10 ^ -&101" = 10 ^ -5 = 0.00001
|
||||||
|
"8 * -&10" = 8 * -2 = -16
|
||||||
etc.
|
etc.
|
||||||
|
|
||||||
we can also use a semicolon for separating any 'x' input strings
|
we can also use a semicolon for separating any 'x' input strings
|
||||||
@@ -122,13 +141,15 @@ class Parser
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
there are 5 mathematical operators as follows:
|
there are 5 mathematical operators as follows (with their standard priorities):
|
||||||
add (+)
|
add (+)
|
||||||
sub (-)
|
sub (-)
|
||||||
mul (*)
|
mul (*)
|
||||||
div (/)
|
div (/)
|
||||||
pow (^)
|
pow (^)
|
||||||
with their standard priorities
|
and 'shortmul' used when there is no any operators between
|
||||||
|
a first parameter and a variable or function
|
||||||
|
(the 'shortmul' has the same priority as the normal multiplication )
|
||||||
*/
|
*/
|
||||||
class MatOperator
|
class MatOperator
|
||||||
{
|
{
|
||||||
@@ -136,7 +157,7 @@ private:
|
|||||||
|
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
none,add,sub,mul,div,pow,lt,gt,let,get,eq,neq,lor,land
|
none,add,sub,mul,div,pow,lt,gt,let,get,eq,neq,lor,land,shortmul
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -173,6 +194,7 @@ private:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case mul:
|
case mul:
|
||||||
|
case shortmul:
|
||||||
case div:
|
case div:
|
||||||
priority = 12;
|
priority = 12;
|
||||||
break;
|
break;
|
||||||
@@ -296,11 +318,21 @@ const char * pstring;
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the base of the mathematic system (for example it may be '10')
|
the base (radix) of the mathematic system (for example it may be '10')
|
||||||
*/
|
*/
|
||||||
int base;
|
int base;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the unit of angles used in: sin,cos,tan,cot,asin,acos,atan,acot
|
||||||
|
0 - deg
|
||||||
|
1 - rad (default)
|
||||||
|
2 - grad
|
||||||
|
*/
|
||||||
|
int deg_rad_grad;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a pointer to an object which tell us whether we should stop calculating or not
|
a pointer to an object which tell us whether we should stop calculating or not
|
||||||
*/
|
*/
|
||||||
@@ -393,7 +425,6 @@ typedef std::map<std::string, pfunction_var> VariablesTable;
|
|||||||
VariablesTable variables_table;
|
VariablesTable variables_table;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
you can't calculate the factorial if the argument is greater than 'factorial_max'
|
you can't calculate the factorial if the argument is greater than 'factorial_max'
|
||||||
default value is zero which means there are not any limitations
|
default value is zero which means there are not any limitations
|
||||||
@@ -410,8 +441,6 @@ static void Error(ErrorCode code)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method skips the white character from the string
|
this method skips the white character from the string
|
||||||
|
|
||||||
@@ -424,9 +453,8 @@ void SkipWhiteCharacters()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a auxiliary method for RecurrenceParsingVariablesOrFunction(...)
|
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
|
||||||
*/
|
*/
|
||||||
void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const std::string & name)
|
void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const std::string & name)
|
||||||
{
|
{
|
||||||
@@ -444,7 +472,7 @@ void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, cons
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a auxiliary method for RecurrenceParsingVariablesOrFunction(...)
|
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
|
||||||
*/
|
*/
|
||||||
void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::string & name)
|
void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::string & name)
|
||||||
{
|
{
|
||||||
@@ -454,8 +482,9 @@ void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::stri
|
|||||||
visited_functions.insert( name );
|
visited_functions.insert( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a auxiliary method for RecurrenceParsingVariablesOrFunction(...)
|
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
|
||||||
*/
|
*/
|
||||||
void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::string & name)
|
void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::string & name)
|
||||||
{
|
{
|
||||||
@@ -465,6 +494,7 @@ void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::s
|
|||||||
visited_functions.erase( name );
|
visited_functions.erase( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns the value of a variable or function
|
this method returns the value of a variable or function
|
||||||
by creating a new instance of the mathematical parser
|
by creating a new instance of the mathematical parser
|
||||||
@@ -599,7 +629,53 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
'silnia' in polish language
|
used by: sin,cos,tan,cot
|
||||||
|
*/
|
||||||
|
ValueType ConvertAngleToRad(const ValueType & input)
|
||||||
|
{
|
||||||
|
if( deg_rad_grad == 1 ) // rad
|
||||||
|
return input;
|
||||||
|
|
||||||
|
ValueType result;
|
||||||
|
ErrorCode err;
|
||||||
|
|
||||||
|
if( deg_rad_grad == 0 ) // deg
|
||||||
|
result = ttmath::DegToRad(input, &err);
|
||||||
|
else // grad
|
||||||
|
result = ttmath::GradToRad(input, &err);
|
||||||
|
|
||||||
|
if( err != err_ok )
|
||||||
|
Error( err );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
used by: asin,acos,atan,acot
|
||||||
|
*/
|
||||||
|
ValueType ConvertRadToAngle(const ValueType & input)
|
||||||
|
{
|
||||||
|
if( deg_rad_grad == 1 ) // rad
|
||||||
|
return input;
|
||||||
|
|
||||||
|
ValueType result;
|
||||||
|
ErrorCode err;
|
||||||
|
|
||||||
|
if( deg_rad_grad == 0 ) // deg
|
||||||
|
result = ttmath::RadToDeg(input, &err);
|
||||||
|
else // grad
|
||||||
|
result = ttmath::RadToGrad(input, &err);
|
||||||
|
|
||||||
|
if( err != err_ok )
|
||||||
|
Error( err );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
factorial
|
||||||
result = 1 * 2 * 3 * 4 * .... * x
|
result = 1 * 2 * 3 * 4 * .... * x
|
||||||
*/
|
*/
|
||||||
void Factorial(int sindex, int amount_of_args, ValueType & result)
|
void Factorial(int sindex, int amount_of_args, ValueType & result)
|
||||||
@@ -632,7 +708,7 @@ void Sin(int sindex, int amount_of_args, ValueType & result)
|
|||||||
if( amount_of_args != 1 )
|
if( amount_of_args != 1 )
|
||||||
Error( err_improper_amount_of_arguments );
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
result = ttmath::Sin(stack[sindex].value);
|
result = ttmath::Sin( ConvertAngleToRad(stack[sindex].value) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cos(int sindex, int amount_of_args, ValueType & result)
|
void Cos(int sindex, int amount_of_args, ValueType & result)
|
||||||
@@ -640,7 +716,7 @@ void Cos(int sindex, int amount_of_args, ValueType & result)
|
|||||||
if( amount_of_args != 1 )
|
if( amount_of_args != 1 )
|
||||||
Error( err_improper_amount_of_arguments );
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
result = ttmath::Cos(stack[sindex].value);
|
result = ttmath::Cos( ConvertAngleToRad(stack[sindex].value) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tan(int sindex, int amount_of_args, ValueType & result)
|
void Tan(int sindex, int amount_of_args, ValueType & result)
|
||||||
@@ -649,7 +725,7 @@ void Tan(int sindex, int amount_of_args, ValueType & result)
|
|||||||
Error( err_improper_amount_of_arguments );
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
ErrorCode err;
|
ErrorCode err;
|
||||||
result = ttmath::Tan(stack[sindex].value, &err);
|
result = ttmath::Tan(ConvertAngleToRad(stack[sindex].value), &err);
|
||||||
|
|
||||||
if(err != err_ok)
|
if(err != err_ok)
|
||||||
Error( err );
|
Error( err );
|
||||||
@@ -661,7 +737,7 @@ void Cot(int sindex, int amount_of_args, ValueType & result)
|
|||||||
Error( err_improper_amount_of_arguments );
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
ErrorCode err;
|
ErrorCode err;
|
||||||
result = ttmath::Cot(stack[sindex].value, &err);
|
result = ttmath::Cot(ConvertAngleToRad(stack[sindex].value), &err);
|
||||||
|
|
||||||
if(err != err_ok)
|
if(err != err_ok)
|
||||||
Error( err );
|
Error( err );
|
||||||
@@ -766,10 +842,12 @@ void ASin(int sindex, int amount_of_args, ValueType & result)
|
|||||||
Error( err_improper_amount_of_arguments );
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
ErrorCode err;
|
ErrorCode err;
|
||||||
result = ttmath::ASin(stack[sindex].value, &err);
|
ValueType temp = ttmath::ASin(stack[sindex].value, &err);
|
||||||
|
|
||||||
if(err != err_ok)
|
if(err != err_ok)
|
||||||
Error( err );
|
Error( err );
|
||||||
|
|
||||||
|
result = ConvertRadToAngle(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -779,10 +857,12 @@ void ACos(int sindex, int amount_of_args, ValueType & result)
|
|||||||
Error( err_improper_amount_of_arguments );
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
ErrorCode err;
|
ErrorCode err;
|
||||||
result = ttmath::ACos(stack[sindex].value, &err);
|
ValueType temp = ttmath::ACos(stack[sindex].value, &err);
|
||||||
|
|
||||||
if(err != err_ok)
|
if(err != err_ok)
|
||||||
Error( err );
|
Error( err );
|
||||||
|
|
||||||
|
result = ConvertRadToAngle(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -791,7 +871,7 @@ void ATan(int sindex, int amount_of_args, ValueType & result)
|
|||||||
if( amount_of_args != 1 )
|
if( amount_of_args != 1 )
|
||||||
Error( err_improper_amount_of_arguments );
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
result = ttmath::ATan(stack[sindex].value);
|
result = ConvertRadToAngle(ttmath::ATan(stack[sindex].value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -800,7 +880,7 @@ void ACot(int sindex, int amount_of_args, ValueType & result)
|
|||||||
if( amount_of_args != 1 )
|
if( amount_of_args != 1 )
|
||||||
Error( err_improper_amount_of_arguments );
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
result = ttmath::ACot(stack[sindex].value);
|
result = ConvertRadToAngle(ttmath::ACot(stack[sindex].value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -941,6 +1021,72 @@ void DegToDeg(int sindex, int amount_of_args, ValueType & result)
|
|||||||
Error( err );
|
Error( err );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GradToRad(int sindex, int amount_of_args, ValueType & result)
|
||||||
|
{
|
||||||
|
ErrorCode err;
|
||||||
|
|
||||||
|
if( amount_of_args != 1 )
|
||||||
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
|
result = ttmath::GradToRad(stack[sindex].value, &err);
|
||||||
|
|
||||||
|
if( err != err_ok )
|
||||||
|
Error( err );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RadToGrad(int sindex, int amount_of_args, ValueType & result)
|
||||||
|
{
|
||||||
|
ErrorCode err;
|
||||||
|
|
||||||
|
if( amount_of_args != 1 )
|
||||||
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
|
result = ttmath::RadToGrad(stack[sindex].value, &err);
|
||||||
|
|
||||||
|
if( err != err_ok )
|
||||||
|
Error( err );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DegToGrad(int sindex, int amount_of_args, ValueType & result)
|
||||||
|
{
|
||||||
|
ErrorCode err;
|
||||||
|
|
||||||
|
if( amount_of_args == 1 )
|
||||||
|
{
|
||||||
|
result = ttmath::DegToGrad(stack[sindex].value, &err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( amount_of_args == 3 )
|
||||||
|
{
|
||||||
|
result = ttmath::DegToGrad( 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 GradToDeg(int sindex, int amount_of_args, ValueType & result)
|
||||||
|
{
|
||||||
|
ErrorCode err;
|
||||||
|
|
||||||
|
if( amount_of_args != 1 )
|
||||||
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
|
result = ttmath::GradToDeg(stack[sindex].value, &err);
|
||||||
|
|
||||||
|
if( err != err_ok )
|
||||||
|
Error( err );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Ceil(int sindex, int amount_of_args, ValueType & result)
|
void Ceil(int sindex, int amount_of_args, ValueType & result)
|
||||||
{
|
{
|
||||||
if( amount_of_args != 1 )
|
if( amount_of_args != 1 )
|
||||||
@@ -1158,6 +1304,35 @@ void BitXor(int sindex, int amount_of_args, ValueType & result)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Sum(int sindex, int amount_of_args, ValueType & result)
|
||||||
|
{
|
||||||
|
if( amount_of_args == 0 )
|
||||||
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
|
result = stack[sindex].value;
|
||||||
|
|
||||||
|
for(int i=1 ; i<amount_of_args ; ++i )
|
||||||
|
if( result.Add( stack[ sindex + i*2 ].value ) )
|
||||||
|
Error( err_overflow );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Avg(int sindex, int amount_of_args, ValueType & result)
|
||||||
|
{
|
||||||
|
if( amount_of_args == 0 )
|
||||||
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
|
result = stack[sindex].value;
|
||||||
|
|
||||||
|
for(int i=1 ; i<amount_of_args ; ++i )
|
||||||
|
if( result.Add( stack[ sindex + i*2 ].value ) )
|
||||||
|
Error( err_overflow );
|
||||||
|
|
||||||
|
if( result.Div( amount_of_args ) )
|
||||||
|
Error( err_overflow );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns the value from a user-defined function
|
this method returns the value from a user-defined function
|
||||||
|
|
||||||
@@ -1235,27 +1410,27 @@ void CallFunction(const std::string & function_name, int amount_of_args, int sin
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
insert a function to the functions' table
|
inserting a function to the functions' table
|
||||||
|
|
||||||
function_name - name of the function
|
function_name - name of the function
|
||||||
pf - pointer to the function (to the wrapper)
|
pf - pointer to the function (to the wrapper)
|
||||||
*/
|
*/
|
||||||
void InsertFunctionToTable(const std::string & function_name, pfunction pf)
|
void InsertFunctionToTable(const char * function_name, pfunction pf)
|
||||||
{
|
{
|
||||||
functions_table.insert( std::make_pair(function_name, pf));
|
functions_table.insert( std::make_pair(std::string(function_name), pf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
insert a function to the variables' table
|
inserting a function to the variables' table
|
||||||
(this function returns value of variable)
|
(this function returns value of variable)
|
||||||
|
|
||||||
variable_name - name of the function
|
variable_name - name of the function
|
||||||
pf - pointer to the function
|
pf - pointer to the function
|
||||||
*/
|
*/
|
||||||
void InsertVariableToTable(const std::string & variable_name, pfunction_var pf)
|
void InsertVariableToTable(const char * variable_name, pfunction_var pf)
|
||||||
{
|
{
|
||||||
variables_table.insert( std::make_pair(variable_name, pf));
|
variables_table.insert( std::make_pair(std::string(variable_name), pf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1267,76 +1442,82 @@ void CreateFunctionsTable()
|
|||||||
/*
|
/*
|
||||||
names of functions should consist of small letters
|
names of functions should consist of small letters
|
||||||
*/
|
*/
|
||||||
InsertFunctionToTable(std::string("factorial"), &Parser<ValueType>::Factorial);
|
InsertFunctionToTable("factorial", &Parser<ValueType>::Factorial);
|
||||||
InsertFunctionToTable(std::string("abs"), &Parser<ValueType>::Abs);
|
InsertFunctionToTable("abs", &Parser<ValueType>::Abs);
|
||||||
InsertFunctionToTable(std::string("sin"), &Parser<ValueType>::Sin);
|
InsertFunctionToTable("sin", &Parser<ValueType>::Sin);
|
||||||
InsertFunctionToTable(std::string("cos"), &Parser<ValueType>::Cos);
|
InsertFunctionToTable("cos", &Parser<ValueType>::Cos);
|
||||||
InsertFunctionToTable(std::string("tan"), &Parser<ValueType>::Tan);
|
InsertFunctionToTable("tan", &Parser<ValueType>::Tan);
|
||||||
InsertFunctionToTable(std::string("tg"), &Parser<ValueType>::Tan);
|
InsertFunctionToTable("tg", &Parser<ValueType>::Tan);
|
||||||
InsertFunctionToTable(std::string("cot"), &Parser<ValueType>::Cot);
|
InsertFunctionToTable("cot", &Parser<ValueType>::Cot);
|
||||||
InsertFunctionToTable(std::string("ctg"), &Parser<ValueType>::Cot);
|
InsertFunctionToTable("ctg", &Parser<ValueType>::Cot);
|
||||||
InsertFunctionToTable(std::string("int"), &Parser<ValueType>::Int);
|
InsertFunctionToTable("int", &Parser<ValueType>::Int);
|
||||||
InsertFunctionToTable(std::string("round"), &Parser<ValueType>::Round);
|
InsertFunctionToTable("round", &Parser<ValueType>::Round);
|
||||||
InsertFunctionToTable(std::string("ln"), &Parser<ValueType>::Ln);
|
InsertFunctionToTable("ln", &Parser<ValueType>::Ln);
|
||||||
InsertFunctionToTable(std::string("log"), &Parser<ValueType>::Log);
|
InsertFunctionToTable("log", &Parser<ValueType>::Log);
|
||||||
InsertFunctionToTable(std::string("exp"), &Parser<ValueType>::Exp);
|
InsertFunctionToTable("exp", &Parser<ValueType>::Exp);
|
||||||
InsertFunctionToTable(std::string("max"), &Parser<ValueType>::Max);
|
InsertFunctionToTable("max", &Parser<ValueType>::Max);
|
||||||
InsertFunctionToTable(std::string("min"), &Parser<ValueType>::Min);
|
InsertFunctionToTable("min", &Parser<ValueType>::Min);
|
||||||
InsertFunctionToTable(std::string("asin"), &Parser<ValueType>::ASin);
|
InsertFunctionToTable("asin", &Parser<ValueType>::ASin);
|
||||||
InsertFunctionToTable(std::string("acos"), &Parser<ValueType>::ACos);
|
InsertFunctionToTable("acos", &Parser<ValueType>::ACos);
|
||||||
InsertFunctionToTable(std::string("atan"), &Parser<ValueType>::ATan);
|
InsertFunctionToTable("atan", &Parser<ValueType>::ATan);
|
||||||
InsertFunctionToTable(std::string("atg"), &Parser<ValueType>::ATan);
|
InsertFunctionToTable("atg", &Parser<ValueType>::ATan);
|
||||||
InsertFunctionToTable(std::string("acot"), &Parser<ValueType>::ACot);
|
InsertFunctionToTable("acot", &Parser<ValueType>::ACot);
|
||||||
InsertFunctionToTable(std::string("actg"), &Parser<ValueType>::ACot);
|
InsertFunctionToTable("actg", &Parser<ValueType>::ACot);
|
||||||
InsertFunctionToTable(std::string("sgn"), &Parser<ValueType>::Sgn);
|
InsertFunctionToTable("sgn", &Parser<ValueType>::Sgn);
|
||||||
InsertFunctionToTable(std::string("mod"), &Parser<ValueType>::Mod);
|
InsertFunctionToTable("mod", &Parser<ValueType>::Mod);
|
||||||
InsertFunctionToTable(std::string("if"), &Parser<ValueType>::If);
|
InsertFunctionToTable("if", &Parser<ValueType>::If);
|
||||||
InsertFunctionToTable(std::string("or"), &Parser<ValueType>::Or);
|
InsertFunctionToTable("or", &Parser<ValueType>::Or);
|
||||||
InsertFunctionToTable(std::string("and"), &Parser<ValueType>::And);
|
InsertFunctionToTable("and", &Parser<ValueType>::And);
|
||||||
InsertFunctionToTable(std::string("not"), &Parser<ValueType>::Not);
|
InsertFunctionToTable("not", &Parser<ValueType>::Not);
|
||||||
InsertFunctionToTable(std::string("degtorad"), &Parser<ValueType>::DegToRad);
|
InsertFunctionToTable("degtorad", &Parser<ValueType>::DegToRad);
|
||||||
InsertFunctionToTable(std::string("radtodeg"), &Parser<ValueType>::RadToDeg);
|
InsertFunctionToTable("radtodeg", &Parser<ValueType>::RadToDeg);
|
||||||
InsertFunctionToTable(std::string("degtodeg"), &Parser<ValueType>::DegToDeg);
|
InsertFunctionToTable("degtodeg", &Parser<ValueType>::DegToDeg);
|
||||||
InsertFunctionToTable(std::string("ceil"), &Parser<ValueType>::Ceil);
|
InsertFunctionToTable("gradtorad", &Parser<ValueType>::GradToRad);
|
||||||
InsertFunctionToTable(std::string("floor"), &Parser<ValueType>::Floor);
|
InsertFunctionToTable("radtograd", &Parser<ValueType>::RadToGrad);
|
||||||
InsertFunctionToTable(std::string("sqrt"), &Parser<ValueType>::Sqrt);
|
InsertFunctionToTable("degtograd", &Parser<ValueType>::DegToGrad);
|
||||||
InsertFunctionToTable(std::string("sinh"), &Parser<ValueType>::Sinh);
|
InsertFunctionToTable("gradtodeg", &Parser<ValueType>::GradToDeg);
|
||||||
InsertFunctionToTable(std::string("cosh"), &Parser<ValueType>::Cosh);
|
InsertFunctionToTable("ceil", &Parser<ValueType>::Ceil);
|
||||||
InsertFunctionToTable(std::string("tanh"), &Parser<ValueType>::Tanh);
|
InsertFunctionToTable("floor", &Parser<ValueType>::Floor);
|
||||||
InsertFunctionToTable(std::string("tgh"), &Parser<ValueType>::Tanh);
|
InsertFunctionToTable("sqrt", &Parser<ValueType>::Sqrt);
|
||||||
InsertFunctionToTable(std::string("coth"), &Parser<ValueType>::Coth);
|
InsertFunctionToTable("sinh", &Parser<ValueType>::Sinh);
|
||||||
InsertFunctionToTable(std::string("ctgh"), &Parser<ValueType>::Coth);
|
InsertFunctionToTable("cosh", &Parser<ValueType>::Cosh);
|
||||||
InsertFunctionToTable(std::string("root"), &Parser<ValueType>::Root);
|
InsertFunctionToTable("tanh", &Parser<ValueType>::Tanh);
|
||||||
InsertFunctionToTable(std::string("asinh"), &Parser<ValueType>::ASinh);
|
InsertFunctionToTable("tgh", &Parser<ValueType>::Tanh);
|
||||||
InsertFunctionToTable(std::string("acosh"), &Parser<ValueType>::ACosh);
|
InsertFunctionToTable("coth", &Parser<ValueType>::Coth);
|
||||||
InsertFunctionToTable(std::string("atanh"), &Parser<ValueType>::ATanh);
|
InsertFunctionToTable("ctgh", &Parser<ValueType>::Coth);
|
||||||
InsertFunctionToTable(std::string("atgh"), &Parser<ValueType>::ATanh);
|
InsertFunctionToTable("root", &Parser<ValueType>::Root);
|
||||||
InsertFunctionToTable(std::string("acoth"), &Parser<ValueType>::ACoth);
|
InsertFunctionToTable("asinh", &Parser<ValueType>::ASinh);
|
||||||
InsertFunctionToTable(std::string("actgh"), &Parser<ValueType>::ACoth);
|
InsertFunctionToTable("acosh", &Parser<ValueType>::ACosh);
|
||||||
InsertFunctionToTable(std::string("bitand"), &Parser<ValueType>::BitAnd);
|
InsertFunctionToTable("atanh", &Parser<ValueType>::ATanh);
|
||||||
InsertFunctionToTable(std::string("bitor"), &Parser<ValueType>::BitOr);
|
InsertFunctionToTable("atgh", &Parser<ValueType>::ATanh);
|
||||||
InsertFunctionToTable(std::string("bitxor"), &Parser<ValueType>::BitXor);
|
InsertFunctionToTable("acoth", &Parser<ValueType>::ACoth);
|
||||||
InsertFunctionToTable(std::string("band"), &Parser<ValueType>::BitAnd);
|
InsertFunctionToTable("actgh", &Parser<ValueType>::ACoth);
|
||||||
InsertFunctionToTable(std::string("bor"), &Parser<ValueType>::BitOr);
|
InsertFunctionToTable("bitand", &Parser<ValueType>::BitAnd);
|
||||||
InsertFunctionToTable(std::string("bxor"), &Parser<ValueType>::BitXor);
|
InsertFunctionToTable("bitor", &Parser<ValueType>::BitOr);
|
||||||
|
InsertFunctionToTable("bitxor", &Parser<ValueType>::BitXor);
|
||||||
|
InsertFunctionToTable("band", &Parser<ValueType>::BitAnd);
|
||||||
|
InsertFunctionToTable("bor", &Parser<ValueType>::BitOr);
|
||||||
|
InsertFunctionToTable("bxor", &Parser<ValueType>::BitXor);
|
||||||
|
InsertFunctionToTable("sum", &Parser<ValueType>::Sum);
|
||||||
|
InsertFunctionToTable("avg", &Parser<ValueType>::Avg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method create the table of variables
|
this method creates the table of variables
|
||||||
*/
|
*/
|
||||||
void CreateVariablesTable()
|
void CreateVariablesTable()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
names of variables should consist of small letters
|
names of variables should consist of small letters
|
||||||
*/
|
*/
|
||||||
InsertVariableToTable(std::string("pi"), &ValueType::SetPi);
|
InsertVariableToTable("pi", &ValueType::SetPi);
|
||||||
InsertVariableToTable(std::string("e"), &ValueType::SetE);
|
InsertVariableToTable("e", &ValueType::SetE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
convert from a big letter to a small one
|
converting from a big letter to a small one
|
||||||
*/
|
*/
|
||||||
int ToLowerCase(int c)
|
int ToLowerCase(int c)
|
||||||
{
|
{
|
||||||
@@ -1347,8 +1528,6 @@ return c;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method read the name of a variable or a function
|
this method read the name of a variable or a function
|
||||||
|
|
||||||
@@ -1365,29 +1544,31 @@ int character;
|
|||||||
|
|
||||||
|
|
||||||
result.erase();
|
result.erase();
|
||||||
character = ToLowerCase(*pstring);
|
character = *pstring;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
the first letter must be from range 'a' - 'z'
|
the first letter must be from range 'a' - 'z' or 'A' - 'Z'
|
||||||
*/
|
*/
|
||||||
if( character<'a' || character>'z' )
|
if( ! (( character>='a' && character<='z' ) || ( character>='A' && character<='Z' )) )
|
||||||
Error( err_unknown_character );
|
Error( err_unknown_character );
|
||||||
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
result += character;
|
result += character;
|
||||||
character = ToLowerCase( * ++pstring );
|
character = * ++pstring;
|
||||||
}
|
}
|
||||||
while( (character>='a' && character<='z') ||
|
while( (character>='a' && character<='z') ||
|
||||||
(character>='0' && character<='9') );
|
(character>='A' && character<='Z') ||
|
||||||
|
(character>='0' && character<='9') ||
|
||||||
|
character=='_' );
|
||||||
|
|
||||||
|
|
||||||
SkipWhiteCharacters();
|
SkipWhiteCharacters();
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if there's character '(' that means this name is a name of a function
|
if there's a character '(' that means this name is a name of a function
|
||||||
*/
|
*/
|
||||||
if( *pstring == '(' )
|
if( *pstring == '(' )
|
||||||
{
|
{
|
||||||
@@ -1454,19 +1635,22 @@ return is_it_name_of_function;
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
we're reading a numerical value directly from the string
|
we're reading a numerical value directly from the string
|
||||||
*/
|
*/
|
||||||
void ReadValue(Item & result)
|
void ReadValue(Item & result, int reading_base)
|
||||||
{
|
{
|
||||||
const char * new_stack_pointer;
|
const char * new_stack_pointer;
|
||||||
|
bool value_read;
|
||||||
|
|
||||||
int carry = result.value.FromString(pstring, base, &new_stack_pointer);
|
int carry = result.value.FromString(pstring, reading_base, &new_stack_pointer, &value_read);
|
||||||
pstring = new_stack_pointer;
|
pstring = new_stack_pointer;
|
||||||
|
|
||||||
if( carry )
|
if( carry )
|
||||||
Error( err_overflow );
|
Error( err_overflow );
|
||||||
}
|
|
||||||
|
|
||||||
|
if( !value_read )
|
||||||
|
Error( err_unknown_character );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -1494,6 +1678,24 @@ return c;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns true if 'character' is a proper first digit for the value (or a comma -- can be first too)
|
||||||
|
*/
|
||||||
|
bool ValueStarts(int character, int base)
|
||||||
|
{
|
||||||
|
if( character == TTMATH_COMMA_CHARACTER_1 )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if( TTMATH_COMMA_CHARACTER_2 != 0 && character == TTMATH_COMMA_CHARACTER_2 )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if( CharToDigit(character, base) != -1 )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
we're reading the item
|
we're reading the item
|
||||||
|
|
||||||
@@ -1553,16 +1755,33 @@ int character;
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( character=='#' || character=='&' || CharToDigit(character, base)!=-1 )
|
if( character == '#' )
|
||||||
{
|
{
|
||||||
/*
|
++pstring;
|
||||||
warning:
|
SkipWhiteCharacters();
|
||||||
if we're using for example the base equal 16
|
|
||||||
we can find a first character like 'e' that is there is not e=2.71..
|
// after '#' character we do not allow '-' or '+' (can be white characters)
|
||||||
but the value 14, for this case we must use something like var::e for variables
|
if( ValueStarts(*pstring, 16) )
|
||||||
(not implemented yet)
|
ReadValue( result, 16 );
|
||||||
*/
|
else
|
||||||
ReadValue( result );
|
Error( err_unknown_character );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( character == '&' )
|
||||||
|
{
|
||||||
|
++pstring;
|
||||||
|
SkipWhiteCharacters();
|
||||||
|
|
||||||
|
// after '&' character we do not allow '-' or '+' (can be white characters)
|
||||||
|
if( ValueStarts(*pstring, 2) )
|
||||||
|
ReadValue( result, 2 );
|
||||||
|
else
|
||||||
|
Error( err_unknown_character );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( ValueStarts(character, base) )
|
||||||
|
{
|
||||||
|
ReadValue( result, base );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( character>='a' && character<='z' )
|
if( character>='a' && character<='z' )
|
||||||
@@ -1598,6 +1817,7 @@ void InsertOperatorToTable(const std::string & name, typename MatOperator::Type
|
|||||||
operators_table.insert( std::make_pair(name, type) );
|
operators_table.insert( std::make_pair(name, type) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method creates the table of operators
|
this method creates the table of operators
|
||||||
*/
|
*/
|
||||||
@@ -1698,6 +1918,14 @@ int ReadOperator(Item & result)
|
|||||||
result.type = Item::semicolon;
|
result.type = Item::semicolon;
|
||||||
++pstring;
|
++pstring;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if( (*pstring>='a' && *pstring<='z') || (*pstring>='A' && *pstring<='Z') )
|
||||||
|
{
|
||||||
|
// short mul (without any operators)
|
||||||
|
|
||||||
|
result.type = Item::mat_operator;
|
||||||
|
result.moperator.SetType( MatOperator::shortmul );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ReadMathematicalOperator(result);
|
ReadMathematicalOperator(result);
|
||||||
|
|
||||||
@@ -1760,6 +1988,7 @@ int res;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MatOperator::mul:
|
case MatOperator::mul:
|
||||||
|
case MatOperator::shortmul:
|
||||||
if( value1.Mul(value2) ) Error( err_overflow );
|
if( value1.Mul(value2) ) Error( err_overflow );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1777,6 +2006,7 @@ int res;
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
on the stack left an unknown operator but we had to recognize its before
|
on the stack left an unknown operator but we had to recognize its before
|
||||||
@@ -1854,9 +2084,9 @@ void TryRollingUpStack()
|
|||||||
*/
|
*/
|
||||||
int ReadValueVariableOrFunctionAndPushItIntoStack(Item & temp)
|
int ReadValueVariableOrFunctionAndPushItIntoStack(Item & temp)
|
||||||
{
|
{
|
||||||
int kod = ReadValueVariableOrFunction( temp );
|
int code = ReadValueVariableOrFunction( temp );
|
||||||
|
|
||||||
if( kod == 0 )
|
if( code == 0 )
|
||||||
{
|
{
|
||||||
if( stack_index < stack.size() )
|
if( stack_index < stack.size() )
|
||||||
stack[stack_index] = temp;
|
stack[stack_index] = temp;
|
||||||
@@ -1866,20 +2096,20 @@ int kod = ReadValueVariableOrFunction( temp );
|
|||||||
++stack_index;
|
++stack_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( kod == 2 )
|
if( code == 2 )
|
||||||
// there was a final bracket, we didn't push it into the stack
|
// there was a final bracket, we didn't push it into the stack
|
||||||
// (it'll be read by the 'ReadOperatorAndCheckFinalBracket' method next)
|
// (it'll be read by the 'ReadOperatorAndCheckFinalBracket' method next)
|
||||||
kod = 0;
|
code = 0;
|
||||||
|
|
||||||
|
|
||||||
return kod;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method calculate how many parameters there are on the stack
|
this method calculate how many parameters there are on the stack
|
||||||
and index of the first parameter
|
and the index of the first parameter
|
||||||
|
|
||||||
if there aren't any parameters on the stack this method returns
|
if there aren't any parameters on the stack this method returns
|
||||||
'size' equals zero and 'index' pointing after the first bracket
|
'size' equals zero and 'index' pointing after the first bracket
|
||||||
@@ -2161,6 +2391,7 @@ Parser(): default_stack_size(100)
|
|||||||
puser_functions = 0;
|
puser_functions = 0;
|
||||||
pfunction_local_variables = 0;
|
pfunction_local_variables = 0;
|
||||||
base = 10;
|
base = 10;
|
||||||
|
deg_rad_grad = 1;
|
||||||
error = err_ok;
|
error = err_ok;
|
||||||
factorial_max.SetZero();
|
factorial_max.SetZero();
|
||||||
|
|
||||||
@@ -2180,6 +2411,7 @@ Parser<ValueType> & operator=(const Parser<ValueType> & p)
|
|||||||
puser_functions = p.puser_functions;
|
puser_functions = p.puser_functions;
|
||||||
pfunction_local_variables = 0;
|
pfunction_local_variables = 0;
|
||||||
base = p.base;
|
base = p.base;
|
||||||
|
deg_rad_grad = p.deg_rad_grad;
|
||||||
error = err_ok;
|
error = err_ok;
|
||||||
factorial_max = p.factorial_max;
|
factorial_max = p.factorial_max;
|
||||||
|
|
||||||
@@ -2217,6 +2449,18 @@ void SetBase(int b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the unit of angles used in: sin,cos,tan,cot,asin,acos,atan,acot
|
||||||
|
0 - deg
|
||||||
|
1 - rad (default)
|
||||||
|
2 - grad
|
||||||
|
*/
|
||||||
|
void SetDegRadGrad(int angle)
|
||||||
|
{
|
||||||
|
if( angle >= 0 || angle <= 2 )
|
||||||
|
deg_rad_grad = angle;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets a pointer to the object which tell us whether we should stop
|
this method sets a pointer to the object which tell us whether we should stop
|
||||||
calculations
|
calculations
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Mathematical Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the (new) BSD licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2007, Tomasz Sowa
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
*/
|
*/
|
||||||
#define TTMATH_MAJOR_VER 0
|
#define TTMATH_MAJOR_VER 0
|
||||||
#define TTMATH_MINOR_VER 8
|
#define TTMATH_MINOR_VER 8
|
||||||
#define TTMATH_REVISION_VER 1
|
#define TTMATH_REVISION_VER 3
|
||||||
#define TTMATH_PRERELEASE_VER 0
|
#define TTMATH_PRERELEASE_VER 0
|
||||||
|
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ namespace ttmath
|
|||||||
which are kept in built-in variables for a Big<> type
|
which are kept in built-in variables for a Big<> type
|
||||||
(these variables are defined in ttmathbig.h)
|
(these variables are defined in ttmathbig.h)
|
||||||
*/
|
*/
|
||||||
#define TTMATH_BUILTIN_VARIABLES_SIZE 128u
|
#define TTMATH_BUILTIN_VARIABLES_SIZE 256u
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ namespace ttmath
|
|||||||
which are kept in built-in variables for a Big<> type
|
which are kept in built-in variables for a Big<> type
|
||||||
(these variables are defined in ttmathbig.h)
|
(these variables are defined in ttmathbig.h)
|
||||||
*/
|
*/
|
||||||
#define TTMATH_BUILTIN_VARIABLES_SIZE 64ul
|
#define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,7 @@ namespace ttmath
|
|||||||
/*!
|
/*!
|
||||||
characters which represent the comma operator
|
characters which represent the comma operator
|
||||||
|
|
||||||
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing
|
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing (default, can be overwritten in ToString() function)
|
||||||
TTMATH_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character
|
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
|
that means you can input values for example 1.2345 and 1,2345 as well
|
||||||
|
|
||||||
@@ -197,6 +197,7 @@ namespace ttmath
|
|||||||
#define TTMATH_COMMA_CHARACTER_2 ','
|
#define TTMATH_COMMA_CHARACTER_2 ','
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this variable defines how many iterations are performed
|
this variable defines how many iterations are performed
|
||||||
during some kind of calculating when we're making any long formulas
|
during some kind of calculating when we're making any long formulas
|
||||||
@@ -247,7 +248,8 @@ namespace ttmath
|
|||||||
err_object_exists,
|
err_object_exists,
|
||||||
err_unknown_object,
|
err_unknown_object,
|
||||||
err_still_calculating,
|
err_still_calculating,
|
||||||
err_too_big_factorial
|
err_too_big_factorial,
|
||||||
|
err_in_short_form_used_function
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
1354
ttmath/ttmathuint.h
1354
ttmath/ttmathuint.h
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Mathematical Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the (new) BSD licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2007, Tomasz Sowa
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -210,10 +210,12 @@ namespace ttmath
|
|||||||
register uint * p2 = const_cast<uint*>(ss2.table);
|
register uint * p2 = const_cast<uint*>(ss2.table);
|
||||||
|
|
||||||
|
|
||||||
|
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
||||||
|
// this algorithm doesn't require it
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
/*
|
/*
|
||||||
@@ -221,48 +223,28 @@ namespace ttmath
|
|||||||
*/
|
*/
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"push %%rbx \n"
|
"push %%rcx \n"
|
||||||
"push %%rcx \n"
|
|
||||||
"push %%rdx \n"
|
|
||||||
|
|
||||||
"movq $0, %%rax \n"
|
"xorq %%rax, %%rax \n"
|
||||||
"subq %%rsi, %%rax \n"
|
"movq %%rax, %%rdx \n"
|
||||||
|
"subq %%rdi, %%rax \n"
|
||||||
|
|
||||||
"1: \n"
|
|
||||||
"movq (%%rbx),%%rax \n"
|
|
||||||
"adcq (%%rdx),%%rax \n"
|
|
||||||
"movq %%rax,(%%rbx) \n"
|
|
||||||
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
|
|
||||||
"loop 1b \n"
|
|
||||||
|
|
||||||
"movq $0, %%rax \n"
|
"1: \n"
|
||||||
"adcq %%rax,%%rax \n"
|
"movq (%%rsi,%%rdx,8),%%rax \n"
|
||||||
"movq %%rax, %%rsi \n"
|
"adcq %%rax, (%%rbx,%%rdx,8) \n"
|
||||||
|
|
||||||
|
"incq %%rdx \n"
|
||||||
|
"decq %%rcx \n"
|
||||||
|
"jnz 1b \n"
|
||||||
|
|
||||||
"pop %%rdx \n"
|
"setc %%al \n"
|
||||||
"pop %%rcx \n"
|
"movzx %%al,%%rdx \n"
|
||||||
"pop %%rbx \n"
|
|
||||||
|
|
||||||
: "=S" (c)
|
"pop %%rcx \n"
|
||||||
: "0" (c), "c" (b), "b" (p1), "d" (p2)
|
|
||||||
|
: "=d" (c)
|
||||||
|
: "D" (c), "c" (b), "b" (p1), "S" (p2)
|
||||||
: "%rax", "cc", "memory" );
|
: "%rax", "cc", "memory" );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -301,54 +283,39 @@ namespace ttmath
|
|||||||
register uint * p1 = table;
|
register uint * p1 = table;
|
||||||
register uint c;
|
register uint c;
|
||||||
|
|
||||||
|
TTMATH_ASSERT( index < value_size )
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"push %%rbx \n"
|
|
||||||
|
"push %%rax \n"
|
||||||
"push %%rcx \n"
|
"push %%rcx \n"
|
||||||
"push %%rdx \n"
|
|
||||||
|
|
||||||
"subq %%rdx, %%rcx \n"
|
"subq %%rdx, %%rcx \n"
|
||||||
|
|
||||||
"leaq (%%rbx,%%rdx,8), %%rbx \n"
|
|
||||||
|
|
||||||
"movq %%rsi, %%rdx \n"
|
|
||||||
"clc \n"
|
|
||||||
"1: \n"
|
"1: \n"
|
||||||
|
"addq %%rax, (%%rbx,%%rdx,8) \n"
|
||||||
"movq (%%rbx), %%rax \n"
|
|
||||||
"adcq %%rdx, %%rax \n"
|
|
||||||
"movq %%rax, (%%rbx) \n"
|
|
||||||
|
|
||||||
"jnc 2f \n"
|
"jnc 2f \n"
|
||||||
|
|
||||||
"movq $0, %%rdx \n"
|
"movq $1, %%rax \n"
|
||||||
|
"incq %%rdx \n"
|
||||||
"inc %%rbx \n"
|
"decq %%rcx \n"
|
||||||
"inc %%rbx \n"
|
"jnz 1b \n"
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
|
|
||||||
"loop 1b \n"
|
|
||||||
|
|
||||||
"2: \n"
|
"2: \n"
|
||||||
|
"setc %%al \n"
|
||||||
|
"movzx %%al, %%rdx \n"
|
||||||
|
|
||||||
"movq $0, %%rax \n"
|
|
||||||
"adcq %%rax,%%rax \n"
|
|
||||||
|
|
||||||
"pop %%rdx \n"
|
|
||||||
"pop %%rcx \n"
|
"pop %%rcx \n"
|
||||||
"pop %%rbx \n"
|
"pop %%rax \n"
|
||||||
|
|
||||||
: "=a" (c)
|
: "=d" (c)
|
||||||
: "c" (b), "d" (index), "b" (p1), "S" (value)
|
: "a" (value), "c" (b), "0" (index), "b" (p1)
|
||||||
: "cc", "memory" );
|
: "cc", "memory" );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -398,6 +365,8 @@ namespace ttmath
|
|||||||
register uint * p1 = table;
|
register uint * p1 = table;
|
||||||
register uint c;
|
register uint c;
|
||||||
|
|
||||||
|
TTMATH_ASSERT( index < value_size - 1 )
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
@@ -405,67 +374,33 @@ namespace ttmath
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"push %%rbx \n"
|
|
||||||
"push %%rcx \n"
|
"push %%rcx \n"
|
||||||
"push %%rdx \n"
|
"push %%rdx \n"
|
||||||
|
|
||||||
"subq %%rdx, %%rcx \n"
|
"subq %%rdx, %%rcx \n"
|
||||||
|
|
||||||
"leaq (%%rbx,%%rdx,8), %%rbx \n"
|
"addq %%rsi, (%%rbx,%%rdx,8) \n"
|
||||||
|
"incq %%rdx \n"
|
||||||
"movq $0, %%rdx \n"
|
"decq %%rcx \n"
|
||||||
|
|
||||||
"movq (%%rbx), %%rax \n"
|
|
||||||
"addq %%rsi, %%rax \n"
|
|
||||||
"movq %%rax, (%%rbx) \n"
|
|
||||||
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
|
|
||||||
"movq (%%rbx), %%rax \n"
|
|
||||||
"adcq %%rdi, %%rax \n"
|
|
||||||
"movq %%rax, (%%rbx) \n"
|
|
||||||
"jnc 2f \n"
|
|
||||||
|
|
||||||
"dec %%rcx \n"
|
|
||||||
"dec %%rcx \n"
|
|
||||||
"jz 2f \n"
|
|
||||||
|
|
||||||
"1: \n"
|
"1: \n"
|
||||||
"inc %%rbx \n"
|
"adcq %%rax, (%%rbx,%%rdx,8) \n"
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
|
|
||||||
"movq (%%rbx), %%rax \n"
|
|
||||||
"adcq %%rdx, %%rax \n"
|
|
||||||
"movq %%rax, (%%rbx) \n"
|
|
||||||
|
|
||||||
"jnc 2f \n"
|
"jnc 2f \n"
|
||||||
|
|
||||||
"loop 1b \n"
|
"mov $0, %%rax \n"
|
||||||
|
"incq %%rdx \n"
|
||||||
|
"decq %%rcx \n"
|
||||||
|
"jnz 1b \n"
|
||||||
|
|
||||||
"2: \n"
|
"2: \n"
|
||||||
|
"setc %%al \n"
|
||||||
"movq $0, %%rax \n"
|
"movzx %%al, %%rax \n"
|
||||||
"adcq %%rax,%%rax \n"
|
|
||||||
|
|
||||||
"pop %%rdx \n"
|
"pop %%rdx \n"
|
||||||
"pop %%rcx \n"
|
"pop %%rcx \n"
|
||||||
"pop %%rbx \n"
|
|
||||||
|
|
||||||
: "=a" (c)
|
: "=a" (c)
|
||||||
: "c" (b), "d" (index), "b" (p1), "S" (x1), "D" (x2)
|
: "c" (b), "d" (index), "b" (p1), "S" (x1), "0" (x2)
|
||||||
: "cc", "memory" );
|
: "cc", "memory" );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -495,6 +430,9 @@ namespace ttmath
|
|||||||
register uint * p1 = table;
|
register uint * p1 = table;
|
||||||
register uint * p2 = const_cast<uint*>(ss2.table);
|
register uint * p2 = const_cast<uint*>(ss2.table);
|
||||||
|
|
||||||
|
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
||||||
|
// this algorithm doesn't require it
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
@@ -502,50 +440,31 @@ namespace ttmath
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"push %%rbx \n"
|
"push %%rcx \n"
|
||||||
"push %%rcx \n"
|
|
||||||
"push %%rdx \n"
|
"xorq %%rax, %%rax \n"
|
||||||
|
"movq %%rax, %%rdx \n"
|
||||||
|
"subq %%rdi, %%rax \n"
|
||||||
|
|
||||||
"movq $0, %%rax \n"
|
|
||||||
"subq %%rsi, %%rax \n"
|
|
||||||
|
|
||||||
"1: \n"
|
"1: \n"
|
||||||
"movq (%%rbx),%%rax \n"
|
"movq (%%rsi,%%rdx,8),%%rax \n"
|
||||||
"sbbq (%%rdx),%%rax \n"
|
"sbbq %%rax, (%%rbx,%%rdx,8) \n"
|
||||||
"movq %%rax,(%%rbx) \n"
|
|
||||||
|
"incq %%rdx \n"
|
||||||
"inc %%rbx \n"
|
"decq %%rcx \n"
|
||||||
"inc %%rbx \n"
|
"jnz 1b \n"
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
"inc %%rdx \n"
|
|
||||||
|
|
||||||
"loop 1b \n"
|
|
||||||
|
|
||||||
"movq $0, %%rax \n"
|
"setc %%al \n"
|
||||||
"adcq %%rax,%%rax \n"
|
"movzx %%al,%%rdx \n"
|
||||||
"movq %%rax, %%rsi \n"
|
|
||||||
|
|
||||||
"pop %%rdx \n"
|
"pop %%rcx \n"
|
||||||
"pop %%rcx \n"
|
|
||||||
"pop %%rbx \n"
|
|
||||||
|
|
||||||
: "=S" (c)
|
: "=d" (c)
|
||||||
: "0" (c), "c" (b), "b" (p1), "d" (p2)
|
: "D" (c), "c" (b), "b" (p1), "S" (p2)
|
||||||
: "%rax", "cc", "memory" );
|
: "%rax", "cc", "memory" );
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -579,6 +498,8 @@ namespace ttmath
|
|||||||
register uint * p1 = table;
|
register uint * p1 = table;
|
||||||
register uint c;
|
register uint c;
|
||||||
|
|
||||||
|
TTMATH_ASSERT( index < value_size )
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
@@ -586,48 +507,29 @@ namespace ttmath
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"push %%rbx \n"
|
"push %%rax \n"
|
||||||
"push %%rcx \n"
|
"push %%rcx \n"
|
||||||
"push %%rdx \n"
|
|
||||||
|
|
||||||
"subq %%rdx, %%rcx \n"
|
"subq %%rdx, %%rcx \n"
|
||||||
|
|
||||||
"leaq (%%rbx,%%rdx,8), %%rbx \n"
|
|
||||||
|
|
||||||
"movq %%rsi, %%rdx \n"
|
|
||||||
"clc \n"
|
|
||||||
"1: \n"
|
"1: \n"
|
||||||
|
"subq %%rax, (%%rbx,%%rdx,8) \n"
|
||||||
"movq (%%rbx), %%rax \n"
|
|
||||||
"sbbq %%rdx, %%rax \n"
|
|
||||||
"movq %%rax, (%%rbx) \n"
|
|
||||||
|
|
||||||
"jnc 2f \n"
|
"jnc 2f \n"
|
||||||
|
|
||||||
"movq $0, %%rdx \n"
|
"movq $1, %%rax \n"
|
||||||
|
"incq %%rdx \n"
|
||||||
"inc %%rbx \n"
|
"decq %%rcx \n"
|
||||||
"inc %%rbx \n"
|
"jnz 1b \n"
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
|
|
||||||
"loop 1b \n"
|
|
||||||
|
|
||||||
"2: \n"
|
"2: \n"
|
||||||
|
"setc %%al \n"
|
||||||
|
"movzx %%al, %%rdx \n"
|
||||||
|
|
||||||
"movq $0, %%rax \n"
|
|
||||||
"adcq %%rax,%%rax \n"
|
|
||||||
|
|
||||||
"pop %%rdx \n"
|
|
||||||
"pop %%rcx \n"
|
"pop %%rcx \n"
|
||||||
"pop %%rbx \n"
|
"pop %%rax \n"
|
||||||
|
|
||||||
: "=a" (c)
|
: "=d" (c)
|
||||||
: "c" (b), "d" (index), "b" (p1), "S" (value)
|
: "a" (value), "c" (b), "0" (index), "b" (p1)
|
||||||
: "cc", "memory" );
|
: "cc", "memory" );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -637,6 +539,119 @@ namespace ttmath
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method moves all bits into the left hand side
|
||||||
|
return value <- this <- c
|
||||||
|
|
||||||
|
the lowest *bit* will be held the 'c' and
|
||||||
|
the state of one additional bit (on the left hand side)
|
||||||
|
will be returned
|
||||||
|
|
||||||
|
for example:
|
||||||
|
let this is 001010000
|
||||||
|
after Rcl2_one(1) there'll be 010100001 and Rcl2_one returns 0
|
||||||
|
|
||||||
|
***this method is created only on a 64bit platform***
|
||||||
|
*/
|
||||||
|
template<uint value_size>
|
||||||
|
uint UInt<value_size>::Rcl2_one(uint c)
|
||||||
|
{
|
||||||
|
register sint b = value_size;
|
||||||
|
register uint * p1 = table;
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __GNUC__
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__asm__ __volatile__(
|
||||||
|
|
||||||
|
"push %%rdx \n"
|
||||||
|
"push %%rcx \n"
|
||||||
|
|
||||||
|
"xorq %%rdx, %%rdx \n" // rdx=0
|
||||||
|
"neg %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
|
||||||
|
|
||||||
|
"1: \n"
|
||||||
|
"rclq $1, (%%rbx, %%rdx, 8) \n"
|
||||||
|
|
||||||
|
"incq %%rdx \n"
|
||||||
|
"decq %%rcx \n"
|
||||||
|
"jnz 1b \n"
|
||||||
|
|
||||||
|
"setc %%al \n"
|
||||||
|
"movzx %%al, %%rax \n"
|
||||||
|
|
||||||
|
"pop %%rcx \n"
|
||||||
|
"pop %%rdx \n"
|
||||||
|
|
||||||
|
: "=a" (c)
|
||||||
|
: "0" (c), "c" (b), "b" (p1)
|
||||||
|
: "cc", "memory" );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method moves all bits into the right hand side
|
||||||
|
c -> this -> return value
|
||||||
|
|
||||||
|
the highest *bit* will be held the 'c' and
|
||||||
|
the state of one additional bit (on the right hand side)
|
||||||
|
will be returned
|
||||||
|
|
||||||
|
for example:
|
||||||
|
let this is 000000010
|
||||||
|
after Rcr2_one(1) there'll be 100000001 and Rcr2_one returns 0
|
||||||
|
|
||||||
|
***this method is created only on a 64bit platform***
|
||||||
|
*/
|
||||||
|
template<uint value_size>
|
||||||
|
uint UInt<value_size>::Rcr2_one(uint c)
|
||||||
|
{
|
||||||
|
register sint b = value_size;
|
||||||
|
register uint * p1 = table;
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __GNUC__
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__asm__ __volatile__(
|
||||||
|
|
||||||
|
"push %%rcx \n"
|
||||||
|
|
||||||
|
"neg %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
|
||||||
|
|
||||||
|
"1: \n"
|
||||||
|
"rcrq $1, -8(%%rbx, %%rcx, 8) \n"
|
||||||
|
|
||||||
|
"decq %%rcx \n"
|
||||||
|
"jnz 1b \n"
|
||||||
|
|
||||||
|
"setc %%al \n"
|
||||||
|
"movzx %%al, %%rax \n"
|
||||||
|
|
||||||
|
"pop %%rcx \n"
|
||||||
|
|
||||||
|
: "=a" (c)
|
||||||
|
: "0" (c), "c" (b), "b" (p1)
|
||||||
|
: "cc", "memory" );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method moves all bits into the left hand side
|
this method moves all bits into the left hand side
|
||||||
return value <- this <- c
|
return value <- this <- c
|
||||||
@@ -654,13 +669,11 @@ namespace ttmath
|
|||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
uint UInt<value_size>::Rcl2(uint bits, uint c)
|
uint UInt<value_size>::Rcl2(uint bits, uint c)
|
||||||
{
|
{
|
||||||
if( bits == 0 )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||||
|
|
||||||
register sint b = value_size;
|
register sint b = value_size;
|
||||||
register uint * p1 = table;
|
register uint * p1 = table;
|
||||||
|
register uint mask;
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
@@ -669,46 +682,46 @@ namespace ttmath
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"push %%rsi \n"
|
"push %%rdx \n"
|
||||||
|
"push %%rsi \n"
|
||||||
|
"push %%rdi \n"
|
||||||
|
|
||||||
|
"movq %%rcx, %%rsi \n"
|
||||||
"2: \n"
|
"movq $64, %%rcx \n"
|
||||||
|
"subq %%rsi, %%rcx \n"
|
||||||
|
"movq $-1, %%rdx \n"
|
||||||
|
"shrq %%cl, %%rdx \n"
|
||||||
|
"movq %%rdx, %[amask] \n"
|
||||||
|
"movq %%rsi, %%rcx \n"
|
||||||
|
|
||||||
"xorq %%rax,%%rax \n"
|
"xorq %%rdx, %%rdx \n"
|
||||||
"subq %%rdx,%%rax \n"
|
"movq %%rdx, %%rsi \n"
|
||||||
|
|
||||||
"push %%rbx \n"
|
"orq %%rax, %%rax \n"
|
||||||
"push %%rcx \n"
|
"cmovnz %[amask], %%rsi \n"
|
||||||
|
|
||||||
"1: \n"
|
"1: \n"
|
||||||
"rclq $1,(%%rbx) \n"
|
"rolq %%cl, (%%rbx,%%rdx,8) \n"
|
||||||
|
|
||||||
|
"movq (%%rbx,%%rdx,8), %%rax \n"
|
||||||
|
"andq %[amask], %%rax \n"
|
||||||
|
"xorq %%rax, (%%rbx,%%rdx,8) \n"
|
||||||
|
"orq %%rsi, (%%rbx,%%rdx,8) \n"
|
||||||
|
"movq %%rax, %%rsi \n"
|
||||||
|
|
||||||
"inc %%rbx \n"
|
"incq %%rdx \n"
|
||||||
"inc %%rbx \n"
|
"decq %%rdi \n"
|
||||||
"inc %%rbx \n"
|
"jnz 1b \n"
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
"inc %%rbx \n"
|
|
||||||
|
|
||||||
"loop 1b \n"
|
"and $1, %%rax \n"
|
||||||
|
|
||||||
"pop %%rcx \n"
|
|
||||||
"pop %%rbx \n"
|
|
||||||
|
|
||||||
"decq %%rsi \n"
|
"pop %%rdi \n"
|
||||||
|
"pop %%rsi \n"
|
||||||
|
"pop %%rdx \n"
|
||||||
|
|
||||||
"jnz 2b \n"
|
: "=a" (c)
|
||||||
|
: "0" (c), "D" (b), "b" (p1), "c" (bits), [amask] "m" (mask)
|
||||||
"movq $0, %%rdx \n"
|
: "cc", "memory" );
|
||||||
"adcq %%rdx, %%rdx \n"
|
|
||||||
|
|
||||||
"pop %%rsi \n"
|
|
||||||
|
|
||||||
: "=d" (c)
|
|
||||||
: "0" (c), "c" (b), "b" (p1), "S" (bits)
|
|
||||||
: "%rax", "cc", "memory" );
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -734,14 +747,11 @@ namespace ttmath
|
|||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
uint UInt<value_size>::Rcr2(uint bits, uint c)
|
uint UInt<value_size>::Rcr2(uint bits, uint c)
|
||||||
{
|
{
|
||||||
if( bits == 0 )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||||
|
|
||||||
register sint b = value_size;
|
register sint b = value_size;
|
||||||
register uint * p1 = table;
|
register uint * p1 = table;
|
||||||
|
register uint mask;
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
@@ -751,49 +761,49 @@ namespace ttmath
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"push %%rsi \n"
|
"push %%rdx \n"
|
||||||
|
"push %%rsi \n"
|
||||||
|
"push %%rdi \n"
|
||||||
"2: \n"
|
|
||||||
|
|
||||||
|
|
||||||
"push %%rbx \n"
|
|
||||||
"push %%rcx \n"
|
|
||||||
|
|
||||||
"leaq (%%rbx,%%rcx,8),%%rbx \n"
|
|
||||||
|
|
||||||
"xorq %%rax, %%rax \n"
|
|
||||||
"subq %%rdx, %%rax \n"
|
|
||||||
|
|
||||||
"1: \n"
|
|
||||||
"dec %%rbx \n"
|
|
||||||
"dec %%rbx \n"
|
|
||||||
"dec %%rbx \n"
|
|
||||||
"dec %%rbx \n"
|
|
||||||
"dec %%rbx \n"
|
|
||||||
"dec %%rbx \n"
|
|
||||||
"dec %%rbx \n"
|
|
||||||
"dec %%rbx \n"
|
|
||||||
|
|
||||||
"rcrq $1,(%%rbx) \n"
|
"movq %%rcx, %%rsi \n"
|
||||||
|
"movq $64, %%rcx \n"
|
||||||
|
"subq %%rsi, %%rcx \n"
|
||||||
|
"movq $-1, %%rdx \n"
|
||||||
|
"shlq %%cl, %%rdx \n"
|
||||||
|
"movq %%rdx, %[amask] \n"
|
||||||
|
"movq %%rsi, %%rcx \n"
|
||||||
|
|
||||||
|
"xorq %%rdx, %%rdx \n"
|
||||||
|
"movq %%rdx, %%rsi \n"
|
||||||
|
"addq %%rdi, %%rdx \n"
|
||||||
|
"decq %%rdx \n"
|
||||||
|
|
||||||
|
"orq %%rax, %%rax \n"
|
||||||
|
"cmovnz %[amask], %%rsi \n"
|
||||||
|
|
||||||
|
"1: \n"
|
||||||
|
"rorq %%cl, (%%rbx,%%rdx,8) \n"
|
||||||
|
|
||||||
|
"movq (%%rbx,%%rdx,8), %%rax \n"
|
||||||
|
"andq %[amask], %%rax \n"
|
||||||
|
"xorq %%rax, (%%rbx,%%rdx,8) \n"
|
||||||
|
"orq %%rsi, (%%rbx,%%rdx,8) \n"
|
||||||
|
"movq %%rax, %%rsi \n"
|
||||||
|
|
||||||
"loop 1b \n"
|
"decq %%rdx \n"
|
||||||
|
"decq %%rdi \n"
|
||||||
|
"jnz 1b \n"
|
||||||
|
|
||||||
|
"rolq $1, %%rax \n"
|
||||||
|
"andq $1, %%rax \n"
|
||||||
|
|
||||||
"pop %%rcx \n"
|
"pop %%rdi \n"
|
||||||
"pop %%rbx \n"
|
"pop %%rsi \n"
|
||||||
|
"pop %%rdx \n"
|
||||||
|
|
||||||
"decq %%rsi \n"
|
: "=a" (c)
|
||||||
|
: "0" (c), "D" (b), "b" (p1), "c" (bits), [amask] "m" (mask)
|
||||||
"jnz 2b \n"
|
: "cc", "memory" );
|
||||||
|
|
||||||
"movq $0, %%rdx \n"
|
|
||||||
"adcq %%rdx,%%rdx \n"
|
|
||||||
|
|
||||||
"pop %%rsi \n"
|
|
||||||
|
|
||||||
: "=d" (c)
|
|
||||||
: "0" (c), "c" (b), "b" (p1), "S" (bits)
|
|
||||||
: "%rax", "cc", "memory" );
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -820,14 +830,13 @@ namespace ttmath
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
|
"bsrq %1, %0 \n"
|
||||||
"bsrq %%rbx, %%rax \n"
|
|
||||||
"jnz 1f \n"
|
"jnz 1f \n"
|
||||||
"movq $-1, %%rax \n"
|
"movq $-1, %0 \n"
|
||||||
"1: \n"
|
"1: \n"
|
||||||
|
|
||||||
: "=a" (result)
|
: "=R" (result)
|
||||||
: "b" (x)
|
: "R" (x)
|
||||||
: "cc" );
|
: "cc" );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -839,20 +848,26 @@ namespace ttmath
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets a special bit in the 'value'
|
this method sets a special bit in the 'value'
|
||||||
and returns the result
|
and returns the last state of the bit (zero or one)
|
||||||
|
|
||||||
***this method is created only on a 64bit platform***
|
***this method is created only on a 64bit platform***
|
||||||
|
|
||||||
bit is from <0,31>
|
bit is from <0,63>
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
SetBitInWord(0,0) = 1
|
uint x = 100;
|
||||||
SetBitInWord(0,2) = 4
|
uint bit = SetBitInWord(x, 3);
|
||||||
SetBitInWord(10, 8) = 266
|
now: x = 108 and bit = 0
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
uint UInt<value_size>::SetBitInWord(uint value, uint bit)
|
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
||||||
{
|
{
|
||||||
|
TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT )
|
||||||
|
|
||||||
|
uint old_bit;
|
||||||
|
uint v = value;
|
||||||
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
@@ -860,15 +875,20 @@ namespace ttmath
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"btsq %%rbx,%%rax \n"
|
"btsq %%rbx, %%rax \n"
|
||||||
|
|
||||||
: "=a" (value)
|
"setc %%bl \n"
|
||||||
: "0" (value), "b" (bit)
|
"movzx %%bl, %%rbx \n"
|
||||||
|
|
||||||
|
: "=a" (v), "=b" (old_bit)
|
||||||
|
: "0" (v), "1" (bit)
|
||||||
: "cc" );
|
: "cc" );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return value;
|
value = v;
|
||||||
|
|
||||||
|
return old_bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -983,4 +1003,3 @@ namespace ttmath
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user