Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
5584adb23d | |||
a4bb0b6f64 | |||
e046aba6d2 | |||
5ef27bdbd0 | |||
b80f73f16b |
129
CHANGELOG
129
CHANGELOG
@@ -1,132 +1,3 @@
|
|||||||
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):
|
Version 0.8.6 (2009.10.25):
|
||||||
* fixed: UInt::SetBitInWord(uint & value, uint bit) set 1 if the bit was
|
* fixed: UInt::SetBitInWord(uint & value, uint bit) set 1 if the bit was
|
||||||
equal 1 (should be set 2)
|
equal 1 (should be set 2)
|
||||||
|
@@ -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
35
README
@@ -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>
|
|
||||||
|
@@ -8,7 +8,7 @@ CFLAGS = -Wall -pedantic -s -O2 -I..
|
|||||||
$(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
|
||||||
|
@@ -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;
|
||||||
@@ -89,12 +86,12 @@ 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.2708
|
||||||
a / b = 0.00124996654580957646
|
a / b = 0.0012499665458095765
|
||||||
Calculating with a carry
|
Calculating with a carry
|
||||||
a = 1.624801256066640878e+646457012
|
a = 1.624801256070839555e+646457012
|
||||||
b = 456.319999999999993
|
b = 456.31999999999999
|
||||||
a + b = 1.624801256066640878e+646457012
|
a + b = 1.624801256070839555e+646457012
|
||||||
a - b = 1.624801256066640878e+646457012
|
a - b = 1.624801256070839555e+646457012
|
||||||
a * b = (carry)
|
a * b = (carry)
|
||||||
a / b = 3.560661939136222174e+646457009
|
a / b = 3.56066193914542334e+646457009
|
||||||
*/
|
*/
|
||||||
|
113
samples/big2.cpp
113
samples/big2.cpp
@@ -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.001249966545809576460596448526166860913
|
|
||||||
Calculating with a carry
|
|
||||||
a = 2.3495345545711177736883282090959505003e+2776511644261678604
|
|
||||||
b = 456.3199999999999931787897367030382156
|
|
||||||
a + b = 2.3495345545711177736883282090959505003e+2776511644261678604
|
|
||||||
a - b = 2.3495345545711177736883282090959505003e+2776511644261678604
|
|
||||||
a * b = (carry)
|
|
||||||
a / b = 5.1488748127873374141170361292780486452e+2776511644261678601
|
|
||||||
*/
|
|
@@ -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.52573107
|
-897705014.52573107
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
the result (on 64 bit platform):
|
|
||||||
-897705014.5257310676097719585259773124
|
|
||||||
*/
|
|
||||||
|
1120
ttmath/ttmath.h
1120
ttmath/ttmath.h
File diff suppressed because it is too large
Load Diff
1745
ttmath/ttmathbig.h
1745
ttmath/ttmathbig.h
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the (new) BSD licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -468,64 +468,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
division this = this / ss2 (ss2 is int)
|
|
||||||
returned values:
|
|
||||||
0 - ok
|
|
||||||
1 - division by zero
|
|
||||||
|
|
||||||
for example: (result means 'this')
|
|
||||||
20 / 3 --> result: 6 remainder: 2
|
|
||||||
-20 / 3 --> result: -6 remainder: -2
|
|
||||||
20 / -3 --> result: -6 remainder: 2
|
|
||||||
-20 / -3 --> result: 6 remainder: -2
|
|
||||||
|
|
||||||
in other words: this(old) = ss2 * this(new)(result) + remainder
|
|
||||||
*/
|
|
||||||
uint DivInt(sint ss2, sint * remainder = 0)
|
|
||||||
{
|
|
||||||
bool ss1_is_sign, ss2_is_sign;
|
|
||||||
|
|
||||||
ss1_is_sign = IsSign();
|
|
||||||
|
|
||||||
/*
|
|
||||||
we don't have to test the carry from Abs as well as in Mul
|
|
||||||
*/
|
|
||||||
Abs();
|
|
||||||
|
|
||||||
if( ss2 < 0 )
|
|
||||||
{
|
|
||||||
ss2 = -ss2;
|
|
||||||
ss2_is_sign = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ss2_is_sign = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint rem;
|
|
||||||
uint c = UInt<value_size>::DivInt((uint)ss2, &rem);
|
|
||||||
|
|
||||||
if( ss1_is_sign != ss2_is_sign )
|
|
||||||
SetSign();
|
|
||||||
|
|
||||||
if( remainder )
|
|
||||||
{
|
|
||||||
if( ss1_is_sign )
|
|
||||||
*remainder = -sint(rem);
|
|
||||||
else
|
|
||||||
*remainder = sint(rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint DivInt(sint ss2, sint & remainder)
|
|
||||||
{
|
|
||||||
return DivInt(ss2, &remainder);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -572,7 +514,7 @@ public:
|
|||||||
return Pow2(pow);
|
return Pow2(pow);
|
||||||
|
|
||||||
if( UInt<value_size>::IsZero() )
|
if( UInt<value_size>::IsZero() )
|
||||||
// if 'pow' is negative then
|
// if 'p' is negative then
|
||||||
// 'this' must be different from zero
|
// 'this' must be different from zero
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
@@ -592,7 +534,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* convertion methods
|
* convertion methods
|
||||||
@@ -886,15 +827,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
a constructor for converting string to this class (with the base=10)
|
|
||||||
*/
|
|
||||||
Int(const wchar_t * s)
|
|
||||||
{
|
|
||||||
FromString(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting a string to this class (with the base=10)
|
a constructor for converting a string to this class (with the base=10)
|
||||||
*/
|
*/
|
||||||
@@ -904,15 +836,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
a constructor for converting a string to this class (with the base=10)
|
|
||||||
*/
|
|
||||||
Int(const std::wstring & s)
|
|
||||||
{
|
|
||||||
FromString( s.c_str() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a default constructor
|
a default constructor
|
||||||
|
|
||||||
@@ -943,13 +866,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
an auxiliary method for converting to a string
|
this method converts the value to a string with a base equal 'b'
|
||||||
*/
|
*/
|
||||||
template<class string_type>
|
void ToString(std::string & result, uint b = 10) const
|
||||||
void ToStringBase(string_type & result, uint b = 10) const
|
|
||||||
{
|
{
|
||||||
if( IsSign() )
|
if( IsSign() )
|
||||||
{
|
{
|
||||||
@@ -965,71 +885,40 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method converts the value to a string with a base equal 'b'
|
|
||||||
*/
|
|
||||||
void ToString(std::string & result, uint b = 10) const
|
|
||||||
{
|
|
||||||
return ToStringBase(result, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method converts the value to a string with a base equal 'b'
|
|
||||||
*/
|
|
||||||
void ToString(std::wstring & result, uint b = 10) const
|
|
||||||
{
|
|
||||||
return ToStringBase(result, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method converts the value to a string with a base equal 'b'
|
|
||||||
*/
|
|
||||||
std::string ToString(uint b = 10) const
|
|
||||||
{
|
|
||||||
std::string result;
|
|
||||||
ToStringBase(result, b);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method converts the value to a string with a base equal 'b'
|
|
||||||
*/
|
|
||||||
std::wstring ToWString(uint b = 10) const
|
|
||||||
{
|
|
||||||
std::wstring result;
|
|
||||||
ToStringBase(result, b);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
an auxiliary method for converting from a string
|
this method converts a string into its value
|
||||||
|
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
|
||||||
|
|
||||||
|
string is ended with a non-digit value, for example:
|
||||||
|
"-12" will be translated to -12
|
||||||
|
as well as:
|
||||||
|
"- 12foo" will be translated to 12 too
|
||||||
|
|
||||||
|
existing first white characters will be ommited
|
||||||
|
(between '-' and a first digit can be white characters too)
|
||||||
|
|
||||||
|
after_source (if exists) is pointing at the end of the parsed string
|
||||||
|
|
||||||
|
value_read (if exists) tells whether something has actually been read (at least one digit)
|
||||||
*/
|
*/
|
||||||
template<class char_type>
|
uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
|
||||||
uint FromStringBase(const char_type * s, uint b = 10, const char_type ** after_source = 0, bool * value_read = 0)
|
|
||||||
{
|
{
|
||||||
bool is_sign = false;
|
bool is_sign = false;
|
||||||
|
|
||||||
Misc::SkipWhiteCharacters(s);
|
UInt<value_size>::SkipWhiteCharacters(s);
|
||||||
|
|
||||||
if( *s == '-' )
|
if( *s == '-' )
|
||||||
{
|
{
|
||||||
is_sign = true;
|
is_sign = true;
|
||||||
Misc::SkipWhiteCharacters(++s);
|
UInt<value_size>::SkipWhiteCharacters(++s);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( *s == '+' )
|
if( *s == '+' )
|
||||||
{
|
{
|
||||||
Misc::SkipWhiteCharacters(++s);
|
UInt<value_size>::SkipWhiteCharacters(++s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( UInt<value_size>::FromString(s,b,after_source,value_read) )
|
if( UInt<value_size>::FromString(s,b,after_source,value_read) )
|
||||||
@@ -1068,39 +957,6 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method converts a string into its value
|
|
||||||
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
|
|
||||||
|
|
||||||
string is ended with a non-digit value, for example:
|
|
||||||
"-12" will be translated to -12
|
|
||||||
as well as:
|
|
||||||
"- 12foo" will be translated to -12 too
|
|
||||||
|
|
||||||
existing first white characters will be ommited
|
|
||||||
(between '-' and a first digit can be white characters too)
|
|
||||||
|
|
||||||
after_source (if exists) is pointing at the end of the parsed string
|
|
||||||
|
|
||||||
value_read (if exists) tells whether something has actually been read (at least one digit)
|
|
||||||
*/
|
|
||||||
uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
|
|
||||||
{
|
|
||||||
return FromStringBase(s, b, after_source, value_read);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method converts a string into its value
|
|
||||||
*/
|
|
||||||
uint FromString(const wchar_t * s, uint b = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
|
|
||||||
{
|
|
||||||
return FromStringBase(s, b, after_source, value_read);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts a string into its value
|
this method converts a string into its value
|
||||||
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
|
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
|
||||||
@@ -1111,16 +967,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method converts a string into its value
|
|
||||||
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
|
|
||||||
*/
|
|
||||||
uint FromString(const std::wstring & s, uint b = 10)
|
|
||||||
{
|
|
||||||
return FromString( s.c_str(), b );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this operator converts a string into its value (with base = 10)
|
this operator converts a string into its value (with base = 10)
|
||||||
*/
|
*/
|
||||||
@@ -1132,17 +978,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this operator converts a string into its value (with base = 10)
|
|
||||||
*/
|
|
||||||
Int<value_size> & operator=(const wchar_t * s)
|
|
||||||
{
|
|
||||||
FromString(s);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this operator converts a string into its value (with base = 10)
|
this operator converts a string into its value (with base = 10)
|
||||||
*/
|
*/
|
||||||
@@ -1154,15 +989,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this operator converts a string into its value (with base = 10)
|
|
||||||
*/
|
|
||||||
Int<value_size> & operator=(const std::wstring & s)
|
|
||||||
{
|
|
||||||
FromString( s.c_str() );
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -1442,15 +1268,9 @@ public:
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private:
|
friend std::ostream & operator<<(std::ostream & s, const Int<value_size> & l)
|
||||||
|
|
||||||
/*!
|
|
||||||
an auxiliary method for outputing to standard streams
|
|
||||||
*/
|
|
||||||
template<class ostream_type, class string_type>
|
|
||||||
static ostream_type & OutputToStream(ostream_type & s, const Int<value_size> & l)
|
|
||||||
{
|
{
|
||||||
string_type ss;
|
std::string ss;
|
||||||
|
|
||||||
l.ToString(ss);
|
l.ToString(ss);
|
||||||
s << ss;
|
s << ss;
|
||||||
@@ -1460,40 +1280,12 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
friend std::istream & operator>>(std::istream & s, Int<value_size> & l)
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
output to standard streams
|
|
||||||
*/
|
|
||||||
friend std::ostream & operator<<(std::ostream & s, const Int<value_size> & l)
|
|
||||||
{
|
{
|
||||||
return OutputToStream<std::ostream, std::string>(s, l);
|
std::string ss;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
output to standard streams
|
|
||||||
*/
|
|
||||||
friend std::wostream & operator<<(std::wostream & s, const Int<value_size> & l)
|
|
||||||
{
|
|
||||||
return OutputToStream<std::wostream, std::wstring>(s, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/*!
|
|
||||||
an auxiliary method for converting from a string
|
|
||||||
*/
|
|
||||||
template<class istream_type, class string_type, class char_type>
|
|
||||||
static istream_type & InputFromStream(istream_type & s, Int<value_size> & l)
|
|
||||||
{
|
|
||||||
string_type ss;
|
|
||||||
|
|
||||||
// char or wchar_t for operator>>
|
// char for operator>>
|
||||||
char_type z;
|
unsigned char z;
|
||||||
|
|
||||||
// operator>> omits white characters if they're set for ommiting
|
// operator>> omits white characters if they're set for ommiting
|
||||||
s >> z;
|
s >> z;
|
||||||
@@ -1505,10 +1297,10 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we're reading only digits (base=10)
|
// we're reading only digits (base=10)
|
||||||
while( s.good() && Misc::CharToDigit(z, 10)>=0 )
|
while( s.good() && UInt<value_size>::CharToDigit(z, 10)>=0 )
|
||||||
{
|
{
|
||||||
ss += z;
|
ss += z;
|
||||||
z = static_cast<char_type>(s.get());
|
z = s.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// we're leaving the last readed character
|
// we're leaving the last readed character
|
||||||
@@ -1520,26 +1312,6 @@ private:
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/*!
|
|
||||||
input from standard streams
|
|
||||||
*/
|
|
||||||
friend std::istream & operator>>(std::istream & s, Int<value_size> & l)
|
|
||||||
{
|
|
||||||
return InputFromStream<std::istream, std::string, char>(s, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
input from standard streams
|
|
||||||
*/
|
|
||||||
friend std::wistream & operator>>(std::wistream & s, Int<value_size> & l)
|
|
||||||
{
|
|
||||||
return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -1,243 +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 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* AddString(result, str)
|
|
||||||
* result += str
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
result += str
|
|
||||||
*/
|
|
||||||
static void AddString(std::string & result, const char * str)
|
|
||||||
{
|
|
||||||
result += str;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
result += str
|
|
||||||
*/
|
|
||||||
static void AddString(std::wstring & result, const char * str)
|
|
||||||
{
|
|
||||||
for( ; *str ; ++str )
|
|
||||||
result += *str;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
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,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* 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 (new) BSD licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -44,13 +44,12 @@
|
|||||||
\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
|
||||||
@@ -74,7 +73,6 @@ 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
|
||||||
@@ -99,7 +97,7 @@ public:
|
|||||||
if 'can_be_digit' is true that means when the 'c' is a digit this
|
if 'can_be_digit' is true that means when the 'c' is a digit this
|
||||||
method returns true otherwise it returns false
|
method returns true otherwise it returns false
|
||||||
*/
|
*/
|
||||||
static bool CorrectCharacter(wchar_t c, bool can_be_digit)
|
static bool CorrectCharacter(int c, bool can_be_digit)
|
||||||
{
|
{
|
||||||
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
|
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
|
||||||
return true;
|
return true;
|
||||||
@@ -114,8 +112,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 std::string & name)
|
||||||
static bool IsNameCorrect(const string_type & name)
|
|
||||||
{
|
{
|
||||||
if( name.empty() )
|
if( name.empty() )
|
||||||
return false;
|
return false;
|
||||||
@@ -123,7 +120,7 @@ public:
|
|||||||
if( !CorrectCharacter(name[0], false) )
|
if( !CorrectCharacter(name[0], false) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
typename string_type::const_iterator i = name.begin();
|
std::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) )
|
||||||
@@ -148,22 +145,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method adds one object (variable of function) into the table
|
this method adds one object (variable of function) into the table
|
||||||
*/
|
*/
|
||||||
@@ -184,23 +165,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns 'true' if the table is empty
|
this method returns 'true' if the table is empty
|
||||||
*/
|
*/
|
||||||
@@ -258,23 +222,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method changes the name of a specific object
|
this method changes the name of a specific object
|
||||||
*/
|
*/
|
||||||
@@ -306,23 +253,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method deletes an object
|
this method deletes an object
|
||||||
*/
|
*/
|
||||||
@@ -342,22 +272,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method gets the value of a specific object
|
this method gets the value of a specific object
|
||||||
*/
|
*/
|
||||||
@@ -380,24 +294,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
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)
|
||||||
@@ -421,23 +317,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
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
|
||||||
@@ -463,25 +342,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
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
|
||||||
@@ -508,25 +368,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns a pointer into the table
|
this method returns a pointer into the table
|
||||||
*/
|
*/
|
||||||
@@ -539,7 +380,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
Table table;
|
Table table;
|
||||||
std::string str_tmp1, str_tmp2;
|
|
||||||
|
|
||||||
}; // end of class Objects
|
}; // end of class Objects
|
||||||
|
|
||||||
@@ -586,11 +426,11 @@ 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()
|
||||||
{
|
{
|
||||||
buffer_max_size = 15;
|
buffer_max_size = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -647,118 +487,10 @@ 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
|
|
||||||
in a second version of Gamma() 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
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the (new) BSD licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
@@ -45,14 +45,13 @@
|
|||||||
\brief A mathematical parser
|
\brief A mathematical parser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstdio>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include "ttmath.h"
|
#include "ttmath.h"
|
||||||
#include "ttmathobjects.h"
|
#include "ttmathobjects.h"
|
||||||
#include "ttmathmisc.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -110,7 +109,8 @@ namespace ttmath
|
|||||||
for example a correct input string can be:
|
for example a correct input string can be:
|
||||||
"1"
|
"1"
|
||||||
"2.1234"
|
"2.1234"
|
||||||
"2,1234" (they are the same, by default we can either use a comma or a dot)
|
"2,1234" (they are the same, we can either use a comma or a dot in values)
|
||||||
|
(look at the macro TTMATH_COMMA_CHARACTER_2)
|
||||||
"1 + 2"
|
"1 + 2"
|
||||||
"(1 + 2) * 3"
|
"(1 + 2) * 3"
|
||||||
"pi"
|
"pi"
|
||||||
@@ -137,6 +137,7 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
class Parser
|
class Parser
|
||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -159,20 +160,14 @@ private:
|
|||||||
none,add,sub,mul,div,pow,lt,gt,let,get,eq,neq,lor,land,shortmul
|
none,add,sub,mul,div,pow,lt,gt,let,get,eq,neq,lor,land,shortmul
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Assoc
|
|
||||||
{
|
|
||||||
right, // right-associative
|
|
||||||
non_right // associative or left-associative
|
|
||||||
};
|
|
||||||
|
|
||||||
Type GetType() const { return type; }
|
Type GetType() const { return type; }
|
||||||
int GetPriority() const { return priority; }
|
int GetPriority() const { return priority; }
|
||||||
Assoc GetAssoc() const { return assoc; }
|
|
||||||
|
|
||||||
void SetType(Type t)
|
void SetType(Type t)
|
||||||
{
|
{
|
||||||
type = t;
|
type = t;
|
||||||
assoc = non_right;
|
|
||||||
|
|
||||||
switch( type )
|
switch( type )
|
||||||
{
|
{
|
||||||
@@ -206,7 +201,6 @@ private:
|
|||||||
|
|
||||||
case pow:
|
case pow:
|
||||||
priority = 14;
|
priority = 14;
|
||||||
assoc = right;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -215,15 +209,15 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MatOperator(): type(none), priority(0), assoc(non_right)
|
MatOperator(): type(none), priority(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
int priority;
|
int priority;
|
||||||
Assoc assoc;
|
|
||||||
}; // end of MatOperator class
|
}; // end of MatOperator class
|
||||||
|
|
||||||
|
|
||||||
@@ -317,7 +311,6 @@ ErrorCode error;
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
pointer to the currently reading char
|
pointer to the currently reading char
|
||||||
it's either char* or wchar_t*
|
|
||||||
|
|
||||||
when an error has occured it may be used to count the index of the wrong character
|
when an error has occured it may be used to count the index of the wrong character
|
||||||
*/
|
*/
|
||||||
@@ -404,7 +397,7 @@ typedef void (ValueType::*pfunction_var)();
|
|||||||
|
|
||||||
this map consists of:
|
this map consists of:
|
||||||
std::string - function's name
|
std::string - function's name
|
||||||
pfunction - pointer to specific function
|
pfunction - pointer to specific function
|
||||||
*/
|
*/
|
||||||
typedef std::map<std::string, pfunction> FunctionsTable;
|
typedef std::map<std::string, pfunction> FunctionsTable;
|
||||||
FunctionsTable functions_table;
|
FunctionsTable functions_table;
|
||||||
@@ -425,7 +418,7 @@ OperatorsTable operators_table;
|
|||||||
table of mathematic variables
|
table of mathematic variables
|
||||||
|
|
||||||
this map consists of:
|
this map consists of:
|
||||||
std::string - variable's name
|
std::string - variable's name
|
||||||
pfunction_var - pointer to specific function which returns value of variable
|
pfunction_var - pointer to specific function which returns value of variable
|
||||||
*/
|
*/
|
||||||
typedef std::map<std::string, pfunction_var> VariablesTable;
|
typedef std::map<std::string, pfunction_var> VariablesTable;
|
||||||
@@ -433,44 +426,10 @@ VariablesTable variables_table;
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
some coefficients used when calculating the gamma (or factorial) function
|
you can't calculate the factorial if the argument is greater than 'factorial_max'
|
||||||
|
default value is zero which means there are not any limitations
|
||||||
*/
|
*/
|
||||||
CGamma<ValueType> cgamma;
|
ValueType factorial_max;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
temporary object for a whole string when Parse(std::wstring) is used
|
|
||||||
*/
|
|
||||||
std::string wide_to_ansi;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
group character (used when parsing)
|
|
||||||
default zero (not used)
|
|
||||||
*/
|
|
||||||
int group;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
characters used as a comma
|
|
||||||
default: '.' and ','
|
|
||||||
comma2 can be zero (it means it is not used)
|
|
||||||
*/
|
|
||||||
int comma, comma2;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
an additional character used as a separator between function parameters
|
|
||||||
(semicolon is used always)
|
|
||||||
*/
|
|
||||||
int param_sep;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
true if something was calculated (at least one mathematical operator was used or a function or a variable)
|
|
||||||
*/
|
|
||||||
bool calculated;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -546,8 +505,7 @@ void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::s
|
|||||||
(there can be a recurrence here therefore we're using 'visited_variables'
|
(there can be a recurrence here therefore we're using 'visited_variables'
|
||||||
and 'visited_functions' sets to make a stop condition)
|
and 'visited_functions' sets to make a stop condition)
|
||||||
*/
|
*/
|
||||||
ValueType RecurrenceParsingVariablesOrFunction(bool variable, const std::string & name, const char * new_string,
|
ValueType RecurrenceParsingVariablesOrFunction(bool variable, const std::string & name, const char * new_string, FunctionLocalVariables * local_variables = 0)
|
||||||
FunctionLocalVariables * local_variables = 0)
|
|
||||||
{
|
{
|
||||||
RecurrenceParsingVariablesOrFunction_CheckStopCondition(variable, name);
|
RecurrenceParsingVariablesOrFunction_CheckStopCondition(variable, name);
|
||||||
RecurrenceParsingVariablesOrFunction_AddName(variable, name);
|
RecurrenceParsingVariablesOrFunction_AddName(variable, name);
|
||||||
@@ -601,7 +559,6 @@ bool GetValueOfUserDefinedVariable(const std::string & variable_name,ValueType &
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
result = RecurrenceParsingVariablesOrFunction(true, variable_name, string_value);
|
result = RecurrenceParsingVariablesOrFunction(true, variable_name, string_value);
|
||||||
calculated = true;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -650,7 +607,6 @@ ValueType result;
|
|||||||
Error( err_unknown_variable );
|
Error( err_unknown_variable );
|
||||||
|
|
||||||
(result.*(i->second))();
|
(result.*(i->second))();
|
||||||
calculated = true;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -718,20 +674,6 @@ return result;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Gamma(int sindex, int amount_of_args, ValueType & result)
|
|
||||||
{
|
|
||||||
if( amount_of_args != 1 )
|
|
||||||
Error( err_improper_amount_of_arguments );
|
|
||||||
|
|
||||||
ErrorCode err;
|
|
||||||
|
|
||||||
result = ttmath::Gamma(stack[sindex].value, cgamma, &err, pstop_calculating);
|
|
||||||
|
|
||||||
if(err != err_ok)
|
|
||||||
Error( err );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
factorial
|
factorial
|
||||||
result = 1 * 2 * 3 * 4 * .... * x
|
result = 1 * 2 * 3 * 4 * .... * x
|
||||||
@@ -742,8 +684,11 @@ void Factorial(int sindex, int amount_of_args, ValueType & result)
|
|||||||
Error( err_improper_amount_of_arguments );
|
Error( err_improper_amount_of_arguments );
|
||||||
|
|
||||||
ErrorCode err;
|
ErrorCode err;
|
||||||
|
|
||||||
|
if( !factorial_max.IsZero() && stack[sindex].value > factorial_max )
|
||||||
|
Error( err_too_big_factorial );
|
||||||
|
|
||||||
result = ttmath::Factorial(stack[sindex].value, cgamma, &err, pstop_calculating);
|
result = ttmath::Factorial(stack[sindex].value, &err, pstop_calculating);
|
||||||
|
|
||||||
if(err != err_ok)
|
if(err != err_ok)
|
||||||
Error( err );
|
Error( err );
|
||||||
@@ -1399,45 +1344,6 @@ void Avg(int sindex, int amount_of_args, ValueType & result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Frac(int sindex, int amount_of_args, ValueType & result)
|
|
||||||
{
|
|
||||||
if( amount_of_args != 1 )
|
|
||||||
Error( err_improper_amount_of_arguments );
|
|
||||||
|
|
||||||
result = stack[sindex].value;
|
|
||||||
result.RemainFraction();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
we use such a method because 'wvsprintf' is not everywhere defined
|
|
||||||
*/
|
|
||||||
void Sprintf(char * buffer, int par)
|
|
||||||
{
|
|
||||||
char buf[30]; // char, not wchar_t etc.
|
|
||||||
int i;
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning( disable: 4996 )
|
|
||||||
//warning C4996: 'sprintf': This function or variable may be unsafe.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sprintf(buf, "%d", par);
|
|
||||||
for(i=0 ; buf[i] != 0 ; ++i)
|
|
||||||
buffer[i] = buf[i];
|
|
||||||
|
|
||||||
buffer[i] = 0;
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning( default: 4996 )
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns the value from a user-defined function
|
this method returns the value from a user-defined function
|
||||||
|
|
||||||
@@ -1462,23 +1368,20 @@ bool GetValueOfUserDefinedFunction(const std::string & function_name, int amount
|
|||||||
|
|
||||||
if( amount_of_args > 0 )
|
if( amount_of_args > 0 )
|
||||||
{
|
{
|
||||||
char buffer[30];
|
char buffer[20];
|
||||||
|
|
||||||
// x = x1
|
// x = x1
|
||||||
buffer[0] = 'x';
|
sprintf(buffer,"x");
|
||||||
buffer[1] = 0;
|
|
||||||
local_variables.insert( std::make_pair(buffer, stack[sindex].value) );
|
local_variables.insert( std::make_pair(buffer, stack[sindex].value) );
|
||||||
|
|
||||||
for(int i=0 ; i<amount_of_args ; ++i)
|
for(int i=0 ; i<amount_of_args ; ++i)
|
||||||
{
|
{
|
||||||
buffer[0] = 'x';
|
sprintf(buffer,"x%d",i+1);
|
||||||
Sprintf(buffer+1, i+1);
|
|
||||||
local_variables.insert( std::make_pair(buffer, stack[sindex + i*2].value) );
|
local_variables.insert( std::make_pair(buffer, stack[sindex + i*2].value) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stack[sindex-1].value = RecurrenceParsingVariablesOrFunction(false, function_name, string_value, &local_variables);
|
stack[sindex-1].value = RecurrenceParsingVariablesOrFunction(false, function_name, string_value, &local_variables);
|
||||||
calculated = true;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1511,7 +1414,6 @@ void CallFunction(const std::string & function_name, int amount_of_args, int sin
|
|||||||
calling the specify function
|
calling the specify function
|
||||||
*/
|
*/
|
||||||
(this->*(i->second))(sindex, amount_of_args, stack[sindex-1].value);
|
(this->*(i->second))(sindex, amount_of_args, stack[sindex-1].value);
|
||||||
calculated = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1526,14 +1428,10 @@ void CallFunction(const std::string & function_name, int amount_of_args, int sin
|
|||||||
*/
|
*/
|
||||||
void InsertFunctionToTable(const char * function_name, pfunction pf)
|
void InsertFunctionToTable(const char * function_name, pfunction pf)
|
||||||
{
|
{
|
||||||
std::string str;
|
functions_table.insert( std::make_pair(std::string(function_name), pf));
|
||||||
Misc::AssignString(str, function_name);
|
|
||||||
|
|
||||||
functions_table.insert( std::make_pair(str, pf) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
inserting a function to the variables' table
|
inserting a function to the variables' table
|
||||||
(this function returns value of variable)
|
(this function returns value of variable)
|
||||||
@@ -1543,10 +1441,7 @@ void InsertFunctionToTable(const char * function_name, pfunction pf)
|
|||||||
*/
|
*/
|
||||||
void InsertVariableToTable(const char * variable_name, pfunction_var pf)
|
void InsertVariableToTable(const char * variable_name, pfunction_var pf)
|
||||||
{
|
{
|
||||||
std::string str;
|
variables_table.insert( std::make_pair(std::string(variable_name), pf));
|
||||||
Misc::AssignString(str, variable_name);
|
|
||||||
|
|
||||||
variables_table.insert( std::make_pair(str, pf) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1555,18 +1450,20 @@ void InsertVariableToTable(const char * variable_name, pfunction_var pf)
|
|||||||
*/
|
*/
|
||||||
void CreateFunctionsTable()
|
void CreateFunctionsTable()
|
||||||
{
|
{
|
||||||
InsertFunctionToTable("gamma", &Parser<ValueType>::Gamma);
|
/*
|
||||||
|
names of functions should consist of small letters
|
||||||
|
*/
|
||||||
InsertFunctionToTable("factorial", &Parser<ValueType>::Factorial);
|
InsertFunctionToTable("factorial", &Parser<ValueType>::Factorial);
|
||||||
InsertFunctionToTable("abs", &Parser<ValueType>::Abs);
|
InsertFunctionToTable("abs", &Parser<ValueType>::Abs);
|
||||||
InsertFunctionToTable("sin", &Parser<ValueType>::Sin);
|
InsertFunctionToTable("sin", &Parser<ValueType>::Sin);
|
||||||
InsertFunctionToTable("cos", &Parser<ValueType>::Cos);
|
InsertFunctionToTable("cos", &Parser<ValueType>::Cos);
|
||||||
InsertFunctionToTable("tan", &Parser<ValueType>::Tan);
|
InsertFunctionToTable("tan", &Parser<ValueType>::Tan);
|
||||||
InsertFunctionToTable("tg", &Parser<ValueType>::Tan);
|
InsertFunctionToTable("tg", &Parser<ValueType>::Tan);
|
||||||
InsertFunctionToTable("cot", &Parser<ValueType>::Cot);
|
InsertFunctionToTable("cot", &Parser<ValueType>::Cot);
|
||||||
InsertFunctionToTable("ctg", &Parser<ValueType>::Cot);
|
InsertFunctionToTable("ctg", &Parser<ValueType>::Cot);
|
||||||
InsertFunctionToTable("int", &Parser<ValueType>::Int);
|
InsertFunctionToTable("int", &Parser<ValueType>::Int);
|
||||||
InsertFunctionToTable("round", &Parser<ValueType>::Round);
|
InsertFunctionToTable("round", &Parser<ValueType>::Round);
|
||||||
InsertFunctionToTable("ln", &Parser<ValueType>::Ln);
|
InsertFunctionToTable("ln", &Parser<ValueType>::Ln);
|
||||||
InsertFunctionToTable("log", &Parser<ValueType>::Log);
|
InsertFunctionToTable("log", &Parser<ValueType>::Log);
|
||||||
InsertFunctionToTable("exp", &Parser<ValueType>::Exp);
|
InsertFunctionToTable("exp", &Parser<ValueType>::Exp);
|
||||||
InsertFunctionToTable("max", &Parser<ValueType>::Max);
|
InsertFunctionToTable("max", &Parser<ValueType>::Max);
|
||||||
@@ -1614,7 +1511,6 @@ void CreateFunctionsTable()
|
|||||||
InsertFunctionToTable("bxor", &Parser<ValueType>::BitXor);
|
InsertFunctionToTable("bxor", &Parser<ValueType>::BitXor);
|
||||||
InsertFunctionToTable("sum", &Parser<ValueType>::Sum);
|
InsertFunctionToTable("sum", &Parser<ValueType>::Sum);
|
||||||
InsertFunctionToTable("avg", &Parser<ValueType>::Avg);
|
InsertFunctionToTable("avg", &Parser<ValueType>::Avg);
|
||||||
InsertFunctionToTable("frac", &Parser<ValueType>::Frac);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1623,6 +1519,9 @@ void CreateFunctionsTable()
|
|||||||
*/
|
*/
|
||||||
void CreateVariablesTable()
|
void CreateVariablesTable()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
names of variables should consist of small letters
|
||||||
|
*/
|
||||||
InsertVariableToTable("pi", &ValueType::SetPi);
|
InsertVariableToTable("pi", &ValueType::SetPi);
|
||||||
InsertVariableToTable("e", &ValueType::SetE);
|
InsertVariableToTable("e", &ValueType::SetE);
|
||||||
}
|
}
|
||||||
@@ -1746,8 +1645,6 @@ return is_it_name_of_function;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
we're reading a numerical value directly from the string
|
we're reading a numerical value directly from the string
|
||||||
*/
|
*/
|
||||||
@@ -1755,15 +1652,9 @@ void ReadValue(Item & result, int reading_base)
|
|||||||
{
|
{
|
||||||
const char * new_stack_pointer;
|
const char * new_stack_pointer;
|
||||||
bool value_read;
|
bool value_read;
|
||||||
Conv conv;
|
|
||||||
|
|
||||||
conv.base = reading_base;
|
int carry = result.value.FromString(pstring, reading_base, &new_stack_pointer, &value_read);
|
||||||
conv.comma = comma;
|
pstring = new_stack_pointer;
|
||||||
conv.comma2 = comma2;
|
|
||||||
conv.group = group;
|
|
||||||
|
|
||||||
uint carry = result.value.FromString(pstring, conv, &new_stack_pointer, &value_read);
|
|
||||||
pstring = new_stack_pointer;
|
|
||||||
|
|
||||||
if( carry )
|
if( carry )
|
||||||
Error( err_overflow );
|
Error( err_overflow );
|
||||||
@@ -1773,18 +1664,43 @@ Conv conv;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the character ascii c into the value in range <0;base-1>
|
||||||
|
|
||||||
|
if the character is incorrect for this base the funcion will return -1
|
||||||
|
*/
|
||||||
|
int CharToDigit(int c, int 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 c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns true if 'character' is a proper first digit for the value (or a comma -- can be first too)
|
this method returns true if 'character' is a proper first digit for the value (or a comma -- can be first too)
|
||||||
*/
|
*/
|
||||||
bool ValueStarts(int character, int base)
|
bool ValueStarts(int character, int base)
|
||||||
{
|
{
|
||||||
if( character == comma )
|
if( character == TTMATH_COMMA_CHARACTER_1 )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if( comma2!=0 && character==comma2 )
|
if( TTMATH_COMMA_CHARACTER_2 != 0 && character == TTMATH_COMMA_CHARACTER_2 )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if( Misc::CharToDigit(character, base) != -1 )
|
if( CharToDigit(character, base) != -1 )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1895,21 +1811,21 @@ int character;
|
|||||||
this value is from a variable or directly from the string
|
this value is from a variable or directly from the string
|
||||||
*/
|
*/
|
||||||
result.type = Item::numerical_value;
|
result.type = Item::numerical_value;
|
||||||
|
|
||||||
if( result.sign )
|
if( result.sign )
|
||||||
{
|
{
|
||||||
result.value.ChangeSign();
|
result.value.ChangeSign();
|
||||||
result.sign = false;
|
result.sign = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsertOperatorToTable(const char * name, typename MatOperator::Type type)
|
void InsertOperatorToTable(const std::string & name, typename MatOperator::Type type)
|
||||||
{
|
{
|
||||||
operators_table.insert( std::make_pair(std::string(name), type) );
|
operators_table.insert( std::make_pair(name, type) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1918,19 +1834,19 @@ void InsertOperatorToTable(const char * name, typename MatOperator::Type type)
|
|||||||
*/
|
*/
|
||||||
void CreateMathematicalOperatorsTable()
|
void CreateMathematicalOperatorsTable()
|
||||||
{
|
{
|
||||||
InsertOperatorToTable("||", MatOperator::lor);
|
InsertOperatorToTable(std::string("||"), MatOperator::lor);
|
||||||
InsertOperatorToTable("&&", MatOperator::land);
|
InsertOperatorToTable(std::string("&&"), MatOperator::land);
|
||||||
InsertOperatorToTable("!=", MatOperator::neq);
|
InsertOperatorToTable(std::string("!="), MatOperator::neq);
|
||||||
InsertOperatorToTable("==", MatOperator::eq);
|
InsertOperatorToTable(std::string("=="), MatOperator::eq);
|
||||||
InsertOperatorToTable(">=", MatOperator::get);
|
InsertOperatorToTable(std::string(">="), MatOperator::get);
|
||||||
InsertOperatorToTable("<=", MatOperator::let);
|
InsertOperatorToTable(std::string("<="), MatOperator::let);
|
||||||
InsertOperatorToTable(">", MatOperator::gt);
|
InsertOperatorToTable(std::string(">"), MatOperator::gt);
|
||||||
InsertOperatorToTable("<", MatOperator::lt);
|
InsertOperatorToTable(std::string("<"), MatOperator::lt);
|
||||||
InsertOperatorToTable("-", MatOperator::sub);
|
InsertOperatorToTable(std::string("-"), MatOperator::sub);
|
||||||
InsertOperatorToTable("+", MatOperator::add);
|
InsertOperatorToTable(std::string("+"), MatOperator::add);
|
||||||
InsertOperatorToTable("/", MatOperator::div);
|
InsertOperatorToTable(std::string("/"), MatOperator::div);
|
||||||
InsertOperatorToTable("*", MatOperator::mul);
|
InsertOperatorToTable(std::string("*"), MatOperator::mul);
|
||||||
InsertOperatorToTable("^", MatOperator::pow);
|
InsertOperatorToTable(std::string("^"), MatOperator::pow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1945,7 +1861,7 @@ bool IsSubstring(const std::string & str1, const std::string & str2)
|
|||||||
if( str2.length() > str1.length() )
|
if( str2.length() > str1.length() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for(typename std::string::size_type i=0 ; i<str2.length() ; ++i)
|
for(std::string::size_type i=0 ; i<str2.length() ; ++i)
|
||||||
if( str1[i] != str2[i] )
|
if( str1[i] != str2[i] )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -1987,31 +1903,6 @@ typename OperatorsTable::iterator iter_old, iter_new;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method makes a calculation for the percentage operator
|
|
||||||
e.g.
|
|
||||||
1000-50% = 1000-(1000*0,5) = 500
|
|
||||||
*/
|
|
||||||
void OperatorPercentage()
|
|
||||||
{
|
|
||||||
if( stack_index < 3 ||
|
|
||||||
stack[stack_index-1].type != Item::numerical_value ||
|
|
||||||
stack[stack_index-2].type != Item::mat_operator ||
|
|
||||||
stack[stack_index-3].type != Item::numerical_value )
|
|
||||||
Error(err_percent_from);
|
|
||||||
|
|
||||||
++pstring;
|
|
||||||
SkipWhiteCharacters();
|
|
||||||
|
|
||||||
uint c = 0;
|
|
||||||
c += stack[stack_index-1].value.Div(100);
|
|
||||||
c += stack[stack_index-1].value.Mul(stack[stack_index-3].value);
|
|
||||||
|
|
||||||
if( c )
|
|
||||||
Error(err_overflow);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method reads a mathematic operators
|
this method reads a mathematic operators
|
||||||
or the final bracket or the semicolon operator
|
or the final bracket or the semicolon operator
|
||||||
@@ -2023,11 +1914,7 @@ void OperatorPercentage()
|
|||||||
int ReadOperator(Item & result)
|
int ReadOperator(Item & result)
|
||||||
{
|
{
|
||||||
SkipWhiteCharacters();
|
SkipWhiteCharacters();
|
||||||
|
|
||||||
if( *pstring == '%' )
|
|
||||||
OperatorPercentage();
|
|
||||||
|
|
||||||
|
|
||||||
if( *pstring == 0 )
|
if( *pstring == 0 )
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
@@ -2037,7 +1924,7 @@ int ReadOperator(Item & result)
|
|||||||
++pstring;
|
++pstring;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( *pstring == ';' || (param_sep!=0 && *pstring==param_sep) )
|
if( *pstring == ';' )
|
||||||
{
|
{
|
||||||
result.type = Item::semicolon;
|
result.type = Item::semicolon;
|
||||||
++pstring;
|
++pstring;
|
||||||
@@ -2067,9 +1954,7 @@ return 0;
|
|||||||
void MakeStandardMathematicOperation(ValueType & value1, typename MatOperator::Type mat_operator,
|
void MakeStandardMathematicOperation(ValueType & value1, typename MatOperator::Type mat_operator,
|
||||||
const ValueType & value2)
|
const ValueType & value2)
|
||||||
{
|
{
|
||||||
uint res;
|
int res;
|
||||||
|
|
||||||
calculated = true;
|
|
||||||
|
|
||||||
switch( mat_operator )
|
switch( mat_operator )
|
||||||
{
|
{
|
||||||
@@ -2132,6 +2017,7 @@ uint res;
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
on the stack left an unknown operator but we had to recognize its before
|
on the stack left an unknown operator but we had to recognize its before
|
||||||
@@ -2160,20 +2046,10 @@ void TryRollingUpStackWithOperatorPriority()
|
|||||||
{
|
{
|
||||||
while( stack_index>=4 &&
|
while( stack_index>=4 &&
|
||||||
stack[stack_index-4].type == Item::numerical_value &&
|
stack[stack_index-4].type == Item::numerical_value &&
|
||||||
stack[stack_index-3].type == Item::mat_operator &&
|
stack[stack_index-3].type == Item::mat_operator &&
|
||||||
stack[stack_index-2].type == Item::numerical_value &&
|
stack[stack_index-2].type == Item::numerical_value &&
|
||||||
stack[stack_index-1].type == Item::mat_operator &&
|
stack[stack_index-1].type == Item::mat_operator &&
|
||||||
(
|
stack[stack_index-3].moperator.GetPriority() >= stack[stack_index-1].moperator.GetPriority()
|
||||||
(
|
|
||||||
// the first operator has greater priority
|
|
||||||
stack[stack_index-3].moperator.GetPriority() > stack[stack_index-1].moperator.GetPriority()
|
|
||||||
) ||
|
|
||||||
(
|
|
||||||
// or both operators have the same priority and the first operator is not right associative
|
|
||||||
stack[stack_index-3].moperator.GetPriority() == stack[stack_index-1].moperator.GetPriority() &&
|
|
||||||
stack[stack_index-3].moperator.GetAssoc() == MatOperator::non_right
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
MakeStandardMathematicOperation(stack[stack_index-4].value,
|
MakeStandardMathematicOperation(stack[stack_index-4].value,
|
||||||
@@ -2356,7 +2232,7 @@ int index;
|
|||||||
stack[index-1].value.ChangeSign();
|
stack[index-1].value.ChangeSign();
|
||||||
|
|
||||||
stack[index-1].type = Item::numerical_value;
|
stack[index-1].type = Item::numerical_value;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
the pointer of the stack will be pointing on the next (non-existing now) element
|
the pointer of the stack will be pointing on the next (non-existing now) element
|
||||||
@@ -2522,16 +2398,13 @@ public:
|
|||||||
Parser(): default_stack_size(100)
|
Parser(): default_stack_size(100)
|
||||||
{
|
{
|
||||||
pstop_calculating = 0;
|
pstop_calculating = 0;
|
||||||
puser_variables = 0;
|
puser_variables = 0;
|
||||||
puser_functions = 0;
|
puser_functions = 0;
|
||||||
pfunction_local_variables = 0;
|
pfunction_local_variables = 0;
|
||||||
base = 10;
|
base = 10;
|
||||||
deg_rad_grad = 1;
|
deg_rad_grad = 1;
|
||||||
error = err_ok;
|
error = err_ok;
|
||||||
group = 0;
|
factorial_max.SetZero();
|
||||||
comma = '.';
|
|
||||||
comma2 = ',';
|
|
||||||
param_sep = 0;
|
|
||||||
|
|
||||||
CreateFunctionsTable();
|
CreateFunctionsTable();
|
||||||
CreateVariablesTable();
|
CreateVariablesTable();
|
||||||
@@ -2548,13 +2421,10 @@ Parser<ValueType> & operator=(const Parser<ValueType> & p)
|
|||||||
puser_variables = p.puser_variables;
|
puser_variables = p.puser_variables;
|
||||||
puser_functions = p.puser_functions;
|
puser_functions = p.puser_functions;
|
||||||
pfunction_local_variables = 0;
|
pfunction_local_variables = 0;
|
||||||
base = p.base;
|
base = p.base;
|
||||||
deg_rad_grad = p.deg_rad_grad;
|
deg_rad_grad = p.deg_rad_grad;
|
||||||
error = p.error;
|
error = err_ok;
|
||||||
group = p.group;
|
factorial_max = p.factorial_max;
|
||||||
comma = p.comma;
|
|
||||||
comma2 = p.comma2;
|
|
||||||
param_sep = p.param_sep;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
we don't have to call 'CreateFunctionsTable()' etc.
|
we don't have to call 'CreateFunctionsTable()' etc.
|
||||||
@@ -2581,8 +2451,7 @@ Parser(const Parser<ValueType> & p): default_stack_size(p.default_stack_size)
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the new base of mathematic system
|
the new base of mathematic system
|
||||||
default is 10
|
|
||||||
*/
|
*/
|
||||||
void SetBase(int b)
|
void SetBase(int b)
|
||||||
{
|
{
|
||||||
@@ -2638,36 +2507,14 @@ void SetFunctions(const Objects * pf)
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
setting the group character
|
you will not be allowed to calculate the factorial
|
||||||
default zero (not used)
|
if its argument is greater than 'm'
|
||||||
|
there'll be: ErrorCode::err_too_big_factorial
|
||||||
|
default 'factorial_max' is zero which means you can calculate what you want to
|
||||||
*/
|
*/
|
||||||
void SetGroup(int g)
|
void SetFactorialMax(const ValueType & m)
|
||||||
{
|
{
|
||||||
group = g;
|
factorial_max = m;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
setting the main comma operator and the additional comma operator
|
|
||||||
the additional operator can be zero (which means it is not used)
|
|
||||||
default are: '.' and ','
|
|
||||||
*/
|
|
||||||
void SetComma(int c, int c2 = 0)
|
|
||||||
{
|
|
||||||
comma = c;
|
|
||||||
comma2 = c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
setting an additional character which is used as a parameters separator
|
|
||||||
the main parameters separator is a semicolon (is used always)
|
|
||||||
|
|
||||||
this character is used also as a global separator
|
|
||||||
*/
|
|
||||||
void SetParamSep(int s)
|
|
||||||
{
|
|
||||||
param_sep = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2679,8 +2526,7 @@ ErrorCode Parse(const char * str)
|
|||||||
stack_index = 0;
|
stack_index = 0;
|
||||||
pstring = str;
|
pstring = str;
|
||||||
error = err_ok;
|
error = err_ok;
|
||||||
calculated = false;
|
|
||||||
|
|
||||||
stack.resize( default_stack_size );
|
stack.resize( default_stack_size );
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -2690,7 +2536,6 @@ ErrorCode Parse(const char * str)
|
|||||||
catch(ErrorCode c)
|
catch(ErrorCode c)
|
||||||
{
|
{
|
||||||
error = c;
|
error = c;
|
||||||
calculated = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NormalizeStack();
|
NormalizeStack();
|
||||||
@@ -2699,55 +2544,11 @@ return error;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
the main method using for parsing string
|
|
||||||
*/
|
|
||||||
ErrorCode Parse(const std::string & str)
|
|
||||||
{
|
|
||||||
return Parse(str.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
the main method using for parsing string
|
|
||||||
*/
|
|
||||||
ErrorCode Parse(const wchar_t * str)
|
|
||||||
{
|
|
||||||
Misc::AssignString(wide_to_ansi, str);
|
|
||||||
|
|
||||||
return Parse(wide_to_ansi.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
the main method using for parsing string
|
|
||||||
*/
|
|
||||||
ErrorCode Parse(const std::wstring & str)
|
|
||||||
{
|
|
||||||
return Parse(str.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method returns true is something was calculated
|
|
||||||
(at least one mathematical operator was used or a function or variable)
|
|
||||||
e.g. true if the string to Parse() looked like this:
|
|
||||||
"1+1"
|
|
||||||
"2*3"
|
|
||||||
"sin(5)"
|
|
||||||
|
|
||||||
if the string was e.g. "678" the result is false
|
|
||||||
*/
|
|
||||||
bool Calculated()
|
|
||||||
{
|
|
||||||
return calculated;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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
|
|
||||||
|
|
@@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the (new) BSD licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the version of the library
|
the version of the library
|
||||||
@@ -63,8 +63,8 @@
|
|||||||
if zero that means this is the release version of the library
|
if zero that means this is the release version of the library
|
||||||
*/
|
*/
|
||||||
#define TTMATH_MAJOR_VER 0
|
#define TTMATH_MAJOR_VER 0
|
||||||
#define TTMATH_MINOR_VER 9
|
#define TTMATH_MINOR_VER 8
|
||||||
#define TTMATH_REVISION_VER 1
|
#define TTMATH_REVISION_VER 6
|
||||||
#define TTMATH_PRERELEASE_VER 0
|
#define TTMATH_PRERELEASE_VER 0
|
||||||
|
|
||||||
|
|
||||||
@@ -112,15 +112,6 @@ namespace ttmath
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
another compilers than MS VC or GCC by default use no asm version (TTMATH_NOASM)
|
|
||||||
*/
|
|
||||||
#if !defined _MSC_VER && !defined __GNUC__
|
|
||||||
#define TTMATH_NOASM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TTMATH_PLATFORM32
|
#ifdef TTMATH_PLATFORM32
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -166,26 +157,13 @@ namespace ttmath
|
|||||||
*/
|
*/
|
||||||
#define TTMATH_BUILTIN_VARIABLES_SIZE 256u
|
#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
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
on 64bit platforms one word (uint, sint) will be equal 64bits
|
on 64bit platforms one word (uint, sint) will be equal 64bits
|
||||||
*/
|
*/
|
||||||
#ifdef _MSC_VER
|
typedef unsigned long uint;
|
||||||
/* in VC 'long' type has 32 bits, __int64 is VC extension */
|
typedef signed long sint;
|
||||||
typedef unsigned __int64 uint;
|
|
||||||
typedef signed __int64 sint;
|
|
||||||
#else
|
|
||||||
typedef unsigned long uint;
|
|
||||||
typedef signed long sint;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
on 64bit platform we do not define ulint
|
on 64bit platform we do not define ulint
|
||||||
@@ -219,28 +197,27 @@ namespace ttmath
|
|||||||
*/
|
*/
|
||||||
#define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
|
#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)
|
/*!
|
||||||
#define TTMATH_WIN32_THREADS
|
characters which represent the comma operator
|
||||||
#elif defined(unix) || defined(__unix__) || defined(__unix)
|
|
||||||
#define TTMATH_POSIX_THREADS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing (default, can be overwritten in ToString() function)
|
||||||
#endif
|
TTMATH_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character
|
||||||
|
that means you can input values for example 1.2345 and 1,2345 as well
|
||||||
|
|
||||||
|
if you don't want it just put 0 there 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 ','
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -265,54 +242,16 @@ namespace ttmath
|
|||||||
if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
|
if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
|
||||||
the Karatsuba algorithm will use standard schoolbook multiplication
|
the Karatsuba algorithm will use standard schoolbook multiplication
|
||||||
*/
|
*/
|
||||||
#ifdef TTMATH_DEBUG_LOG
|
#ifdef __GNUC__
|
||||||
// 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
|
||||||
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
|
|
||||||
#else
|
#else
|
||||||
#ifdef __GNUC__
|
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
|
||||||
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
|
|
||||||
#else
|
|
||||||
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
|
|
||||||
#endif
|
|
||||||
#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
|
||||||
*/
|
*/
|
||||||
@@ -343,132 +282,11 @@ namespace ttmath
|
|||||||
err_object_exists,
|
err_object_exists,
|
||||||
err_unknown_object,
|
err_unknown_object,
|
||||||
err_still_calculating,
|
err_still_calculating,
|
||||||
err_in_short_form_used_function,
|
err_too_big_factorial,
|
||||||
err_percent_from
|
err_in_short_form_used_function
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
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 print 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;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
*/
|
|
||||||
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_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)
|
||||||
@@ -522,7 +340,7 @@ namespace ttmath
|
|||||||
can throw an exception of this type
|
can throw an exception 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_REFERENCE_ASSERT
|
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
|
||||||
was used)
|
was used)
|
||||||
|
|
||||||
@@ -546,12 +364,12 @@ namespace ttmath
|
|||||||
{
|
{
|
||||||
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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,7 +388,7 @@ 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)
|
||||||
*/
|
*/
|
||||||
@@ -578,12 +396,12 @@ namespace ttmath
|
|||||||
{
|
{
|
||||||
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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,22 +443,18 @@ namespace ttmath
|
|||||||
|
|
||||||
|
|
||||||
#ifdef TTMATH_DEBUG_LOG
|
#ifdef TTMATH_DEBUG_LOG
|
||||||
#define TTMATH_LOG(msg) PrintLog(msg, std::cout);
|
|
||||||
#define TTMATH_LOGC(msg, carry) PrintLog(msg, carry, std::cout);
|
#define TTMATH_LOG(msg) \
|
||||||
#define TTMATH_VECTOR_LOG(msg, vector, len) PrintVectorLog(msg, std::cout, vector, len);
|
PrintLog(msg, std::cout);
|
||||||
#define TTMATH_VECTOR_LOGC(msg, carry, vector, len) PrintVectorLog(msg, carry, std::cout, vector, len);
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define TTMATH_LOG(msg)
|
#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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the (new) BSD licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -51,56 +51,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 +95,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 +131,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 +184,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 +224,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 +232,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 +273,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 +311,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 +351,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 +385,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,7 +424,7 @@ namespace ttmath
|
|||||||
c = new_c;
|
c = new_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcr2_one", c)
|
TTMATH_LOG("UInt::Rcr2_one")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -518,7 +462,7 @@ namespace ttmath
|
|||||||
c = new_c;
|
c = new_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcl2", c)
|
TTMATH_LOG("UInt::Rcl2")
|
||||||
|
|
||||||
return (c & 1);
|
return (c & 1);
|
||||||
}
|
}
|
||||||
@@ -557,7 +501,7 @@ namespace ttmath
|
|||||||
c = new_c;
|
c = new_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcr2", c)
|
TTMATH_LOG("UInt::Rcr2")
|
||||||
|
|
||||||
return (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
|
return (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
|
||||||
}
|
}
|
||||||
@@ -565,9 +509,10 @@ namespace ttmath
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*
|
||||||
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)
|
||||||
@@ -588,34 +533,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;
|
||||||
@@ -817,11 +741,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;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the (new) BSD licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -60,50 +60,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()
|
|
||||||
{
|
|
||||||
#ifndef __GNUC__
|
|
||||||
static const char info[] = "asm_vc_32";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
static const char info[] = "asm_gcc_32";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
returning the currect type of the library
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
LibTypeCode UInt<value_size>::LibType()
|
|
||||||
{
|
|
||||||
#ifndef __GNUC__
|
|
||||||
LibTypeCode info = asm_vc_32;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
LibTypeCode info = asm_gcc_32;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* basic mathematic functions
|
* basic mathematic functions
|
||||||
@@ -196,7 +152,7 @@ namespace ttmath
|
|||||||
: "cc", "memory" );
|
: "cc", "memory" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Add", c)
|
TTMATH_LOG("UInt::Add")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -297,7 +253,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::AddInt", c)
|
TTMATH_LOG("UInt::AddInt")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -418,7 +374,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::AddTwoInts", c)
|
TTMATH_LOG("UInt::AddTwoInts")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -550,7 +506,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
|
TTMATH_LOG("UInt::AddVector")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -638,7 +594,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Sub", c)
|
TTMATH_LOG("UInt::Sub")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -740,7 +696,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::SubInt", c)
|
TTMATH_LOG("UInt::SubInt")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -878,7 +834,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
|
TTMATH_LOG("UInt::SubVector")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -956,7 +912,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcl2_one", c)
|
TTMATH_LOG("UInt::Rcl2_one")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -1028,7 +984,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcr2_one", c)
|
TTMATH_LOG("UInt::Rcr2_one")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -1162,7 +1118,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcl2", c)
|
TTMATH_LOG("UInt::Rcl2")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -1296,7 +1252,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcr2", c)
|
TTMATH_LOG("UInt::Rcr2")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -1353,50 +1309,6 @@ namespace ttmath
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
this method returns the number of the smallest set bit in one 32-bit word
|
|
||||||
if the 'x' is zero this method returns '-1'
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
sint UInt<value_size>::FindLowestBitInWord(uint x)
|
|
||||||
{
|
|
||||||
sint result;
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
push eax
|
|
||||||
push edx
|
|
||||||
|
|
||||||
mov edx,-1
|
|
||||||
bsf eax,[x]
|
|
||||||
cmovz eax,edx
|
|
||||||
mov [result], eax
|
|
||||||
|
|
||||||
pop edx
|
|
||||||
pop eax
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
uint dummy;
|
|
||||||
|
|
||||||
__asm__ (
|
|
||||||
|
|
||||||
"movl $-1, %1 \n"
|
|
||||||
"bsfl %2, %0 \n"
|
|
||||||
"cmovz %1, %0 \n"
|
|
||||||
|
|
||||||
: "=r" (result), "=&r" (dummy)
|
|
||||||
: "r" (x)
|
|
||||||
: "cc" );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the (new) BSD licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -51,77 +51,10 @@
|
|||||||
this file is included at the end of ttmathuint.h
|
this file is included at the end of ttmathuint.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include <intrin.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
uint __fastcall ttmath_adc_x64(uint* p1, const uint* p2, uint nSize, uint c);
|
|
||||||
uint __fastcall ttmath_addindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue);
|
|
||||||
uint __fastcall ttmath_addindexed2_x64(uint* p1, uint nSize, uint nPos, uint nValue1, uint nValue2);
|
|
||||||
uint __fastcall ttmath_addvector_x64(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
|
|
||||||
uint __fastcall ttmath_sbb_x64(uint* p1, const uint* p2, uint nSize, uint c);
|
|
||||||
uint __fastcall ttmath_subindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue);
|
|
||||||
uint __fastcall ttmath_subvector_x64(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
|
|
||||||
uint __fastcall ttmath_rcl_x64(uint* p1, uint nSize, uint nLowestBit);
|
|
||||||
uint __fastcall ttmath_rcr_x64(uint* p1, uint nSize, uint nLowestBit);
|
|
||||||
uint __fastcall ttmath_div_x64(uint* pnValHi, uint* pnValLo, uint nDiv);
|
|
||||||
uint __fastcall ttmath_rcl2_x64(uint* p1, uint nSize, uint nBits, uint c);
|
|
||||||
uint __fastcall ttmath_rcr2_x64(uint* p1, uint nSize, uint nBits, uint c);
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
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 _MSC_VER
|
|
||||||
static const char info[] = "asm_vc_64";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
static const char info[] = "asm_gcc_64";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
returning the currect type of the library
|
|
||||||
*/
|
|
||||||
template<uint value_size>
|
|
||||||
LibTypeCode UInt<value_size>::LibType()
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
LibTypeCode info = asm_vc_64;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
LibTypeCode info = asm_gcc_64;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* basic mathematic functions
|
* basic mathematic functions
|
||||||
@@ -149,12 +82,8 @@ namespace ttmath
|
|||||||
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
||||||
// this algorithm doesn't require it
|
// this algorithm doesn't require it
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_adc_x64(p1,p2,b,c);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
@@ -184,7 +113,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Add", c)
|
TTMATH_LOG("UInt::Add")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -220,16 +149,10 @@ namespace ttmath
|
|||||||
|
|
||||||
TTMATH_ASSERT( index < value_size )
|
TTMATH_ASSERT( index < value_size )
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_addindexed_x64(p1,b,index,value);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
uint dummy, dummy2;
|
uint dummy, dummy2;
|
||||||
|
|
||||||
@@ -256,7 +179,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::AddInt", c)
|
TTMATH_LOG("UInt::AddInt")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -304,16 +227,10 @@ namespace ttmath
|
|||||||
|
|
||||||
TTMATH_ASSERT( index < value_size - 1 )
|
TTMATH_ASSERT( index < value_size - 1 )
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_addindexed2_x64(p1,b,index,x1,x2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
uint dummy, dummy2;
|
uint dummy, dummy2;
|
||||||
|
|
||||||
@@ -344,7 +261,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::AddTwoInts", c)
|
TTMATH_LOG("UInt::AddTwoInts")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -376,21 +293,15 @@ namespace ttmath
|
|||||||
{
|
{
|
||||||
TTMATH_ASSERT( ss1_size >= ss2_size )
|
TTMATH_ASSERT( ss1_size >= ss2_size )
|
||||||
|
|
||||||
|
uint rest = ss1_size - ss2_size;
|
||||||
uint c;
|
uint c;
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_addvector_x64(ss1, ss2, ss1_size, ss2_size, result);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
uint dummy1, dummy2, dummy3;
|
uint dummy1, dummy2, dummy3;
|
||||||
uint rest = ss1_size - ss2_size;
|
|
||||||
|
|
||||||
// this part should be compiled with gcc
|
// this part should be compiled with gcc
|
||||||
|
|
||||||
@@ -432,13 +343,15 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
|
TTMATH_LOG("UInt::AddVector")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method's subtracting ss2 from the 'this' and subtracting
|
this method's subtracting ss2 from the 'this' and subtracting
|
||||||
carry if it has been defined
|
carry if it has been defined
|
||||||
@@ -460,16 +373,10 @@ namespace ttmath
|
|||||||
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
||||||
// this algorithm doesn't require it
|
// this algorithm doesn't require it
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_sbb_x64(p1,p2,b,c);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
uint dummy, dummy2;
|
uint dummy, dummy2;
|
||||||
|
|
||||||
@@ -494,13 +401,12 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Sub", c)
|
TTMATH_LOG("UInt::Sub")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method subtracts one word (at a specific position)
|
this method subtracts one word (at a specific position)
|
||||||
and returns a carry (if it was)
|
and returns a carry (if it was)
|
||||||
@@ -526,22 +432,15 @@ namespace ttmath
|
|||||||
uint b = value_size;
|
uint b = value_size;
|
||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
uint c;
|
uint c;
|
||||||
|
uint dummy, dummy2;
|
||||||
|
|
||||||
TTMATH_ASSERT( index < value_size )
|
TTMATH_ASSERT( index < value_size )
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_subindexed_x64(p1,b,index,value);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
uint dummy, dummy2;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"subq %%rdx, %%rcx \n"
|
"subq %%rdx, %%rcx \n"
|
||||||
@@ -565,12 +464,14 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::SubInt", c)
|
TTMATH_LOG("UInt::SubInt")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this static method subtractes one vector from the other
|
this static method subtractes one vector from the other
|
||||||
'ss1' is larger in size or equal to 'ss2'
|
'ss1' is larger in size or equal to 'ss2'
|
||||||
@@ -597,25 +498,20 @@ namespace ttmath
|
|||||||
{
|
{
|
||||||
TTMATH_ASSERT( ss1_size >= ss2_size )
|
TTMATH_ASSERT( ss1_size >= ss2_size )
|
||||||
|
|
||||||
|
uint rest = ss1_size - ss2_size;
|
||||||
uint c;
|
uint c;
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_subvector_x64(ss1, ss2, ss1_size, ss2_size, result);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
||||||
// the asm code is nearly the same as in AddVector
|
/*
|
||||||
// only two instructions 'adc' are changed to 'sbb'
|
the asm code is nearly the same as in AddVector
|
||||||
|
only two instructions 'adc' are changed to 'sbb'
|
||||||
|
*/
|
||||||
uint dummy1, dummy2, dummy3;
|
uint dummy1, dummy2, dummy3;
|
||||||
uint rest = ss1_size - ss2_size;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"mov %%rdx, %%r8 \n"
|
"mov %%rdx, %%r8 \n"
|
||||||
@@ -655,12 +551,13 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
|
TTMATH_LOG("UInt::SubVector")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method moves all bits into the left hand side
|
this method moves all bits into the left hand side
|
||||||
return value <- this <- c
|
return value <- this <- c
|
||||||
@@ -682,16 +579,10 @@ namespace ttmath
|
|||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
|
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_rcl_x64(p1,b,c);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
uint dummy, dummy2;
|
uint dummy, dummy2;
|
||||||
|
|
||||||
@@ -715,7 +606,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcl2_one", c)
|
TTMATH_LOG("UInt::Rcl2_one")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -742,16 +633,10 @@ namespace ttmath
|
|||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
|
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_rcr_x64(p1,b,c);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
uint dummy;
|
uint dummy;
|
||||||
|
|
||||||
@@ -773,7 +658,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcr2_one", c)
|
TTMATH_LOG("UInt::Rcr2_one")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -803,16 +688,10 @@ namespace ttmath
|
|||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
|
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_rcl2_x64(p1,b,bits,c);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
uint dummy, dummy2, dummy3;
|
uint dummy, dummy2, dummy3;
|
||||||
|
|
||||||
@@ -852,7 +731,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcl2", c)
|
TTMATH_LOG("UInt::Rcl2")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -879,20 +758,14 @@ namespace ttmath
|
|||||||
|
|
||||||
sint b = value_size;
|
sint b = value_size;
|
||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
|
uint dummy, dummy2, dummy3;
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_rcr2_x64(p1,b,bits,c);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
uint dummy, dummy2, dummy3;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"movq %%rcx, %%rsi \n"
|
"movq %%rcx, %%rsi \n"
|
||||||
@@ -932,7 +805,7 @@ namespace ttmath
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcr2", c)
|
TTMATH_LOG("UInt::Rcr2")
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -950,23 +823,10 @@ namespace ttmath
|
|||||||
sint result;
|
sint result;
|
||||||
|
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
|
||||||
unsigned long nIndex = 0;
|
|
||||||
|
|
||||||
if( _BitScanReverse64(&nIndex,x) == 0 )
|
|
||||||
result = -1;
|
|
||||||
else
|
|
||||||
result = nIndex;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
uint dummy;
|
uint dummy;
|
||||||
|
|
||||||
@@ -987,55 +847,6 @@ namespace ttmath
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
this method returns the number of the highest set bit in one 64-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>::FindLowestBitInWord(uint x)
|
|
||||||
{
|
|
||||||
sint result;
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
|
||||||
unsigned long nIndex = 0;
|
|
||||||
|
|
||||||
if( _BitScanForward64(&nIndex,x) == 0 )
|
|
||||||
result = -1;
|
|
||||||
else
|
|
||||||
result = nIndex;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
uint dummy;
|
|
||||||
|
|
||||||
__asm__ (
|
|
||||||
|
|
||||||
"movq $-1, %1 \n"
|
|
||||||
"bsfq %2, %0 \n"
|
|
||||||
"cmovz %1, %0 \n"
|
|
||||||
|
|
||||||
: "=r" (result), "=&r" (dummy)
|
|
||||||
: "r" (x)
|
|
||||||
: "cc" );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
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)
|
||||||
@@ -1057,16 +868,11 @@ namespace ttmath
|
|||||||
uint old_bit;
|
uint old_bit;
|
||||||
uint v = value;
|
uint v = value;
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#ifndef __GNUC__
|
||||||
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
old_bit = _bittestandset64((__int64*)&value,bit) != 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
||||||
__asm__ (
|
__asm__ (
|
||||||
@@ -1118,16 +924,10 @@ namespace ttmath
|
|||||||
uint result1_;
|
uint result1_;
|
||||||
uint result2_;
|
uint result2_;
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
result1_ = _umul128(a,b,&result2_);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
||||||
__asm__ (
|
__asm__ (
|
||||||
@@ -1181,20 +981,10 @@ namespace ttmath
|
|||||||
|
|
||||||
TTMATH_ASSERT( c != 0 )
|
TTMATH_ASSERT( c != 0 )
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
|
||||||
ttmath_div_x64(&a,&b,c);
|
|
||||||
r_ = a;
|
|
||||||
rest_ = b;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
||||||
__asm__ (
|
__asm__ (
|
||||||
@@ -1212,6 +1002,7 @@ namespace ttmath
|
|||||||
*rest = rest_;
|
*rest = rest_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,548 +0,0 @@
|
|||||||
;
|
|
||||||
; This file is a part of TTMath Bignum Library
|
|
||||||
; and is distributed under the (new) BSD licence.
|
|
||||||
; Author: Christian Kaiser <chk@online.de>
|
|
||||||
;
|
|
||||||
|
|
||||||
;
|
|
||||||
; Copyright (c) 2009, Christian Kaiser
|
|
||||||
; 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 /Zd /Zi ttmathuint_x86_64_msvc.asm
|
|
||||||
; compile without debug info: ml64.exe ttmathuint_x86_64_msvc.asm
|
|
||||||
; this create ttmathuint_x86_64_msvc.obj file which can be linked with your program
|
|
||||||
;
|
|
||||||
|
|
||||||
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
|
|
||||||
; [esp+0x28] = nValue2
|
|
||||||
|
|
||||||
xor rax, rax ; return value
|
|
||||||
mov r11, rcx ; table
|
|
||||||
sub rdx, r8 ; rdx = remaining count of uints
|
|
||||||
mov r10, [esp+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
|
|
||||||
; [esp+0x28] = result
|
|
||||||
|
|
||||||
mov r10, [esp+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
|
|
||||||
; [esp+0x28] = result
|
|
||||||
|
|
||||||
mov r10, [esp+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
|
|
Reference in New Issue
Block a user