21 Commits
0.9.2 ... chk

Author SHA1 Message Date
Christian Kaiser
51e938eaa7 - update to current root trunc's version
- update to root trunc's UNICODE support

git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@182 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-07-29 10:46:48 +00:00
Christian Kaiser
e102086f80 - fixed a bug in 64 bit ASM for MSVC
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@181 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-07-28 16:34:04 +00:00
Christian Kaiser
51b2c974a1 - changed "AboutEqualWithoutSign()" to "AboutEqual()" because we need to take the sign into account!
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@173 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-26 15:24:27 +00:00
Christian Kaiser
5597373093 - "streamlined" ttmathconfig.h a bit:
a) Unicode support if TTMATH_USE_WCHAR is set (compiler must know wchar_t etc, of course)
  b) threading synchonisation uses WIN32 instead of __MSVC__ define, as this is OS dependent, not compiler dependent

git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@172 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-26 11:14:51 +00:00
Christian Kaiser
de58378488 - added AboutEqualWithoutSign() to big<> to allow 'suppression' of some unexpected results (that are perfectly logical though, given the possibly unrepresentable nature of binary representation of decimals) like
big<>("10.456466") * 2 == big<>("20.912932")

resulting in FALSE result.

git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@171 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-25 14:11:17 +00:00
Christian Kaiser
de64608eba Merged against the current original ttmath trunk
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@170 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-25 11:07:55 +00:00
Christian Kaiser
be8913866a - 32 bit ASM code and ASSERTS did not work as the ASM code put its result in EAX, but the ASSERT afterwards did destroy the EAX's contents, of course.
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@155 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-28 14:42:19 +00:00
Christian Kaiser
b31d34ebdd - fixed a bug in ttmath.g (missing closing brace in Cos())
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@154 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-28 11:52:31 +00:00
Christian Kaiser
be821b59dd - optimizations
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@153 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-28 11:31:29 +00:00
Christian Kaiser
de1e7ac957 more optimizations for MSVC assembler (parallelism, prefetch optimization, loop alignment, ...)
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@151 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-20 08:48:51 +00:00
Christian Kaiser
fdc292e91a current chk version - too many changes on both sides for now ;-(
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@150 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-19 10:50:41 +00:00
Christian Kaiser
9b576ddbe2 - corrected 64 bit assembler code (ebx was not preserved)
- minor optimization

git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@147 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-15 14:42:43 +00:00
Christian Kaiser
a8c3a506ea MSVC ASM improvements (no register saves necessary, as this is done automatically by the C compiler)
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@146 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-14 12:59:12 +00:00
Christian Kaiser
3ba94dca90 git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@145 e52654a7-88a9-db11-a3e9-0013d4bc506e 2009-05-11 12:30:05 +00:00
Christian Kaiser
cae50cd425 - merged Tomasz' version 0.8.5
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@144 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-11 12:25:25 +00:00
Christian Kaiser
00e39d3608 added thread-safety to static history buffers (factorial and logarithm) for MSVC
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@135 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-07 11:37:10 +00:00
Christian Kaiser
37379d2f1f - fulfills test file log diff (32 and 64 bit)
- macro for issuing the debug output to something else than std::out if specified


git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@134 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-07 09:33:57 +00:00
Christian Kaiser
d7b67e4d47 - minor changes for ASSERT macros
- some more "unification" of 32 and 64 bits in typedefs
- use of 'char' instead of 'unsigned char', as I may hope that 'char' usually is set to 'unsigned' in most development environments

git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@133 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-06 15:47:15 +00:00
Christian Kaiser
c91bd24e98 - support for MS specific code (__int64 etc) and warnings
- support for AMD64 assembler (not thoroughly tested)
- support for UNICODE I/O (strings and streams)

git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@132 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-06 15:11:29 +00:00
Christian Kaiser
cbc12db22f dummy commit (user/password checking)
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@131 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-06 13:24:00 +00:00
3e9bd5b093 creating a chk branch for ChristianK
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@130 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-06 13:16:56 +00:00
22 changed files with 16742 additions and 21627 deletions

235
CHANGELOG
View File

@@ -1,119 +1,15 @@
Version 0.9.2 (2010.09.23): Version 0.9.0 prerelease (2009.07.16):
* fixed: Big::Add() sometimes incorrectly rounded the last bit from its mantissa * added: support for wide characters (wchar_t)
* fixed: Big::BigAnd() Big::BigOr() Big::BigXor() should have set NaN wide characters are used when macro TTMATH_USE_WCHAR is defined
when the argument was negative (they only returned 2) this macro is defined automatically when there is macro UNICODE or _UNICODE defined
* fixed: recurrence calling in Big::FromString(const std::string &, uint, const wchar_t **, bool *) some types have been changed
it should have the signature: Big::FromString(const std::string &, uint, const char **, bool *) char -> tt_char
* fixed: Big::ToString method std::string -> tt_string
in some cases when in the output string the exponent should be equal zero std::ostringstream -> tt_ostringstream
the method changes the exponent to one so the last digit from the mantissa std::ostream -> tt_ostream
was lost std::istream -> tt_istream
* fixed: Big::ToDouble(double &) set always +INF (infinity) normally tt_char is equal char but when you are using wide characters then tt_char will be wchar_t (and so on)
when the value was too large (even for negative values) (all typedef's are in ttmathtypes.h)
(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() * added: Big::IsInteger()
returns true if the value is integer (without fraction) returns true if the value is integer (without fraction)
(NaN flag is not checked) (NaN flag is not checked)
@@ -121,117 +17,10 @@ Version 0.9.0 (2009.11.25):
* added: gamma() function to the parser * added: gamma() function to the parser
* added: CGamma<ValueType> class * added: CGamma<ValueType> class
is used with Gamma() and Factorial() in multithreaded environment 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: 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 * removed: Parser<>::SetFactorialMax() method
the factorial() is such a fast now that we don't need the method longer the factorial() is such a fast now that we don't need the method longer
* removed: ErrorCode::err_too_big_factorial * 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): Version 0.8.5 (2009.06.16):

View File

@@ -1,4 +1,4 @@
Copyright (c) 2006-2010, Tomasz Sowa Copyright (c) 2006-2009, Tomasz Sowa
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

35
README
View File

@@ -1,23 +1,26 @@
A bignum library for C++ TTMath - a bignum library for C++
TTMath is a small library which allows one to perform arithmetic operations TTMath is a small library which allows one to perform arithmetic operations
with big unsigned integer, big signed integer and big floating point numbers. with big unsigned integer, big signed integer and big floating point
It provides standard mathematical operations like adding, subtracting, numbers. It provides standard mathematical operations like adding,
multiplying, dividing. With the library also goes a mathematical parser to subtracting, multiplying, dividing etc. With the library also goes
help you solving mathematical expressions. a mathematical parser which helps you solving input formulas read directly
from a user.
TTMath is developed under the BSD licence which means that it is free for TTMath is developed under the BSD licence which means that it is free
both personal and commercial use. for both personal and commercial use.
The library has some technical limitations:
* there are only two platforms that are supported: x86 and x86_64,
* you can use this library only with the C++ programming language.
The main goal of the library is to allow one to use big values in the same The main goal of the library is to allow one to use big values in the same
way as the standard types like int or float. It does not need to be compiled way as the standard types like int, float, etc. It does not need to be
first because the whole library is written as the C++ templates. This means compiled first because the whole library is written as the C++ templates.
only C++ developers can use this library and one thing they have to do is This means only C++ developers can use this library and one thing they have
to use 'include' directive of the preprocessor. How big the values can be to do is to use 'include' directive of the preprocessor. How big the
is set at compile time. values can be is set directly in the source code by the programmer.
Author: Tomasz Sowa <t.sowa@ttmath.org> Author: Tomasz Sowa <t.sowa@ttmath.org>
WWW: http://www.ttmath.org Project pages: http://www.ttmath.org
http://sourceforge.net/projects/ttmath
Contributors:
Christian Kaiser <chk@online.de>

View File

@@ -31,7 +31,7 @@ PROJECT_NAME = TTMath
# This could be handy for archiving the generated documentation or # This could be handy for archiving the generated documentation or
# if some version control system is used. # if some version control system is used.
PROJECT_NUMBER = 0.9.2 PROJECT_NUMBER = 0.8.2
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put. # base path where the generated documentation will be put.

View File

@@ -1,5 +1,5 @@
CC = g++ CC = g++
CFLAGS = -Wall -pedantic -s -O2 -I.. -DTTMATH_DONT_USE_WCHAR CFLAGS = -Wall -pedantic -s -O2 -I..
.SUFFIXES: .cpp .o .SUFFIXES: .cpp .o
@@ -8,7 +8,7 @@ CFLAGS = -Wall -pedantic -s -O2 -I.. -DTTMATH_DONT_USE_WCHAR
$(CC) -c $(CFLAGS) $< $(CC) -c $(CFLAGS) $<
all: uint int big big2 parser all: uint int big parser
uint: uint.o uint: uint.o
@@ -20,9 +20,6 @@ int: int.o
big: big.o big: big.o
$(CC) -o big $(CFLAGS) big.o $(CC) -o big $(CFLAGS) big.o
big2: big2.o
$(CC) -o big2 $(CFLAGS) big2.o
parser: parser.o parser: parser.o
$(CC) -o parser $(CFLAGS) parser.o $(CC) -o parser $(CFLAGS) parser.o
@@ -30,7 +27,6 @@ parser: 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
@@ -40,7 +36,6 @@ 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 can automatically be added suffixes .exe to the names of output programs
rm -f *.exe rm -f *.exe

View File

@@ -5,10 +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;
void SimpleCalculating(const MyBig & a, const MyBig & b) void SimpleCalculating(const MyBig & a, const MyBig & b)
{ {
@@ -58,7 +56,6 @@ MyBig atemp;
} }
int main() int main()
{ {
MyBig a,b; MyBig a,b;
@@ -88,13 +85,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.27076 a * b = 12193540837712.2708
a / b = 0.00124996654580957646 a / b = 0.0012499665458095765
Calculating with a carry Calculating with a carry
a = 1.6248012560666408782e+646457012 a = 1.624801256070839555e+646457012
b = 456.319999999999993 b = 456.31999999999999
a + b = 1.6248012560666408782e+646457012 a + b = 1.624801256070839555e+646457012
a - b = 1.6248012560666408782e+646457012 a - b = 1.624801256070839555e+646457012
a * b = (carry) a * b = (carry)
a / b = 3.560661939136222174e+646457009 a / b = 3.56066193914542334e+646457009
*/ */

View File

@@ -1,113 +0,0 @@
#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
*/

View File

@@ -29,11 +29,6 @@ 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
*/ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

110
ttmath/ttmathconfig.h Normal file
View File

@@ -0,0 +1,110 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the PNG licence.
* Author: Christian Kaiser <chk@online.de>
*/
/*
Copyright (c) 2009 Christian Kaiser
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#ifndef headerfilettmathconfig
#define headerfilettmathconfig
#pragma once
#include <sstream>
namespace ttmath
{
#if defined(WIN32)
#include <windows.h>
#if defined(_MT)
class clsCrit
{
private:
mutable CRITICAL_SECTION _Crit;
clsCrit(const clsCrit&) // inhibit copy (easy mistake to do; use clsCritObj instead!!!)
{
}
clsCrit& operator=(const clsCrit& rhs); // inhibit assignment
public:
clsCrit(void)
{
InitializeCriticalSection(&_Crit);
}
virtual ~clsCrit(void)
{
DeleteCriticalSection(&_Crit);
}
void Enter(void) const
{
EnterCriticalSection(&_Crit);
}
void Leave(void) const
{
LeaveCriticalSection(&_Crit);
}
};
class clsCritObj
{
private:
const clsCrit& _Crit;
clsCritObj& operator=(const clsCritObj& rhs); // not applicable
public:
clsCritObj(const clsCrit& Sync)
: _Crit(Sync)
{
_Crit.Enter();
}
~clsCritObj(void)
{
_Crit.Leave();
}
};
#define TTMATH_IMPLEMENT_THREADSAFE_OBJ \
private: \
clsCrit CritSect; \
public: \
operator clsCrit&() \
{ \
return(CritSect); \
}
#define TTMATH_USE_THREADSAFE_OBJ(c) clsCritObj lock(c)
#endif
#else // defined(WIN32)
// not Windows world: no threading synchronization for now
#endif
#if !defined(TTMATH_IMPLEMENT_THREADSAFE_OBJ)
// if we don't know about serialization, make it a no-op
#define TTMATH_IMPLEMENT_THREADSAFE_OBJ /* */
#define TTMATH_USE_THREADSAFE_OBJ(c) /* */
#endif
} // namespace
#endif // headerfilettmathconfig

File diff suppressed because it is too large Load Diff

View File

@@ -1,250 +0,0 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) 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

View File

@@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2006-2010, Tomasz Sowa * Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -44,13 +44,13 @@
\brief Mathematic functions. \brief Mathematic functions.
*/ */
#include "ttmathtypes.h"
#include <string> #include <string>
#include <vector> #include <vector>
#include <list> #include <list>
#include <map> #include <map>
#include "ttmathtypes.h"
#include "ttmathmisc.h"
namespace ttmath namespace ttmath
@@ -74,19 +74,19 @@ 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) // (either std::string or std::wstring)
std::string value; tt_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() {}
Item(const std::string & v, int p) : value(v), param(p) {} Item(const tt_string & v, int p) : value(v), param(p) {}
}; };
// 'Table' is the type of our table // 'Table' is the type of our table
typedef std::map<std::string, Item> Table; typedef std::map<tt_string, Item> Table;
typedef Table::iterator Iterator; typedef Table::iterator Iterator;
typedef Table::const_iterator CIterator; typedef Table::const_iterator CIterator;
@@ -114,8 +114,7 @@ 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
*/ */
template<class string_type> static bool IsNameCorrect(const tt_string & name)
static bool IsNameCorrect(const string_type & name)
{ {
if( name.empty() ) if( name.empty() )
return false; return false;
@@ -123,7 +122,7 @@ public:
if( !CorrectCharacter(name[0], false) ) if( !CorrectCharacter(name[0], false) )
return false; return false;
typename string_type::const_iterator i = name.begin(); tt_string::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) )
@@ -136,7 +135,7 @@ public:
/*! /*!
this method returns true if such an object is defined (name exists) this method returns true if such an object is defined (name exists)
*/ */
bool IsDefined(const std::string & name) bool IsDefined(const tt_string & name)
{ {
Iterator i = table.find(name); Iterator i = table.find(name);
@@ -148,31 +147,10 @@ public:
} }
#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
*/ */
ErrorCode Add(const std::string & name, const std::string & value, int param = 0) ErrorCode Add(const tt_string & name, const tt_string & value, int param = 0)
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -189,27 +167,6 @@ 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
*/ */
@@ -250,7 +207,7 @@ public:
/*! /*!
this method changes the value and the number of parameters for a specific object this method changes the value and the number of parameters for a specific object
*/ */
ErrorCode EditValue(const std::string & name, const std::string & value, int param = 0) ErrorCode EditValue(const tt_string & name, const tt_string & value, int param = 0)
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -267,32 +224,10 @@ 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
*/ */
ErrorCode EditName(const std::string & old_name, const std::string & new_name) ErrorCode EditName(const tt_string & old_name, const tt_string & new_name)
{ {
if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) ) if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
return err_incorrect_name; return err_incorrect_name;
@@ -320,33 +255,10 @@ 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
*/ */
ErrorCode Delete(const std::string & name) ErrorCode Delete(const tt_string & name)
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -362,31 +274,10 @@ public:
} }
#ifndef TTMATH_DONT_USE_WCHAR
/*!
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 this method gets the value of a specific object
*/ */
ErrorCode GetValue(const std::string & name, std::string & value) const ErrorCode GetValue(const tt_string & name, tt_string & value) const
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -405,33 +296,11 @@ public:
} }
#ifndef TTMATH_DONT_USE_WCHAR
/*!
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 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 tt_string & name, const tt_char ** value) const
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -450,32 +319,11 @@ public:
} }
#ifndef TTMATH_DONT_USE_WCHAR
/*!
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 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 tt_string & name, tt_string & value, int * param) const
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -496,35 +344,12 @@ 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
(this version is used for not copying the whole string) (this version is used for not copying the whole string)
*/ */
ErrorCode GetValueAndParam(const std::string & name, const char ** value, int * param) const ErrorCode GetValueAndParam(const tt_string & name, const tt_char ** value, int * param) const
{ {
if( !IsNameCorrect(name) ) if( !IsNameCorrect(name) )
return err_incorrect_name; return err_incorrect_name;
@@ -545,31 +370,6 @@ 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
*/ */
@@ -582,7 +382,6 @@ public:
private: private:
Table table; Table table;
std::string str_tmp1, str_tmp2;
}; // end of class Objects }; // end of class Objects
@@ -629,7 +428,7 @@ public:
/*! /*!
default constructor default constructor
default max size of the History's container is 15 items default max size of the History's container is 10 items
*/ */
History() History()
{ {
@@ -792,8 +591,8 @@ struct CGamma
you don't have to call this method, these coefficients will be automatically calculated you don't have to call this method, these coefficients will be automatically calculated
when they are needed when they are needed
you must note that calculating these coefficients is a little time-consuming operation, you must note that calculating of the coefficients is a little time-consuming operation,
(especially when the mantissa is large) and first call to Gamma() or Factorial() (especially when the mantissa is large) and first called to Gamma() or Factorial()
can take more time than next calls, and in the end this is the point when InitAll() 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 comes in handy: you can call this method somewhere at the beginning of your program
*/ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,250 +0,0 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) 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
*/
/*
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)
*/
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;
/*!
objects of this class are used to synchronize
*/
class ThreadLock
{
public:
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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2006-2010, Tomasz Sowa * Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,8 @@
#ifdef TTMATH_NOASM #ifdef TTMATH_NOASM
#pragma message("TTMATH_NOASM")
/*! /*!
\file ttmathuint_noasm.h \file ttmathuint_noasm.h
\brief template class UInt<uint> with methods without any assembler code \brief template class UInt<uint> with methods without any assembler code
@@ -51,56 +53,6 @@
namespace ttmath namespace ttmath
{ {
/*!
returning the string 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
*/
template<uint value_size>
const char * UInt<value_size>::LibTypeStr()
{
#ifdef TTMATH_PLATFORM32
static const char info[] = "no_asm_32";
#endif
#ifdef TTMATH_PLATFORM64
static const char info[] = "no_asm_64";
#endif
return info;
}
/*!
returning the currect type of the library
*/
template<uint value_size>
LibTypeCode UInt<value_size>::LibType()
{
#ifdef TTMATH_PLATFORM32
LibTypeCode info = no_asm_32;
#endif
#ifdef TTMATH_PLATFORM64
LibTypeCode info = no_asm_64;
#endif
return info;
}
/*!
this method adds two words together
returns carry
this method is created only when TTMATH_NOASM macro is defined
*/
template<uint value_size> template<uint value_size>
uint UInt<value_size>::AddTwoWords(uint a, uint b, uint carry, uint * result) uint UInt<value_size>::AddTwoWords(uint a, uint b, uint carry, uint * result)
{ {
@@ -145,7 +97,7 @@ namespace ttmath
for(i=0 ; i<value_size ; ++i) for(i=0 ; i<value_size ; ++i)
c = AddTwoWords(table[i], ss2.table[i], c, &table[i]); c = AddTwoWords(table[i], ss2.table[i], c, &table[i]);
TTMATH_LOGC("UInt::Add", c) TTMATH_LOG("UInt::Add")
return c; return c;
} }
@@ -181,7 +133,7 @@ namespace ttmath
for(i=index+1 ; i<value_size && c ; ++i) for(i=index+1 ; i<value_size && c ; ++i)
c = AddTwoWords(table[i], 0, c, &table[i]); c = AddTwoWords(table[i], 0, c, &table[i]);
TTMATH_LOGC("UInt::AddInt", c) TTMATH_LOG("UInt::AddInt")
return c; return c;
} }
@@ -234,7 +186,7 @@ namespace ttmath
for(i=index+2 ; i<value_size && c ; ++i) for(i=index+2 ; i<value_size && c ; ++i)
c = AddTwoWords(table[i], 0, c, &table[i]); c = AddTwoWords(table[i], 0, c, &table[i]);
TTMATH_LOGC("UInt::AddTwoInts", c) TTMATH_LOG("UInt::AddTwoInts")
return c; return c;
} }
@@ -274,7 +226,7 @@ namespace ttmath
for( ; i<ss1_size ; ++i) for( ; i<ss1_size ; ++i)
c = AddTwoWords(ss1[i], 0, c, &result[i]); c = AddTwoWords(ss1[i], 0, c, &result[i]);
TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size) TTMATH_LOG("UInt::AddVector")
return c; return c;
} }
@@ -282,12 +234,6 @@ namespace ttmath
/*!
this method subtractes one word from the other
returns carry
this method is created only when TTMATH_NOASM macro is defined
*/
template<uint value_size> template<uint value_size>
uint UInt<value_size>::SubTwoWords(uint a, uint b, uint carry, uint * result) uint UInt<value_size>::SubTwoWords(uint a, uint b, uint carry, uint * result)
{ {
@@ -329,7 +275,7 @@ namespace ttmath
for(i=0 ; i<value_size ; ++i) for(i=0 ; i<value_size ; ++i)
c = SubTwoWords(table[i], ss2.table[i], c, &table[i]); c = SubTwoWords(table[i], ss2.table[i], c, &table[i]);
TTMATH_LOGC("UInt::Sub", c) TTMATH_LOG("UInt::Sub")
return c; return c;
} }
@@ -367,7 +313,7 @@ namespace ttmath
for(i=index+1 ; i<value_size && c ; ++i) for(i=index+1 ; i<value_size && c ; ++i)
c = SubTwoWords(table[i], 0, c, &table[i]); c = SubTwoWords(table[i], 0, c, &table[i]);
TTMATH_LOGC("UInt::SubInt", c) TTMATH_LOG("UInt::SubInt")
return c; return c;
} }
@@ -407,7 +353,7 @@ namespace ttmath
for( ; i<ss1_size ; ++i) for( ; i<ss1_size ; ++i)
c = SubTwoWords(ss1[i], 0, c, &result[i]); c = SubTwoWords(ss1[i], 0, c, &result[i]);
TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size) TTMATH_LOG("UInt::SubVector")
return c; return c;
} }
@@ -441,7 +387,7 @@ namespace ttmath
c = new_c; c = new_c;
} }
TTMATH_LOGC("UInt::Rcl2_one", c) TTMATH_LOG("UInt::Rcl2_one")
return c; return c;
} }
@@ -480,9 +426,7 @@ namespace ttmath
c = new_c; c = new_c;
} }
c = (c != 0)? 1 : 0; TTMATH_LOG("UInt::Rcr2_one")
TTMATH_LOGC("UInt::Rcr2_one", c)
return c; return c;
} }
@@ -520,7 +464,7 @@ namespace ttmath
c = new_c; c = new_c;
} }
TTMATH_LOGC("UInt::Rcl2", (c & 1)) TTMATH_LOG("UInt::Rcl2")
return (c & 1); return (c & 1);
} }
@@ -559,19 +503,18 @@ namespace ttmath
c = new_c; c = new_c;
} }
c = (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0; TTMATH_LOG("UInt::Rcr2")
TTMATH_LOGC("UInt::Rcr2", c) return (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
return c;
} }
/*! /*
this method returns the number of the highest set bit in x this method returns the number of the highest set bit in x
if the 'x' is zero this method returns '-1' if the 'x' is zero this method returns '-1'
*/ */
template<uint value_size> template<uint value_size>
sint UInt<value_size>::FindLeadingBitInWord(uint x) sint UInt<value_size>::FindLeadingBitInWord(uint x)
@@ -592,34 +535,13 @@ namespace ttmath
/*!
this method returns the number of the highest set bit in x
if the 'x' is zero this method returns '-1'
*/
template<uint value_size>
sint UInt<value_size>::FindLowestBitInWord(uint x)
{
if( x == 0 )
return -1;
uint bit = 0;
while( (x & 1) == 0 )
{
x = x >> 1;
++bit;
}
return bit;
}
/*! /*!
this method sets a special bit in the 'value' this method sets a special bit in the 'value'
and returns the last state of the bit (zero or one) and returns the last state of the bit (zero or one)
bit is from <0,TTMATH_BITS_PER_UINT-1> bit is from <0,63>
e.g. e.g.
uint x = 100; uint x = 100;
@@ -633,7 +555,7 @@ namespace ttmath
uint mask = 1; uint mask = 1;
if( bit > 0 ) if( bit > 1 )
mask = mask << bit; mask = mask << bit;
uint last = value & mask; uint last = value & mask;
@@ -821,11 +743,11 @@ namespace ttmath
temp1.u_.high = a_.u_.low; temp1.u_.high = a_.u_.low;
temp1.u_.low = b_.u_.high; temp1.u_.low = b_.u_.high;
res_.u_.high = (unsigned int)(temp1.u / c); res_.u_.high = temp1.u / c;
temp2.u_.high = (unsigned int)(temp1.u % c); temp2.u_.high = temp1.u % c;
temp2.u_.low = b_.u_.low; temp2.u_.low = b_.u_.low;
res_.u_.low = (unsigned int)(temp2.u / c); res_.u_.low = temp2.u / c;
*rest = temp2.u % c; *rest = temp2.u % c;
*r = res_.u; *r = res_.u;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,548 +1,386 @@
; PUBLIC adc_x64
; This file is a part of TTMath Bignum Library PUBLIC addindexed_x64
; and is distributed under the (new) BSD licence. PUBLIC addindexed2_x64
; Author: Christian Kaiser <chk@online.de>
; PUBLIC sbb_x64
PUBLIC subindexed_x64
;
; Copyright (c) 2009, Christian Kaiser PUBLIC rcl_x64
; All rights reserved. PUBLIC rcr_x64
;
; Redistribution and use in source and binary forms, with or without PUBLIC rcl2_x64
; modification, are permitted provided that the following conditions are met: PUBLIC rcr2_x64
;
; * Redistributions of source code must retain the above copyright notice, PUBLIC div_x64
; this list of conditions and the following disclaimer.
; ;
; * Redistributions in binary form must reproduce the above copyright ; "rax, rcx, rdx, r8-r11 are volatile."
; notice, this list of conditions and the following disclaimer in the ; "rbx, rbp, rdi, rsi, r12-r15 are nonvolatile."
; documentation and/or other materials provided with the distribution. ;
;
; * Neither the name Christian Kaiser nor the names of contributors to this .CODE
; project may be used to endorse or promote products derived
; from this software without specific prior written permission. ALIGN 8
;
; 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 adc_x64 PROC
; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ; rcx = p1
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ; rdx = p2
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ; r8 = nSize
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ; r9 = nCarry
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) xor rax, rax
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF xor r11, r11
; THE POSSIBILITY OF SUCH DAMAGE. sub rax, r9 ; sets CARRY if r9 != 0
;
ALIGN 16
; loop1:
; compile with debug info: ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm mov rax,qword ptr [rdx + r11 * 8]
; compile without debug info: ml64.exe /c ttmathuint_x86_64_msvc.asm adc qword ptr [rcx + r11 * 8], rax
; this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program lea r11, [r11+1]
; dec r8
jnz loop1
PUBLIC ttmath_adc_x64
PUBLIC ttmath_addindexed_x64 setc al
PUBLIC ttmath_addindexed2_x64 movzx rax, al
PUBLIC ttmath_addvector_x64
ret
PUBLIC ttmath_sbb_x64
PUBLIC ttmath_subindexed_x64 adc_x64 ENDP
PUBLIC ttmath_subvector_x64
;----------------------------------------
PUBLIC ttmath_rcl_x64
PUBLIC ttmath_rcr_x64 ALIGN 8
PUBLIC ttmath_rcl2_x64 ;----------------------------------------
PUBLIC ttmath_rcr2_x64
addindexed_x64 PROC
PUBLIC ttmath_div_x64
; rcx = p1
; ; rdx = nSize
; Microsoft x86_64 convention: http://msdn.microsoft.com/en-us/library/9b372w95.aspx ; r8 = nPos
; ; r9 = nValue
; "rax, rcx, rdx, r8-r11 are volatile."
; "rbx, rbp, rdi, rsi, r12-r15 are nonvolatile." xor rax, rax ; rax = result
; sub rdx, r8 ; rdx = remaining count of uints
add qword ptr [rcx + r8 * 8], r9
.CODE jc next1
ret
ALIGN 8
next1:
;---------------------------------------- mov r9, 1
ttmath_adc_x64 PROC ALIGN 16
; rcx = p1 loop1:
; rdx = p2 dec rdx
; r8 = nSize jz done_with_cy
; r9 = nCarry lea r8, [r8+1]
add qword ptr [rcx + r8 * 8], r9
xor rax, rax jc loop1
xor r11, r11
sub rax, r9 ; sets CARRY if r9 != 0 ret
ALIGN 16 done_with_cy:
loop1: lea rax, [rax+1] ; rax = 1
mov rax,qword ptr [rdx + r11 * 8]
adc qword ptr [rcx + r11 * 8], rax ret
lea r11, [r11+1]
dec r8 addindexed_x64 ENDP
jnz loop1
;----------------------------------------
setc al
movzx rax, al ALIGN 8
ret ;----------------------------------------
ttmath_adc_x64 ENDP addindexed2_x64 PROC
;---------------------------------------- ; rcx = p1 (pointer)
; rdx = b (value size)
ALIGN 8 ; r8 = nPos
; r9 = nValue1
;---------------------------------------- ; [esp+0x28] = nValue2
ttmath_addindexed_x64 PROC xor rax, rax ; return value
mov r11, rcx ; table
; rcx = p1 sub rdx, r8 ; rdx = remaining count of uints
; rdx = nSize mov r10, [esp+028h] ; r10 = nValue2
; r8 = nPos
; r9 = nValue add qword ptr [r11 + r8 * 8], r9
lea r8, [r8+1]
xor rax, rax ; rax = result lea rdx, [rdx-1]
sub rdx, r8 ; rdx = remaining count of uints adc qword ptr [r11 + r8 * 8], r10
jc next
add qword ptr [rcx + r8 * 8], r9 ret
jc next1
ALIGN 16
ret loop1:
lea r8, [r8+1]
next1: add qword ptr [r11 + r8 * 8], 1
mov r9, 1 jc next
ret
ALIGN 16
loop1: next:
dec rdx dec rdx ; does not modify CY too...
jz done_with_cy jnz loop1
lea r8, [r8+1] lea rax, [rax+1]
add qword ptr [rcx + r8 * 8], r9 ret
jc loop1
addindexed2_x64 ENDP
ret
;----------------------------------------
done_with_cy:
lea rax, [rax+1] ; rax = 1 ALIGN 8
ret ;----------------------------------------
ttmath_addindexed_x64 ENDP sbb_x64 PROC
;---------------------------------------- ; rcx = p1
; rdx = p2
ALIGN 8 ; r8 = nCount
; r9 = nCarry
;----------------------------------------
xor rax, rax
ttmath_addindexed2_x64 PROC xor r11, r11
sub rax, r9 ; sets CARRY if r9 != 0
; rcx = p1 (pointer)
; rdx = b (value size) ALIGN 16
; r8 = nPos loop1:
; r9 = nValue1 mov rax,qword ptr [rdx + r11 * 8]
; [esp+0x28] = nValue2 sbb qword ptr [rcx + r11 * 8], rax
lea r11, [r11+1]
xor rax, rax ; return value dec r8
mov r11, rcx ; table jnz loop1
sub rdx, r8 ; rdx = remaining count of uints
mov r10, [esp+028h] ; r10 = nValue2 setc al
movzx rax, al
add qword ptr [r11 + r8 * 8], r9
lea r8, [r8+1] ret
lea rdx, [rdx-1]
adc qword ptr [r11 + r8 * 8], r10 sbb_x64 ENDP
jc next
ret ;----------------------------------------
ALIGN 16 ALIGN 8
loop1:
lea r8, [r8+1] ;----------------------------------------
add qword ptr [r11 + r8 * 8], 1
jc next subindexed_x64 PROC
ret ; rcx = p1
; rdx = nSize
next: ; r8 = nPos
dec rdx ; does not modify CY too... ; r9 = nValue
jnz loop1
lea rax, [rax+1] sub rdx, r8 ; rdx = remaining count of uints
ret
ALIGN 16
ttmath_addindexed2_x64 ENDP loop1:
sub qword ptr [rcx + r8 * 8], r9
jnc done
;---------------------------------------- lea r8, [r8+1]
mov r9, 1
ALIGN 8 dec rdx
jnz loop1
;---------------------------------------- jc return_1 ; most of the times, there will be NO carry (I hope)
done:
ttmath_addvector_x64 PROC xor rax, rax
; rcx = ss1 ret
; rdx = ss2
; r8 = ss1_size return_1:
; r9 = ss2_size mov rax, 1
; [esp+0x28] = result ret
mov r10, [esp+028h] subindexed_x64 ENDP
sub r8, r9
xor r11, r11 ; r11=0, cf=0 ;----------------------------------------
ALIGN 16 ALIGN 8
loop1:
mov rax, qword ptr [rcx + r11 * 8] ;----------------------------------------
adc rax, qword ptr [rdx + r11 * 8]
mov qword ptr [r10 + r11 * 8], rax rcl_x64 PROC
inc r11 ; rcx = p1
dec r9 ; rdx = b
jnz loop1 ; r8 = nLowestBit
adc r9, r9 ; r9 has the cf state mov r11, rcx ; table
xor r10, r10
or r8, r8 neg r8 ; CY set if r8 <> 0
jz done
ALIGN 16
neg r9 ; setting cf from r9 loop1:
mov r9, 0 ; don't use xor here (cf is used) rcl qword ptr [r11 + r10 * 8], 1
loop2: lea r10, [r10+1]
mov rax, qword ptr [rcx + r11 * 8] dec rdx
adc rax, r9 jnz loop1
mov qword ptr [r10 + r11 * 8], rax
inc r11 setc al
dec r8 movzx rax, al
jnz loop2
ret
adc r8, r8
mov rax, r8 rcl_x64 ENDP
ret ;----------------------------------------
done: ALIGN 8
mov rax, r9
ret ;----------------------------------------
ttmath_addvector_x64 ENDP rcr_x64 PROC
; rcx = p1
; rdx = nSize
;---------------------------------------- ; r8 = nLowestBit
ALIGN 8 xor r10, r10
neg r8 ; CY set if r8 <> 0
;----------------------------------------
ALIGN 16
ttmath_sbb_x64 PROC loop1:
rcr qword ptr -8[rcx + rdx * 8], 1
; rcx = p1 dec rdx
; rdx = p2 jnz loop1
; r8 = nCount
; r9 = nCarry setc al
movzx rax, al
xor rax, rax
xor r11, r11 ret
sub rax, r9 ; sets CARRY if r9 != 0
rcr_x64 ENDP
ALIGN 16
loop1: ;----------------------------------------
mov rax,qword ptr [rdx + r11 * 8]
sbb qword ptr [rcx + r11 * 8], rax ALIGN 8
lea r11, [r11+1]
dec r8 ;----------------------------------------
jnz loop1
div_x64 PROC
setc al
movzx rax, al ; rcx = &Hi
; rdx = &Lo
ret ; r8 = nDiv
ttmath_sbb_x64 ENDP mov r11, rcx
mov r10, rdx
;----------------------------------------
mov rdx, qword ptr [r11]
ALIGN 8 mov rax, qword ptr [r10]
div r8
;---------------------------------------- mov qword ptr [r10], rdx ; remainder
mov qword ptr [r11], rax ; value
ttmath_subindexed_x64 PROC
; rcx = p1 ret
; rdx = nSize
; r8 = nPos div_x64 ENDP
; r9 = nValue
;----------------------------------------
sub rdx, r8 ; rdx = remaining count of uints
ALIGN 8
ALIGN 16
loop1: ;----------------------------------------
sub qword ptr [rcx + r8 * 8], r9
jnc done rcl2_x64 PROC
; rcx = p1
lea r8, [r8+1] ; rdx = nSize
mov r9, 1 ; r8 = bits
dec rdx ; r9 = c
jnz loop1
push rbx
mov rax, 1
ret mov r10, rcx ; r10 = p1
xor rax, rax
done:
xor rax, rax mov rcx, 64
ret sub rcx, r8
ttmath_subindexed_x64 ENDP mov r11, -1
shr r11, cl ; r11 = mask
mov rcx, r8 ; rcx = count of bits
;----------------------------------------
mov rbx, rax ; rbx = old value = 0
ALIGN 8 or r9, r9
cmovnz rbx, r11 ; if (c) then old value = mask
;----------------------------------------
mov r9, rax ; r9 = index (0..nSize-1)
; the same asm code as in addvector_x64 only two instructions 'adc' changed to 'sbb'
ALIGN 16
ttmath_subvector_x64 PROC loop1:
; rcx = ss1 rol qword ptr [r10+r9*8], cl
; rdx = ss2 mov rax, qword ptr [r10+r9*8]
; r8 = ss1_size and rax, r11
; r9 = ss2_size xor qword ptr [r10+r9*8], rax
; [esp+0x28] = result or qword ptr [r10+r9*8], rbx
mov rbx, rax
mov r10, [esp+028h]
sub r8, r9 lea r9, [r9+1]
xor r11, r11 ; r11=0, cf=0 dec rdx
ALIGN 16 jnz loop1
loop1:
mov rax, qword ptr [rcx + r11 * 8] and rax, 1
sbb rax, qword ptr [rdx + r11 * 8] pop rbx
mov qword ptr [r10 + r11 * 8], rax ret
inc r11
dec r9 rcl2_x64 ENDP
jnz loop1
;----------------------------------------
adc r9, r9 ; r9 has the cf state
ALIGN 8
or r8, r8
jz done ;----------------------------------------
neg r9 ; setting cf from r9 rcr2_x64 PROC
mov r9, 0 ; don't use xor here (cf is used) ; rcx = p1
loop2: ; rdx = nSize
mov rax, qword ptr [rcx + r11 * 8] ; r8 = bits
sbb rax, r9 ; r9 = c
mov qword ptr [r10 + r11 * 8], rax
inc r11 push rbx
dec r8 mov r10, rcx ; r10 = p1
jnz loop2 xor rax, rax
adc r8, r8 mov rcx, 64
mov rax, r8 sub rcx, r8
ret mov r11, -1
shl r11, cl ; r11 = mask
done:
mov rax, r9 mov rcx, r8 ; rcx = count of bits
ret
mov rbx, rax ; rbx = old value = 0
ttmath_subvector_x64 ENDP 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
ALIGN 8 loop1:
ror qword ptr [r10+r9*8], cl
;---------------------------------------- mov rax, qword ptr [r10+r9*8]
and rax, r11
ttmath_rcl_x64 PROC xor qword ptr [r10+r9*8], rax
; rcx = p1 or qword ptr [r10+r9*8], rbx
; rdx = b mov rbx, rax
; r8 = nLowestBit
lea r9, [r9-1]
mov r11, rcx ; table dec rdx
xor r10, r10
neg r8 ; CY set if r8 <> 0 jnz loop1
ALIGN 16 rol rax, 1
loop1: and rax, 1
rcl qword ptr [r11 + r10 * 8], 1 pop rbx
lea r10, [r10+1]
dec rdx ret
jnz loop1
rcr2_x64 ENDP
setc al
movzx rax, al END
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