Compare commits
162 Commits
Author | SHA1 | Date |
---|---|---|
Tomasz Sowa | aad580f51e | |
Tomasz Sowa | 3b113374b7 | |
Tomasz Sowa | 0f2fcaf547 | |
Tomasz Sowa | f88cba2688 | |
Tomasz Sowa | 48d694a47f | |
Tomasz Sowa | 9a93db39c4 | |
Tomasz Sowa | f98c434fc4 | |
Tomasz Sowa | 132fa10cd4 | |
Tomasz Sowa | dcdb1db9ec | |
Tomasz Sowa | d93d5ffd74 | |
Tomasz Sowa | 9b279276f2 | |
Tomasz Sowa | 83b5ab7170 | |
Tomasz Sowa | 35333b1e32 | |
Tomasz Sowa | c73af9c116 | |
Tomasz Sowa | f06592376f | |
Tomasz Sowa | b36821024b | |
Tomasz Sowa | cd740c5924 | |
Tomasz Sowa | 46ed8c3108 | |
Tomasz Sowa | f4f7882387 | |
Tomasz Sowa | 86dc01cdee | |
Tomasz Sowa | 2067301d1c | |
Tomasz Sowa | e2cdeac423 | |
Tomasz Sowa | 5893ffa9e3 | |
Tomasz Sowa | b862422bd9 | |
Tomasz Sowa | cb15ac0cd8 | |
Tomasz Sowa | 77c41e644a | |
Tomasz Sowa | 506840787a | |
Tomasz Sowa | e58253a078 | |
Tomasz Sowa | 6862321fad | |
Tomasz Sowa | 2e192969b0 | |
Tomasz Sowa | e8daa77d75 | |
Tomasz Sowa | 231164f6ea | |
Tomasz Sowa | c51b2fdcc9 | |
Tomasz Sowa | 84f34ebe52 | |
Tomasz Sowa | 3190f3011f | |
Tomasz Sowa | a34cf55155 | |
Tomasz Sowa | 648de47400 | |
Tomasz Sowa | 362207e2f1 | |
Tomasz Sowa | a40e951923 | |
Tomasz Sowa | b028896118 | |
Tomasz Sowa | a67a088e3a | |
Tomasz Sowa | 996fac15f1 | |
Tomasz Sowa | 1e268f1808 | |
Tomasz Sowa | 90674c9505 | |
Tomasz Sowa | b6fe168e3c | |
Tomasz Sowa | ae61b302a8 | |
Tomasz Sowa | a1c41c02db | |
Tomasz Sowa | 69f065245e | |
Tomasz Sowa | c65dac524a | |
Tomasz Sowa | b3c3dd8c3f | |
Tomasz Sowa | 1b7e13a9fd | |
Tomasz Sowa | aeadb8a04a | |
Tomasz Sowa | 053861655d | |
Tomasz Sowa | 35f2a8a28b | |
Tomasz Sowa | d5a5ea1a7d | |
Tomasz Sowa | 32b8c7a957 | |
Tomasz Sowa | e727eacce0 | |
Tomasz Sowa | 39db6fc469 | |
Tomasz Sowa | 0ada20b4cb | |
Tomasz Sowa | 31563ce343 | |
Tomasz Sowa | 418db51f46 | |
Tomasz Sowa | 82711f4441 | |
Tomasz Sowa | e5fc7a52e8 | |
Tomasz Sowa | 357524ae13 | |
Tomasz Sowa | 72052420dd | |
Tomasz Sowa | 321953e833 | |
Tomasz Sowa | 125c051ea1 | |
Tomasz Sowa | de150d00ec | |
Tomasz Sowa | 2d821bbad9 | |
Tomasz Sowa | e083c5f889 | |
Tomasz Sowa | 11b9f389b9 | |
Tomasz Sowa | bac79e0bfa | |
Tomasz Sowa | 0d1a57bdb4 | |
Tomasz Sowa | 4b4b30392a | |
Tomasz Sowa | 4f1763d773 | |
Tomasz Sowa | cccf82797f | |
Tomasz Sowa | e73ce2f8bc | |
Tomasz Sowa | 2feabc64e2 | |
Tomasz Sowa | 413c83de45 | |
Tomasz Sowa | bf520689fb | |
Tomasz Sowa | af4fbf3098 | |
Tomasz Sowa | 462ff7cc65 | |
Tomasz Sowa | 02da809583 | |
Tomasz Sowa | 32ebbbfd9e | |
Tomasz Sowa | e765fba8a1 | |
Tomasz Sowa | a8eb29e57d | |
Tomasz Sowa | 31b8c242bd | |
Tomasz Sowa | 4c0d8c26ff | |
Tomasz Sowa | 01a86e40d9 | |
Tomasz Sowa | f19078f9f1 | |
Tomasz Sowa | adc5015ad9 | |
Tomasz Sowa | da730d1c70 | |
Tomasz Sowa | 9ccacd8817 | |
Tomasz Sowa | b3d27979d0 | |
Tomasz Sowa | e13e5eb329 | |
Tomasz Sowa | 74b31b1f54 | |
Tomasz Sowa | 28964d30f7 | |
Tomasz Sowa | 0d71b0cec2 | |
Tomasz Sowa | 3544a1df3c | |
Tomasz Sowa | 00519ff26d | |
Tomasz Sowa | 799e2c32a7 | |
Tomasz Sowa | 53547cfab5 | |
Tomasz Sowa | d3a64b79ca | |
Tomasz Sowa | c70a947c07 | |
Tomasz Sowa | 8972fdfdb3 | |
Tomasz Sowa | 019a902fed | |
Tomasz Sowa | 74553109a5 | |
Tomasz Sowa | 9e42a5a9fd | |
Tomasz Sowa | 1b6858616d | |
Tomasz Sowa | d789ac5396 | |
Tomasz Sowa | bb2583649e | |
Tomasz Sowa | 5e5a106605 | |
Tomasz Sowa | eaa19dd46a | |
Tomasz Sowa | 939d0f7519 | |
Tomasz Sowa | 05b67e7103 | |
Tomasz Sowa | 3231780a85 | |
Tomasz Sowa | 1bae0d6cb8 | |
Tomasz Sowa | 277dd72fb6 | |
Tomasz Sowa | a7a7eb7808 | |
Tomasz Sowa | e665f91682 | |
Tomasz Sowa | 85945b2bb0 | |
Tomasz Sowa | 1efe39686b | |
Tomasz Sowa | d8b829f4c5 | |
Tomasz Sowa | fca1bc1a33 | |
Tomasz Sowa | c65857297b | |
Tomasz Sowa | f530635262 | |
Tomasz Sowa | 9327b4ebd4 | |
Tomasz Sowa | d695785cbb | |
Tomasz Sowa | 85d1b87ac0 | |
Tomasz Sowa | bfdc6d3df3 | |
Tomasz Sowa | 5668fbecf5 | |
Tomasz Sowa | 3899b8631c | |
Tomasz Sowa | 460608859c | |
Tomasz Sowa | 978815f12d | |
Tomasz Sowa | 404727f3de | |
Tomasz Sowa | 4aebe9aa18 | |
Tomasz Sowa | e18201ba35 | |
Tomasz Sowa | 5b24101a83 | |
Tomasz Sowa | 6da0386a2d | |
Tomasz Sowa | c7c859fc76 | |
Tomasz Sowa | 1d81dc75ff | |
Tomasz Sowa | 712bfc9c3b | |
Tomasz Sowa | 91e7badb62 | |
Tomasz Sowa | cfd719cca2 | |
Tomasz Sowa | f1115a2ce9 | |
Tomasz Sowa | ca51020fe6 | |
Tomasz Sowa | f8f324f98f | |
Tomasz Sowa | cdd95f602c | |
Tomasz Sowa | 98c2379182 | |
Tomasz Sowa | 2933213a02 | |
Tomasz Sowa | 4d0241c9c9 | |
Tomasz Sowa | 4f3f05fa9d | |
Tomasz Sowa | f139e6457c | |
Tomasz Sowa | 29bb4fb3f7 | |
Tomasz Sowa | 5002f435ae | |
Tomasz Sowa | 61886fc829 | |
Tomasz Sowa | 25f876762a | |
Tomasz Sowa | 692ff5406e | |
Tomasz Sowa | 669698c6d7 | |
Tomasz Sowa | 93ba8ce17d | |
Tomasz Sowa | d27cabec93 | |
Tomasz Sowa | bc9d528a75 |
554
CHANGELOG
554
CHANGELOG
|
@ -1,3 +1,494 @@
|
||||||
|
Version 0.9.4_prerelease (....):
|
||||||
|
* fixed: cannot compile on MS Windows when compiling with GCC (Mingw) for 64 bit platform:
|
||||||
|
incorrect size of ttmath::uint and ::sint were used
|
||||||
|
they were 'long' but 'long' is a 32bit type on Windows
|
||||||
|
* fixed: a crash in Big::Add() (buffer overflow)
|
||||||
|
there was an offset calculated from Int type by using Abs() method and a carry was not checked
|
||||||
|
(if there is a carry we should not make addition -- the argument is too small)
|
||||||
|
this had no impact on calculated values because there was a crash (bus error) immediately
|
||||||
|
following program could crash (64bit):
|
||||||
|
typedef ttmath::Big<1, 8> MyBig;
|
||||||
|
ttmath::Parser<MyBig> parser;
|
||||||
|
parser.Parse("2^(2^63) + 1");
|
||||||
|
* fixed: similar problems were in methods Big::BitAnd() Big::BitOr() and Big::BitXor() (bitwise operations)
|
||||||
|
and they could return incorrect values
|
||||||
|
* fixed: in x86_64 asm code (*.asm for Win64) there was in some places esp register used,
|
||||||
|
there should be rsp used instead
|
||||||
|
this affects MS Windows users when they use the asm version (ttmathuint_x86_64_msvc.asm)
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.9.3 (2012.11.28):
|
||||||
|
* fixed: in Big::FromDouble(double value) (only 32 bit version)
|
||||||
|
buffer overflow in referencing to UInt<2>
|
||||||
|
this was used when 'value' was in so called "unnormalized" state
|
||||||
|
(E=0 and F is nonzero)
|
||||||
|
it produced incorrect mantissa (on about 8th decimal digit up)
|
||||||
|
* added: Parser::InitCGamma()
|
||||||
|
initializing coefficients used when calculating the gamma (or factorial) function
|
||||||
|
this speed up the next calculations
|
||||||
|
you don't have to call this method explicitly
|
||||||
|
these coefficients will be calculated when needed
|
||||||
|
* added: option 'group_digits' to Conv struct
|
||||||
|
you can set how many digits should be grouped
|
||||||
|
* changed: small optimizations in UInt::ToString() and Big::FromString()
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.9.2 (2010.09.23):
|
||||||
|
* fixed: Big::Add() sometimes incorrectly rounded the last bit from its mantissa
|
||||||
|
* fixed: Big::BigAnd() Big::BigOr() Big::BigXor() should have set NaN
|
||||||
|
when the argument was negative (they only returned 2)
|
||||||
|
* fixed: recurrence calling in Big::FromString(const std::string &, uint, const wchar_t **, bool *)
|
||||||
|
it should have the signature: Big::FromString(const std::string &, uint, const char **, bool *)
|
||||||
|
* fixed: Big::ToString method
|
||||||
|
in some cases when in the output string the exponent should be equal zero
|
||||||
|
the method changes the exponent to one so the last digit from the mantissa
|
||||||
|
was lost
|
||||||
|
* fixed: Big::ToDouble(double &) set always +INF (infinity)
|
||||||
|
when the value was too large (even for negative values)
|
||||||
|
(it should set -INF in such a case)
|
||||||
|
* added: some missing operators
|
||||||
|
UInt::operator~() /* bitwise neg */
|
||||||
|
UInt::operator&() /* bitwise and */
|
||||||
|
UInt::operator&=()
|
||||||
|
UInt::operator|() /* bitwise or */
|
||||||
|
UInt::operator|=()
|
||||||
|
UInt::operator^() /* bitwise xor */
|
||||||
|
UInt::operator^=()
|
||||||
|
Big::operator&()
|
||||||
|
Big::operator&=()
|
||||||
|
Big::operator|()
|
||||||
|
Big::operator|=()
|
||||||
|
Big::operator^()
|
||||||
|
Big::operator^=()
|
||||||
|
for Big<> we do not define bitwise neg
|
||||||
|
Big::operator++()
|
||||||
|
Big::operator++(int)
|
||||||
|
Big::operator--()
|
||||||
|
Big::operator--(int)
|
||||||
|
* added: macro TTMATH_DONT_USE_WCHAR
|
||||||
|
if defined then the library does not use wide characters
|
||||||
|
(wchar_t, std::wstring, ...) this is a workaround for some compilers
|
||||||
|
* added: bool UInt::IsOnlyTheHighestBitSet()
|
||||||
|
bool UInt::IsOnlyTheLowestBitSet()
|
||||||
|
returning true if only the highest/lowest bit is set
|
||||||
|
* added: uint Int::MulInt(sint ss2)
|
||||||
|
* added: void UInt::Swap(UInt<value_size> & ss2)
|
||||||
|
void Big::Swap(UInt<value_size> & ss2)
|
||||||
|
method for swapping this for an argument
|
||||||
|
* added: macro TTMATH_BIG_DEFAULT_CLEAR
|
||||||
|
when defined the default constructor from Big<> clears its mantissa and exponent
|
||||||
|
Big<1, 2> var;
|
||||||
|
var.mantissa and var.exponent will be set to zero
|
||||||
|
(but var has the NaN flag set too - it is not zero value, this is mainly for debug purposes)
|
||||||
|
* added: only on 32bit platforms:
|
||||||
|
uint UInt::FromUInt(uint64_t n)
|
||||||
|
uint Int::FromInt(int64_t n)
|
||||||
|
void Big::FromUInt(uint64_t n)
|
||||||
|
void Big::FromInt(int64_t n)
|
||||||
|
and appropriate constructors and operators
|
||||||
|
* added: TTMATH_FORCEASM macro
|
||||||
|
asm version of the library is available by default only for:
|
||||||
|
x86 and amd64 platforms and for Microsoft Visual and GCC compilers,
|
||||||
|
but you can force using asm version (the same asm as for Microsoft Visual)
|
||||||
|
by defining TTMATH_FORCEASM macro
|
||||||
|
you have to be sure that your compiler accept such an asm format
|
||||||
|
* added: some missing methods for converting
|
||||||
|
for UInt<>, Int<> and Big<> classes:
|
||||||
|
uint ToUInt()
|
||||||
|
sint ToInt()
|
||||||
|
ToUInt(uint32_t &)
|
||||||
|
ToInt(uint32_t &)
|
||||||
|
ToInt(int32_t &)
|
||||||
|
ToUInt(uint64_t &)
|
||||||
|
ToInt(uint64_t &)
|
||||||
|
ToInt(int64_t &)
|
||||||
|
FromUInt(uint32_t &)
|
||||||
|
FromInt(uint32_t &)
|
||||||
|
FromInt(int32_t &)
|
||||||
|
FromUInt(uint64_t &)
|
||||||
|
FromInt(uint64_t &)
|
||||||
|
FromInt(int64_t &)
|
||||||
|
and appropriate constructors and operators
|
||||||
|
* added: double Big::ToDouble() /there was only Big::ToDouble(double &) /
|
||||||
|
uint Big::ToFloat(float &)
|
||||||
|
float Big::ToFloat()
|
||||||
|
* changed: now asm version is available only on x86 and amd64
|
||||||
|
(and only for GCC and MS VC compilers)
|
||||||
|
* removed: macro TTMATH_RELEASE (now the 'release' version is default)
|
||||||
|
for debug version define TTMATH_DEBUG macro
|
||||||
|
TTMATH_DEBUG is also automatically defined when DEBUG or _DEBUG is set
|
||||||
|
* removed: macro TTMATH_REFERENCE_ASSERT from all methods in public interface
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.9.1 (2010.02.07):
|
||||||
|
* fixed: the parser didn't use characters for changing the base (# and &)
|
||||||
|
those characters were skipped
|
||||||
|
(this bug was introduced in 0.9.0)
|
||||||
|
* fixed: added in the parser: operator's associativity
|
||||||
|
operator ^ (powering) is right-associative:
|
||||||
|
sample: 2^3^4 is equal 2^(3^4) and it is: 2.41e+24
|
||||||
|
previously was: 2^3^4 = (2^3)^4 = 4096
|
||||||
|
* fixed: in Big::ToString_CreateNewMantissaAndExponent() changed the formula:
|
||||||
|
new_exp_ = [log base (2^exponent)] + 1
|
||||||
|
now the part '+ 1' is only made when the logarithm is positive and with fraction
|
||||||
|
if the value is negative we can only skip the fraction, previously
|
||||||
|
we lost some last digits from the new mantissa
|
||||||
|
Consider this binary value (32 bit mantissa):
|
||||||
|
(bin)1.0000000000000000000000000000011
|
||||||
|
previously ToString() gave 1, now we have: 1.000000001
|
||||||
|
* changed: in Big::ToString() the base rounding is made only if the result value
|
||||||
|
would not be an integer, e.g. if the value is 1.999999999999 then
|
||||||
|
the base rounding will not be done - because as the result would be 2
|
||||||
|
* added: IEEE 754 half-to-even rounding (bankers' rounding) to the following
|
||||||
|
floating point algorithms: Big::Add, Big::Sub, Big::Mul, Big::Div
|
||||||
|
* added: static sint UInt<value_size>::FindLowestBitInWord(uint x)
|
||||||
|
this method is looking for the lowest set bit in a word
|
||||||
|
* added: UInt::FindLowestBit(uint & table_id, uint & index)
|
||||||
|
this method is looking for the lowest set bit
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.9.0 (2009.11.25):
|
||||||
|
* added: support for wide characters (wchar_t, std::wstring)
|
||||||
|
* added: Big::IsInteger()
|
||||||
|
returns true if the value is integer (without fraction)
|
||||||
|
(NaN flag is not checked)
|
||||||
|
* added: global Gamma() function
|
||||||
|
* added: gamma() function to the parser
|
||||||
|
* added: CGamma<ValueType> class
|
||||||
|
is used with Gamma() and Factorial() in multithreaded environment
|
||||||
|
* added: multithread support for Big<> class
|
||||||
|
you should compile with TTMATH_MULTITHREADS
|
||||||
|
and use TTMATH_MULTITHREADS_HELPER macro somewhere in your *.cpp file
|
||||||
|
* added: x86_64 asm code for Microsoft Visual compiler
|
||||||
|
file: ttmathuint_x86_64_msvc.asm
|
||||||
|
(this file should be compiled first because MS VC doesn't support inline assembler in x86_64 mode)
|
||||||
|
* added: flag TTMATH_BIG_ZERO to Big<> class
|
||||||
|
if this flag is set then there is a value zero
|
||||||
|
Big::IsZero() is faster now
|
||||||
|
* added: Big::ClearInfoBit(unsigned char)
|
||||||
|
Big::SetInfoBit(unsigned char)
|
||||||
|
Big::IsInfoBit(unsigned char)
|
||||||
|
some methods for manipulating the info flags
|
||||||
|
* added: macro: TTMATH_BITS(min_bits)
|
||||||
|
which returns the number of machine words
|
||||||
|
capable to hold min_bits bits
|
||||||
|
* added: bool Parser::Calculated()
|
||||||
|
this method returns true is something was calculated
|
||||||
|
(at least one mathematical operator was used or a function or variable)
|
||||||
|
* added: to the parser: operator percentage
|
||||||
|
e.g. 1000-50%=1000-(1000*0,5)=500
|
||||||
|
* added: struct: Conv
|
||||||
|
consists of some parameters used
|
||||||
|
in ToString() and FromString()
|
||||||
|
* added: Big::ToString() can group digits
|
||||||
|
e.g. 1234567 -> 1`234`567
|
||||||
|
* added: Parser::SetGroup(int g)
|
||||||
|
Parser::SetComma(int c, int c2 = 0)
|
||||||
|
Parser::SetParamSep(int s)
|
||||||
|
* added: std::string UInt::ToString(uint b = 10)
|
||||||
|
std::wstring UInt::ToWString(uint b = 10)
|
||||||
|
std::string Int::ToString(uint b = 10)
|
||||||
|
std::wstring Int::ToWString(uint b = 10)
|
||||||
|
uint Big::ToString(std::string & result, const Conv & conv)
|
||||||
|
uint Big::ToString(std::wstring & result, const Conv & conv)
|
||||||
|
std::string Big::ToString(const Conv & conv)
|
||||||
|
std::string Big::ToString()
|
||||||
|
std::wstring Big::ToWString(const Conv & conv)
|
||||||
|
std::wstring Big::ToWString()
|
||||||
|
* added: uint FromString(const char * source, const Conv & conv, const char **, bool *)
|
||||||
|
uint FromString(const wchar_t * source, const Conv & conv, const wchar_t **, bool *)
|
||||||
|
uint FromString(const std::string & string, const Conv & conv, const wchar_t **, bool *)
|
||||||
|
uint FromString(const std::wstring & string, const Conv & conv, const wchar_t **, bool *)
|
||||||
|
* added: UInt::Sqrt() - a new algorithm for calculating the square root
|
||||||
|
* added: to the parser: function frac() - returns a value without the integer part
|
||||||
|
(only fraction remains)
|
||||||
|
* added: Int::DivInt(sint divisor, sint * remainder)
|
||||||
|
* added: const char * UInt::LibTypeStr()
|
||||||
|
const char * Big::LibTypeStr()
|
||||||
|
LibTypeCode UInt::LibType()
|
||||||
|
LibTypeCode Big::LibType()
|
||||||
|
returning a string/enum represents the currect type of the library
|
||||||
|
we have following types:
|
||||||
|
asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
||||||
|
asm_gcc_32 - with asm code designed for GCC (32 bits)
|
||||||
|
asm_vc_64 - with asm for VC (64 bit)
|
||||||
|
asm_gcc_64 - with asm for GCC (64 bit)
|
||||||
|
no_asm_32 - pure C++ version (32 bit) - without any asm code
|
||||||
|
no_asm_64 - pure C++ version (64 bit) - without any asm code
|
||||||
|
* added: UInt::operator>>(int)
|
||||||
|
UInt::operator>>=(int)
|
||||||
|
UInt::operator<<(int)
|
||||||
|
UInt::operator<<=(int)
|
||||||
|
* changed: Factorial() is using the Gamma() function now
|
||||||
|
* changed: Big::Div(ss2)
|
||||||
|
Big::Mod(ss2)
|
||||||
|
they return 2 when ss2 is zero
|
||||||
|
previously returned 1
|
||||||
|
* changed: algorithms in Big::Sqrt() and ttmath::Root(x ; n)
|
||||||
|
they were not too much accurate for some integers
|
||||||
|
e.g. Root(16;4) returned a value very closed to 2 (not exactly 2)
|
||||||
|
* changed: added specializations to Big::ToString() when the base is equal 4, 8 or 16
|
||||||
|
the previous version was not accurate on some last digits (after the comma operator)
|
||||||
|
consider this binary value (32 bit mantissa):
|
||||||
|
base 2: 1.1111 1111 1111 1111 1111 1111 1110 101
|
||||||
|
previous ToString() gave:
|
||||||
|
base 4: 1.33333333333332
|
||||||
|
base 8: 1.777777777
|
||||||
|
base 16: 1.FFFFFF
|
||||||
|
now we have:
|
||||||
|
base 4: 1.3333333333333222
|
||||||
|
base 8: 1.77777777724
|
||||||
|
base 16: 1.FFFFFFEA
|
||||||
|
* changed: in Big::ToString() some additional rounding (base_round) is now made only
|
||||||
|
when the value is not an integer
|
||||||
|
* changed: another compilers than MS VC or GCC by default use no asm version (TTMATH_NOASM)
|
||||||
|
* removed: Parser<>::SetFactorialMax() method
|
||||||
|
the factorial() is such a fast now that we don't need the method longer
|
||||||
|
* removed: ErrorCode::err_too_big_factorial
|
||||||
|
* removed: macros: TTMATH_COMMA_CHARACTER_1 and TTMATH_COMMA_CHARACTER_2
|
||||||
|
the comma characters we have in Conv struct now
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.8.6 (2009.10.25):
|
||||||
|
* fixed: UInt::SetBitInWord(uint & value, uint bit) set 1 if the bit was
|
||||||
|
equal 1 (should be set 2)
|
||||||
|
this affected only no-asm parts - when macro TTMATH_NOASM was defined
|
||||||
|
* fixed: UInt<value_size>::MulInt(uint ss2)
|
||||||
|
there was a buffer overflow when value_size was equal 1
|
||||||
|
* fixed: UInt::AddVector() and UInt::SubVector() didn't want to compile
|
||||||
|
when macro TTMATH_NOASM was defined
|
||||||
|
* fixed: Big::operator>> didn't correctly recognize values in scientific mode (with 'e' character)
|
||||||
|
* fixed: Int::FromString(const tt_string & s, uint b = 10)
|
||||||
|
didn't use 'b' (always was '10')
|
||||||
|
* fixed: buffer overflow in Big::ToInt(Int<int_size> & result)
|
||||||
|
* fixed: powering algorithm in:
|
||||||
|
UInt::Pow(UInt<value_size> pow)
|
||||||
|
Big::Pow(UInt<pow_size> pow)
|
||||||
|
Big::PowUInt(Big<exp, man> pow)
|
||||||
|
when 'pow' was sufficient large the algorithm returned carry
|
||||||
|
but the result could have been calculated correctly
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.8.5 (2009.06.16):
|
||||||
|
* fixed: Big::Mod(x) didn't correctly return a carry
|
||||||
|
and the result was sometimes very big (even greater than x)
|
||||||
|
* fixed: global function Mod(x) didn't set an ErrorCode object
|
||||||
|
* fixed: global function Round() didn't test a carry
|
||||||
|
now it sets ErrorCode object
|
||||||
|
* changed: function Sin(x) to Sin(x, ErrorCode * err=0)
|
||||||
|
when x was very big the function returns zero
|
||||||
|
now it sets ErrorCode object to err_overflow
|
||||||
|
and the result has a NaN flag set
|
||||||
|
the same is to Cos() function
|
||||||
|
* changed: PrepareSin(x) is using Big::Mod() now when reducing 2PI period
|
||||||
|
should be a little accurate especially on a very big 'x'
|
||||||
|
* changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
|
||||||
|
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
|
||||||
|
those methods by default use MulFastest() and MulFastestBig()
|
||||||
|
* changed: changed a little Mul2Big() to cooperate with Mul3Big()
|
||||||
|
* added: uint UInt::Mul3(const UInt<value_size> & ss2)
|
||||||
|
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
|
||||||
|
a new multiplication algorithm: Karatsuba multiplication,
|
||||||
|
on a vector UInt<100> with all items different from zero this algorithm is faster
|
||||||
|
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
|
||||||
|
zero this algorithm is faster more than 5 times than Mul2Big()
|
||||||
|
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
|
||||||
|
* added: uint MulFastest(const UInt<value_size> & ss2)
|
||||||
|
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
|
||||||
|
those methods are trying to select the fastest multiplication algorithm
|
||||||
|
* added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
|
||||||
|
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
|
||||||
|
three forms: asm x86, asm x86_64, no-asm
|
||||||
|
those methods are used by the Karatsuba multiplication algorithm
|
||||||
|
* added: to Big<> class: support for NaN flag (Not a Number)
|
||||||
|
bool Big::IsNan() - returns true if the NaN flag is set
|
||||||
|
void Big::SetNan() - sets the NaN flag
|
||||||
|
The NaN flag is set by default after creating an object:
|
||||||
|
Big<1, 2> a; // NaN is set (it means the object has not a valid number)
|
||||||
|
std::cout << a; // cout gives "NaN"
|
||||||
|
a = 123; // now NaN is not set
|
||||||
|
std::cout << a; // cout gives "123"
|
||||||
|
The NaN is set if there was a carry during calculations
|
||||||
|
a.Mul(very_big_value); // a will have a NaN set
|
||||||
|
The NaN is set if an argument is NaN too
|
||||||
|
b.SetNan();
|
||||||
|
a.Add(b); // a will have NaN because b has NaN too
|
||||||
|
If you try to do something on a NaN object, the result is a NaN too
|
||||||
|
a.SetNan();
|
||||||
|
a.Add(2); // a is still a NaN
|
||||||
|
The NaN is set if you use incorrect arguments
|
||||||
|
a.Ln(-10); // a will have the NaN flag
|
||||||
|
The only way to clear the NaN flag is to assign a correct value or other correct object,
|
||||||
|
supposing 'a' has NaN flag, to remove the flag you can either:
|
||||||
|
a = 10;
|
||||||
|
a.FromInt(30);
|
||||||
|
a.SetOne();
|
||||||
|
a.FromBig(other_object_without_nan);
|
||||||
|
etc.
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.8.4 (2009.05.08):
|
||||||
|
* fixed: UInt::DivInt() didn't check whether the divisor is zero
|
||||||
|
there was a hardware interruption when the divisor was zero
|
||||||
|
(now the method returns one)
|
||||||
|
* fixed: the problem with GCC optimization on x86_64
|
||||||
|
sometimes when using -O2 or -O3 GCC doesn't set correctly
|
||||||
|
the stack pointer (actually the stack is used for other things)
|
||||||
|
and you can't use instructions like push/pop in assembler code.
|
||||||
|
All the asm code in x86_64 have been rewritten, now instructions
|
||||||
|
push/pop are not used, other thing which have access to stack
|
||||||
|
(like "m" (mask) constraints in Rcl2 and Rcr2) have also gone away,
|
||||||
|
now the library works well with -O2 and -O3 and the asm code
|
||||||
|
is a little faster
|
||||||
|
* added: UInt::PrintLog(const char * msg, std::ostream & output)
|
||||||
|
used (for debugging purposes) by macro TTMATH_LOG(msg)
|
||||||
|
(it is used in nearly all methods in UInt class)
|
||||||
|
* added: macro TTMATH_DEBUG_LOG: when defined then TTMATH_LOG()
|
||||||
|
put some debug information (to std::cout)
|
||||||
|
* added: ttmathuint_x86.h, ttmathuint_x86_64.h, ttmathuint_noasm.h,
|
||||||
|
all the methods which are using assembler code have been
|
||||||
|
rewritten to no-asm forms, now we have:
|
||||||
|
1. asm for x86 file: ttmathuint_x86.h
|
||||||
|
2. asm for x86_64 file: ttmathuint_x86_64.h
|
||||||
|
3. no asm file: ttmathuint_noasm.h
|
||||||
|
(it's used when macro TTMATH_NOASM is defined)
|
||||||
|
The third form can be used on x86 and x86_64 as well and
|
||||||
|
on other platforms with a little effort.
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.8.3 (2009.04.06):
|
||||||
|
* fixed: RclMoveAllWords() and RcrMoveAllWords() sometimes didn't return
|
||||||
|
the proper carry, (when 'bits' was greater than or equal to 'value_size')
|
||||||
|
this had impact on Rcl() and Rcr(), they also returned the wrong carry
|
||||||
|
* fixed: UInt::Div() didn't return a correct result when the divisor was equal 1
|
||||||
|
there was an error in UInt::DivInt() - when the divisor was 1 it returned
|
||||||
|
zero and the carry was set
|
||||||
|
* fixed: there was a TTMATH_REREFENCE_ASSERT error in Big::PowUInt() caused by: start.Mul(start)
|
||||||
|
* fixed: Big::Add incorrectly rounded 'this' when both exponents were equal
|
||||||
|
it caused that sometimes when adding a zero the result has changed
|
||||||
|
this had impact among other things on FromString() method
|
||||||
|
"0,8" had different binary representation from "0,80"
|
||||||
|
* fixed: template Big::FromBig(const Big<another_exp, another_man> & another)
|
||||||
|
didn't correctly set the exponent (when the mantisses had different size -
|
||||||
|
when 'man' was different from 'another_man')
|
||||||
|
this had impact on operator= too
|
||||||
|
sample:
|
||||||
|
Big<2,3> a = 100;
|
||||||
|
Big<3,5> b;
|
||||||
|
b = a; // b had a wrong value
|
||||||
|
* fixed: Big::Pow(const Big<exp, man> & pow)
|
||||||
|
it's using PowInt() only when pow.exponent is in range (-man*TTMATH_BITS_PER_UINT; 0]
|
||||||
|
previously the powering 'hung' on an input like this: "(1+ 1e-10000) ^ 10e100000000"
|
||||||
|
(there was 10e100000000 iterations in PowInt())
|
||||||
|
* fixed: in function DegToRad(const ValueType & x, ErrorCode * err = 0) it is better
|
||||||
|
to make division first and then mutliplication -- the result is more
|
||||||
|
accurate especially when x is: 90,180,270 or 360
|
||||||
|
* fixed: the parser didn't correctly treat operators for changing the base
|
||||||
|
(radix) -- operators '#' and '&', e.g.:
|
||||||
|
'#sin(1)' was equal '0' -- there was a zero from '#' and then
|
||||||
|
it was multipied by 'sin(1)'
|
||||||
|
the parser didn't check whether Big::FromString() has actually
|
||||||
|
read a proper value -- the method Big::FromString() didn't have
|
||||||
|
something to report such a situation
|
||||||
|
* fixed: Big::FromString() when the base is 10, the method reads the scientific
|
||||||
|
part only if such a part it correctly supplied, e.g:
|
||||||
|
'1234e10', '1234e+10', '1234e-5'
|
||||||
|
previous '1234e' was treated as: '1234e0' (now parsing stops on 'e' and
|
||||||
|
the 'e' can be parsed by other parsers, e.g. the mathematical
|
||||||
|
parser -- now in the parser would be: '1234e' = '1234 * e' = '3354,3597...' )
|
||||||
|
* changed: renamed: Big::PowUInt(UInt<pow_size> pow) -> Big::Pow(UInt<pow_size> pow)
|
||||||
|
it returns 2 when there is: 0^0
|
||||||
|
* changed: renamed: Big::PowInt(Int<pow_size> pow) -> Big::Pow(Int<pow_size> pow)
|
||||||
|
it returns 2 when there is: 0^0 or 0^(-something)
|
||||||
|
* changed: renamed: Big::PowBUInt() -> PowUInt(), Big::PowBInt() -> Big::PowInt()
|
||||||
|
they return 2 when the arguments are incorrect (like above)
|
||||||
|
* changed: UInt::SetBitInWord(uint & value, uint bit) is taking the first argument by a reference now,
|
||||||
|
the specific bit is set in the 'value' and the method returns the last state of the bit (zero or one)
|
||||||
|
* changed: UInt::SetBit(uint bit_index) - it's using TTMATH_ASSERT now
|
||||||
|
* changed: the size of built-in variables (constants) in ttmathbig.h
|
||||||
|
now they consist of 256 32bit words
|
||||||
|
macro TTMATH_BUILTIN_VARIABLES_SIZE is equal: 256u on a 32bit platform and 128ul on a 64bit platform
|
||||||
|
* changed: the asm code in ttmathuint.h and ttmathuint64.h has been completely rewritten
|
||||||
|
now UInt<> is faster about 15-30% than UInt<> from 0.8.2
|
||||||
|
this has impact on Big<> too - it's faster about 10% now
|
||||||
|
* changed: in the parser: the form with operators '#' and '&' is as follows:
|
||||||
|
[-|+][#|&]numeric_value
|
||||||
|
previous was: [-|+][#|&][-|+]numeric_value
|
||||||
|
* changed: in the parser: the short form of multiplication has the same
|
||||||
|
priority as the normal multiplication, e.g.:
|
||||||
|
'2x^3' = 2 * (x^3)
|
||||||
|
previous the priority was greater than powering priority
|
||||||
|
previous: '2x^3' = (2*x) ^ 3
|
||||||
|
* added: UInt::GetBit(uint bit_index) - returning the state of the specific bit
|
||||||
|
* added: Big::operator=(double) and Big::Big(double)
|
||||||
|
* added: UInt::Pow(UInt<value_size> pow) and Int::Pow(Int<value_size> pow)
|
||||||
|
* added: global template functions in ttmath.h:
|
||||||
|
ValueType GradToRad(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
ValueType RadToGrad(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
ValueType DegToGrad(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
ValueType DegToGrad(const ValueType & d, const ValueType & m,
|
||||||
|
const ValueType & s, ErrorCode * err = 0)
|
||||||
|
ValueType GradToDeg(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
* added: Parser::SetDegRadGrad(int angle) - 0 deg, 1 rad (default), 2 grad
|
||||||
|
this affects following functions (in the parser only): sin, cos, tan, cot,
|
||||||
|
asin, acos, atan, acot
|
||||||
|
* added: functions to the parser: gradtorad(grad), radtograd(rad), degtograd(deg),
|
||||||
|
degtograd(d,m,s), gradtodeg(grad)
|
||||||
|
* added: UInt::FromString, added a parametr 'after_source'
|
||||||
|
which is pointing at the end of the parsed string
|
||||||
|
* added: Int::FromString(): parameter 'const char ** after_source = 0'
|
||||||
|
if exists it's pointing at the end of the parsed string
|
||||||
|
* added: to UInt::FromString(), Int::FromString(), Big::FromString():
|
||||||
|
parameter 'bool * value_read = 0' - (if exists) tells
|
||||||
|
whether something has actually been read (at least one digit)
|
||||||
|
* added: Objects::IsDefined(const std::string & name)
|
||||||
|
returning true if such an object is defined
|
||||||
|
* removed: Big::FromString() this method doesn't longer recognize operators
|
||||||
|
for changing the base ('#' and '&')
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.8.2 (2008.06.18):
|
||||||
|
* added: UInt::BitNot2() this method has been proposed by
|
||||||
|
Arek <kmicicc AnTispam users.sourceforge.net>
|
||||||
|
* changed: Int::FromInt(const Int<argument_size> & p),
|
||||||
|
Int::FromInt(sint value) (it returns zero now)
|
||||||
|
Int::operator=(uint i)
|
||||||
|
Int::Int(uint i)
|
||||||
|
* added: Int::FromUInt(const UInt<argument_size> & p),
|
||||||
|
Int::FromUInt(uint value)
|
||||||
|
and appropriate constructors and assignment
|
||||||
|
operators as well
|
||||||
|
* changed: Big::FromInt(Int<int_size> value),
|
||||||
|
* added: Big::FromUInt(UInt<int_size> value),
|
||||||
|
Big::operator=(const UInt<int_size> & value)
|
||||||
|
Big::Big(const UInt<int_size> & value)
|
||||||
|
* changed: the parser is allowed to recognize values which
|
||||||
|
begin with a dot, e.g '.5' is treated as '0.5'
|
||||||
|
* added: a method Big::FromDouble(double) which converts from
|
||||||
|
standard double into a Big
|
||||||
|
* added: uint Big::ToDouble(double&) - converting into double
|
||||||
|
* added: Big::FromBig() and an operator= and a contructor
|
||||||
|
for converting from another kind of a Big class
|
||||||
|
* added: to the parser: avg(), sum()
|
||||||
|
* added: 'decimal_point' parameter into Big::ToString(...)
|
||||||
|
* fixed: Big::operator>> didn't use TTMATH_COMMA_CHARACTER_2 macro
|
||||||
|
* added: a short form of multiplication (without the '*' character)
|
||||||
|
e.g. '5y', (it's used only if the second parameter
|
||||||
|
is a variable or function)
|
||||||
|
* changed: variables and functions are case-sensitive now
|
||||||
|
* added: variables and functions can have underline characters
|
||||||
|
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):
|
Version 0.8.1 (2007.04.17):
|
||||||
* fixed: Big::PowFrac(..) didn't return a correct error code
|
* fixed: Big::PowFrac(..) didn't return a correct error code
|
||||||
(when 'this' was negative)
|
(when 'this' was negative)
|
||||||
|
@ -36,14 +527,15 @@ Version 0.8.1 (2007.04.17):
|
||||||
* changed: the way of parsing operators in the mathematical parser
|
* changed: the way of parsing operators in the mathematical parser
|
||||||
(the parser is not too much greedy now)
|
(the parser is not too much greedy now)
|
||||||
|
|
||||||
|
|
||||||
Version 0.8.0 (2007.03.28):
|
Version 0.8.0 (2007.03.28):
|
||||||
* added: into the parser: SetFactorialMax()
|
* added: into the parser: SetFactorialMax()
|
||||||
* added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
|
* added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
|
||||||
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
|
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
|
||||||
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
|
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
|
||||||
* changed: class Objects in ttmathobjects.h has been completely rewritten,
|
* changed: class Objects in ttmathobjects.h has been completely rewritten,
|
||||||
we can change the names of user-defined variables or functions, and the
|
we can change the names of user-defined variables or functions,
|
||||||
names are case-sensitive now
|
and the names are case-sensitive now
|
||||||
* added: class History which is used in functions which take a lot of time
|
* added: class History which is used in functions which take a lot of time
|
||||||
during calculating e.g. Factorial(x)
|
during calculating e.g. Factorial(x)
|
||||||
* added: Tg(x) a wrapper for Tan(x)
|
* added: Tg(x) a wrapper for Tan(x)
|
||||||
|
@ -54,14 +546,14 @@ Version 0.8.0 (2007.03.28):
|
||||||
* added: ACtg(x) a wrapper for ACot(x)
|
* added: ACtg(x) a wrapper for ACot(x)
|
||||||
* added: UInt::PrintTable() (for debugging etc.)
|
* added: UInt::PrintTable() (for debugging etc.)
|
||||||
* changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have
|
* changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have
|
||||||
been rewritten, now they have 128 32bit words (it's about 1232 valid
|
been rewritten, now they have 128 32bit words (it's about
|
||||||
decimal digits)
|
1232 valid decimal digits)
|
||||||
* fixed: previous values from Big::SetPi() Big::SetE() and
|
* fixed: previous values from Big::SetPi() Big::SetE() and
|
||||||
Big::SetLn2() were not too much accurate (last 2-3 words were wrong)
|
Big::SetLn2() were not too much accurate (last 2-3 words were wrong)
|
||||||
* added: Big::SetLn10() (128 32bit words as well)
|
* added: Big::SetLn10() (128 32bit words as well)
|
||||||
* added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on
|
* added: macro TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on
|
||||||
32bit platforms and 64ul on 64bit platforms (128/2=64)
|
32bit platforms and 64ul on 64bit platforms (128/2=64)
|
||||||
* added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
|
* added: macros TTMATH_PLATFORM32 and TTMATH_PLATFORM64
|
||||||
* changed: a small optimisation in UInt::Mul2Big()
|
* changed: a small optimisation in UInt::Mul2Big()
|
||||||
* added: at the end of ttmath.h: #include "ttmathparser.h"
|
* added: at the end of ttmath.h: #include "ttmathparser.h"
|
||||||
this is for convenience for a programmer, he can only use #include
|
this is for convenience for a programmer, he can only use #include
|
||||||
|
@ -69,13 +561,14 @@ Version 0.8.0 (2007.03.28):
|
||||||
* added: to samples: big.cpp, parser.cpp
|
* added: to samples: big.cpp, parser.cpp
|
||||||
* added/changes/fixed: in copy-constructors and operators= in Int,
|
* added/changes/fixed: in copy-constructors and operators= in Int,
|
||||||
Uint and Big (more info in the commit log)
|
Uint and Big (more info in the commit log)
|
||||||
* renamed Big::SetDotOne() into Big::Set05()
|
* renamed: Big::SetDotOne() into Big::Set05()
|
||||||
* changes: a few small optimisations in Big
|
* changes: a few small optimisations in Big
|
||||||
* deleted: the word 'virtual' from destructors: UInt, Int, Big
|
* deleted: the word 'virtual' from destructors: UInt, Int, Big
|
||||||
(types in this library are not projected to be base-classes for
|
(types in this library are not projected to be base-classes for
|
||||||
another ones derived from them)
|
another ones derived from them)
|
||||||
* and more small changes (look at the commit log)
|
* and more small changes (look at the commit log)
|
||||||
|
|
||||||
|
|
||||||
Version 0.7.2 (2007.03.09):
|
Version 0.7.2 (2007.03.09):
|
||||||
* added: Big::Mod - the remainder from a division
|
* added: Big::Mod - the remainder from a division
|
||||||
* added: Big::Sgn - the 'sign' from the value (-1,0,1)
|
* added: Big::Sgn - the 'sign' from the value (-1,0,1)
|
||||||
|
@ -86,37 +579,42 @@ Version 0.7.2 (2007.03.09):
|
||||||
* added: into the parser: logical functions: and() or() not() if()
|
* added: into the parser: logical functions: and() or() not() if()
|
||||||
* added: ErrorCode::err_unknown_operator when the parser couldn't read an operator
|
* added: ErrorCode::err_unknown_operator when the parser couldn't read an operator
|
||||||
|
|
||||||
|
|
||||||
Version 0.7.1 (2007.02.27):
|
Version 0.7.1 (2007.02.27):
|
||||||
* fixed the error 'overflow during printing' which was caused
|
* 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)
|
by Big::FromInt(Int<int_size> value) (the sign has to be set at the end)
|
||||||
* fixed many small errors
|
* fixed: many small errors
|
||||||
* added ATan (arctan), ACTan (arc ctan) functions
|
* added: ATan (arctan), ACTan (arc ctan) functions
|
||||||
|
|
||||||
|
|
||||||
Version 0.7.0 (2007.02.24):
|
Version 0.7.0 (2007.02.24):
|
||||||
* finished support for 64bit platforms
|
* finished: support for 64bit platforms
|
||||||
* added ASin (arcsin), ACos (arccos) functions
|
* added: ASin (arcsin), ACos (arccos) functions
|
||||||
|
|
||||||
|
|
||||||
Version 0.6.4 (2007.01.29):
|
Version 0.6.4 (2007.01.29):
|
||||||
* fixed the problem with a sign in the mathematical parser /-(1) was 1/
|
* fixed: the problem with a sign in the mathematical parser /-(1) was 1/
|
||||||
* added UInt::AddInt and UInt::SubInt
|
* added: UInt::AddInt and UInt::SubInt
|
||||||
* changed UInt::AddOne and UInt::SubOne (much faster now)
|
* changed: UInt::AddOne and UInt::SubOne (much faster now)
|
||||||
* added UInt::SetBitInWord
|
* added: UInt::SetBitInWord
|
||||||
* changed UInt::SetBit (much faster now)
|
* changed: UInt::SetBit (much faster now)
|
||||||
* UInt::AddTwoUints renamed to UInt::AddTwoInts
|
UInt::AddTwoUints renamed to UInt::AddTwoInts
|
||||||
* UInt::FindLeadingBit32 renamed to UInt::FindLeadingBitInWord
|
UInt::FindLeadingBit32 renamed to UInt::FindLeadingBitInWord
|
||||||
* added UInt::SetBitInWord
|
UInt::Mul64 renamed to UInt::MulTwoWords
|
||||||
* UInt::Mul64 renamed to UInt::MulTwoWords
|
UInt::Div64 renamed to UInt::DivTwoWords
|
||||||
* UInt::Div64 renamed to UInt::DivTwoWords
|
* added: UInt::SetBitInWord
|
||||||
* and more small changes in UInt type
|
* and more small changes in UInt type
|
||||||
* start adding support for Amd64 (not finished yet) (added ttmathuint64.h)
|
* start adding support for Amd64 (not finished yet) (added ttmathuint64.h)
|
||||||
|
|
||||||
|
|
||||||
Version 0.6.3 (2007.01.22):
|
Version 0.6.3 (2007.01.22):
|
||||||
* position of arguments (x and base) in logarithm functions are swapped
|
* changed: position of arguments (x and base) in logarithm functions are swapped
|
||||||
* it's possible to use any multiplication algorithms in the same time
|
* changed: it's possible to use any multiplication algorithms in the same time
|
||||||
(macros UINT_MUL_VERSION_'X' have gone)
|
(macros UINT_MUL_VERSION_'X' have gone)
|
||||||
* added ExceptionInfo, ReferenceError and RuntimeError classes
|
* added: ExceptionInfo, ReferenceError and RuntimeError classes
|
||||||
* the mess in macros has been cleaned up
|
* changed: the mess in macros has been cleaned up
|
||||||
* added TTMATH_RELEASE macro
|
* added: TTMATH_RELEASE macro
|
||||||
|
|
||||||
|
|
||||||
Version 0.6.2 (2007.01.10):
|
Version 0.6.2 (2007.01.10):
|
||||||
* New division algorithm (radix b) where b is 2^32
|
* added: New division algorithm (radix b) where b is 2^32
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
# CMake configuration for ttmath
|
||||||
|
cmake_minimum_required (VERSION 3.0)
|
||||||
|
project(ttmath)
|
||||||
|
enable_testing()
|
||||||
|
include_directories(${ttmath_SOURCE_DIR})
|
||||||
|
add_subdirectory(samples)
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2006-2007, Tomasz Sowa
|
Copyright (c) 2006-2017, 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
|
||||||
|
|
35
README
35
README
|
@ -1,24 +1,23 @@
|
||||||
TTMath - a bignum library for C++
|
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.
|
||||||
numbers. It provides standard mathematical operations like adding,
|
It provides standard mathematical operations like adding, subtracting,
|
||||||
subtracting, multiplying, dividing etc. With the library also goes
|
multiplying, dividing. With the library also goes a mathematical parser to
|
||||||
a mathematical parser which helps you solving input formulas read directly
|
help you solving mathematical expressions.
|
||||||
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
|
||||||
for both personal and commercial use but the library has some technical
|
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
|
|
||||||
well), and you can use this library only with the C++ programming language.
|
|
||||||
|
|
||||||
The main goal of the library is to allow one to use big values in the same
|
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
|
way as the standard types like int or float. It does not need to be compiled
|
||||||
compiled first because the whole library is written as the C++ templates.
|
first because the whole library is written as the C++ templates. This means
|
||||||
This means only C++ developers can use this library and one thing they have
|
only C++ developers can use this library and one thing they have to do is
|
||||||
to do is to use 'include' directive of the preprocessor. How big the
|
to use 'include' directive of the preprocessor. How big the values can be
|
||||||
values can be is set directly in the source code by the programmer.
|
is set at compile time.
|
||||||
|
|
||||||
Author: Tomasz Sowa <t.sowa AnTispam slimaczek.pl>
|
Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
Project page: http://sourceforge.net/projects/ttmath
|
WWW: http://www.ttmath.org
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Christian Kaiser <chk@online.de>
|
||||||
|
|
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
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
o = main.o
|
||||||
|
CC = clang++
|
||||||
|
CFLAGS = -O2 -DTTMATH_CONSTANTSGENERATOR
|
||||||
|
name = gen
|
||||||
|
|
||||||
|
|
||||||
|
.SUFFIXES: .cpp .o
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
|
||||||
|
|
||||||
|
all: $(name)
|
||||||
|
|
||||||
|
$(name): $(o)
|
||||||
|
$(CC) -o $(name) -s $(CFLAGS) $(o)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
main.o: main.cpp
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o
|
||||||
|
rm -f *.s
|
||||||
|
rm -f $(name)
|
||||||
|
rm -f $(name).exe
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 TTMATH_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 TTMATH_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;
|
||||||
|
}
|
2533
doxygen.cfg
2533
doxygen.cfg
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,137 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
a=""
|
||||||
|
b=""
|
||||||
|
c=""
|
||||||
|
p=""
|
||||||
|
d=""
|
||||||
|
doxygen=""
|
||||||
|
|
||||||
|
# reading until not empty
|
||||||
|
|
||||||
|
while [ -z $a ]
|
||||||
|
do
|
||||||
|
echo -n "Major: " ; read a
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $b ]
|
||||||
|
do
|
||||||
|
echo -n "Minor: " ; read b;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $c ]
|
||||||
|
do
|
||||||
|
echo -n "Revision: " ; read c;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $p ]
|
||||||
|
do
|
||||||
|
echo -n "Prerelease? (y/n): " ; read p;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $d ]
|
||||||
|
do
|
||||||
|
echo -n "Add date? (y/n): " ; read d;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $doxygen ]
|
||||||
|
do
|
||||||
|
echo -n "Clean make and add to the package doxygen doc? (y/n): " ; read doxygen;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
mkdir -p releases
|
||||||
|
package_dir_name="ttmath-$a.$b.$c"
|
||||||
|
datestr=""
|
||||||
|
|
||||||
|
|
||||||
|
if [ $p = "y" -o $p = "Y" ]
|
||||||
|
then
|
||||||
|
package_dir_name=${package_dir_name}.prerelease
|
||||||
|
fi
|
||||||
|
|
||||||
|
package_dir_name=${package_dir_name}-src
|
||||||
|
|
||||||
|
if [ $d = "y" -o $d = "Y" ]
|
||||||
|
then
|
||||||
|
datestr=`/bin/date "+%G.%m.%d"`;
|
||||||
|
package_dir_name=${package_dir_name}-$datestr
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dir="releases/"${package_dir_name}
|
||||||
|
package=${package_dir_name}.tar.gz
|
||||||
|
|
||||||
|
|
||||||
|
if [ -d $dir ]
|
||||||
|
then
|
||||||
|
echo "Directory $dir exists! (exiting)";
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "releases/"${package} ] ; then
|
||||||
|
echo "File releases/${package} exists! (exiting)"
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
mkdir $dir
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if [ $doxygen = "y" -o $doxygen = "Y" ]
|
||||||
|
then
|
||||||
|
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
echo "creating doxygen doc"
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
|
||||||
|
rm -rf doc/doxygen
|
||||||
|
doxygen doxygen.cfg
|
||||||
|
|
||||||
|
cp -r doc $dir/
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
echo "make clean in samples"
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
|
||||||
|
make -C samples clean
|
||||||
|
make -C constgen clean
|
||||||
|
|
||||||
|
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
echo "making source package"
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
|
||||||
|
mkdir $dir/ttmath
|
||||||
|
mkdir $dir/samples
|
||||||
|
mkdir $dir/res
|
||||||
|
|
||||||
|
cp ttmath/* $dir/ttmath/
|
||||||
|
|
||||||
|
cp samples/* $dir/samples/
|
||||||
|
# cmake is not ready yet (cmake will generate Makefile which overwrites our own one)
|
||||||
|
rm $dir/samples/CMakeLists.txt
|
||||||
|
|
||||||
|
cp COPYRIGHT $dir/
|
||||||
|
cp README $dir/
|
||||||
|
cp CHANGELOG $dir/
|
||||||
|
|
||||||
|
cp res/ttmath_logo.svg $dir/res/
|
||||||
|
|
||||||
|
cd releases
|
||||||
|
tar -czf $package ${package_dir_name}
|
||||||
|
|
||||||
|
echo "the package has been created to:" releases/${package}
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="38.084499"
|
||||||
|
height="38.083"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="ttmath_logo.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="11.2"
|
||||||
|
inkscape:cx="24.511255"
|
||||||
|
inkscape:cy="17.621314"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1440"
|
||||||
|
inkscape:window-height="830"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="25"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-350.08291,-424.26987)">
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.625;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 369.125,424.28125 c -10.50699,0 -19.03125,8.52426 -19.03125,19.03125 0,10.50603 8.52426,19.03125 19.03125,19.03125 10.50746,0 19.03125,-8.52522 19.03125,-19.03125 0,-10.50699 -8.52379,-19.03125 -19.03125,-19.03125 z"
|
||||||
|
id="path3773" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffaa35;fill-opacity:1;stroke:none;stroke-width:1.62500000000000000;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 369.125,425.90625 c 9.62928,0 17.40625,7.77748 17.40625,17.40625 0,9.62773 -7.77697,17.40625 -17.40625,17.40625 -9.62877,0 -17.40625,-7.77852 -17.40625,-17.40625 0,-9.62877 7.77748,-17.40625 17.40625,-17.40625 z"
|
||||||
|
id="path2999-2" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 368.1875,432.65625 -0.1875,0.5 -6.34375,16.71875 -1.40625,-4 -0.5,-1.40625 -0.84375,1.25 -2.0625,3.125 1.25,0.8125 1.25,-1.875 1.5625,4.53125 0.6875,1.9375 0.71875,-1.9375 6.90625,-18.15625 8.65625,0 0,-1.5 -9.15625,0 -0.53125,0 z"
|
||||||
|
id="path3003-3"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 359.84375,434.34375 0,3 -3,0 0,1.5 3,0 0,3.21875 1.5,0 0,-3.21875 3,0 0,-1.5 -3,0 0,-3 -1.5,0 z"
|
||||||
|
id="path3005-3"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.9375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 371.0625,443.5625 0,0.46875 -0.125,4.6875 0,0.15625 0.125,0.15625 c 0,0 0.37411,0.46147 0.9375,0.9375 0.2817,0.23802 0.59509,0.49145 0.96875,0.6875 0.37366,0.19605 0.8013,0.32003 1.25,0.34375 0.93515,0.0491 1.77613,-0.36791 2.40625,-0.78125 0.63012,-0.41334 1.0625,-0.84375 1.0625,-0.84375 l 0.125,-0.15625 0,-0.1875 -0.0937,-5 0,-0.46875 -0.46875,0 -5.71875,0 -0.46875,0 z"
|
||||||
|
id="path3009-7"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccsscsccccccccc" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.9375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 377.65625,450.375 -0.0312,0.0312 -0.21875,0.125 c -2.30252,1.65271 -4.15395,1.52806 -6.1125,-0.1562 -1.78014,2.66032 -3.73192,7.25254 -4.29375,8.18745 -0.56183,0.93491 -0.17739,2.37424 -0.28125,3.375 l 0.5625,-0.0312 8.03125,-0.71875 0.125,-0.0312 0.0937,-0.0625 6.96875,-4.5625 0.1875,-0.125 0.0937,-0.0625 -0.0625,-0.3125 c 0.0108,-0.11043 0.0366,-0.43638 0,-0.96875 -0.0466,-1.03041 -0.48309,-1.60724 -0.93745,-2.24995 -0.5467,-0.58055 -1.33798,-1.08483 -2.15625,-1.5 -0.91162,-0.46254 -1.66155,-0.7891 -1.71875,-0.8125 l -0.0625,-0.0312 -0.1875,-0.0937 z"
|
||||||
|
id="path3013-6"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccczcccccccccccscccc" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.625;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 374.0625,438.21875 c -1.68685,0.1362 -5.3125,0.8125 -5.3125,0.8125 l -0.125,0.0312 -0.0625,0.125 -1.375,2.09375 -0.0312,0.0625 0,0.0937 0.1875,6.15625 0.0312,0.15625 0.125,0.0937 0.3125,0.21875 0.5,0.3125 -0.0312,-0.59375 -0.0937,-5.90625 c 0.081,-0.0694 0.35604,-0.32331 0.6875,-0.4375 l 0.0312,0 c 0.0323,-0.01 0.0883,0.01 0.125,0 l 1.46875,-0.0937 c 0.1093,0.60186 0.39332,1.20774 0.4812,1.8125 1.27397,-0.0782 2.40491,-0.17552 3.5031,-0.16892 1.08715,0.0103 2.17115,0.13001 3.2344,0.12517 l 0.0312,-0.6125 c 0,0 0.0422,-0.16533 0.0625,-0.28125 l 0.40625,-0.9375 c 0.004,-0.005 -0.004,-0.0267 0,-0.0312 l 0.0312,0 c 0.17093,-0.1709 0.53319,-0.25585 0.8125,-0.375 0.26159,-0.11159 0.42068,-0.28594 0.75,-0.375 l 0.0312,0 0.125,-0.0312 2.28125,-0.1875 0.0312,0 0.28125,0 0,-0.0312 0,-0.28125 0,-0.71875 0,-0.25 -0.25,-0.0625 -3.75,-0.71875 c -0.0114,-10e-4 -0.02,0.001 -0.0312,0 -1.37083,-0.13192 -2.78705,-0.1247 -4.40625,0 l -0.0312,0 -0.0312,0 z"
|
||||||
|
id="path3017-6"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccccccccccccccccccccccccccsccccccccccccccccc" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,16 @@
|
||||||
|
# CMake configuration for ttmath/samples
|
||||||
|
|
||||||
|
# Building with Visual C++ x86_64 needs to compile the asm utilities first
|
||||||
|
if (MSVC AND "x${CMAKE_VS_PLATFORM_NAME}" STREQUAL "xx64")
|
||||||
|
set(TTMATH_MSVC64_ASM ttmathuint_x86_64_msvc.asm)
|
||||||
|
enable_language(ASM_MASM)
|
||||||
|
message(STATUS "Enabled MASM to compile '${TTMATH_MSVC64_ASM}'")
|
||||||
|
set(TTMATH_SRC_ASM ${ttmath_SOURCE_DIR}/ttmath/${TTMATH_MSVC64_ASM})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(SAMPLES big big2 int uint parser)
|
||||||
|
foreach(sample ${SAMPLES})
|
||||||
|
add_executable(${sample} ${sample}.cpp ${TTMATH_SRC_ASM})
|
||||||
|
# Allow to run all utilities at once as a test
|
||||||
|
add_test(${sample} ${sample})
|
||||||
|
endforeach()
|
|
@ -1,5 +1,6 @@
|
||||||
CC = g++
|
CC = g++
|
||||||
CFLAGS = -Wall -pedantic -s -O2 -I..
|
#CC = clang++
|
||||||
|
CFLAGS = -Wall -pedantic -O2 -I.. -DTTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
.SUFFIXES: .cpp .o
|
.SUFFIXES: .cpp .o
|
||||||
|
@ -8,25 +9,29 @@ CFLAGS = -Wall -pedantic -s -O2 -I..
|
||||||
$(CC) -c $(CFLAGS) $<
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
|
||||||
|
|
||||||
all: uint int big parser
|
all: uint int big big2 parser
|
||||||
|
|
||||||
|
|
||||||
uint: uint.o
|
uint: uint.o
|
||||||
$(CC) -o uint $(CFLAGS) uint.o
|
$(CC) -o uint -s $(CFLAGS) uint.o
|
||||||
|
|
||||||
int: int.o
|
int: int.o
|
||||||
$(CC) -o int $(CFLAGS) int.o
|
$(CC) -o int -s $(CFLAGS) int.o
|
||||||
|
|
||||||
big: big.o
|
big: big.o
|
||||||
$(CC) -o big $(CFLAGS) big.o
|
$(CC) -o big -s $(CFLAGS) big.o
|
||||||
|
|
||||||
|
big2: big2.o
|
||||||
|
$(CC) -o big2 -s $(CFLAGS) big2.o
|
||||||
|
|
||||||
parser: parser.o
|
parser: parser.o
|
||||||
$(CC) -o parser $(CFLAGS) parser.o
|
$(CC) -o parser -s $(CFLAGS) parser.o
|
||||||
|
|
||||||
|
|
||||||
uint.o: uint.cpp
|
uint.o: uint.cpp
|
||||||
int.o: int.cpp
|
int.o: int.cpp
|
||||||
big.o: big.cpp
|
big.o: big.cpp
|
||||||
|
big2.o: big2.cpp
|
||||||
parser.o: parser.cpp
|
parser.o: parser.cpp
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +41,7 @@ clean:
|
||||||
rm -f uint
|
rm -f uint
|
||||||
rm -f int
|
rm -f int
|
||||||
rm -f big
|
rm -f big
|
||||||
|
rm -f big2
|
||||||
rm -f parser
|
rm -f parser
|
||||||
# on MS Windows can automatically be added suffixes .exe to the names of output programs
|
# on MS Windows suffixes .exe will be automatically added
|
||||||
rm -f *.exe
|
rm -f *.exe
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
// this type has 2 words for its mantissa and 1 word for its exponent
|
// this type has 2 words for its mantissa and 1 word for its exponent
|
||||||
// (on a 32bit platform one word means a word of 32 bits,
|
// (on a 32bit platform one word means a word of 32 bits,
|
||||||
// and on a 64bit platform one word means a word of 64 bits)
|
// and on a 64bit platform one word means a word of 64 bits)
|
||||||
|
|
||||||
|
// Big<exponent, mantissa>
|
||||||
typedef ttmath::Big<1,2> MyBig;
|
typedef ttmath::Big<1,2> MyBig;
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,20 +34,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) )
|
||||||
|
@ -55,6 +58,7 @@ MyBig atemp;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
MyBig a,b;
|
MyBig a,b;
|
||||||
|
@ -68,9 +72,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
|
||||||
|
@ -85,13 +88,13 @@ a = 123456.543456
|
||||||
b = 98767878.124322
|
b = 98767878.124322
|
||||||
a + b = 98891334.667778
|
a + b = 98891334.667778
|
||||||
a - b = -98644421.580866
|
a - b = -98644421.580866
|
||||||
a * b = 12193540837712.2708
|
a * b = 12193540837712.27076
|
||||||
a / b = 0.0012499665458095765
|
a / b = 0.00124996654580957646
|
||||||
Calculating with a carry
|
Calculating with a carry
|
||||||
a = 1.624801256070839555e+646457012
|
a = 1.6248012560666408782e+646457012
|
||||||
b = 456.32
|
b = 456.319999999999993
|
||||||
a + b = 1.624801256070839555e+646457012
|
a + b = 1.6248012560666408782e+646457012
|
||||||
a - b = 1.624801256070839555e+646457012
|
a - b = 1.6248012560666408782e+646457012
|
||||||
a * b = (carry: the result is too big)
|
a * b = (carry)
|
||||||
a / b = 3.56066193914542329e+646457009
|
a / b = 3.560661939136222174e+646457009
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
#include <ttmath/ttmath.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
// this is a similar example to big.cpp
|
||||||
|
// but now we're using TTMATH_BITS() macro
|
||||||
|
// this macro returns how many words we need to store
|
||||||
|
// the given number of bits
|
||||||
|
|
||||||
|
// TTMATH_BITS(64)
|
||||||
|
// on a 32bit platform the macro returns 2 (2*32=64)
|
||||||
|
// on a 64bit platform the macro returns 1
|
||||||
|
|
||||||
|
// TTMATH_BITS(128)
|
||||||
|
// on a 32bit platform the macro returns 4 (4*32=128)
|
||||||
|
// on a 64bit platform the macro returns 2 (2*64=128)
|
||||||
|
|
||||||
|
// Big<exponent, mantissa>
|
||||||
|
typedef ttmath::Big<TTMATH_BITS(64), TTMATH_BITS(128)> MyBig;
|
||||||
|
|
||||||
|
// consequently on a 32bit platform we define: Big<2, 4>
|
||||||
|
// and on a 64bit platform: Big<1, 2>
|
||||||
|
// and the calculations will be the same on both platforms
|
||||||
|
|
||||||
|
|
||||||
|
void SimpleCalculating(const MyBig & a, const MyBig & b)
|
||||||
|
{
|
||||||
|
std::cout << "Simple calculating" << std::endl;
|
||||||
|
std::cout << "a = " << a << std::endl;
|
||||||
|
std::cout << "b = " << b << std::endl;
|
||||||
|
std::cout << "a + b = " << a+b << std::endl;
|
||||||
|
std::cout << "a - b = " << a-b << std::endl;
|
||||||
|
std::cout << "a * b = " << a*b << std::endl;
|
||||||
|
std::cout << "a / b = " << a/b << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CalculatingWithCarry(const MyBig & a, const MyBig & b)
|
||||||
|
{
|
||||||
|
MyBig atemp;
|
||||||
|
|
||||||
|
std::cout << "Calculating with a carry" << std::endl;
|
||||||
|
std::cout << "a = " << a << std::endl;
|
||||||
|
std::cout << "b = " << b << std::endl;
|
||||||
|
|
||||||
|
atemp = a;
|
||||||
|
if( !atemp.Add(b) )
|
||||||
|
std::cout << "a + b = " << atemp << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "a + b = (carry)" << std::endl;
|
||||||
|
// it have no sense to print 'atemp' (it's undefined)
|
||||||
|
|
||||||
|
atemp = a;
|
||||||
|
if( !atemp.Sub(b) )
|
||||||
|
std::cout << "a - b = " << atemp << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "a - b = (carry)" << std::endl;
|
||||||
|
|
||||||
|
atemp = a;
|
||||||
|
if( !atemp.Mul(b) )
|
||||||
|
std::cout << "a * b = " << atemp << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "a * b = (carry)" << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
atemp = a;
|
||||||
|
if( !atemp.Div(b) )
|
||||||
|
std::cout << "a / b = " << atemp << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "a / b = (carry or division by zero) " << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
MyBig a,b;
|
||||||
|
|
||||||
|
// conversion from 'const char *'
|
||||||
|
a = "123456.543456";
|
||||||
|
b = "98767878.124322";
|
||||||
|
|
||||||
|
SimpleCalculating(a,b);
|
||||||
|
|
||||||
|
// 'a' will have the max value which can be held in this type
|
||||||
|
a.SetMax();
|
||||||
|
|
||||||
|
// conversion from double
|
||||||
|
b = 456.32;
|
||||||
|
|
||||||
|
// Look at the value 'a' and the product from a+b and a-b
|
||||||
|
// Don't worry this is the nature of floating point numbers
|
||||||
|
CalculatingWithCarry(a,b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
the result (the same on a 32 or 64bit platform):
|
||||||
|
|
||||||
|
Simple calculating
|
||||||
|
a = 123456.543456
|
||||||
|
b = 98767878.124322
|
||||||
|
a + b = 98891334.667778
|
||||||
|
a - b = -98644421.580866
|
||||||
|
a * b = 12193540837712.270763536832
|
||||||
|
a / b = 0.0012499665458095764605964485261668609133
|
||||||
|
Calculating with a carry
|
||||||
|
a = 2.34953455457111777368832820909595050034e+2776511644261678604
|
||||||
|
b = 456.3199999999999931787897367030382156
|
||||||
|
a + b = 2.34953455457111777368832820909595050034e+2776511644261678604
|
||||||
|
a - b = 2.34953455457111777368832820909595050034e+2776511644261678604
|
||||||
|
a * b = (carry)
|
||||||
|
a / b = 5.1488748127873374141170361292780486452e+2776511644261678601
|
||||||
|
*/
|
|
@ -29,6 +29,11 @@ const char equation[] = " (34 + 24) * 123 - 34.32 ^ 6 * sin(2.56) - atan(10)";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
the result (on 32 bit platform):
|
the result (on 32 bit platform):
|
||||||
|
-897705014.525731067
|
||||||
-897705014.52573107
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
the result (on 64 bit platform):
|
||||||
|
-897705014.5257310676097719585259773124
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
CC = clang++
|
||||||
|
o = main.o uinttest.o
|
||||||
|
CFLAGS = -Wall -O2
|
||||||
|
ttmath = ..
|
||||||
|
name = tests
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.SUFFIXES: .cpp .o
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CC) -c $(CFLAGS) -I$(ttmath) $<
|
||||||
|
|
||||||
|
|
||||||
|
all: $(name)
|
||||||
|
|
||||||
|
|
||||||
|
$(name): $(o)
|
||||||
|
$(CC) -o $(name) -s $(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
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,424 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
|
@ -0,0 +1,133 @@
|
||||||
|
#CC = g++6
|
||||||
|
#CFLAGS = -Wall -pedantic -O3 -s -I.. -Wl,-rpath=/usr/local/lib/gcc6
|
||||||
|
#CFLAGS = -Wall -pedantic -O3 -DTTMATH_NOASM -s -I.. -Wl,-rpath=/usr/local/lib/gcc6
|
||||||
|
|
||||||
|
CC = clang++
|
||||||
|
CFLAGS = -Wall -pedantic -O3 -s -I..
|
||||||
|
#CFLAGS = -Wall -pedantic -O3 -DTTMATH_NOASM -s -I..
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.SUFFIXES: .cpp .o
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
all: big_64_64 big_64_128 big_64_192 big_64_256 big_64_512 big_64_1024 big_64_2048 big_64_4096 big_128_512 big_256_1024 big_512_2048 big_128_4096
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
big_64_64: main.cpp
|
||||||
|
$(CC) -o big_64_64 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=64 main.cpp
|
||||||
|
|
||||||
|
big_64_128: main.cpp
|
||||||
|
$(CC) -o big_64_128 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=128 main.cpp
|
||||||
|
|
||||||
|
big_64_192: main.cpp
|
||||||
|
$(CC) -o big_64_192 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=192 main.cpp
|
||||||
|
|
||||||
|
big_64_256: main.cpp
|
||||||
|
$(CC) -o big_64_256 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=256 main.cpp
|
||||||
|
|
||||||
|
big_64_512: main.cpp
|
||||||
|
$(CC) -o big_64_512 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=512 main.cpp
|
||||||
|
|
||||||
|
big_64_1024: main.cpp
|
||||||
|
$(CC) -o big_64_1024 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=1024 main.cpp
|
||||||
|
|
||||||
|
big_64_2048: main.cpp
|
||||||
|
$(CC) -o big_64_2048 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=2048 main.cpp
|
||||||
|
|
||||||
|
big_64_4096: main.cpp
|
||||||
|
$(CC) -o big_64_4096 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=4096 main.cpp
|
||||||
|
|
||||||
|
big_128_512: main.cpp
|
||||||
|
$(CC) -o big_128_512 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=128 -DTTMATH_TEST_BIG_MANTISSA=512 main.cpp
|
||||||
|
|
||||||
|
big_256_1024: main.cpp
|
||||||
|
$(CC) -o big_256_1024 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=256 -DTTMATH_TEST_BIG_MANTISSA=1024 main.cpp
|
||||||
|
|
||||||
|
big_512_2048: main.cpp
|
||||||
|
$(CC) -o big_512_2048 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=512 -DTTMATH_TEST_BIG_MANTISSA=2048 main.cpp
|
||||||
|
|
||||||
|
big_128_4096: main.cpp
|
||||||
|
$(CC) -o big_128_4096 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=128 -DTTMATH_TEST_BIG_MANTISSA=4096 main.cpp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
test: all
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=64"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_64 "foo" | tee big_64_64.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=128"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_128 "foo" | tee big_64_128.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=192"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_192 "foo" | tee big_64_192.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=256"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_256 "foo" | tee big_64_256.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=512"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_512 "foo" | tee big_64_512.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=1024"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_1024 "foo" | tee big_64_1024.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=2048"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_2048 "foo" | tee big_64_2048.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=4096"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_4096 "foo" | tee big_64_4096.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=128 and mantissa=512"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_128_512 "foo" | tee big_128_512.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=128 and mantissa=4096"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_128_4096 "foo" | tee big_128_4096.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=256 and mantissa=1024"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_256_1024 "foo" | tee big_256_1024.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=512 and mantissa=2048"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_512_2048 "foo" | tee big_512_2048.out
|
||||||
|
|
||||||
|
./check_files.sh
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.out
|
||||||
|
rm -f big_64_64 big_64_128 big_64_192 big_64_256 big_64_512 big_64_1024 big_64_2048 big_64_4096 big_128_512 big_256_1024 big_512_2048 big_128_4096
|
||||||
|
# on MS Windows suffixes .exe will be automatically added
|
||||||
|
rm -f *.exe
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
was_error=0
|
||||||
|
|
||||||
|
for expected in *.expected ; do
|
||||||
|
|
||||||
|
out=`basename $expected .expected`.out
|
||||||
|
|
||||||
|
if [ -f $out ] ; then
|
||||||
|
diff -u $out $expected
|
||||||
|
|
||||||
|
if [ `diff -u $out $expected | wc -l` -ne 0 ] ; then
|
||||||
|
was_error=1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "there is no file: $out"
|
||||||
|
was_error=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
if [ $was_error -eq 0 ] ; then
|
||||||
|
echo "****************************************************************************"
|
||||||
|
echo " congratulations: all tests passed successfully"
|
||||||
|
echo "****************************************************************************"
|
||||||
|
else
|
||||||
|
echo "****************************************************************************"
|
||||||
|
echo " error: not all tests passed successfully"
|
||||||
|
echo "****************************************************************************"
|
||||||
|
fi
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include <ttmath/ttmath.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main(int argc, char ** argv)
|
||||||
|
{
|
||||||
|
typedef ttmath::Big<TTMATH_BITS(TTMATH_TEST_BIG_EXPONENT), TTMATH_BITS(TTMATH_TEST_BIG_MANTISSA)> MyBig;
|
||||||
|
ttmath::Parser<MyBig> parser;
|
||||||
|
std::string all_input;
|
||||||
|
|
||||||
|
for(int i=1 ; i<argc ; ++i)
|
||||||
|
{
|
||||||
|
if( i > 1 )
|
||||||
|
all_input += ' ';
|
||||||
|
|
||||||
|
all_input += argv[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << all_input << " = ";
|
||||||
|
ttmath::ErrorCode err = parser.Parse(all_input);
|
||||||
|
|
||||||
|
if( err == ttmath::err_ok )
|
||||||
|
{
|
||||||
|
for(size_t i=0 ; i < parser.stack.size() ; ++i)
|
||||||
|
{
|
||||||
|
if( i > 0 )
|
||||||
|
std::cout << " ; ";
|
||||||
|
|
||||||
|
std::cout << parser.stack[i].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "error: " << static_cast<int>(err) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
1528
ttmath/ttmath.h
1528
ttmath/ttmath.h
File diff suppressed because it is too large
Load Diff
4702
ttmath/ttmathbig.h
4702
ttmath/ttmathbig.h
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,419 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, 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 headerfilettmathdec
|
||||||
|
#define headerfilettmathdec
|
||||||
|
|
||||||
|
#include "ttmathtypes.h"
|
||||||
|
#include "ttmaththreads.h"
|
||||||
|
#include "ttmathuint.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace ttmath
|
||||||
|
{
|
||||||
|
|
||||||
|
template<uint value_size, uint dec_digits>
|
||||||
|
class Dec
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
UInt<value_size> value;
|
||||||
|
unsigned char info;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sign
|
||||||
|
the mask of a bit from 'info' which means that there is a sign
|
||||||
|
(when the bit is set)
|
||||||
|
*/
|
||||||
|
#define TTMATH_DEC_SIGN 128
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Not a number
|
||||||
|
if this bit is set that there is not a valid number
|
||||||
|
*/
|
||||||
|
#define TTMATH_DEC_NAN 64
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Dec()
|
||||||
|
{
|
||||||
|
info = TTMATH_DEC_NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Dec(const char * s)
|
||||||
|
{
|
||||||
|
info = TTMATH_DEC_NAN;
|
||||||
|
FromString(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Dec<value_size, dec_digits> & operator=(const char * s)
|
||||||
|
{
|
||||||
|
FromString(s);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint FromString(const char * s, const char ** after_source = 0, bool * value_read = 0)
|
||||||
|
{
|
||||||
|
return FromStringBase(s, after_source, value_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ToString(std::string & result) const
|
||||||
|
{
|
||||||
|
ToStringBase(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method clears a specific bit in the 'info' variable
|
||||||
|
|
||||||
|
bit is one of:
|
||||||
|
*/
|
||||||
|
void ClearInfoBit(unsigned char bit)
|
||||||
|
{
|
||||||
|
info = info & (~bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method sets a specific bit in the 'info' variable
|
||||||
|
|
||||||
|
bit is one of:
|
||||||
|
|
||||||
|
*/
|
||||||
|
void SetInfoBit(unsigned char bit)
|
||||||
|
{
|
||||||
|
info = info | bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns true if a specific bit in the 'info' variable is set
|
||||||
|
|
||||||
|
bit is one of:
|
||||||
|
*/
|
||||||
|
bool IsInfoBit(unsigned char bit) const
|
||||||
|
{
|
||||||
|
return (info & bit) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsNan() const
|
||||||
|
{
|
||||||
|
return IsInfoBit(TTMATH_DEC_NAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsSign() const
|
||||||
|
{
|
||||||
|
return IsInfoBit(TTMATH_DEC_SIGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method sets the sign
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
-1 -> -1
|
||||||
|
2 -> -2
|
||||||
|
|
||||||
|
we do not check whether there is a zero or not, if you're using this method
|
||||||
|
you must be sure that the value is (or will be afterwards) different from zero
|
||||||
|
*/
|
||||||
|
void SetSign()
|
||||||
|
{
|
||||||
|
SetInfoBit(TTMATH_DEC_SIGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetNaN()
|
||||||
|
{
|
||||||
|
SetInfoBit(TTMATH_DEC_NAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Abs()
|
||||||
|
{
|
||||||
|
ClearInfoBit(TTMATH_DEC_SIGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint Add(const Dec<value_size, dec_digits> & arg)
|
||||||
|
{
|
||||||
|
uint c = 0;
|
||||||
|
|
||||||
|
if( IsSign() == arg.IsSign() )
|
||||||
|
{
|
||||||
|
c += value.Add(arg.value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool is_sign;
|
||||||
|
|
||||||
|
if( value > arg.value )
|
||||||
|
{
|
||||||
|
is_sign = IsSign();
|
||||||
|
value.Sub(arg.value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is_sign = arg.IsSign();
|
||||||
|
UInt<value_size> temp(this->value);
|
||||||
|
value = arg.value;
|
||||||
|
value.Sub(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
is_sign ? SetSign() : Abs();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( c )
|
||||||
|
SetNaN();
|
||||||
|
|
||||||
|
return (c==0)? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
uint Sub(const Dec<value_size, dec_digits> & arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_MULTITHREADS
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*/
|
||||||
|
void SetMultipler(UInt<value_size> & result)
|
||||||
|
{
|
||||||
|
// this guardian is initialized before the program runs (static POD type)
|
||||||
|
static int guardian = 0;
|
||||||
|
static UInt<value_size> multipler;
|
||||||
|
|
||||||
|
if( guardian == 0 )
|
||||||
|
{
|
||||||
|
multipler = 10;
|
||||||
|
multipler.Pow(dec_digits);
|
||||||
|
guardian = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = multipler;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*/
|
||||||
|
void SetMultipler(UInt<value_size> & result)
|
||||||
|
{
|
||||||
|
// this guardian is initialized before the program runs (static POD type)
|
||||||
|
volatile static sig_atomic_t guardian = 0;
|
||||||
|
static UInt<value_size> * pmultipler;
|
||||||
|
|
||||||
|
// double-checked locking
|
||||||
|
if( guardian == 0 )
|
||||||
|
{
|
||||||
|
ThreadLock thread_lock;
|
||||||
|
|
||||||
|
// locking
|
||||||
|
if( thread_lock.Lock() )
|
||||||
|
{
|
||||||
|
static UInt<value_size> multipler;
|
||||||
|
|
||||||
|
if( guardian == 0 )
|
||||||
|
{
|
||||||
|
pmultipler = &multipler;
|
||||||
|
multipler = 10;
|
||||||
|
multipler.Pow(dec_digits);
|
||||||
|
guardian = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// there was a problem with locking, we store the result directly in 'result' object
|
||||||
|
result = 10;
|
||||||
|
result.Pow(dec_digits);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// automatically unlocking
|
||||||
|
}
|
||||||
|
|
||||||
|
result = *pmultipler;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
an auxiliary method for converting from a string
|
||||||
|
*/
|
||||||
|
template<class char_type>
|
||||||
|
uint FromStringBase(const char_type * s, const char_type ** after_source = 0, bool * value_read = 0)
|
||||||
|
{
|
||||||
|
UInt<value_size> multipler;
|
||||||
|
const char_type * after;
|
||||||
|
uint c = 0;
|
||||||
|
info = 0;
|
||||||
|
|
||||||
|
Misc::SkipWhiteCharacters(s);
|
||||||
|
|
||||||
|
if( *s == '-' )
|
||||||
|
{
|
||||||
|
s += 1;
|
||||||
|
SetSign();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( *s == '+' )
|
||||||
|
{
|
||||||
|
s += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c += value.FromString(s, 10, &after, value_read);
|
||||||
|
|
||||||
|
if( after_source )
|
||||||
|
*after_source = after;
|
||||||
|
|
||||||
|
SetMultipler(multipler);
|
||||||
|
c += value.Mul(multipler);
|
||||||
|
|
||||||
|
if( *after == '.' )
|
||||||
|
c += FromStringBaseAfterComma(after+1, after_source);
|
||||||
|
|
||||||
|
if( c )
|
||||||
|
SetInfoBit(TTMATH_DEC_NAN);
|
||||||
|
|
||||||
|
return (c==0)? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class char_type>
|
||||||
|
uint FromStringBaseAfterComma(const char_type * s, const char_type ** after_source = 0, bool * value_read = 0)
|
||||||
|
{
|
||||||
|
UInt<value_size> temp;
|
||||||
|
UInt<value_size> multipler;
|
||||||
|
sint z;
|
||||||
|
uint c = 0;
|
||||||
|
size_t i = dec_digits;
|
||||||
|
|
||||||
|
SetMultipler(multipler);
|
||||||
|
|
||||||
|
for( ; i>0 && (z=Misc::CharToDigit(*s, 10)) != -1 ; --i, ++s )
|
||||||
|
{
|
||||||
|
multipler.DivInt(10);
|
||||||
|
temp.SetZero();
|
||||||
|
|
||||||
|
if( value_read )
|
||||||
|
*value_read = true;
|
||||||
|
|
||||||
|
if( c == 0 )
|
||||||
|
{
|
||||||
|
temp.table[0] = z;
|
||||||
|
c += temp.Mul(multipler);
|
||||||
|
c += value.Add(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( i == 0 && (z=Misc::CharToDigit(*s, 10)) != -1 && z >= 5 )
|
||||||
|
c += value.AddOne();
|
||||||
|
|
||||||
|
if( after_source )
|
||||||
|
{
|
||||||
|
while( (z=Misc::CharToDigit(*s, 10)) != -1 )
|
||||||
|
s += 1;
|
||||||
|
|
||||||
|
*after_source = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class string_type>
|
||||||
|
void ToStringBase(string_type & result) const
|
||||||
|
{
|
||||||
|
if( IsNan() )
|
||||||
|
{
|
||||||
|
result = "NaN";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
value.ToStringBase(result, 10, IsSign());
|
||||||
|
|
||||||
|
if( dec_digits > 0 )
|
||||||
|
{
|
||||||
|
size_t size = result.size();
|
||||||
|
|
||||||
|
if( IsSign() && size > 0 )
|
||||||
|
size -= 1;
|
||||||
|
|
||||||
|
if( dec_digits >= size )
|
||||||
|
{
|
||||||
|
size_t zeroes = dec_digits - size + 1;
|
||||||
|
size_t start = IsSign() ? 1 : 0;
|
||||||
|
result.insert(start, zeroes, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
result.insert(result.end() - dec_digits, '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif
|
1081
ttmath/ttmathint.h
1081
ttmath/ttmathint.h
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,250 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2010, 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 headerfilettmathmisc
|
||||||
|
#define headerfilettmathmisc
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\file ttmathmisc.h
|
||||||
|
\brief some helpful functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace ttmath
|
||||||
|
{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
some helpful functions
|
||||||
|
*/
|
||||||
|
class Misc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* AssignString(result, str)
|
||||||
|
* result = str
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result = str
|
||||||
|
*/
|
||||||
|
static void AssignString(std::string & result, const char * str)
|
||||||
|
{
|
||||||
|
result = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result = str
|
||||||
|
*/
|
||||||
|
static void AssignString(std::wstring & result, const char * str)
|
||||||
|
{
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
for( ; *str ; ++str )
|
||||||
|
result += *str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result = str
|
||||||
|
*/
|
||||||
|
static void AssignString(std::wstring & result, const std::string & str)
|
||||||
|
{
|
||||||
|
return AssignString(result, str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result = str
|
||||||
|
*/
|
||||||
|
static void AssignString(std::string & result, const wchar_t * str)
|
||||||
|
{
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
for( ; *str ; ++str )
|
||||||
|
result += static_cast<char>(*str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result = str
|
||||||
|
*/
|
||||||
|
static void AssignString(std::string & result, const std::wstring & str)
|
||||||
|
{
|
||||||
|
return AssignString(result, str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* AddString(result, str)
|
||||||
|
* result += str
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result += str
|
||||||
|
*/
|
||||||
|
static void AddString(std::string & result, const char * str)
|
||||||
|
{
|
||||||
|
result += str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
/*!
|
||||||
|
result += str
|
||||||
|
*/
|
||||||
|
static void AddString(std::wstring & result, const char * str)
|
||||||
|
{
|
||||||
|
for( ; *str ; ++str )
|
||||||
|
result += *str;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
this method omits any white characters from the string
|
||||||
|
char_type is char or wchar_t
|
||||||
|
*/
|
||||||
|
template<class char_type>
|
||||||
|
static void SkipWhiteCharacters(const char_type * & c)
|
||||||
|
{
|
||||||
|
// 13 is at the end in a DOS text file (\r\n)
|
||||||
|
while( (*c==' ' ) || (*c=='\t') || (*c==13 ) || (*c=='\n') )
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this static method converts one character into its value
|
||||||
|
|
||||||
|
for example:
|
||||||
|
- 1 -> 1
|
||||||
|
- 8 -> 8
|
||||||
|
- A -> 10
|
||||||
|
- f -> 15
|
||||||
|
|
||||||
|
this method don't check whether c is correct or not
|
||||||
|
*/
|
||||||
|
static uint CharToDigit(uint c)
|
||||||
|
{
|
||||||
|
if(c>='0' && c<='9')
|
||||||
|
return c-'0';
|
||||||
|
|
||||||
|
if(c>='a' && c<='z')
|
||||||
|
return c-'a'+10;
|
||||||
|
|
||||||
|
return c-'A'+10;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method changes a character 'c' into its value
|
||||||
|
(if there can't be a correct value it returns -1)
|
||||||
|
|
||||||
|
for example:
|
||||||
|
- c=2, base=10 -> function returns 2
|
||||||
|
- c=A, base=10 -> function returns -1
|
||||||
|
- c=A, base=16 -> function returns 10
|
||||||
|
*/
|
||||||
|
static sint CharToDigit(uint c, uint base)
|
||||||
|
{
|
||||||
|
if( c>='0' && c<='9' )
|
||||||
|
c=c-'0';
|
||||||
|
else
|
||||||
|
if( c>='a' && c<='z' )
|
||||||
|
c=c-'a'+10;
|
||||||
|
else
|
||||||
|
if( c>='A' && c<='Z' )
|
||||||
|
c=c-'A'+10;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
|
if( c >= base )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
|
return sint(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts a digit into a char
|
||||||
|
digit should be from <0,F>
|
||||||
|
(we don't have to get a base)
|
||||||
|
|
||||||
|
for example:
|
||||||
|
- 1 -> 1
|
||||||
|
- 8 -> 8
|
||||||
|
- 10 -> A
|
||||||
|
- 15 -> F
|
||||||
|
*/
|
||||||
|
static uint DigitToChar(uint digit)
|
||||||
|
{
|
||||||
|
if( digit < 10 )
|
||||||
|
return digit + '0';
|
||||||
|
|
||||||
|
return digit - 10 + 'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}; // struct Misc
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Mathematical Library
|
* This file is a part of TTMath Mathematical Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2007, Tomasz Sowa
|
* Copyright (c) 2006-2017, 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
|
||||||
|
@ -44,12 +44,13 @@
|
||||||
\brief Mathematic functions.
|
\brief Mathematic functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ttmathtypes.h"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include "ttmathtypes.h"
|
||||||
|
#include "ttmathmisc.h"
|
||||||
|
|
||||||
|
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
|
@ -73,13 +74,14 @@ public:
|
||||||
struct Item
|
struct Item
|
||||||
{
|
{
|
||||||
// name of a variable of a function
|
// name of a variable of a function
|
||||||
|
// internally we store variables and funcions as std::string (not std::wstring even when wide characters are used)
|
||||||
std::string value;
|
std::string value;
|
||||||
|
|
||||||
// number of parameters required by the function
|
// number of parameters required by the function
|
||||||
// (if there's a variable this 'param' is ignored)
|
// (if there's a variable this 'param' is ignored)
|
||||||
int param;
|
int param;
|
||||||
|
|
||||||
Item() {}
|
Item() { param = 0; }
|
||||||
Item(const std::string & v, int p) : value(v), param(p) {}
|
Item(const std::string & v, int p) : value(v), param(p) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -102,7 +104,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;
|
||||||
|
@ -112,7 +114,8 @@ public:
|
||||||
/*!
|
/*!
|
||||||
this method returns true if the name can be as a name of an object
|
this method returns true if the name can be as a name of an object
|
||||||
*/
|
*/
|
||||||
static bool IsNameCorrect(const std::string & name)
|
template<class string_type>
|
||||||
|
static bool IsNameCorrect(const string_type & name)
|
||||||
{
|
{
|
||||||
if( name.empty() )
|
if( name.empty() )
|
||||||
return false;
|
return false;
|
||||||
|
@ -120,7 +123,7 @@ public:
|
||||||
if( !CorrectCharacter(name[0], false) )
|
if( !CorrectCharacter(name[0], false) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::string::const_iterator i=name.begin();
|
typename string_type::const_iterator i = name.begin();
|
||||||
|
|
||||||
for(++i ; i!=name.end() ; ++i)
|
for(++i ; i!=name.end() ; ++i)
|
||||||
if( !CorrectCharacter(*i, true) )
|
if( !CorrectCharacter(*i, true) )
|
||||||
|
@ -130,6 +133,42 @@ 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns true if such an object is defined (name exists)
|
||||||
|
*/
|
||||||
|
bool IsDefined(const std::wstring & name)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
|
||||||
|
return IsDefined(str_tmp1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method adds one object (variable of function) into the table
|
this method adds one object (variable of function) into the table
|
||||||
*/
|
*/
|
||||||
|
@ -150,6 +189,27 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method adds one object (variable of function) into the table
|
||||||
|
*/
|
||||||
|
ErrorCode Add(const std::wstring & name, const std::wstring & value, int param = 0)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
Misc::AssignString(str_tmp2, value);
|
||||||
|
|
||||||
|
return Add(str_tmp1, str_tmp2, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns 'true' if the table is empty
|
this method returns 'true' if the table is empty
|
||||||
*/
|
*/
|
||||||
|
@ -207,6 +267,28 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method changes the value and the number of parameters for a specific object
|
||||||
|
*/
|
||||||
|
ErrorCode EditValue(const std::wstring & name, const std::wstring & value, int param = 0)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
Misc::AssignString(str_tmp2, value);
|
||||||
|
|
||||||
|
return EditValue(str_tmp1, str_tmp2, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method changes the name of a specific object
|
this method changes the name of a specific object
|
||||||
*/
|
*/
|
||||||
|
@ -238,6 +320,29 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method changes the name of a specific object
|
||||||
|
*/
|
||||||
|
ErrorCode EditName(const std::wstring & old_name, const std::wstring & new_name)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, old_name);
|
||||||
|
Misc::AssignString(str_tmp2, new_name);
|
||||||
|
|
||||||
|
return EditName(str_tmp1, str_tmp2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method deletes an object
|
this method deletes an object
|
||||||
*/
|
*/
|
||||||
|
@ -257,8 +362,29 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets the value of a specific object
|
this method deletes an object
|
||||||
|
*/
|
||||||
|
ErrorCode Delete(const std::wstring & name)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
|
||||||
|
return Delete(str_tmp1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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
|
||||||
{
|
{
|
||||||
|
@ -279,8 +405,30 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets the value of a specific object
|
this method gets the value of a specific object
|
||||||
|
*/
|
||||||
|
ErrorCode GetValue(const std::wstring & name, std::wstring & value)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
ErrorCode err = GetValue(str_tmp1, str_tmp2);
|
||||||
|
Misc::AssignString(value, str_tmp2);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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
|
||||||
|
@ -302,8 +450,29 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets the value and the number of parameters
|
this method gets the value of a specific object
|
||||||
|
(this version is used for not copying the whole string)
|
||||||
|
*/
|
||||||
|
ErrorCode GetValue(const std::wstring & name, const char ** value)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
|
||||||
|
return GetValue(str_tmp1, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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
|
||||||
|
@ -315,7 +484,7 @@ public:
|
||||||
|
|
||||||
if( i == table.end() )
|
if( i == table.end() )
|
||||||
{
|
{
|
||||||
value.empty();
|
value.clear();
|
||||||
*param = 0;
|
*param = 0;
|
||||||
return err_unknown_object;
|
return err_unknown_object;
|
||||||
}
|
}
|
||||||
|
@ -327,6 +496,29 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method gets the value and the number of parameters
|
||||||
|
of a specific object
|
||||||
|
*/
|
||||||
|
ErrorCode GetValueAndParam(const std::wstring & name, std::wstring & value, int * param)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
ErrorCode err = GetValueAndParam(str_tmp1, str_tmp2, param);
|
||||||
|
Misc::AssignString(value, str_tmp2);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets the value and the number of parameters
|
this method sets the value and the number of parameters
|
||||||
of a specific object
|
of a specific object
|
||||||
|
@ -353,6 +545,31 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method sets the value and the number of parameters
|
||||||
|
of a specific object
|
||||||
|
(this version is used for not copying the whole string
|
||||||
|
but in fact we make one copying during AssignString())
|
||||||
|
*/
|
||||||
|
ErrorCode GetValueAndParam(const std::wstring & name, const char ** value, int * param)
|
||||||
|
{
|
||||||
|
// we should check whether the name (in wide characters) are correct
|
||||||
|
// before calling AssignString() function
|
||||||
|
if( !IsNameCorrect(name) )
|
||||||
|
return err_incorrect_name;
|
||||||
|
|
||||||
|
Misc::AssignString(str_tmp1, name);
|
||||||
|
|
||||||
|
return GetValueAndParam(str_tmp1, value, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns a pointer into the table
|
this method returns a pointer into the table
|
||||||
*/
|
*/
|
||||||
|
@ -365,6 +582,7 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Table table;
|
Table table;
|
||||||
|
std::string str_tmp1, str_tmp2;
|
||||||
|
|
||||||
}; // end of class Objects
|
}; // end of class Objects
|
||||||
|
|
||||||
|
@ -411,11 +629,11 @@ public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
default constructor
|
default constructor
|
||||||
default max size of the History's container is 10 items
|
default max size of the History's container is 15 items
|
||||||
*/
|
*/
|
||||||
History()
|
History()
|
||||||
{
|
{
|
||||||
buffer_max_size = 10;
|
buffer_max_size = 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -472,10 +690,121 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this methods deletes an item
|
||||||
|
|
||||||
|
we assume that there is only one item with the 'key'
|
||||||
|
(this methods removes the first one)
|
||||||
|
*/
|
||||||
|
bool Remove(const ValueType & key)
|
||||||
|
{
|
||||||
|
typename buffer_type::iterator i = buffer.begin();
|
||||||
|
|
||||||
|
for( ; i != buffer.end() ; ++i )
|
||||||
|
{
|
||||||
|
if( i->key == key )
|
||||||
|
{
|
||||||
|
buffer.erase(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}; // end of class History
|
}; // end of class History
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this is an auxiliary class used when calculating Gamma() or Factorial()
|
||||||
|
|
||||||
|
in multithreaded environment you can provide an object of this class to
|
||||||
|
the Gamma() or Factorial() function, e.g;
|
||||||
|
|
||||||
|
typedef Big<1, 3> MyBig;
|
||||||
|
MyBig x = 123456;
|
||||||
|
CGamma<MyBig> cgamma;
|
||||||
|
std::cout << Gamma(x, cgamma);
|
||||||
|
|
||||||
|
each thread should have its own CGamma<> object
|
||||||
|
|
||||||
|
in a single-thread environment a CGamma<> object is a static variable
|
||||||
|
and you don't have to explicitly use it, e.g.
|
||||||
|
|
||||||
|
typedef Big<1, 3> MyBig;
|
||||||
|
MyBig x = 123456;
|
||||||
|
std::cout << Gamma(x);
|
||||||
|
*/
|
||||||
|
template<class ValueType>
|
||||||
|
struct CGamma
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
this table holds factorials
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
6
|
||||||
|
24
|
||||||
|
120
|
||||||
|
720
|
||||||
|
.......
|
||||||
|
*/
|
||||||
|
std::vector<ValueType> fact;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this table holds Bernoulli numbers
|
||||||
|
1
|
||||||
|
-0.5
|
||||||
|
0.166666666666666666666666667
|
||||||
|
0
|
||||||
|
-0.0333333333333333333333333333
|
||||||
|
0
|
||||||
|
0.0238095238095238095238095238
|
||||||
|
0
|
||||||
|
-0.0333333333333333333333333333
|
||||||
|
0
|
||||||
|
0.075757575757575757575757576
|
||||||
|
.....
|
||||||
|
*/
|
||||||
|
std::vector<ValueType> bern;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
here we store some calculated values
|
||||||
|
(this is for speeding up, if the next argument of Gamma() or Factorial()
|
||||||
|
is in the 'history' then the result we are not calculating but simply
|
||||||
|
return from the 'history' object)
|
||||||
|
*/
|
||||||
|
History<ValueType> history;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method prepares some coefficients: factorials and Bernoulli numbers
|
||||||
|
stored in 'fact' and 'bern' objects
|
||||||
|
|
||||||
|
how many values should be depends on the size of the mantissa - if
|
||||||
|
the mantissa is larger then we must calculate more values
|
||||||
|
for a mantissa which consists of 256 bits (8 words on a 32bit platform)
|
||||||
|
we have to calculate about 30 values (the size of fact and bern will be 30),
|
||||||
|
and for a 2048 bits mantissa we have to calculate 306 coefficients
|
||||||
|
|
||||||
|
you don't have to call this method, these coefficients will be automatically calculated
|
||||||
|
when they are needed
|
||||||
|
|
||||||
|
you must note that calculating these coefficients is a little time-consuming operation,
|
||||||
|
(especially when the mantissa is large) and first call to Gamma() or Factorial()
|
||||||
|
can take more time than next calls, and in the end this is the point when InitAll()
|
||||||
|
comes in handy: you can call this method somewhere at the beginning of your program
|
||||||
|
*/
|
||||||
|
void InitAll();
|
||||||
|
// definition is in ttmath.h
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,252 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 headerfilettmaththreads
|
||||||
|
#define headerfilettmaththreads
|
||||||
|
|
||||||
|
#include "ttmathtypes.h"
|
||||||
|
|
||||||
|
#ifdef TTMATH_WIN32_THREADS
|
||||||
|
#include <windows.h>
|
||||||
|
#include <cstdio>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TTMATH_POSIX_THREADS
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\file ttmaththreads.h
|
||||||
|
\brief Some objects used in multithreads environment
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace ttmath
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TTMATH_WIN32_THREADS
|
||||||
|
|
||||||
|
/*
|
||||||
|
we use win32 threads
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
|
||||||
|
somewhere in *.cpp file
|
||||||
|
|
||||||
|
(at the moment in win32 this macro does nothing)
|
||||||
|
*/
|
||||||
|
#define TTMATH_MULTITHREADS_HELPER
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
objects of this class are used to synchronize
|
||||||
|
*/
|
||||||
|
class ThreadLock
|
||||||
|
{
|
||||||
|
HANDLE mutex_handle;
|
||||||
|
|
||||||
|
|
||||||
|
void CreateName(char * buffer) const
|
||||||
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning (disable : 4996)
|
||||||
|
// warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sprintf(buffer, "TTMATH_LOCK_%ul", (unsigned long)GetCurrentProcessId());
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning (default : 4996)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool Lock()
|
||||||
|
{
|
||||||
|
char buffer[50];
|
||||||
|
|
||||||
|
CreateName(buffer);
|
||||||
|
mutex_handle = CreateMutexA(0, false, buffer);
|
||||||
|
|
||||||
|
if( mutex_handle == 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
WaitForSingleObject(mutex_handle, INFINITE);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ThreadLock()
|
||||||
|
{
|
||||||
|
mutex_handle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
~ThreadLock()
|
||||||
|
{
|
||||||
|
if( mutex_handle != 0 )
|
||||||
|
{
|
||||||
|
ReleaseMutex(mutex_handle);
|
||||||
|
CloseHandle(mutex_handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // #ifdef TTMATH_WIN32_THREADS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TTMATH_POSIX_THREADS
|
||||||
|
|
||||||
|
/*
|
||||||
|
we use posix threads
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
|
||||||
|
somewhere in *.cpp file
|
||||||
|
(this macro defines a pthread_mutex_t object used by TTMath library)
|
||||||
|
*/
|
||||||
|
#define TTMATH_MULTITHREADS_HELPER \
|
||||||
|
namespace ttmath \
|
||||||
|
{ \
|
||||||
|
pthread_mutex_t ttmath_mutex = PTHREAD_MUTEX_INITIALIZER; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
ttmath_mutex will be defined by TTMATH_MULTITHREADS_HELPER macro
|
||||||
|
*/
|
||||||
|
extern pthread_mutex_t ttmath_mutex;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief objects of this class are used to synchronize
|
||||||
|
|
||||||
|
this is a simple skeleton of a program in multithreads environment:
|
||||||
|
|
||||||
|
#define TTMATH_MULTITHREADS
|
||||||
|
#include<ttmath/ttmath.h>
|
||||||
|
|
||||||
|
TTMATH_MULTITHREADS_HELPER
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
[...]
|
||||||
|
}
|
||||||
|
|
||||||
|
make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file)
|
||||||
|
use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope)
|
||||||
|
*/
|
||||||
|
class ThreadLock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/*!
|
||||||
|
lock the current thread
|
||||||
|
|
||||||
|
it uses a global mutex created by TTMATH_MULTITHREADS_HELPER macro
|
||||||
|
*/
|
||||||
|
bool Lock()
|
||||||
|
{
|
||||||
|
if( pthread_mutex_lock(&ttmath_mutex) != 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
~ThreadLock()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&ttmath_mutex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // #ifdef TTMATH_POSIX_THREADS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
we don't use win32 and pthreads
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*/
|
||||||
|
#define TTMATH_MULTITHREADS_HELPER
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
objects of this class are used to synchronize
|
||||||
|
actually we don't synchronize, the method Lock() returns always 'false'
|
||||||
|
*/
|
||||||
|
class ThreadLock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool Lock()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // #if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -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 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2007, Tomasz Sowa
|
* Copyright (c) 2006-2019, 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
|
||||||
|
@ -54,63 +54,123 @@
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
/*!
|
#include <stdint.h>
|
||||||
the version of the library
|
// for uint64_t and int64_t on a 32 bit platform
|
||||||
|
|
||||||
TTMATH_PRERELEASE_VER is either zero or one
|
|
||||||
if zero that means this is the release version of the library
|
|
||||||
*/
|
|
||||||
#define TTMATH_MAJOR_VER 0
|
|
||||||
#define TTMATH_MINOR_VER 8
|
|
||||||
#define TTMATH_REVISION_VER 1
|
|
||||||
#define TTMATH_PRERELEASE_VER 0
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
TTMATH_DEBUG
|
|
||||||
this macro enables further testing during writing your code
|
|
||||||
you don't have to define it in a release mode
|
|
||||||
|
|
||||||
if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
|
|
||||||
are set as well and these macros can throw an exception if a condition in it
|
|
||||||
is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
|
|
||||||
|
|
||||||
TTMATH_RELEASE
|
|
||||||
if you are confident that your code is perfect you can define TTMATH_RELEASE
|
|
||||||
macro for example by using -D option in gcc
|
|
||||||
gcc -DTTMATH_RELEASE -o myprogram myprogram.cpp
|
|
||||||
or by defining this macro in your code before using any header files of this library
|
|
||||||
|
|
||||||
if TTMATH_RELEASE is not set then TTMATH_DEBUG is set
|
|
||||||
*/
|
|
||||||
#ifndef TTMATH_RELEASE
|
|
||||||
#define TTMATH_DEBUG
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the major version of the library
|
||||||
|
|
||||||
|
the version present to the end user is constructed in this way:
|
||||||
|
|
||||||
|
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
|
||||||
|
*/
|
||||||
|
#define TTMATH_MAJOR_VER 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the minor version of the library
|
||||||
|
|
||||||
|
the version present to the end user is constructed in this way:
|
||||||
|
|
||||||
|
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
|
||||||
|
*/
|
||||||
|
#define TTMATH_MINOR_VER 9
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the revision version of the library
|
||||||
|
|
||||||
|
the version present to the end user is constructed in this way:
|
||||||
|
|
||||||
|
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
|
||||||
|
*/
|
||||||
|
#define TTMATH_REVISION_VER 4
|
||||||
|
|
||||||
|
/*!
|
||||||
|
TTMATH_PRERELEASE_VER is either zero or one
|
||||||
|
zero means that this is the release version of the library
|
||||||
|
(one means something like beta)
|
||||||
|
|
||||||
|
the version present to the end user is constructed in this way:
|
||||||
|
|
||||||
|
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
|
||||||
|
*/
|
||||||
|
#define TTMATH_PRERELEASE_VER 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
you can define a platform explicitly by defining either
|
||||||
|
TTMATH_PLATFORM32 or TTMATH_PLATFORM64 macro
|
||||||
|
*/
|
||||||
|
#if !defined TTMATH_PLATFORM32 && !defined TTMATH_PLATFORM64
|
||||||
|
|
||||||
|
#if !defined _M_X64 && !defined __x86_64__
|
||||||
|
|
||||||
|
/*
|
||||||
|
other platforms than x86 and amd64 are not recognized at the moment
|
||||||
|
so you should set TTMATH_PLATFORMxx manually
|
||||||
|
*/
|
||||||
|
|
||||||
|
// we're using a 32bit platform
|
||||||
|
#define TTMATH_PLATFORM32
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// we're using a 64bit platform
|
||||||
|
#define TTMATH_PLATFORM64
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
asm version of the library is available by default only for:
|
||||||
|
x86 and amd64 platforms and for Microsoft Visual and GCC compilers
|
||||||
|
|
||||||
|
but you can force using asm version (the same asm as for Microsoft Visual)
|
||||||
|
by defining TTMATH_FORCEASM macro
|
||||||
|
you have to be sure that your compiler accept such an asm format
|
||||||
|
*/
|
||||||
|
#ifndef TTMATH_FORCEASM
|
||||||
|
|
||||||
|
#if !defined __i386__ && !defined _X86_ && !defined _M_IX86 && !defined __x86_64__ && !defined _M_X64
|
||||||
|
/*!
|
||||||
|
x86 architecture:
|
||||||
|
__i386__ defined by GNU C
|
||||||
|
_X86_ defined by MinGW32
|
||||||
|
_M_IX86 defined by Visual Studio, Intel C/C++, Digital Mars and Watcom C/C++
|
||||||
|
|
||||||
|
amd64 architecture:
|
||||||
|
__x86_64__ defined by GNU C, CLANG (LLVM) and Sun Studio
|
||||||
|
_M_X64 defined by Visual Studio
|
||||||
|
|
||||||
|
asm version is available only for x86 or amd64 platforms
|
||||||
|
*/
|
||||||
|
#define TTMATH_NOASM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined _MSC_VER && !defined __GNUC__
|
||||||
|
/*!
|
||||||
|
another compilers than MS VC or GCC or CLANG (LLVM) by default use no asm version
|
||||||
|
(CLANG defines __GNUC__ too)
|
||||||
|
*/
|
||||||
|
#define TTMATH_NOASM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
|
||||||
#if !defined _M_X64 && !defined __x86_64__
|
|
||||||
|
|
||||||
/*!
|
|
||||||
we're using a 32bit platform
|
|
||||||
*/
|
|
||||||
#define TTMATH_PLATFORM32
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*!
|
|
||||||
we're using a 64bit platform
|
|
||||||
*/
|
|
||||||
#define TTMATH_PLATFORM64
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TTMATH_PLATFORM32
|
#ifdef TTMATH_PLATFORM32
|
||||||
|
|
||||||
|
@ -120,6 +180,21 @@ namespace ttmath
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
typedef signed int sint;
|
typedef signed int sint;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
on 32 bit platform ulint and slint will be equal 64 bits
|
||||||
|
*/
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// long long on MS Windows (Visual and GCC mingw compilers) have 64 bits
|
||||||
|
// stdint.h is not available on Visual Studio prior to VS 2010 version
|
||||||
|
typedef unsigned long long int ulint;
|
||||||
|
typedef signed long long int slint;
|
||||||
|
#else
|
||||||
|
// we do not use 'long' here because there is a difference in unix and windows
|
||||||
|
// environments: in unix 'long' has 64 bits but in windows it has only 32 bits
|
||||||
|
typedef uint64_t ulint;
|
||||||
|
typedef int64_t slint;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
how many bits there are in the uint type
|
how many bits there are in the uint type
|
||||||
*/
|
*/
|
||||||
|
@ -141,15 +216,36 @@ 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
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this macro returns the number of machine words
|
||||||
|
capable to hold min_bits bits
|
||||||
|
e.g. TTMATH_BITS(128) returns 4
|
||||||
|
*/
|
||||||
|
#define TTMATH_BITS(min_bits) ((min_bits-1)/32 + 1)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
/* in VC 'long' type has 32 bits, __int64 is VC extension */
|
||||||
|
typedef unsigned __int64 uint;
|
||||||
|
typedef signed __int64 sint;
|
||||||
|
#else
|
||||||
|
/*!
|
||||||
|
on 64bit platforms one word (uint, sint) will be equal 64bits
|
||||||
|
*/
|
||||||
|
typedef uint64_t uint;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
on 64bit platforms one word (uint, sint) will be equal 64bits
|
on 64bit platforms one word (uint, sint) will be equal 64bits
|
||||||
*/
|
*/
|
||||||
typedef unsigned long uint;
|
typedef int64_t sint;
|
||||||
typedef signed long sint;
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
on 64bit platforms we do not define ulint and slint
|
||||||
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
how many bits there are in the uint type
|
how many bits there are in the uint type
|
||||||
|
@ -172,29 +268,31 @@ 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
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this macro returns the number of machine words
|
||||||
|
capable to hold min_bits bits
|
||||||
|
e.g. TTMATH_BITS(128) returns 2
|
||||||
|
*/
|
||||||
|
#define TTMATH_BITS(min_bits) ((min_bits-1)/64 + 1)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(TTMATH_MULTITHREADS) && !defined(TTMATH_MULTITHREADS_NOSYNC)
|
||||||
|
#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
|
||||||
|
|
||||||
/*!
|
#if defined(_WIN32)
|
||||||
characters which represent the comma operator
|
#define TTMATH_WIN32_THREADS
|
||||||
|
#elif defined(unix) || defined(__unix__) || defined(__unix)
|
||||||
|
#define TTMATH_POSIX_THREADS
|
||||||
|
#endif
|
||||||
|
|
||||||
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing
|
#endif
|
||||||
TTMATH_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character
|
#endif
|
||||||
that means you can input values for example 1.2345 and 1,2345 as well
|
|
||||||
|
|
||||||
if you don't want it just put 0 there e.g.
|
|
||||||
#define TTMATH_COMMA_CHARACTER_2 0
|
|
||||||
then only TTMATH_COMMA_CHARACTER_1 will be used
|
|
||||||
|
|
||||||
don't put there any special character which is used by the parser
|
|
||||||
(for example a semicolon ';' shouldn't be there)
|
|
||||||
*/
|
|
||||||
#define TTMATH_COMMA_CHARACTER_1 '.'
|
|
||||||
#define TTMATH_COMMA_CHARACTER_2 ','
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -213,10 +311,59 @@ namespace ttmath
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this is a limit when calculating Karatsuba multiplication
|
||||||
|
if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
|
||||||
|
the Karatsuba algorithm will use standard schoolbook multiplication
|
||||||
|
*/
|
||||||
|
#ifdef TTMATH_DEBUG_LOG
|
||||||
|
// if TTMATH_DEBUG_LOG is defined then we should use the same size regardless of the compiler
|
||||||
|
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
|
||||||
|
#else
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
|
||||||
|
#else
|
||||||
|
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this is a special value used when calculating the Gamma(x) function
|
||||||
|
if x is greater than this value then the Gamma(x) will be calculated using
|
||||||
|
some kind of series
|
||||||
|
|
||||||
|
don't use smaller values than about 100
|
||||||
|
*/
|
||||||
|
#define TTMATH_GAMMA_BOUNDARY 2000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
lib type codes:
|
||||||
|
- asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
||||||
|
- asm_gcc_32 - with asm code designed for GCC (32 bits)
|
||||||
|
- asm_vc_64 - with asm for VC (64 bit)
|
||||||
|
- asm_gcc_64 - with asm for GCC (64 bit)
|
||||||
|
- no_asm_32 - pure C++ version (32 bit) - without any asm code
|
||||||
|
- no_asm_64 - pure C++ version (64 bit) - without any asm code
|
||||||
|
*/
|
||||||
|
enum LibTypeCode
|
||||||
|
{
|
||||||
|
asm_vc_32 = 0,
|
||||||
|
asm_gcc_32,
|
||||||
|
asm_vc_64,
|
||||||
|
asm_gcc_64,
|
||||||
|
no_asm_32,
|
||||||
|
no_asm_64
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
error codes
|
error codes
|
||||||
*/
|
*/
|
||||||
|
@ -247,10 +394,142 @@ 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_in_short_form_used_function,
|
||||||
|
err_percent_from,
|
||||||
|
err_assignment_requires_variable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this struct is used when converting to/from a string
|
||||||
|
/temporarily only in Big::ToString() and Big::FromString()/
|
||||||
|
*/
|
||||||
|
struct Conv
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
base (radix) on which the value will be shown (or read)
|
||||||
|
default: 10
|
||||||
|
*/
|
||||||
|
uint base;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
used only in Big::ToString()
|
||||||
|
if true the value will be always shown in the scientific mode, e.g: 123e+30
|
||||||
|
default: false
|
||||||
|
*/
|
||||||
|
bool scient;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
used only in Big::ToString()
|
||||||
|
if scient is false then the value will be printed in the scientific mode
|
||||||
|
only if the exponent is greater than scien_from
|
||||||
|
default: 15
|
||||||
|
*/
|
||||||
|
sint scient_from;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
if 'base_round' is true and 'base' is different from 2, 4, 8, or 16
|
||||||
|
and the result value is not an integer then we make an additional rounding
|
||||||
|
(after converting the last digit from the result is skipped)
|
||||||
|
default: true
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
|
||||||
|
Conv c;
|
||||||
|
c.base_round = false;
|
||||||
|
Big<1, 1> a = "0.1"; // decimal input
|
||||||
|
std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999
|
||||||
|
*/
|
||||||
|
bool base_round;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
used only in Big::ToString()
|
||||||
|
tells how many digits after comma are possible
|
||||||
|
default: -1 which means all digits are printed
|
||||||
|
|
||||||
|
set it to zero if you want integer value only
|
||||||
|
|
||||||
|
for example when the value is:
|
||||||
|
12.345678 and 'round' is 4
|
||||||
|
then the result will be
|
||||||
|
12.3457 (the last digit was rounded)
|
||||||
|
*/
|
||||||
|
sint round;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
if true that not mattered digits in the mantissa will be cut off
|
||||||
|
(zero characters at the end -- after the comma operator)
|
||||||
|
e.g. 1234,78000 will be: 1234,78
|
||||||
|
default: true
|
||||||
|
*/
|
||||||
|
bool trim_zeroes;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the main comma operator (used when reading and writing)
|
||||||
|
default is a dot '.'
|
||||||
|
*/
|
||||||
|
uint comma;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
additional comma operator (used only when reading)
|
||||||
|
if you don't want it just set it to zero
|
||||||
|
default is a comma ','
|
||||||
|
|
||||||
|
this allowes you to convert from a value:
|
||||||
|
123.45 as well as from 123,45
|
||||||
|
*/
|
||||||
|
uint comma2;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
it sets the character which is used for grouping
|
||||||
|
if group=' ' then: 1234,56789 will be printed as: 1 234,567 89
|
||||||
|
|
||||||
|
if you don't want grouping just set it to zero (which is default)
|
||||||
|
*/
|
||||||
|
uint group;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
how many digits should be grouped (it is used if 'group' is non zero)
|
||||||
|
default: 3
|
||||||
|
*/
|
||||||
|
uint group_digits;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*/
|
||||||
|
uint group_exp; // not implemented yet
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Conv()
|
||||||
|
{
|
||||||
|
// default values
|
||||||
|
base = 10;
|
||||||
|
scient = false;
|
||||||
|
scient_from = 15;
|
||||||
|
base_round = true;
|
||||||
|
round = -1;
|
||||||
|
trim_zeroes = true;
|
||||||
|
comma = '.';
|
||||||
|
comma2 = ',';
|
||||||
|
group = 0;
|
||||||
|
group_digits = 3;
|
||||||
|
group_exp = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this simple class can be used in multithreading model
|
this simple class can be used in multithreading model
|
||||||
(you can write your own class derived from this one)
|
(you can write your own class derived from this one)
|
||||||
|
@ -303,37 +582,24 @@ namespace ttmath
|
||||||
In the library is used macro TTMATH_REFERENCE_ASSERT which
|
In the library is used macro TTMATH_REFERENCE_ASSERT which
|
||||||
can throw an exception of this type
|
can throw an exception of this type
|
||||||
|
|
||||||
|
** from version 0.9.2 this macro is removed from all methods
|
||||||
|
in public interface so you don't have to worry about it **
|
||||||
|
|
||||||
If you compile with gcc you can get a small benefit
|
If you compile with gcc you can get a small benefit
|
||||||
from using method Where() (it returns std::string with
|
from using method Where() (it returns std::string) with
|
||||||
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
|
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
|
||||||
was used)
|
was used)
|
||||||
|
|
||||||
What is the 'reference' error?
|
|
||||||
Some kind of methods use a reference as their argument to another object,
|
|
||||||
and the another object not always can be the same which is calling, e.g.
|
|
||||||
Big<1,2> foo(10);
|
|
||||||
foo.Mul(foo); // this is incorrect
|
|
||||||
above method Mul is making something more with 'this' object and
|
|
||||||
'this' cannot be passed as the argument because the result will be undefined
|
|
||||||
|
|
||||||
macro TTMATH_REFERENCE_ASSERT helps us to solve the above problem
|
|
||||||
|
|
||||||
note! some methods can use 'this' object as the argument
|
|
||||||
for example this code is correct:
|
|
||||||
UInt<2> foo(10);
|
|
||||||
foo.Add(foo);
|
|
||||||
but there are only few methods which can do that
|
|
||||||
*/
|
*/
|
||||||
class ReferenceError : public std::logic_error, ExceptionInfo
|
class ReferenceError : public std::logic_error, public ExceptionInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ReferenceError() : std::logic_error ("reference error")
|
ReferenceError() : std::logic_error("reference error")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ReferenceError(const char * f, int l) :
|
ReferenceError(const char * f, int l) :
|
||||||
std::logic_error ("reference error"), ExceptionInfo(f,l)
|
std::logic_error("reference error"), ExceptionInfo(f,l)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,20 +618,20 @@ namespace ttmath
|
||||||
of this type
|
of this type
|
||||||
|
|
||||||
if you compile with gcc you can get a small benefit
|
if you compile with gcc you can get a small benefit
|
||||||
from using method Where() (it returns std::string with
|
from using method Where() (it returns std::string) with
|
||||||
the name and the line of a file where the macro TTMATH_ASSERT
|
the name and the line of a file where the macro TTMATH_ASSERT
|
||||||
was used)
|
was used)
|
||||||
*/
|
*/
|
||||||
class RuntimeError : public std::runtime_error, ExceptionInfo
|
class RuntimeError : public std::runtime_error, public ExceptionInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RuntimeError() : std::runtime_error ("internal error")
|
RuntimeError() : std::runtime_error("internal error")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
RuntimeError(const char * f, int l) :
|
RuntimeError(const char * f, int l) :
|
||||||
std::runtime_error ("internal error"), ExceptionInfo(f,l)
|
std::runtime_error("internal error"), ExceptionInfo(f,l)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,8 +644,21 @@ namespace ttmath
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
look at the description of macros TTMATH_RELEASE and TTMATH_DEBUG
|
TTMATH_DEBUG
|
||||||
|
this macro enables further testing during writing your code
|
||||||
|
you don't have to define it in a release mode
|
||||||
|
|
||||||
|
if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
|
||||||
|
are set as well and these macros can throw an exception if a condition in it
|
||||||
|
is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
|
||||||
|
|
||||||
|
TTMATH_DEBUG is set automatically if DEBUG or _DEBUG are defined
|
||||||
*/
|
*/
|
||||||
|
#if defined DEBUG || defined _DEBUG
|
||||||
|
#define TTMATH_DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef TTMATH_DEBUG
|
#ifdef TTMATH_DEBUG
|
||||||
|
|
||||||
#if defined(__FILE__) && defined(__LINE__)
|
#if defined(__FILE__) && defined(__LINE__)
|
||||||
|
@ -405,7 +684,24 @@ namespace ttmath
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TTMATH_DEBUG_LOG
|
||||||
|
#define TTMATH_LOG(msg) PrintLog(msg, std::cout);
|
||||||
|
#define TTMATH_LOGC(msg, carry) PrintLog(msg, carry, std::cout);
|
||||||
|
#define TTMATH_VECTOR_LOG(msg, vector, len) PrintVectorLog(msg, std::cout, vector, len);
|
||||||
|
#define TTMATH_VECTOR_LOGC(msg, carry, vector, len) PrintVectorLog(msg, carry, std::cout, vector, len);
|
||||||
|
#else
|
||||||
|
#define TTMATH_LOG(msg)
|
||||||
|
#define TTMATH_LOGC(msg, carry)
|
||||||
|
#define TTMATH_VECTOR_LOG(msg, vector, len)
|
||||||
|
#define TTMATH_VECTOR_LOGC(msg, carry, vector, len)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
3670
ttmath/ttmathuint.h
3670
ttmath/ttmathuint.h
File diff suppressed because it is too large
Load Diff
|
@ -1,986 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is a part of TTMath Mathematical Library
|
|
||||||
* and is distributed under the (new) BSD licence.
|
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2006-2007, 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\file ttmathuint.h
|
|
||||||
\brief template class UInt<uint> for 64bit processors
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
namespace ttmath
|
|
||||||
{
|
|
||||||
|
|
||||||
/*!
|
|
||||||
*
|
|
||||||
* basic mathematic functions
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef TTMATH_PLATFORM64
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
in 64bit platforms we must define additional operators and contructors
|
|
||||||
in order to allow a user initializing the objects in this way:
|
|
||||||
UInt<...> type = 20;
|
|
||||||
or
|
|
||||||
UInt<...> type;
|
|
||||||
type = 30;
|
|
||||||
|
|
||||||
decimal constants such as 20, 30 etc. are integer literal of type int,
|
|
||||||
if the value is greater it can even be long int,
|
|
||||||
0 is an octal integer of type int
|
|
||||||
(ISO 14882 p2.13.1 Integer literals)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this operator converts the unsigned int type to this class
|
|
||||||
|
|
||||||
***this operator is created only on a 64bit platform***
|
|
||||||
it takes one argument of 32bit
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
UInt<value_size> & UInt<value_size>::operator=(unsigned int i)
|
|
||||||
{
|
|
||||||
FromUInt(uint(i));
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
a constructor for converting the unsigned int to this class
|
|
||||||
|
|
||||||
***this constructor is created only on a 64bit platform***
|
|
||||||
it takes one argument of 32bit
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
UInt<value_size>::UInt(unsigned int i)
|
|
||||||
{
|
|
||||||
FromUInt(uint(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
an operator for converting the signed int to this class
|
|
||||||
|
|
||||||
***this constructor is created only on a 64bit platform***
|
|
||||||
it takes one argument of 32bit
|
|
||||||
|
|
||||||
look at the description of UInt::operator=(sint)
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
UInt<value_size> & UInt<value_size>::operator=(signed int i)
|
|
||||||
{
|
|
||||||
FromUInt(uint(i));
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
a constructor for converting the signed int to this class
|
|
||||||
|
|
||||||
***this constructor is created only on a 64bit platform***
|
|
||||||
it takes one argument of 32bit
|
|
||||||
|
|
||||||
look at the description of UInt::operator=(sint)
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
UInt<value_size>::UInt(signed int i)
|
|
||||||
{
|
|
||||||
FromUInt(uint(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method copies the value stored in an another table
|
|
||||||
(warning: first values in temp_table are the highest words -- it's different
|
|
||||||
from our table)
|
|
||||||
|
|
||||||
***this method is created only on a 64bit platform***
|
|
||||||
|
|
||||||
we copy as many words as it is possible
|
|
||||||
|
|
||||||
if temp_table_len is bigger than value_size we'll try to round
|
|
||||||
the lowest word from table depending on the last not used bit in temp_table
|
|
||||||
(this rounding isn't a perfect rounding -- look at the description below)
|
|
||||||
|
|
||||||
and if temp_table_len is smaller than value_size we'll clear the rest words
|
|
||||||
in the table
|
|
||||||
|
|
||||||
warning: we're using 'temp_table' as a pointer at 32bit words
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
void UInt<value_size>::SetFromTable(const unsigned int * temp_table, uint temp_table_len)
|
|
||||||
{
|
|
||||||
uint temp_table_index = 0;
|
|
||||||
sint i; // 'i' with a sign
|
|
||||||
|
|
||||||
for(i=value_size-1 ; i>=0 && temp_table_index<temp_table_len; --i, ++temp_table_index)
|
|
||||||
{
|
|
||||||
table[i] = uint(temp_table[ temp_table_index ]) << 32;
|
|
||||||
|
|
||||||
++temp_table_index;
|
|
||||||
|
|
||||||
if( temp_table_index<temp_table_len )
|
|
||||||
table[i] |= temp_table[ temp_table_index ];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// rounding mantissa
|
|
||||||
if( temp_table_index < temp_table_len )
|
|
||||||
{
|
|
||||||
if( (temp_table[temp_table_index] & TTMATH_UINT_HIGHEST_BIT) != 0 )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
very simply rounding
|
|
||||||
if the bit from not used last word from temp_table is set to one
|
|
||||||
we're rouding the lowest word in the table
|
|
||||||
|
|
||||||
in fact there should be a normal addition but
|
|
||||||
we don't use Add() or AddTwoInts() because these methods
|
|
||||||
can set a carry and then there'll be a small problem
|
|
||||||
for optimization
|
|
||||||
*/
|
|
||||||
if( table[0] != TTMATH_UINT_MAX_VALUE )
|
|
||||||
++table[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleaning the rest of the mantissa
|
|
||||||
for( ; i >= 0 ; --i)
|
|
||||||
table[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method adding ss2 to the this and adding carry if it's defined
|
|
||||||
(this = this + ss2 + c)
|
|
||||||
|
|
||||||
***this method is created only on a 64bit platform***
|
|
||||||
|
|
||||||
c must be zero or one (might be a bigger value than 1)
|
|
||||||
function returns carry (1) (if it was)
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
uint UInt<value_size>::Add(const UInt<value_size> & ss2, uint c)
|
|
||||||
{
|
|
||||||
register uint b = value_size;
|
|
||||||
register uint * p1 = table;
|
|
||||||
register uint * p2 = const_cast<uint*>(ss2.table);
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
/*
|
|
||||||
this part should be compiled with gcc
|
|
||||||
*/
|
|
||||||
__asm__ __volatile__(
|
|
||||||
|
|
||||||
"push %%rbx \n"
|
|
||||||
"push %%rcx \n"
|
|
||||||
"push %%rdx \n"
|
|
||||||
|
|
||||||
"movq $0, %%rax \n"
|
|
||||||
"subq %%rsi, %%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"
|
|
||||||
"adcq %%rax,%%rax \n"
|
|
||||||
"movq %%rax, %%rsi \n"
|
|
||||||
|
|
||||||
"pop %%rdx \n"
|
|
||||||
"pop %%rcx \n"
|
|
||||||
"pop %%rbx \n"
|
|
||||||
|
|
||||||
: "=S" (c)
|
|
||||||
: "0" (c), "c" (b), "b" (p1), "d" (p2)
|
|
||||||
: "%rax", "cc", "memory" );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method adds one word (at a specific position)
|
|
||||||
and returns a carry (if it was)
|
|
||||||
|
|
||||||
***this method is created only on a 64bit platform***
|
|
||||||
|
|
||||||
|
|
||||||
if we've got (value_size=3):
|
|
||||||
table[0] = 10;
|
|
||||||
table[1] = 30;
|
|
||||||
table[2] = 5;
|
|
||||||
and we call:
|
|
||||||
AddInt(2,1)
|
|
||||||
then it'll be:
|
|
||||||
table[0] = 10;
|
|
||||||
table[1] = 30 + 2;
|
|
||||||
table[2] = 5;
|
|
||||||
|
|
||||||
of course if there was a carry from table[3] it would be returned
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
uint UInt<value_size>::AddInt(uint value, uint index)
|
|
||||||
{
|
|
||||||
register uint b = value_size;
|
|
||||||
register uint * p1 = table;
|
|
||||||
register uint c;
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"push %%rbx \n"
|
|
||||||
"push %%rcx \n"
|
|
||||||
"push %%rdx \n"
|
|
||||||
|
|
||||||
"subq %%rdx, %%rcx \n"
|
|
||||||
|
|
||||||
"leaq (%%rbx,%%rdx,8), %%rbx \n"
|
|
||||||
|
|
||||||
"movq %%rsi, %%rdx \n"
|
|
||||||
"clc \n"
|
|
||||||
"1: \n"
|
|
||||||
|
|
||||||
"movq (%%rbx), %%rax \n"
|
|
||||||
"adcq %%rdx, %%rax \n"
|
|
||||||
"movq %%rax, (%%rbx) \n"
|
|
||||||
|
|
||||||
"jnc 2f \n"
|
|
||||||
|
|
||||||
"movq $0, %%rdx \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"
|
|
||||||
|
|
||||||
"loop 1b \n"
|
|
||||||
|
|
||||||
"2: \n"
|
|
||||||
|
|
||||||
"movq $0, %%rax \n"
|
|
||||||
"adcq %%rax,%%rax \n"
|
|
||||||
|
|
||||||
"pop %%rdx \n"
|
|
||||||
"pop %%rcx \n"
|
|
||||||
"pop %%rbx \n"
|
|
||||||
|
|
||||||
: "=a" (c)
|
|
||||||
: "c" (b), "d" (index), "b" (p1), "S" (value)
|
|
||||||
: "cc", "memory" );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method adds only two unsigned words to the existing value
|
|
||||||
and these words begin on the 'index' position
|
|
||||||
(it's used in the multiplication algorithm 2)
|
|
||||||
|
|
||||||
***this method is created only on a 64bit platform***
|
|
||||||
|
|
||||||
index should be equal or smaller than value_size-2 (index <= value_size-2)
|
|
||||||
x1 - lower word, x2 - higher word
|
|
||||||
|
|
||||||
for example if we've got value_size equal 4 and:
|
|
||||||
table[0] = 3
|
|
||||||
table[1] = 4
|
|
||||||
table[2] = 5
|
|
||||||
table[3] = 6
|
|
||||||
then let
|
|
||||||
x1 = 10
|
|
||||||
x2 = 20
|
|
||||||
and
|
|
||||||
index = 1
|
|
||||||
|
|
||||||
the result of this method will be:
|
|
||||||
table[0] = 3
|
|
||||||
table[1] = 4 + x1 = 14
|
|
||||||
table[2] = 5 + x2 = 25
|
|
||||||
table[3] = 6
|
|
||||||
|
|
||||||
and no carry at the end of table[3]
|
|
||||||
|
|
||||||
(of course if there was a carry in table[2](5+20) then
|
|
||||||
this carry would be passed to the table[3] etc.)
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
uint UInt<value_size>::AddTwoInts(uint x2, uint x1, uint index)
|
|
||||||
{
|
|
||||||
register uint b = value_size;
|
|
||||||
register uint * p1 = table;
|
|
||||||
register uint c;
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
__asm__ __volatile__(
|
|
||||||
|
|
||||||
"push %%rbx \n"
|
|
||||||
"push %%rcx \n"
|
|
||||||
"push %%rdx \n"
|
|
||||||
|
|
||||||
"subq %%rdx, %%rcx \n"
|
|
||||||
|
|
||||||
"leaq (%%rbx,%%rdx,8), %%rbx \n"
|
|
||||||
|
|
||||||
"movq $0, %%rdx \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"
|
|
||||||
"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 %%rdx, %%rax \n"
|
|
||||||
"movq %%rax, (%%rbx) \n"
|
|
||||||
|
|
||||||
"jnc 2f \n"
|
|
||||||
|
|
||||||
"loop 1b \n"
|
|
||||||
|
|
||||||
"2: \n"
|
|
||||||
|
|
||||||
"movq $0, %%rax \n"
|
|
||||||
"adcq %%rax,%%rax \n"
|
|
||||||
|
|
||||||
"pop %%rdx \n"
|
|
||||||
"pop %%rcx \n"
|
|
||||||
"pop %%rbx \n"
|
|
||||||
|
|
||||||
: "=a" (c)
|
|
||||||
: "c" (b), "d" (index), "b" (p1), "S" (x1), "D" (x2)
|
|
||||||
: "cc", "memory" );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method's subtracting ss2 from the 'this' and subtracting
|
|
||||||
carry if it has been defined
|
|
||||||
(this = this - ss2 - c)
|
|
||||||
|
|
||||||
***this method is created only on a 64bit platform***
|
|
||||||
|
|
||||||
c must be zero or one (might be a bigger value than 1)
|
|
||||||
function returns carry (1) (if it was)
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
uint UInt<value_size>::Sub(const UInt<value_size> & ss2, uint c)
|
|
||||||
{
|
|
||||||
register uint b = value_size;
|
|
||||||
register uint * p1 = table;
|
|
||||||
register uint * p2 = const_cast<uint*>(ss2.table);
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
__asm__ __volatile__(
|
|
||||||
|
|
||||||
"push %%rbx \n"
|
|
||||||
"push %%rcx \n"
|
|
||||||
"push %%rdx \n"
|
|
||||||
|
|
||||||
"movq $0, %%rax \n"
|
|
||||||
"subq %%rsi, %%rax \n"
|
|
||||||
|
|
||||||
"1: \n"
|
|
||||||
"movq (%%rbx),%%rax \n"
|
|
||||||
"sbbq (%%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"
|
|
||||||
"adcq %%rax,%%rax \n"
|
|
||||||
"movq %%rax, %%rsi \n"
|
|
||||||
|
|
||||||
"pop %%rdx \n"
|
|
||||||
"pop %%rcx \n"
|
|
||||||
"pop %%rbx \n"
|
|
||||||
|
|
||||||
: "=S" (c)
|
|
||||||
: "0" (c), "c" (b), "b" (p1), "d" (p2)
|
|
||||||
: "%rax", "cc", "memory" );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method subtracts one word (at a specific position)
|
|
||||||
and returns a carry (if it was)
|
|
||||||
|
|
||||||
***this method is created only on a 64bit platform***
|
|
||||||
|
|
||||||
if we've got (value_size=3):
|
|
||||||
table[0] = 10;
|
|
||||||
table[1] = 30;
|
|
||||||
table[2] = 5;
|
|
||||||
and we call:
|
|
||||||
SubInt(2,1)
|
|
||||||
then it'll be:
|
|
||||||
table[0] = 10;
|
|
||||||
table[1] = 30 - 2;
|
|
||||||
table[2] = 5;
|
|
||||||
|
|
||||||
of course if there was a carry from table[3] it would be returned
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
uint UInt<value_size>::SubInt(uint value, uint index)
|
|
||||||
{
|
|
||||||
register uint b = value_size;
|
|
||||||
register uint * p1 = table;
|
|
||||||
register uint c;
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
__asm__ __volatile__(
|
|
||||||
|
|
||||||
"push %%rbx \n"
|
|
||||||
"push %%rcx \n"
|
|
||||||
"push %%rdx \n"
|
|
||||||
|
|
||||||
"subq %%rdx, %%rcx \n"
|
|
||||||
|
|
||||||
"leaq (%%rbx,%%rdx,8), %%rbx \n"
|
|
||||||
|
|
||||||
"movq %%rsi, %%rdx \n"
|
|
||||||
"clc \n"
|
|
||||||
"1: \n"
|
|
||||||
|
|
||||||
"movq (%%rbx), %%rax \n"
|
|
||||||
"sbbq %%rdx, %%rax \n"
|
|
||||||
"movq %%rax, (%%rbx) \n"
|
|
||||||
|
|
||||||
"jnc 2f \n"
|
|
||||||
|
|
||||||
"movq $0, %%rdx \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"
|
|
||||||
|
|
||||||
"loop 1b \n"
|
|
||||||
|
|
||||||
"2: \n"
|
|
||||||
|
|
||||||
"movq $0, %%rax \n"
|
|
||||||
"adcq %%rax,%%rax \n"
|
|
||||||
|
|
||||||
"pop %%rdx \n"
|
|
||||||
"pop %%rcx \n"
|
|
||||||
"pop %%rbx \n"
|
|
||||||
|
|
||||||
: "=a" (c)
|
|
||||||
: "c" (b), "d" (index), "b" (p1), "S" (value)
|
|
||||||
: "cc", "memory" );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method moves all bits into the left hand side
|
|
||||||
return value <- this <- c
|
|
||||||
|
|
||||||
the lowest *bits* 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(3, 1) there'll be 010000111 and Rcl2 returns 1
|
|
||||||
|
|
||||||
***this method is created only on a 64bit platform***
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
uint UInt<value_size>::Rcl2(uint bits, uint c)
|
|
||||||
{
|
|
||||||
if( bits == 0 )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
|
||||||
|
|
||||||
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 %%rsi \n"
|
|
||||||
|
|
||||||
|
|
||||||
"2: \n"
|
|
||||||
|
|
||||||
"xorq %%rax,%%rax \n"
|
|
||||||
"subq %%rdx,%%rax \n"
|
|
||||||
|
|
||||||
"push %%rbx \n"
|
|
||||||
"push %%rcx \n"
|
|
||||||
|
|
||||||
"1: \n"
|
|
||||||
"rclq $1,(%%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"
|
|
||||||
|
|
||||||
"loop 1b \n"
|
|
||||||
|
|
||||||
"pop %%rcx \n"
|
|
||||||
"pop %%rbx \n"
|
|
||||||
|
|
||||||
"decq %%rsi \n"
|
|
||||||
|
|
||||||
"jnz 2b \n"
|
|
||||||
|
|
||||||
"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
|
|
||||||
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method moves all bits into the right hand side
|
|
||||||
C -> this -> return value
|
|
||||||
|
|
||||||
the highest *bits* 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(2, 1) there'll be 110000000 and Rcr2 returns 1
|
|
||||||
|
|
||||||
***this method is created only on a 64bit platform***
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
uint UInt<value_size>::Rcr2(uint bits, uint c)
|
|
||||||
{
|
|
||||||
if( bits == 0 )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
|
||||||
|
|
||||||
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 %%rsi \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"
|
|
||||||
|
|
||||||
"loop 1b \n"
|
|
||||||
|
|
||||||
"pop %%rcx \n"
|
|
||||||
"pop %%rbx \n"
|
|
||||||
|
|
||||||
"decq %%rsi \n"
|
|
||||||
|
|
||||||
"jnz 2b \n"
|
|
||||||
|
|
||||||
"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
|
|
||||||
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
this method returns the number of the highest set bit in one 32-bit word
|
|
||||||
if the 'x' is zero this method returns '-1'
|
|
||||||
|
|
||||||
***this method is created only on a 64bit platform***
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
sint UInt<value_size>::FindLeadingBitInWord(uint x)
|
|
||||||
{
|
|
||||||
register sint result;
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
__asm__ __volatile__(
|
|
||||||
|
|
||||||
|
|
||||||
"bsrq %%rbx, %%rax \n"
|
|
||||||
"jnz 1f \n"
|
|
||||||
"movq $-1, %%rax \n"
|
|
||||||
"1: \n"
|
|
||||||
|
|
||||||
: "=a" (result)
|
|
||||||
: "b" (x)
|
|
||||||
: "cc" );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method sets a special bit in the 'value'
|
|
||||||
and returns the result
|
|
||||||
|
|
||||||
***this method is created only on a 64bit platform***
|
|
||||||
|
|
||||||
bit is from <0,31>
|
|
||||||
|
|
||||||
e.g.
|
|
||||||
SetBitInWord(0,0) = 1
|
|
||||||
SetBitInWord(0,2) = 4
|
|
||||||
SetBitInWord(10, 8) = 266
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
uint UInt<value_size>::SetBitInWord(uint value, uint bit)
|
|
||||||
{
|
|
||||||
#ifndef __GNUC__
|
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
__asm__ __volatile__(
|
|
||||||
|
|
||||||
"btsq %%rbx,%%rax \n"
|
|
||||||
|
|
||||||
: "=a" (value)
|
|
||||||
: "0" (value), "b" (bit)
|
|
||||||
: "cc" );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
*
|
|
||||||
* Multiplication
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
multiplication: result2:result1 = a * b
|
|
||||||
result2 - higher word
|
|
||||||
result1 - lower word of the result
|
|
||||||
|
|
||||||
this methos never returns a carry
|
|
||||||
|
|
||||||
***this method is created only on a 64bit platform***
|
|
||||||
|
|
||||||
it is an auxiliary method for version two of the multiplication algorithm
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
void UInt<value_size>::MulTwoWords(uint a, uint b, uint * result2, uint * result1)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
we must use these temporary variables in order to inform the compilator
|
|
||||||
that value pointed with result1 and result2 has changed
|
|
||||||
|
|
||||||
this has no effect in visual studio but it's usefull when
|
|
||||||
using gcc and options like -O
|
|
||||||
*/
|
|
||||||
register uint result1_;
|
|
||||||
register uint result2_;
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
|
|
||||||
"mulq %%rdx \n"
|
|
||||||
|
|
||||||
: "=a" (result1_), "=d" (result2_)
|
|
||||||
: "0" (a), "1" (b)
|
|
||||||
: "cc" );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
*result1 = result1_;
|
|
||||||
*result2 = result2_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
*
|
|
||||||
* Division
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method calculates 64bits word a:b / 32bits c (a higher, b lower word)
|
|
||||||
r = a:b / c and rest - remainder
|
|
||||||
|
|
||||||
***this method is created only on a 64bit platform***
|
|
||||||
|
|
||||||
*
|
|
||||||
* WARNING:
|
|
||||||
* if r (one word) is too small for the result or c is equal zero
|
|
||||||
* there'll be a hardware interruption (0)
|
|
||||||
* and probably the end of your program
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
void UInt<value_size>::DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest)
|
|
||||||
{
|
|
||||||
register uint r_;
|
|
||||||
register uint rest_;
|
|
||||||
/*
|
|
||||||
these variables have similar meaning like those in
|
|
||||||
the multiplication algorithm MulTwoWords
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
|
|
||||||
"divq %%rcx \n"
|
|
||||||
|
|
||||||
: "=a" (r_), "=d" (rest_)
|
|
||||||
: "d" (a), "a" (b), "c" (c)
|
|
||||||
: "cc" );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
*r = r_;
|
|
||||||
*rest = rest_;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} //namespace
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,551 @@
|
||||||
|
;
|
||||||
|
; This file is a part of TTMath Bignum Library
|
||||||
|
; and is distributed under the 3-Clause BSD Licence.
|
||||||
|
; Author: Christian Kaiser <chk@online.de>, Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
; Copyright (c) 2009-2017, Christian Kaiser, 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 Christian Kaiser 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.
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
; compile with debug info: ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
|
||||||
|
; compile without debug info: ml64.exe /c ttmathuint_x86_64_msvc.asm
|
||||||
|
; this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program
|
||||||
|
;
|
||||||
|
|
||||||
|
; doxygen info is put to ttmathuint_x86_64.h file
|
||||||
|
|
||||||
|
|
||||||
|
PUBLIC ttmath_adc_x64
|
||||||
|
PUBLIC ttmath_addindexed_x64
|
||||||
|
PUBLIC ttmath_addindexed2_x64
|
||||||
|
PUBLIC ttmath_addvector_x64
|
||||||
|
|
||||||
|
PUBLIC ttmath_sbb_x64
|
||||||
|
PUBLIC ttmath_subindexed_x64
|
||||||
|
PUBLIC ttmath_subvector_x64
|
||||||
|
|
||||||
|
PUBLIC ttmath_rcl_x64
|
||||||
|
PUBLIC ttmath_rcr_x64
|
||||||
|
|
||||||
|
PUBLIC ttmath_rcl2_x64
|
||||||
|
PUBLIC ttmath_rcr2_x64
|
||||||
|
|
||||||
|
PUBLIC ttmath_div_x64
|
||||||
|
|
||||||
|
;
|
||||||
|
; Microsoft x86_64 convention: http://msdn.microsoft.com/en-us/library/9b372w95.aspx
|
||||||
|
;
|
||||||
|
; "rax, rcx, rdx, r8-r11 are volatile."
|
||||||
|
; "rbx, rbp, rdi, rsi, r12-r15 are nonvolatile."
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
.CODE
|
||||||
|
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_adc_x64 PROC
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = p2
|
||||||
|
; r8 = nSize
|
||||||
|
; r9 = nCarry
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
xor r11, r11
|
||||||
|
sub rax, r9 ; sets CARRY if r9 != 0
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
mov rax,qword ptr [rdx + r11 * 8]
|
||||||
|
adc qword ptr [rcx + r11 * 8], rax
|
||||||
|
lea r11, [r11+1]
|
||||||
|
dec r8
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
setc al
|
||||||
|
movzx rax, al
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_adc_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_addindexed_x64 PROC
|
||||||
|
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = nSize
|
||||||
|
; r8 = nPos
|
||||||
|
; r9 = nValue
|
||||||
|
|
||||||
|
xor rax, rax ; rax = result
|
||||||
|
sub rdx, r8 ; rdx = remaining count of uints
|
||||||
|
|
||||||
|
add qword ptr [rcx + r8 * 8], r9
|
||||||
|
jc next1
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
next1:
|
||||||
|
mov r9, 1
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
dec rdx
|
||||||
|
jz done_with_cy
|
||||||
|
lea r8, [r8+1]
|
||||||
|
add qword ptr [rcx + r8 * 8], r9
|
||||||
|
jc loop1
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
done_with_cy:
|
||||||
|
lea rax, [rax+1] ; rax = 1
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_addindexed_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_addindexed2_x64 PROC
|
||||||
|
|
||||||
|
; rcx = p1 (pointer)
|
||||||
|
; rdx = b (value size)
|
||||||
|
; r8 = nPos
|
||||||
|
; r9 = nValue1
|
||||||
|
; [rsp+0x28] = nValue2
|
||||||
|
|
||||||
|
xor rax, rax ; return value
|
||||||
|
mov r11, rcx ; table
|
||||||
|
sub rdx, r8 ; rdx = remaining count of uints
|
||||||
|
mov r10, [rsp+028h] ; r10 = nValue2
|
||||||
|
|
||||||
|
add qword ptr [r11 + r8 * 8], r9
|
||||||
|
lea r8, [r8+1]
|
||||||
|
lea rdx, [rdx-1]
|
||||||
|
adc qword ptr [r11 + r8 * 8], r10
|
||||||
|
jc next
|
||||||
|
ret
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
lea r8, [r8+1]
|
||||||
|
add qword ptr [r11 + r8 * 8], 1
|
||||||
|
jc next
|
||||||
|
ret
|
||||||
|
|
||||||
|
next:
|
||||||
|
dec rdx ; does not modify CY too...
|
||||||
|
jnz loop1
|
||||||
|
lea rax, [rax+1]
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_addindexed2_x64 ENDP
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
ttmath_addvector_x64 PROC
|
||||||
|
; rcx = ss1
|
||||||
|
; rdx = ss2
|
||||||
|
; r8 = ss1_size
|
||||||
|
; r9 = ss2_size
|
||||||
|
; [rsp+0x28] = result
|
||||||
|
|
||||||
|
mov r10, [rsp+028h]
|
||||||
|
sub r8, r9
|
||||||
|
xor r11, r11 ; r11=0, cf=0
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
mov rax, qword ptr [rcx + r11 * 8]
|
||||||
|
adc rax, qword ptr [rdx + r11 * 8]
|
||||||
|
mov qword ptr [r10 + r11 * 8], rax
|
||||||
|
inc r11
|
||||||
|
dec r9
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
adc r9, r9 ; r9 has the cf state
|
||||||
|
|
||||||
|
or r8, r8
|
||||||
|
jz done
|
||||||
|
|
||||||
|
neg r9 ; setting cf from r9
|
||||||
|
mov r9, 0 ; don't use xor here (cf is used)
|
||||||
|
loop2:
|
||||||
|
mov rax, qword ptr [rcx + r11 * 8]
|
||||||
|
adc rax, r9
|
||||||
|
mov qword ptr [r10 + r11 * 8], rax
|
||||||
|
inc r11
|
||||||
|
dec r8
|
||||||
|
jnz loop2
|
||||||
|
|
||||||
|
adc r8, r8
|
||||||
|
mov rax, r8
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
done:
|
||||||
|
mov rax, r9
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_addvector_x64 ENDP
|
||||||
|
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_sbb_x64 PROC
|
||||||
|
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = p2
|
||||||
|
; r8 = nCount
|
||||||
|
; r9 = nCarry
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
xor r11, r11
|
||||||
|
sub rax, r9 ; sets CARRY if r9 != 0
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
mov rax,qword ptr [rdx + r11 * 8]
|
||||||
|
sbb qword ptr [rcx + r11 * 8], rax
|
||||||
|
lea r11, [r11+1]
|
||||||
|
dec r8
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
setc al
|
||||||
|
movzx rax, al
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_sbb_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_subindexed_x64 PROC
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = nSize
|
||||||
|
; r8 = nPos
|
||||||
|
; r9 = nValue
|
||||||
|
|
||||||
|
sub rdx, r8 ; rdx = remaining count of uints
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
sub qword ptr [rcx + r8 * 8], r9
|
||||||
|
jnc done
|
||||||
|
|
||||||
|
lea r8, [r8+1]
|
||||||
|
mov r9, 1
|
||||||
|
dec rdx
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
mov rax, 1
|
||||||
|
ret
|
||||||
|
|
||||||
|
done:
|
||||||
|
xor rax, rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_subindexed_x64 ENDP
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
; the same asm code as in addvector_x64 only two instructions 'adc' changed to 'sbb'
|
||||||
|
|
||||||
|
ttmath_subvector_x64 PROC
|
||||||
|
; rcx = ss1
|
||||||
|
; rdx = ss2
|
||||||
|
; r8 = ss1_size
|
||||||
|
; r9 = ss2_size
|
||||||
|
; [rsp+0x28] = result
|
||||||
|
|
||||||
|
mov r10, [rsp+028h]
|
||||||
|
sub r8, r9
|
||||||
|
xor r11, r11 ; r11=0, cf=0
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
mov rax, qword ptr [rcx + r11 * 8]
|
||||||
|
sbb rax, qword ptr [rdx + r11 * 8]
|
||||||
|
mov qword ptr [r10 + r11 * 8], rax
|
||||||
|
inc r11
|
||||||
|
dec r9
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
adc r9, r9 ; r9 has the cf state
|
||||||
|
|
||||||
|
or r8, r8
|
||||||
|
jz done
|
||||||
|
|
||||||
|
neg r9 ; setting cf from r9
|
||||||
|
mov r9, 0 ; don't use xor here (cf is used)
|
||||||
|
loop2:
|
||||||
|
mov rax, qword ptr [rcx + r11 * 8]
|
||||||
|
sbb rax, r9
|
||||||
|
mov qword ptr [r10 + r11 * 8], rax
|
||||||
|
inc r11
|
||||||
|
dec r8
|
||||||
|
jnz loop2
|
||||||
|
|
||||||
|
adc r8, r8
|
||||||
|
mov rax, r8
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
done:
|
||||||
|
mov rax, r9
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_subvector_x64 ENDP
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_rcl_x64 PROC
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = b
|
||||||
|
; r8 = nLowestBit
|
||||||
|
|
||||||
|
mov r11, rcx ; table
|
||||||
|
xor r10, r10
|
||||||
|
neg r8 ; CY set if r8 <> 0
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
rcl qword ptr [r11 + r10 * 8], 1
|
||||||
|
lea r10, [r10+1]
|
||||||
|
dec rdx
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
setc al
|
||||||
|
movzx rax, al
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_rcl_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_rcr_x64 PROC
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = nSize
|
||||||
|
; r8 = nLowestBit
|
||||||
|
|
||||||
|
xor r10, r10
|
||||||
|
neg r8 ; CY set if r8 <> 0
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
rcr qword ptr -8[rcx + rdx * 8], 1
|
||||||
|
dec rdx
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
setc al
|
||||||
|
movzx rax, al
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_rcr_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_div_x64 PROC
|
||||||
|
|
||||||
|
; rcx = &Hi
|
||||||
|
; rdx = &Lo
|
||||||
|
; r8 = nDiv
|
||||||
|
|
||||||
|
mov r11, rcx
|
||||||
|
mov r10, rdx
|
||||||
|
|
||||||
|
mov rdx, qword ptr [r11]
|
||||||
|
mov rax, qword ptr [r10]
|
||||||
|
div r8
|
||||||
|
mov qword ptr [r10], rdx ; remainder
|
||||||
|
mov qword ptr [r11], rax ; value
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_div_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_rcl2_x64 PROC
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = nSize
|
||||||
|
; r8 = bits
|
||||||
|
; r9 = c
|
||||||
|
|
||||||
|
push rbx
|
||||||
|
|
||||||
|
mov r10, rcx ; r10 = p1
|
||||||
|
xor rax, rax
|
||||||
|
|
||||||
|
mov rcx, 64
|
||||||
|
sub rcx, r8
|
||||||
|
|
||||||
|
mov r11, -1
|
||||||
|
shr r11, cl ; r11 = mask
|
||||||
|
|
||||||
|
mov rcx, r8 ; rcx = count of bits
|
||||||
|
|
||||||
|
mov rbx, rax ; rbx = old value = 0
|
||||||
|
or r9, r9
|
||||||
|
cmovnz rbx, r11 ; if (c) then old value = mask
|
||||||
|
|
||||||
|
mov r9, rax ; r9 = index (0..nSize-1)
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
rol qword ptr [r10+r9*8], cl
|
||||||
|
mov rax, qword ptr [r10+r9*8]
|
||||||
|
and rax, r11
|
||||||
|
xor qword ptr [r10+r9*8], rax
|
||||||
|
or qword ptr [r10+r9*8], rbx
|
||||||
|
mov rbx, rax
|
||||||
|
|
||||||
|
lea r9, [r9+1]
|
||||||
|
dec rdx
|
||||||
|
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
and rax, 1
|
||||||
|
pop rbx
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_rcl2_x64 ENDP
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ALIGN 8
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
|
||||||
|
ttmath_rcr2_x64 PROC
|
||||||
|
; rcx = p1
|
||||||
|
; rdx = nSize
|
||||||
|
; r8 = bits
|
||||||
|
; r9 = c
|
||||||
|
|
||||||
|
push rbx
|
||||||
|
mov r10, rcx ; r10 = p1
|
||||||
|
xor rax, rax
|
||||||
|
|
||||||
|
mov rcx, 64
|
||||||
|
sub rcx, r8
|
||||||
|
|
||||||
|
mov r11, -1
|
||||||
|
shl r11, cl ; r11 = mask
|
||||||
|
|
||||||
|
mov rcx, r8 ; rcx = count of bits
|
||||||
|
|
||||||
|
mov rbx, rax ; rbx = old value = 0
|
||||||
|
or r9, r9
|
||||||
|
cmovnz rbx, r11 ; if (c) then old value = mask
|
||||||
|
|
||||||
|
mov r9, rdx ; r9 = index (0..nSize-1)
|
||||||
|
lea r9, [r9-1]
|
||||||
|
|
||||||
|
ALIGN 16
|
||||||
|
loop1:
|
||||||
|
ror qword ptr [r10+r9*8], cl
|
||||||
|
mov rax, qword ptr [r10+r9*8]
|
||||||
|
and rax, r11
|
||||||
|
xor qword ptr [r10+r9*8], rax
|
||||||
|
or qword ptr [r10+r9*8], rbx
|
||||||
|
mov rbx, rax
|
||||||
|
|
||||||
|
lea r9, [r9-1]
|
||||||
|
dec rdx
|
||||||
|
|
||||||
|
jnz loop1
|
||||||
|
|
||||||
|
rol rax, 1
|
||||||
|
and rax, 1
|
||||||
|
pop rbx
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
ttmath_rcr2_x64 ENDP
|
||||||
|
|
||||||
|
END
|
|
@ -0,0 +1,9 @@
|
||||||
|
rem make sure this is a proper path to the 64 bit assembler
|
||||||
|
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\ml64.exe" /c ttmathuint_x86_64_msvc.asm
|
||||||
|
rem ml64.exe will produce ttmathuint_x86_64_msvc.obj which should be added (linked) to your project
|
||||||
|
|
||||||
|
rem or you can assemble with debug info
|
||||||
|
rem ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
|
||||||
|
|
||||||
|
rem be nice, most Windows users just click on the file
|
||||||
|
pause
|
Loading…
Reference in New Issue