Compare commits
101 Commits
Author | SHA1 | Date |
---|---|---|
Tomasz Sowa | aad580f51e | |
Tomasz Sowa | 3b113374b7 | |
Tomasz Sowa | 0f2fcaf547 | |
Tomasz Sowa | f88cba2688 | |
Tomasz Sowa | 48d694a47f | |
Tomasz Sowa | 9a93db39c4 | |
Tomasz Sowa | f98c434fc4 | |
Tomasz Sowa | 132fa10cd4 | |
Tomasz Sowa | dcdb1db9ec | |
Tomasz Sowa | d93d5ffd74 | |
Tomasz Sowa | 9b279276f2 | |
Tomasz Sowa | 83b5ab7170 | |
Tomasz Sowa | 35333b1e32 | |
Tomasz Sowa | c73af9c116 | |
Tomasz Sowa | f06592376f | |
Tomasz Sowa | b36821024b | |
Tomasz Sowa | cd740c5924 | |
Tomasz Sowa | 46ed8c3108 | |
Tomasz Sowa | f4f7882387 | |
Tomasz Sowa | 86dc01cdee | |
Tomasz Sowa | 2067301d1c | |
Tomasz Sowa | e2cdeac423 | |
Tomasz Sowa | 5893ffa9e3 | |
Tomasz Sowa | b862422bd9 | |
Tomasz Sowa | cb15ac0cd8 | |
Tomasz Sowa | 77c41e644a | |
Tomasz Sowa | 506840787a | |
Tomasz Sowa | e58253a078 | |
Tomasz Sowa | 6862321fad | |
Tomasz Sowa | 2e192969b0 | |
Tomasz Sowa | e8daa77d75 | |
Tomasz Sowa | 231164f6ea | |
Tomasz Sowa | c51b2fdcc9 | |
Tomasz Sowa | 84f34ebe52 | |
Tomasz Sowa | 3190f3011f | |
Tomasz Sowa | a34cf55155 | |
Tomasz Sowa | 648de47400 | |
Tomasz Sowa | 362207e2f1 | |
Tomasz Sowa | a40e951923 | |
Tomasz Sowa | b028896118 | |
Tomasz Sowa | a67a088e3a | |
Tomasz Sowa | 996fac15f1 | |
Tomasz Sowa | 1e268f1808 | |
Tomasz Sowa | 90674c9505 | |
Tomasz Sowa | b6fe168e3c | |
Tomasz Sowa | ae61b302a8 | |
Tomasz Sowa | a1c41c02db | |
Tomasz Sowa | 69f065245e | |
Tomasz Sowa | c65dac524a | |
Tomasz Sowa | b3c3dd8c3f | |
Tomasz Sowa | 1b7e13a9fd | |
Tomasz Sowa | aeadb8a04a | |
Tomasz Sowa | 053861655d | |
Tomasz Sowa | 35f2a8a28b | |
Tomasz Sowa | d5a5ea1a7d | |
Tomasz Sowa | 32b8c7a957 | |
Tomasz Sowa | e727eacce0 | |
Tomasz Sowa | 39db6fc469 | |
Tomasz Sowa | 0ada20b4cb | |
Tomasz Sowa | 31563ce343 | |
Tomasz Sowa | 418db51f46 | |
Tomasz Sowa | 82711f4441 | |
Tomasz Sowa | e5fc7a52e8 | |
Tomasz Sowa | 357524ae13 | |
Tomasz Sowa | 72052420dd | |
Tomasz Sowa | 321953e833 | |
Tomasz Sowa | 125c051ea1 | |
Tomasz Sowa | de150d00ec | |
Tomasz Sowa | 2d821bbad9 | |
Tomasz Sowa | e083c5f889 | |
Tomasz Sowa | 11b9f389b9 | |
Tomasz Sowa | bac79e0bfa | |
Tomasz Sowa | 0d1a57bdb4 | |
Tomasz Sowa | 4b4b30392a | |
Tomasz Sowa | 4f1763d773 | |
Tomasz Sowa | cccf82797f | |
Tomasz Sowa | e73ce2f8bc | |
Tomasz Sowa | 2feabc64e2 | |
Tomasz Sowa | 413c83de45 | |
Tomasz Sowa | bf520689fb | |
Tomasz Sowa | af4fbf3098 | |
Tomasz Sowa | 462ff7cc65 | |
Tomasz Sowa | 02da809583 | |
Tomasz Sowa | 32ebbbfd9e | |
Tomasz Sowa | e765fba8a1 | |
Tomasz Sowa | a8eb29e57d | |
Tomasz Sowa | 31b8c242bd | |
Tomasz Sowa | 4c0d8c26ff | |
Tomasz Sowa | 01a86e40d9 | |
Tomasz Sowa | f19078f9f1 | |
Tomasz Sowa | adc5015ad9 | |
Tomasz Sowa | da730d1c70 | |
Tomasz Sowa | 9ccacd8817 | |
Tomasz Sowa | b3d27979d0 | |
Tomasz Sowa | e13e5eb329 | |
Tomasz Sowa | 74b31b1f54 | |
Tomasz Sowa | 28964d30f7 | |
Tomasz Sowa | 0d71b0cec2 | |
Tomasz Sowa | 3544a1df3c | |
Tomasz Sowa | 00519ff26d | |
Tomasz Sowa | 799e2c32a7 |
270
CHANGELOG
270
CHANGELOG
|
@ -1,15 +1,154 @@
|
|||
Version 0.9.0 prerelease (2009.07.16):
|
||||
* added: support for wide characters (wchar_t)
|
||||
wide characters are used when macro TTMATH_USE_WCHAR is defined
|
||||
this macro is defined automatically when there is macro UNICODE or _UNICODE defined
|
||||
some types have been changed
|
||||
char -> tt_char
|
||||
std::string -> tt_string
|
||||
std::ostringstream -> tt_ostringstream
|
||||
std::ostream -> tt_ostream
|
||||
std::istream -> tt_istream
|
||||
normally tt_char is equal char but when you are using wide characters then tt_char will be wchar_t (and so on)
|
||||
(all typedef's are in ttmathtypes.h)
|
||||
Version 0.9.4_prerelease (....):
|
||||
* fixed: cannot compile on MS Windows when compiling with GCC (Mingw) for 64 bit platform:
|
||||
incorrect size of ttmath::uint and ::sint were used
|
||||
they were 'long' but 'long' is a 32bit type on Windows
|
||||
* fixed: a crash in Big::Add() (buffer overflow)
|
||||
there was an offset calculated from Int type by using Abs() method and a carry was not checked
|
||||
(if there is a carry we should not make addition -- the argument is too small)
|
||||
this had no impact on calculated values because there was a crash (bus error) immediately
|
||||
following program could crash (64bit):
|
||||
typedef ttmath::Big<1, 8> MyBig;
|
||||
ttmath::Parser<MyBig> parser;
|
||||
parser.Parse("2^(2^63) + 1");
|
||||
* fixed: similar problems were in methods Big::BitAnd() Big::BitOr() and Big::BitXor() (bitwise operations)
|
||||
and they could return incorrect values
|
||||
* fixed: in x86_64 asm code (*.asm for Win64) there was in some places esp register used,
|
||||
there should be rsp used instead
|
||||
this affects MS Windows users when they use the asm version (ttmathuint_x86_64_msvc.asm)
|
||||
|
||||
|
||||
Version 0.9.3 (2012.11.28):
|
||||
* fixed: in Big::FromDouble(double value) (only 32 bit version)
|
||||
buffer overflow in referencing to UInt<2>
|
||||
this was used when 'value' was in so called "unnormalized" state
|
||||
(E=0 and F is nonzero)
|
||||
it produced incorrect mantissa (on about 8th decimal digit up)
|
||||
* added: Parser::InitCGamma()
|
||||
initializing coefficients used when calculating the gamma (or factorial) function
|
||||
this speed up the next calculations
|
||||
you don't have to call this method explicitly
|
||||
these coefficients will be calculated when needed
|
||||
* added: option 'group_digits' to Conv struct
|
||||
you can set how many digits should be grouped
|
||||
* changed: small optimizations in UInt::ToString() and Big::FromString()
|
||||
|
||||
|
||||
Version 0.9.2 (2010.09.23):
|
||||
* fixed: Big::Add() sometimes incorrectly rounded the last bit from its mantissa
|
||||
* fixed: Big::BigAnd() Big::BigOr() Big::BigXor() should have set NaN
|
||||
when the argument was negative (they only returned 2)
|
||||
* fixed: recurrence calling in Big::FromString(const std::string &, uint, const wchar_t **, bool *)
|
||||
it should have the signature: Big::FromString(const std::string &, uint, const char **, bool *)
|
||||
* fixed: Big::ToString method
|
||||
in some cases when in the output string the exponent should be equal zero
|
||||
the method changes the exponent to one so the last digit from the mantissa
|
||||
was lost
|
||||
* fixed: Big::ToDouble(double &) set always +INF (infinity)
|
||||
when the value was too large (even for negative values)
|
||||
(it should set -INF in such a case)
|
||||
* added: some missing operators
|
||||
UInt::operator~() /* bitwise neg */
|
||||
UInt::operator&() /* bitwise and */
|
||||
UInt::operator&=()
|
||||
UInt::operator|() /* bitwise or */
|
||||
UInt::operator|=()
|
||||
UInt::operator^() /* bitwise xor */
|
||||
UInt::operator^=()
|
||||
Big::operator&()
|
||||
Big::operator&=()
|
||||
Big::operator|()
|
||||
Big::operator|=()
|
||||
Big::operator^()
|
||||
Big::operator^=()
|
||||
for Big<> we do not define bitwise neg
|
||||
Big::operator++()
|
||||
Big::operator++(int)
|
||||
Big::operator--()
|
||||
Big::operator--(int)
|
||||
* added: macro TTMATH_DONT_USE_WCHAR
|
||||
if defined then the library does not use wide characters
|
||||
(wchar_t, std::wstring, ...) this is a workaround for some compilers
|
||||
* added: bool UInt::IsOnlyTheHighestBitSet()
|
||||
bool UInt::IsOnlyTheLowestBitSet()
|
||||
returning true if only the highest/lowest bit is set
|
||||
* added: uint Int::MulInt(sint ss2)
|
||||
* added: void UInt::Swap(UInt<value_size> & ss2)
|
||||
void Big::Swap(UInt<value_size> & ss2)
|
||||
method for swapping this for an argument
|
||||
* added: macro TTMATH_BIG_DEFAULT_CLEAR
|
||||
when defined the default constructor from Big<> clears its mantissa and exponent
|
||||
Big<1, 2> var;
|
||||
var.mantissa and var.exponent will be set to zero
|
||||
(but var has the NaN flag set too - it is not zero value, this is mainly for debug purposes)
|
||||
* added: only on 32bit platforms:
|
||||
uint UInt::FromUInt(uint64_t n)
|
||||
uint Int::FromInt(int64_t n)
|
||||
void Big::FromUInt(uint64_t n)
|
||||
void Big::FromInt(int64_t n)
|
||||
and appropriate constructors and operators
|
||||
* added: TTMATH_FORCEASM macro
|
||||
asm version of the library is available by default only for:
|
||||
x86 and amd64 platforms and for Microsoft Visual and GCC compilers,
|
||||
but you can force using asm version (the same asm as for Microsoft Visual)
|
||||
by defining TTMATH_FORCEASM macro
|
||||
you have to be sure that your compiler accept such an asm format
|
||||
* added: some missing methods for converting
|
||||
for UInt<>, Int<> and Big<> classes:
|
||||
uint ToUInt()
|
||||
sint ToInt()
|
||||
ToUInt(uint32_t &)
|
||||
ToInt(uint32_t &)
|
||||
ToInt(int32_t &)
|
||||
ToUInt(uint64_t &)
|
||||
ToInt(uint64_t &)
|
||||
ToInt(int64_t &)
|
||||
FromUInt(uint32_t &)
|
||||
FromInt(uint32_t &)
|
||||
FromInt(int32_t &)
|
||||
FromUInt(uint64_t &)
|
||||
FromInt(uint64_t &)
|
||||
FromInt(int64_t &)
|
||||
and appropriate constructors and operators
|
||||
* added: double Big::ToDouble() /there was only Big::ToDouble(double &) /
|
||||
uint Big::ToFloat(float &)
|
||||
float Big::ToFloat()
|
||||
* changed: now asm version is available only on x86 and amd64
|
||||
(and only for GCC and MS VC compilers)
|
||||
* removed: macro TTMATH_RELEASE (now the 'release' version is default)
|
||||
for debug version define TTMATH_DEBUG macro
|
||||
TTMATH_DEBUG is also automatically defined when DEBUG or _DEBUG is set
|
||||
* removed: macro TTMATH_REFERENCE_ASSERT from all methods in public interface
|
||||
|
||||
|
||||
Version 0.9.1 (2010.02.07):
|
||||
* fixed: the parser didn't use characters for changing the base (# and &)
|
||||
those characters were skipped
|
||||
(this bug was introduced in 0.9.0)
|
||||
* fixed: added in the parser: operator's associativity
|
||||
operator ^ (powering) is right-associative:
|
||||
sample: 2^3^4 is equal 2^(3^4) and it is: 2.41e+24
|
||||
previously was: 2^3^4 = (2^3)^4 = 4096
|
||||
* fixed: in Big::ToString_CreateNewMantissaAndExponent() changed the formula:
|
||||
new_exp_ = [log base (2^exponent)] + 1
|
||||
now the part '+ 1' is only made when the logarithm is positive and with fraction
|
||||
if the value is negative we can only skip the fraction, previously
|
||||
we lost some last digits from the new mantissa
|
||||
Consider this binary value (32 bit mantissa):
|
||||
(bin)1.0000000000000000000000000000011
|
||||
previously ToString() gave 1, now we have: 1.000000001
|
||||
* changed: in Big::ToString() the base rounding is made only if the result value
|
||||
would not be an integer, e.g. if the value is 1.999999999999 then
|
||||
the base rounding will not be done - because as the result would be 2
|
||||
* added: IEEE 754 half-to-even rounding (bankers' rounding) to the following
|
||||
floating point algorithms: Big::Add, Big::Sub, Big::Mul, Big::Div
|
||||
* added: static sint UInt<value_size>::FindLowestBitInWord(uint x)
|
||||
this method is looking for the lowest set bit in a word
|
||||
* added: UInt::FindLowestBit(uint & table_id, uint & index)
|
||||
this method is looking for the lowest set bit
|
||||
|
||||
|
||||
Version 0.9.0 (2009.11.25):
|
||||
* added: support for wide characters (wchar_t, std::wstring)
|
||||
* added: Big::IsInteger()
|
||||
returns true if the value is integer (without fraction)
|
||||
(NaN flag is not checked)
|
||||
|
@ -17,10 +156,117 @@ Version 0.9.0 prerelease (2009.07.16):
|
|||
* added: gamma() function to the parser
|
||||
* added: CGamma<ValueType> class
|
||||
is used with Gamma() and Factorial() in multithreaded environment
|
||||
* added: multithread support for Big<> class
|
||||
you should compile with TTMATH_MULTITHREADS
|
||||
and use TTMATH_MULTITHREADS_HELPER macro somewhere in your *.cpp file
|
||||
* added: x86_64 asm code for Microsoft Visual compiler
|
||||
file: ttmathuint_x86_64_msvc.asm
|
||||
(this file should be compiled first because MS VC doesn't support inline assembler in x86_64 mode)
|
||||
* added: flag TTMATH_BIG_ZERO to Big<> class
|
||||
if this flag is set then there is a value zero
|
||||
Big::IsZero() is faster now
|
||||
* added: Big::ClearInfoBit(unsigned char)
|
||||
Big::SetInfoBit(unsigned char)
|
||||
Big::IsInfoBit(unsigned char)
|
||||
some methods for manipulating the info flags
|
||||
* added: macro: TTMATH_BITS(min_bits)
|
||||
which returns the number of machine words
|
||||
capable to hold min_bits bits
|
||||
* added: bool Parser::Calculated()
|
||||
this method returns true is something was calculated
|
||||
(at least one mathematical operator was used or a function or variable)
|
||||
* added: to the parser: operator percentage
|
||||
e.g. 1000-50%=1000-(1000*0,5)=500
|
||||
* added: struct: Conv
|
||||
consists of some parameters used
|
||||
in ToString() and FromString()
|
||||
* added: Big::ToString() can group digits
|
||||
e.g. 1234567 -> 1`234`567
|
||||
* added: Parser::SetGroup(int g)
|
||||
Parser::SetComma(int c, int c2 = 0)
|
||||
Parser::SetParamSep(int s)
|
||||
* added: std::string UInt::ToString(uint b = 10)
|
||||
std::wstring UInt::ToWString(uint b = 10)
|
||||
std::string Int::ToString(uint b = 10)
|
||||
std::wstring Int::ToWString(uint b = 10)
|
||||
uint Big::ToString(std::string & result, const Conv & conv)
|
||||
uint Big::ToString(std::wstring & result, const Conv & conv)
|
||||
std::string Big::ToString(const Conv & conv)
|
||||
std::string Big::ToString()
|
||||
std::wstring Big::ToWString(const Conv & conv)
|
||||
std::wstring Big::ToWString()
|
||||
* added: uint FromString(const char * source, const Conv & conv, const char **, bool *)
|
||||
uint FromString(const wchar_t * source, const Conv & conv, const wchar_t **, bool *)
|
||||
uint FromString(const std::string & string, const Conv & conv, const wchar_t **, bool *)
|
||||
uint FromString(const std::wstring & string, const Conv & conv, const wchar_t **, bool *)
|
||||
* added: UInt::Sqrt() - a new algorithm for calculating the square root
|
||||
* added: to the parser: function frac() - returns a value without the integer part
|
||||
(only fraction remains)
|
||||
* added: Int::DivInt(sint divisor, sint * remainder)
|
||||
* added: const char * UInt::LibTypeStr()
|
||||
const char * Big::LibTypeStr()
|
||||
LibTypeCode UInt::LibType()
|
||||
LibTypeCode Big::LibType()
|
||||
returning a string/enum represents the currect type of the library
|
||||
we have following types:
|
||||
asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
||||
asm_gcc_32 - with asm code designed for GCC (32 bits)
|
||||
asm_vc_64 - with asm for VC (64 bit)
|
||||
asm_gcc_64 - with asm for GCC (64 bit)
|
||||
no_asm_32 - pure C++ version (32 bit) - without any asm code
|
||||
no_asm_64 - pure C++ version (64 bit) - without any asm code
|
||||
* added: UInt::operator>>(int)
|
||||
UInt::operator>>=(int)
|
||||
UInt::operator<<(int)
|
||||
UInt::operator<<=(int)
|
||||
* changed: Factorial() is using the Gamma() function now
|
||||
* changed: Big::Div(ss2)
|
||||
Big::Mod(ss2)
|
||||
they return 2 when ss2 is zero
|
||||
previously returned 1
|
||||
* changed: algorithms in Big::Sqrt() and ttmath::Root(x ; n)
|
||||
they were not too much accurate for some integers
|
||||
e.g. Root(16;4) returned a value very closed to 2 (not exactly 2)
|
||||
* changed: added specializations to Big::ToString() when the base is equal 4, 8 or 16
|
||||
the previous version was not accurate on some last digits (after the comma operator)
|
||||
consider this binary value (32 bit mantissa):
|
||||
base 2: 1.1111 1111 1111 1111 1111 1111 1110 101
|
||||
previous ToString() gave:
|
||||
base 4: 1.33333333333332
|
||||
base 8: 1.777777777
|
||||
base 16: 1.FFFFFF
|
||||
now we have:
|
||||
base 4: 1.3333333333333222
|
||||
base 8: 1.77777777724
|
||||
base 16: 1.FFFFFFEA
|
||||
* changed: in Big::ToString() some additional rounding (base_round) is now made only
|
||||
when the value is not an integer
|
||||
* changed: another compilers than MS VC or GCC by default use no asm version (TTMATH_NOASM)
|
||||
* removed: Parser<>::SetFactorialMax() method
|
||||
the factorial() is such a fast now that we don't need the method longer
|
||||
* removed: ErrorCode::err_too_big_factorial
|
||||
* removed: macros: TTMATH_COMMA_CHARACTER_1 and TTMATH_COMMA_CHARACTER_2
|
||||
the comma characters we have in Conv struct now
|
||||
|
||||
|
||||
Version 0.8.6 (2009.10.25):
|
||||
* fixed: UInt::SetBitInWord(uint & value, uint bit) set 1 if the bit was
|
||||
equal 1 (should be set 2)
|
||||
this affected only no-asm parts - when macro TTMATH_NOASM was defined
|
||||
* fixed: UInt<value_size>::MulInt(uint ss2)
|
||||
there was a buffer overflow when value_size was equal 1
|
||||
* fixed: UInt::AddVector() and UInt::SubVector() didn't want to compile
|
||||
when macro TTMATH_NOASM was defined
|
||||
* fixed: Big::operator>> didn't correctly recognize values in scientific mode (with 'e' character)
|
||||
* fixed: Int::FromString(const tt_string & s, uint b = 10)
|
||||
didn't use 'b' (always was '10')
|
||||
* fixed: buffer overflow in Big::ToInt(Int<int_size> & result)
|
||||
* fixed: powering algorithm in:
|
||||
UInt::Pow(UInt<value_size> pow)
|
||||
Big::Pow(UInt<pow_size> pow)
|
||||
Big::PowUInt(Big<exp, man> pow)
|
||||
when 'pow' was sufficient large the algorithm returned carry
|
||||
but the result could have been calculated correctly
|
||||
|
||||
|
||||
Version 0.8.5 (2009.06.16):
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
# CMake configuration for ttmath
|
||||
cmake_minimum_required (VERSION 3.0)
|
||||
project(ttmath)
|
||||
enable_testing()
|
||||
include_directories(${ttmath_SOURCE_DIR})
|
||||
add_subdirectory(samples)
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2006-2009, Tomasz Sowa
|
||||
Copyright (c) 2006-2017, Tomasz Sowa
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
35
README
35
README
|
@ -1,26 +1,23 @@
|
|||
TTMath - a bignum library for C++
|
||||
A bignum library for C++
|
||||
|
||||
TTMath is a small library which allows one to perform arithmetic operations
|
||||
with big unsigned integer, big signed integer and big floating point
|
||||
numbers. It provides standard mathematical operations like adding,
|
||||
subtracting, multiplying, dividing etc. With the library also goes
|
||||
a mathematical parser which helps you solving input formulas read directly
|
||||
from a user.
|
||||
with big unsigned integer, big signed integer and big floating point numbers.
|
||||
It provides standard mathematical operations like adding, subtracting,
|
||||
multiplying, dividing. With the library also goes a mathematical parser to
|
||||
help you solving mathematical expressions.
|
||||
|
||||
TTMath is developed under the BSD licence which means that it is free
|
||||
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.
|
||||
TTMath is developed under the BSD licence which means that it is free for
|
||||
both personal and commercial use.
|
||||
|
||||
The main goal of the library is to allow one to use big values in the same
|
||||
way as the standard types like int, float, etc. It does not need to be
|
||||
compiled first because the whole library is written as the C++ templates.
|
||||
This means only C++ developers can use this library and one thing they have
|
||||
to do is to use 'include' directive of the preprocessor. How big the
|
||||
values can be is set directly in the source code by the programmer.
|
||||
way as the standard types like int or float. It does not need to be compiled
|
||||
first because the whole library is written as the C++ templates. This means
|
||||
only C++ developers can use this library and one thing they have to do is
|
||||
to use 'include' directive of the preprocessor. How big the values can be
|
||||
is set at compile time.
|
||||
|
||||
Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
Project pages: http://www.ttmath.org
|
||||
http://sourceforge.net/projects/ttmath
|
||||
WWW: http://www.ttmath.org
|
||||
|
||||
Contributors:
|
||||
Christian Kaiser <chk@online.de>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
o = main.o
|
||||
CC = g++
|
||||
CFLAGS = -s -O2 -DTTMATH_CONSTANTSGENERATOR
|
||||
CC = clang++
|
||||
CFLAGS = -O2 -DTTMATH_CONSTANTSGENERATOR
|
||||
name = gen
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@ name = gen
|
|||
all: $(name)
|
||||
|
||||
$(name): $(o)
|
||||
$(CC) -o $(name) $(CFLAGS) $(o)
|
||||
$(CC) -o $(name) -s $(CFLAGS) $(o)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||
* and is distributed under the 3-Clause BSD Licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
2543
doxygen.cfg
2543
doxygen.cfg
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,137 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
a=""
|
||||
b=""
|
||||
c=""
|
||||
p=""
|
||||
d=""
|
||||
doxygen=""
|
||||
|
||||
# reading until not empty
|
||||
|
||||
while [ -z $a ]
|
||||
do
|
||||
echo -n "Major: " ; read a
|
||||
done
|
||||
|
||||
|
||||
while [ -z $b ]
|
||||
do
|
||||
echo -n "Minor: " ; read b;
|
||||
done
|
||||
|
||||
|
||||
while [ -z $c ]
|
||||
do
|
||||
echo -n "Revision: " ; read c;
|
||||
done
|
||||
|
||||
|
||||
while [ -z $p ]
|
||||
do
|
||||
echo -n "Prerelease? (y/n): " ; read p;
|
||||
done
|
||||
|
||||
|
||||
while [ -z $d ]
|
||||
do
|
||||
echo -n "Add date? (y/n): " ; read d;
|
||||
done
|
||||
|
||||
|
||||
while [ -z $doxygen ]
|
||||
do
|
||||
echo -n "Clean make and add to the package doxygen doc? (y/n): " ; read doxygen;
|
||||
done
|
||||
|
||||
|
||||
mkdir -p releases
|
||||
package_dir_name="ttmath-$a.$b.$c"
|
||||
datestr=""
|
||||
|
||||
|
||||
if [ $p = "y" -o $p = "Y" ]
|
||||
then
|
||||
package_dir_name=${package_dir_name}.prerelease
|
||||
fi
|
||||
|
||||
package_dir_name=${package_dir_name}-src
|
||||
|
||||
if [ $d = "y" -o $d = "Y" ]
|
||||
then
|
||||
datestr=`/bin/date "+%G.%m.%d"`;
|
||||
package_dir_name=${package_dir_name}-$datestr
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
dir="releases/"${package_dir_name}
|
||||
package=${package_dir_name}.tar.gz
|
||||
|
||||
|
||||
if [ -d $dir ]
|
||||
then
|
||||
echo "Directory $dir exists! (exiting)";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [ -f "releases/"${package} ] ; then
|
||||
echo "File releases/${package} exists! (exiting)"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
|
||||
mkdir $dir
|
||||
|
||||
|
||||
|
||||
if [ $doxygen = "y" -o $doxygen = "Y" ]
|
||||
then
|
||||
|
||||
echo "------------------------------------------------------"
|
||||
echo "creating doxygen doc"
|
||||
echo "------------------------------------------------------"
|
||||
|
||||
rm -rf doc/doxygen
|
||||
doxygen doxygen.cfg
|
||||
|
||||
cp -r doc $dir/
|
||||
fi
|
||||
|
||||
|
||||
echo "------------------------------------------------------"
|
||||
echo "make clean in samples"
|
||||
echo "------------------------------------------------------"
|
||||
|
||||
make -C samples clean
|
||||
make -C constgen clean
|
||||
|
||||
|
||||
echo "------------------------------------------------------"
|
||||
echo "making source package"
|
||||
echo "------------------------------------------------------"
|
||||
|
||||
mkdir $dir/ttmath
|
||||
mkdir $dir/samples
|
||||
mkdir $dir/res
|
||||
|
||||
cp ttmath/* $dir/ttmath/
|
||||
|
||||
cp samples/* $dir/samples/
|
||||
# cmake is not ready yet (cmake will generate Makefile which overwrites our own one)
|
||||
rm $dir/samples/CMakeLists.txt
|
||||
|
||||
cp COPYRIGHT $dir/
|
||||
cp README $dir/
|
||||
cp CHANGELOG $dir/
|
||||
|
||||
cp res/ttmath_logo.svg $dir/res/
|
||||
|
||||
cd releases
|
||||
tar -czf $package ${package_dir_name}
|
||||
|
||||
echo "the package has been created to:" releases/${package}
|
||||
|
||||
exit 0
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="38.084499"
|
||||
height="38.083"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="ttmath_logo.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:cx="24.511255"
|
||||
inkscape:cy="17.621314"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="830"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-350.08291,-424.26987)">
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.625;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
d="m 369.125,424.28125 c -10.50699,0 -19.03125,8.52426 -19.03125,19.03125 0,10.50603 8.52426,19.03125 19.03125,19.03125 10.50746,0 19.03125,-8.52522 19.03125,-19.03125 0,-10.50699 -8.52379,-19.03125 -19.03125,-19.03125 z"
|
||||
id="path3773" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffaa35;fill-opacity:1;stroke:none;stroke-width:1.62500000000000000;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
d="m 369.125,425.90625 c 9.62928,0 17.40625,7.77748 17.40625,17.40625 0,9.62773 -7.77697,17.40625 -17.40625,17.40625 -9.62877,0 -17.40625,-7.77852 -17.40625,-17.40625 0,-9.62877 7.77748,-17.40625 17.40625,-17.40625 z"
|
||||
id="path2999-2" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
d="m 368.1875,432.65625 -0.1875,0.5 -6.34375,16.71875 -1.40625,-4 -0.5,-1.40625 -0.84375,1.25 -2.0625,3.125 1.25,0.8125 1.25,-1.875 1.5625,4.53125 0.6875,1.9375 0.71875,-1.9375 6.90625,-18.15625 8.65625,0 0,-1.5 -9.15625,0 -0.53125,0 z"
|
||||
id="path3003-3"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
d="m 359.84375,434.34375 0,3 -3,0 0,1.5 3,0 0,3.21875 1.5,0 0,-3.21875 3,0 0,-1.5 -3,0 0,-3 -1.5,0 z"
|
||||
id="path3005-3"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.9375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
d="m 371.0625,443.5625 0,0.46875 -0.125,4.6875 0,0.15625 0.125,0.15625 c 0,0 0.37411,0.46147 0.9375,0.9375 0.2817,0.23802 0.59509,0.49145 0.96875,0.6875 0.37366,0.19605 0.8013,0.32003 1.25,0.34375 0.93515,0.0491 1.77613,-0.36791 2.40625,-0.78125 0.63012,-0.41334 1.0625,-0.84375 1.0625,-0.84375 l 0.125,-0.15625 0,-0.1875 -0.0937,-5 0,-0.46875 -0.46875,0 -5.71875,0 -0.46875,0 z"
|
||||
id="path3009-7"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccsscsccccccccc" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.9375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
d="m 377.65625,450.375 -0.0312,0.0312 -0.21875,0.125 c -2.30252,1.65271 -4.15395,1.52806 -6.1125,-0.1562 -1.78014,2.66032 -3.73192,7.25254 -4.29375,8.18745 -0.56183,0.93491 -0.17739,2.37424 -0.28125,3.375 l 0.5625,-0.0312 8.03125,-0.71875 0.125,-0.0312 0.0937,-0.0625 6.96875,-4.5625 0.1875,-0.125 0.0937,-0.0625 -0.0625,-0.3125 c 0.0108,-0.11043 0.0366,-0.43638 0,-0.96875 -0.0466,-1.03041 -0.48309,-1.60724 -0.93745,-2.24995 -0.5467,-0.58055 -1.33798,-1.08483 -2.15625,-1.5 -0.91162,-0.46254 -1.66155,-0.7891 -1.71875,-0.8125 l -0.0625,-0.0312 -0.1875,-0.0937 z"
|
||||
id="path3013-6"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccczcccccccccccscccc" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.625;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
d="m 374.0625,438.21875 c -1.68685,0.1362 -5.3125,0.8125 -5.3125,0.8125 l -0.125,0.0312 -0.0625,0.125 -1.375,2.09375 -0.0312,0.0625 0,0.0937 0.1875,6.15625 0.0312,0.15625 0.125,0.0937 0.3125,0.21875 0.5,0.3125 -0.0312,-0.59375 -0.0937,-5.90625 c 0.081,-0.0694 0.35604,-0.32331 0.6875,-0.4375 l 0.0312,0 c 0.0323,-0.01 0.0883,0.01 0.125,0 l 1.46875,-0.0937 c 0.1093,0.60186 0.39332,1.20774 0.4812,1.8125 1.27397,-0.0782 2.40491,-0.17552 3.5031,-0.16892 1.08715,0.0103 2.17115,0.13001 3.2344,0.12517 l 0.0312,-0.6125 c 0,0 0.0422,-0.16533 0.0625,-0.28125 l 0.40625,-0.9375 c 0.004,-0.005 -0.004,-0.0267 0,-0.0312 l 0.0312,0 c 0.17093,-0.1709 0.53319,-0.25585 0.8125,-0.375 0.26159,-0.11159 0.42068,-0.28594 0.75,-0.375 l 0.0312,0 0.125,-0.0312 2.28125,-0.1875 0.0312,0 0.28125,0 0,-0.0312 0,-0.28125 0,-0.71875 0,-0.25 -0.25,-0.0625 -3.75,-0.71875 c -0.0114,-10e-4 -0.02,0.001 -0.0312,0 -1.37083,-0.13192 -2.78705,-0.1247 -4.40625,0 l -0.0312,0 -0.0312,0 z"
|
||||
id="path3017-6"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccccccccccccccccccsccccccccccccccccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,16 @@
|
|||
# CMake configuration for ttmath/samples
|
||||
|
||||
# Building with Visual C++ x86_64 needs to compile the asm utilities first
|
||||
if (MSVC AND "x${CMAKE_VS_PLATFORM_NAME}" STREQUAL "xx64")
|
||||
set(TTMATH_MSVC64_ASM ttmathuint_x86_64_msvc.asm)
|
||||
enable_language(ASM_MASM)
|
||||
message(STATUS "Enabled MASM to compile '${TTMATH_MSVC64_ASM}'")
|
||||
set(TTMATH_SRC_ASM ${ttmath_SOURCE_DIR}/ttmath/${TTMATH_MSVC64_ASM})
|
||||
endif()
|
||||
|
||||
set(SAMPLES big big2 int uint parser)
|
||||
foreach(sample ${SAMPLES})
|
||||
add_executable(${sample} ${sample}.cpp ${TTMATH_SRC_ASM})
|
||||
# Allow to run all utilities at once as a test
|
||||
add_test(${sample} ${sample})
|
||||
endforeach()
|
|
@ -1,5 +1,6 @@
|
|||
CC = g++
|
||||
CFLAGS = -Wall -pedantic -s -O2 -I..
|
||||
#CC = clang++
|
||||
CFLAGS = -Wall -pedantic -O2 -I.. -DTTMATH_DONT_USE_WCHAR
|
||||
|
||||
|
||||
.SUFFIXES: .cpp .o
|
||||
|
@ -8,25 +9,29 @@ CFLAGS = -Wall -pedantic -s -O2 -I..
|
|||
$(CC) -c $(CFLAGS) $<
|
||||
|
||||
|
||||
all: uint int big parser
|
||||
all: uint int big big2 parser
|
||||
|
||||
|
||||
uint: uint.o
|
||||
$(CC) -o uint $(CFLAGS) uint.o
|
||||
$(CC) -o uint -s $(CFLAGS) uint.o
|
||||
|
||||
int: int.o
|
||||
$(CC) -o int $(CFLAGS) int.o
|
||||
$(CC) -o int -s $(CFLAGS) int.o
|
||||
|
||||
big: big.o
|
||||
$(CC) -o big $(CFLAGS) big.o
|
||||
$(CC) -o big -s $(CFLAGS) big.o
|
||||
|
||||
big2: big2.o
|
||||
$(CC) -o big2 -s $(CFLAGS) big2.o
|
||||
|
||||
parser: parser.o
|
||||
$(CC) -o parser $(CFLAGS) parser.o
|
||||
$(CC) -o parser -s $(CFLAGS) parser.o
|
||||
|
||||
|
||||
uint.o: uint.cpp
|
||||
int.o: int.cpp
|
||||
big.o: big.cpp
|
||||
big2.o: big2.cpp
|
||||
parser.o: parser.cpp
|
||||
|
||||
|
||||
|
@ -36,6 +41,7 @@ clean:
|
|||
rm -f uint
|
||||
rm -f int
|
||||
rm -f big
|
||||
rm -f big2
|
||||
rm -f parser
|
||||
# on MS Windows can automatically be added suffixes .exe to the names of output programs
|
||||
# on MS Windows suffixes .exe will be automatically added
|
||||
rm -f *.exe
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
// this type has 2 words for its mantissa and 1 word for its exponent
|
||||
// (on a 32bit platform one word means a word of 32 bits,
|
||||
// and on a 64bit platform one word means a word of 64 bits)
|
||||
|
||||
// Big<exponent, mantissa>
|
||||
typedef ttmath::Big<1,2> MyBig;
|
||||
|
||||
|
||||
|
@ -56,6 +58,7 @@ MyBig atemp;
|
|||
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
MyBig a,b;
|
||||
|
@ -85,13 +88,13 @@ a = 123456.543456
|
|||
b = 98767878.124322
|
||||
a + b = 98891334.667778
|
||||
a - b = -98644421.580866
|
||||
a * b = 12193540837712.2708
|
||||
a / b = 0.0012499665458095765
|
||||
a * b = 12193540837712.27076
|
||||
a / b = 0.00124996654580957646
|
||||
Calculating with a carry
|
||||
a = 1.624801256070839555e+646457012
|
||||
b = 456.31999999999999
|
||||
a + b = 1.624801256070839555e+646457012
|
||||
a - b = 1.624801256070839555e+646457012
|
||||
a = 1.6248012560666408782e+646457012
|
||||
b = 456.319999999999993
|
||||
a + b = 1.6248012560666408782e+646457012
|
||||
a - b = 1.6248012560666408782e+646457012
|
||||
a * b = (carry)
|
||||
a / b = 3.56066193914542334e+646457009
|
||||
a / b = 3.560661939136222174e+646457009
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
#include <ttmath/ttmath.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
// this is a similar example to big.cpp
|
||||
// but now we're using TTMATH_BITS() macro
|
||||
// this macro returns how many words we need to store
|
||||
// the given number of bits
|
||||
|
||||
// TTMATH_BITS(64)
|
||||
// on a 32bit platform the macro returns 2 (2*32=64)
|
||||
// on a 64bit platform the macro returns 1
|
||||
|
||||
// TTMATH_BITS(128)
|
||||
// on a 32bit platform the macro returns 4 (4*32=128)
|
||||
// on a 64bit platform the macro returns 2 (2*64=128)
|
||||
|
||||
// Big<exponent, mantissa>
|
||||
typedef ttmath::Big<TTMATH_BITS(64), TTMATH_BITS(128)> MyBig;
|
||||
|
||||
// consequently on a 32bit platform we define: Big<2, 4>
|
||||
// and on a 64bit platform: Big<1, 2>
|
||||
// and the calculations will be the same on both platforms
|
||||
|
||||
|
||||
void SimpleCalculating(const MyBig & a, const MyBig & b)
|
||||
{
|
||||
std::cout << "Simple calculating" << std::endl;
|
||||
std::cout << "a = " << a << std::endl;
|
||||
std::cout << "b = " << b << std::endl;
|
||||
std::cout << "a + b = " << a+b << std::endl;
|
||||
std::cout << "a - b = " << a-b << std::endl;
|
||||
std::cout << "a * b = " << a*b << std::endl;
|
||||
std::cout << "a / b = " << a/b << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void CalculatingWithCarry(const MyBig & a, const MyBig & b)
|
||||
{
|
||||
MyBig atemp;
|
||||
|
||||
std::cout << "Calculating with a carry" << std::endl;
|
||||
std::cout << "a = " << a << std::endl;
|
||||
std::cout << "b = " << b << std::endl;
|
||||
|
||||
atemp = a;
|
||||
if( !atemp.Add(b) )
|
||||
std::cout << "a + b = " << atemp << std::endl;
|
||||
else
|
||||
std::cout << "a + b = (carry)" << std::endl;
|
||||
// it have no sense to print 'atemp' (it's undefined)
|
||||
|
||||
atemp = a;
|
||||
if( !atemp.Sub(b) )
|
||||
std::cout << "a - b = " << atemp << std::endl;
|
||||
else
|
||||
std::cout << "a - b = (carry)" << std::endl;
|
||||
|
||||
atemp = a;
|
||||
if( !atemp.Mul(b) )
|
||||
std::cout << "a * b = " << atemp << std::endl;
|
||||
else
|
||||
std::cout << "a * b = (carry)" << std::endl;
|
||||
|
||||
|
||||
atemp = a;
|
||||
if( !atemp.Div(b) )
|
||||
std::cout << "a / b = " << atemp << std::endl;
|
||||
else
|
||||
std::cout << "a / b = (carry or division by zero) " << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
MyBig a,b;
|
||||
|
||||
// conversion from 'const char *'
|
||||
a = "123456.543456";
|
||||
b = "98767878.124322";
|
||||
|
||||
SimpleCalculating(a,b);
|
||||
|
||||
// 'a' will have the max value which can be held in this type
|
||||
a.SetMax();
|
||||
|
||||
// conversion from double
|
||||
b = 456.32;
|
||||
|
||||
// Look at the value 'a' and the product from a+b and a-b
|
||||
// Don't worry this is the nature of floating point numbers
|
||||
CalculatingWithCarry(a,b);
|
||||
}
|
||||
|
||||
/*
|
||||
the result (the same on a 32 or 64bit platform):
|
||||
|
||||
Simple calculating
|
||||
a = 123456.543456
|
||||
b = 98767878.124322
|
||||
a + b = 98891334.667778
|
||||
a - b = -98644421.580866
|
||||
a * b = 12193540837712.270763536832
|
||||
a / b = 0.0012499665458095764605964485261668609133
|
||||
Calculating with a carry
|
||||
a = 2.34953455457111777368832820909595050034e+2776511644261678604
|
||||
b = 456.3199999999999931787897367030382156
|
||||
a + b = 2.34953455457111777368832820909595050034e+2776511644261678604
|
||||
a - b = 2.34953455457111777368832820909595050034e+2776511644261678604
|
||||
a * b = (carry)
|
||||
a / b = 5.1488748127873374141170361292780486452e+2776511644261678601
|
||||
*/
|
|
@ -29,6 +29,11 @@ const char equation[] = " (34 + 24) * 123 - 34.32 ^ 6 * sin(2.56) - atan(10)";
|
|||
|
||||
/*
|
||||
the result (on 32 bit platform):
|
||||
|
||||
-897705014.52573107
|
||||
-897705014.525731067
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
the result (on 64 bit platform):
|
||||
-897705014.5257310676097719585259773124
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
CC = g++
|
||||
CC = clang++
|
||||
o = main.o uinttest.o
|
||||
CFLAGS = -Wall -O2 -s
|
||||
CFLAGS = -Wall -O2
|
||||
ttmath = ..
|
||||
name = tests
|
||||
|
||||
|
@ -16,7 +16,7 @@ all: $(name)
|
|||
|
||||
|
||||
$(name): $(o)
|
||||
$(CC) -o $(name) $(CFLAGS) -I$(ttmath) $(o)
|
||||
$(CC) -o $(name) -s $(CFLAGS) -I$(ttmath) $(o)
|
||||
|
||||
|
||||
main.o: main.cpp uinttest.h
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||
* and is distributed under the 3-Clause BSD Licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||
* and is distributed under the 3-Clause BSD Licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||
* and is distributed under the 3-Clause BSD Licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
#CC = g++6
|
||||
#CFLAGS = -Wall -pedantic -O3 -s -I.. -Wl,-rpath=/usr/local/lib/gcc6
|
||||
#CFLAGS = -Wall -pedantic -O3 -DTTMATH_NOASM -s -I.. -Wl,-rpath=/usr/local/lib/gcc6
|
||||
|
||||
CC = clang++
|
||||
CFLAGS = -Wall -pedantic -O3 -s -I..
|
||||
#CFLAGS = -Wall -pedantic -O3 -DTTMATH_NOASM -s -I..
|
||||
|
||||
|
||||
|
||||
.SUFFIXES: .cpp .o
|
||||
|
||||
.cpp.o:
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
|
||||
|
||||
|
||||
|
||||
all: big_64_64 big_64_128 big_64_192 big_64_256 big_64_512 big_64_1024 big_64_2048 big_64_4096 big_128_512 big_256_1024 big_512_2048 big_128_4096
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
big_64_64: main.cpp
|
||||
$(CC) -o big_64_64 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=64 main.cpp
|
||||
|
||||
big_64_128: main.cpp
|
||||
$(CC) -o big_64_128 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=128 main.cpp
|
||||
|
||||
big_64_192: main.cpp
|
||||
$(CC) -o big_64_192 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=192 main.cpp
|
||||
|
||||
big_64_256: main.cpp
|
||||
$(CC) -o big_64_256 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=256 main.cpp
|
||||
|
||||
big_64_512: main.cpp
|
||||
$(CC) -o big_64_512 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=512 main.cpp
|
||||
|
||||
big_64_1024: main.cpp
|
||||
$(CC) -o big_64_1024 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=1024 main.cpp
|
||||
|
||||
big_64_2048: main.cpp
|
||||
$(CC) -o big_64_2048 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=2048 main.cpp
|
||||
|
||||
big_64_4096: main.cpp
|
||||
$(CC) -o big_64_4096 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=4096 main.cpp
|
||||
|
||||
big_128_512: main.cpp
|
||||
$(CC) -o big_128_512 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=128 -DTTMATH_TEST_BIG_MANTISSA=512 main.cpp
|
||||
|
||||
big_256_1024: main.cpp
|
||||
$(CC) -o big_256_1024 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=256 -DTTMATH_TEST_BIG_MANTISSA=1024 main.cpp
|
||||
|
||||
big_512_2048: main.cpp
|
||||
$(CC) -o big_512_2048 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=512 -DTTMATH_TEST_BIG_MANTISSA=2048 main.cpp
|
||||
|
||||
big_128_4096: main.cpp
|
||||
$(CC) -o big_128_4096 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=128 -DTTMATH_TEST_BIG_MANTISSA=4096 main.cpp
|
||||
|
||||
|
||||
|
||||
|
||||
test: all
|
||||
@echo "****************************************************************************"
|
||||
@echo "making tests for exponent=64 and mantissa=64"
|
||||
@echo "****************************************************************************"
|
||||
cat tests.txt | xargs -S 4096 -I foo ./big_64_64 "foo" | tee big_64_64.out
|
||||
|
||||
@echo "****************************************************************************"
|
||||
@echo "making tests for exponent=64 and mantissa=128"
|
||||
@echo "****************************************************************************"
|
||||
cat tests.txt | xargs -S 4096 -I foo ./big_64_128 "foo" | tee big_64_128.out
|
||||
|
||||
@echo "****************************************************************************"
|
||||
@echo "making tests for exponent=64 and mantissa=192"
|
||||
@echo "****************************************************************************"
|
||||
cat tests.txt | xargs -S 4096 -I foo ./big_64_192 "foo" | tee big_64_192.out
|
||||
|
||||
@echo "****************************************************************************"
|
||||
@echo "making tests for exponent=64 and mantissa=256"
|
||||
@echo "****************************************************************************"
|
||||
cat tests.txt | xargs -S 4096 -I foo ./big_64_256 "foo" | tee big_64_256.out
|
||||
|
||||
@echo "****************************************************************************"
|
||||
@echo "making tests for exponent=64 and mantissa=512"
|
||||
@echo "****************************************************************************"
|
||||
cat tests.txt | xargs -S 4096 -I foo ./big_64_512 "foo" | tee big_64_512.out
|
||||
|
||||
@echo "****************************************************************************"
|
||||
@echo "making tests for exponent=64 and mantissa=1024"
|
||||
@echo "****************************************************************************"
|
||||
cat tests.txt | xargs -S 4096 -I foo ./big_64_1024 "foo" | tee big_64_1024.out
|
||||
|
||||
@echo "****************************************************************************"
|
||||
@echo "making tests for exponent=64 and mantissa=2048"
|
||||
@echo "****************************************************************************"
|
||||
cat tests.txt | xargs -S 4096 -I foo ./big_64_2048 "foo" | tee big_64_2048.out
|
||||
|
||||
@echo "****************************************************************************"
|
||||
@echo "making tests for exponent=64 and mantissa=4096"
|
||||
@echo "****************************************************************************"
|
||||
cat tests.txt | xargs -S 4096 -I foo ./big_64_4096 "foo" | tee big_64_4096.out
|
||||
|
||||
@echo "****************************************************************************"
|
||||
@echo "making tests for exponent=128 and mantissa=512"
|
||||
@echo "****************************************************************************"
|
||||
cat tests.txt | xargs -S 4096 -I foo ./big_128_512 "foo" | tee big_128_512.out
|
||||
|
||||
@echo "****************************************************************************"
|
||||
@echo "making tests for exponent=128 and mantissa=4096"
|
||||
@echo "****************************************************************************"
|
||||
cat tests.txt | xargs -S 4096 -I foo ./big_128_4096 "foo" | tee big_128_4096.out
|
||||
|
||||
@echo "****************************************************************************"
|
||||
@echo "making tests for exponent=256 and mantissa=1024"
|
||||
@echo "****************************************************************************"
|
||||
cat tests.txt | xargs -S 4096 -I foo ./big_256_1024 "foo" | tee big_256_1024.out
|
||||
|
||||
@echo "****************************************************************************"
|
||||
@echo "making tests for exponent=512 and mantissa=2048"
|
||||
@echo "****************************************************************************"
|
||||
cat tests.txt | xargs -S 4096 -I foo ./big_512_2048 "foo" | tee big_512_2048.out
|
||||
|
||||
./check_files.sh
|
||||
|
||||
|
||||
clean:
|
||||
rm -f *.out
|
||||
rm -f big_64_64 big_64_128 big_64_192 big_64_256 big_64_512 big_64_1024 big_64_2048 big_64_4096 big_128_512 big_256_1024 big_512_2048 big_128_4096
|
||||
# on MS Windows suffixes .exe will be automatically added
|
||||
rm -f *.exe
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
|||
#!/bin/sh
|
||||
|
||||
was_error=0
|
||||
|
||||
for expected in *.expected ; do
|
||||
|
||||
out=`basename $expected .expected`.out
|
||||
|
||||
if [ -f $out ] ; then
|
||||
diff -u $out $expected
|
||||
|
||||
if [ `diff -u $out $expected | wc -l` -ne 0 ] ; then
|
||||
was_error=1
|
||||
fi
|
||||
else
|
||||
echo "there is no file: $out"
|
||||
was_error=1
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
||||
if [ $was_error -eq 0 ] ; then
|
||||
echo "****************************************************************************"
|
||||
echo " congratulations: all tests passed successfully"
|
||||
echo "****************************************************************************"
|
||||
else
|
||||
echo "****************************************************************************"
|
||||
echo " error: not all tests passed successfully"
|
||||
echo "****************************************************************************"
|
||||
fi
|
|
@ -0,0 +1,39 @@
|
|||
#include <ttmath/ttmath.h>
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
typedef ttmath::Big<TTMATH_BITS(TTMATH_TEST_BIG_EXPONENT), TTMATH_BITS(TTMATH_TEST_BIG_MANTISSA)> MyBig;
|
||||
ttmath::Parser<MyBig> parser;
|
||||
std::string all_input;
|
||||
|
||||
for(int i=1 ; i<argc ; ++i)
|
||||
{
|
||||
if( i > 1 )
|
||||
all_input += ' ';
|
||||
|
||||
all_input += argv[i];
|
||||
}
|
||||
|
||||
std::cout << all_input << " = ";
|
||||
ttmath::ErrorCode err = parser.Parse(all_input);
|
||||
|
||||
if( err == ttmath::err_ok )
|
||||
{
|
||||
for(size_t i=0 ; i < parser.stack.size() ; ++i)
|
||||
{
|
||||
if( i > 0 )
|
||||
std::cout << " ; ";
|
||||
|
||||
std::cout << parser.stack[i].value;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "error: " << static_cast<int>(err) << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
600
ttmath/ttmath.h
600
ttmath/ttmath.h
File diff suppressed because it is too large
Load Diff
3467
ttmath/ttmathbig.h
3467
ttmath/ttmathbig.h
File diff suppressed because it is too large
Load Diff
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the PNG licence.
|
||||
* Author: Christian Kaiser <chk@online.de>
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2009 Christian Kaiser
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
#ifndef headerfilettmathconfig
|
||||
#define headerfilettmathconfig
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace ttmath
|
||||
{
|
||||
#if defined(WIN32)
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(_MT)
|
||||
class clsCrit
|
||||
{
|
||||
private:
|
||||
mutable CRITICAL_SECTION _Crit;
|
||||
|
||||
clsCrit(const clsCrit&) // inhibit copy (easy mistake to do; use clsCritObj instead!!!)
|
||||
{
|
||||
}
|
||||
clsCrit& operator=(const clsCrit& rhs); // inhibit assignment
|
||||
public:
|
||||
clsCrit(void)
|
||||
{
|
||||
InitializeCriticalSection(&_Crit);
|
||||
}
|
||||
virtual ~clsCrit(void)
|
||||
{
|
||||
DeleteCriticalSection(&_Crit);
|
||||
}
|
||||
|
||||
void Enter(void) const
|
||||
{
|
||||
EnterCriticalSection(&_Crit);
|
||||
}
|
||||
void Leave(void) const
|
||||
{
|
||||
LeaveCriticalSection(&_Crit);
|
||||
}
|
||||
};
|
||||
|
||||
class clsCritObj
|
||||
{
|
||||
private:
|
||||
const clsCrit& _Crit;
|
||||
|
||||
clsCritObj& operator=(const clsCritObj& rhs); // not applicable
|
||||
public:
|
||||
clsCritObj(const clsCrit& Sync)
|
||||
: _Crit(Sync)
|
||||
{
|
||||
_Crit.Enter();
|
||||
}
|
||||
~clsCritObj(void)
|
||||
{
|
||||
_Crit.Leave();
|
||||
}
|
||||
};
|
||||
#define TTMATH_IMPLEMENT_THREADSAFE_OBJ \
|
||||
private: \
|
||||
clsCrit CritSect; \
|
||||
public: \
|
||||
operator clsCrit&() \
|
||||
{ \
|
||||
return(CritSect); \
|
||||
}
|
||||
#define TTMATH_USE_THREADSAFE_OBJ(c) clsCritObj lock(c)
|
||||
#endif
|
||||
#else // defined(WIN32)
|
||||
// not Windows world: no threading synchronization for now
|
||||
#endif
|
||||
|
||||
#if !defined(TTMATH_IMPLEMENT_THREADSAFE_OBJ)
|
||||
// if we don't know about serialization, make it a no-op
|
||||
#define TTMATH_IMPLEMENT_THREADSAFE_OBJ /* */
|
||||
#define TTMATH_USE_THREADSAFE_OBJ(c) /* */
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // headerfilettmathconfig
|
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the 3-Clause BSD Licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||
* project may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef headerfilettmathdec
|
||||
#define headerfilettmathdec
|
||||
|
||||
#include "ttmathtypes.h"
|
||||
#include "ttmaththreads.h"
|
||||
#include "ttmathuint.h"
|
||||
|
||||
|
||||
|
||||
namespace ttmath
|
||||
{
|
||||
|
||||
template<uint value_size, uint dec_digits>
|
||||
class Dec
|
||||
{
|
||||
public:
|
||||
|
||||
UInt<value_size> value;
|
||||
unsigned char info;
|
||||
|
||||
|
||||
/*!
|
||||
Sign
|
||||
the mask of a bit from 'info' which means that there is a sign
|
||||
(when the bit is set)
|
||||
*/
|
||||
#define TTMATH_DEC_SIGN 128
|
||||
|
||||
|
||||
/*!
|
||||
Not a number
|
||||
if this bit is set that there is not a valid number
|
||||
*/
|
||||
#define TTMATH_DEC_NAN 64
|
||||
|
||||
|
||||
|
||||
|
||||
Dec()
|
||||
{
|
||||
info = TTMATH_DEC_NAN;
|
||||
}
|
||||
|
||||
|
||||
Dec(const char * s)
|
||||
{
|
||||
info = TTMATH_DEC_NAN;
|
||||
FromString(s);
|
||||
}
|
||||
|
||||
|
||||
Dec<value_size, dec_digits> & operator=(const char * s)
|
||||
{
|
||||
FromString(s);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
uint FromString(const char * s, const char ** after_source = 0, bool * value_read = 0)
|
||||
{
|
||||
return FromStringBase(s, after_source, value_read);
|
||||
}
|
||||
|
||||
|
||||
void ToString(std::string & result) const
|
||||
{
|
||||
ToStringBase(result);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method clears a specific bit in the 'info' variable
|
||||
|
||||
bit is one of:
|
||||
*/
|
||||
void ClearInfoBit(unsigned char bit)
|
||||
{
|
||||
info = info & (~bit);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method sets a specific bit in the 'info' variable
|
||||
|
||||
bit is one of:
|
||||
|
||||
*/
|
||||
void SetInfoBit(unsigned char bit)
|
||||
{
|
||||
info = info | bit;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method returns true if a specific bit in the 'info' variable is set
|
||||
|
||||
bit is one of:
|
||||
*/
|
||||
bool IsInfoBit(unsigned char bit) const
|
||||
{
|
||||
return (info & bit) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool IsNan() const
|
||||
{
|
||||
return IsInfoBit(TTMATH_DEC_NAN);
|
||||
}
|
||||
|
||||
|
||||
bool IsSign() const
|
||||
{
|
||||
return IsInfoBit(TTMATH_DEC_SIGN);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method sets the sign
|
||||
|
||||
e.g.
|
||||
-1 -> -1
|
||||
2 -> -2
|
||||
|
||||
we do not check whether there is a zero or not, if you're using this method
|
||||
you must be sure that the value is (or will be afterwards) different from zero
|
||||
*/
|
||||
void SetSign()
|
||||
{
|
||||
SetInfoBit(TTMATH_DEC_SIGN);
|
||||
}
|
||||
|
||||
|
||||
void SetNaN()
|
||||
{
|
||||
SetInfoBit(TTMATH_DEC_NAN);
|
||||
}
|
||||
|
||||
|
||||
void Abs()
|
||||
{
|
||||
ClearInfoBit(TTMATH_DEC_SIGN);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint Add(const Dec<value_size, dec_digits> & arg)
|
||||
{
|
||||
uint c = 0;
|
||||
|
||||
if( IsSign() == arg.IsSign() )
|
||||
{
|
||||
c += value.Add(arg.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool is_sign;
|
||||
|
||||
if( value > arg.value )
|
||||
{
|
||||
is_sign = IsSign();
|
||||
value.Sub(arg.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
is_sign = arg.IsSign();
|
||||
UInt<value_size> temp(this->value);
|
||||
value = arg.value;
|
||||
value.Sub(temp);
|
||||
}
|
||||
|
||||
is_sign ? SetSign() : Abs();
|
||||
}
|
||||
|
||||
if( c )
|
||||
SetNaN();
|
||||
|
||||
return (c==0)? 0 : 1;
|
||||
}
|
||||
|
||||
/*
|
||||
uint Sub(const Dec<value_size, dec_digits> & arg)
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef TTMATH_MULTITHREADS
|
||||
|
||||
/*!
|
||||
*/
|
||||
void SetMultipler(UInt<value_size> & result)
|
||||
{
|
||||
// this guardian is initialized before the program runs (static POD type)
|
||||
static int guardian = 0;
|
||||
static UInt<value_size> multipler;
|
||||
|
||||
if( guardian == 0 )
|
||||
{
|
||||
multipler = 10;
|
||||
multipler.Pow(dec_digits);
|
||||
guardian = 1;
|
||||
}
|
||||
|
||||
result = multipler;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*!
|
||||
*/
|
||||
void SetMultipler(UInt<value_size> & result)
|
||||
{
|
||||
// this guardian is initialized before the program runs (static POD type)
|
||||
volatile static sig_atomic_t guardian = 0;
|
||||
static UInt<value_size> * pmultipler;
|
||||
|
||||
// double-checked locking
|
||||
if( guardian == 0 )
|
||||
{
|
||||
ThreadLock thread_lock;
|
||||
|
||||
// locking
|
||||
if( thread_lock.Lock() )
|
||||
{
|
||||
static UInt<value_size> multipler;
|
||||
|
||||
if( guardian == 0 )
|
||||
{
|
||||
pmultipler = &multipler;
|
||||
multipler = 10;
|
||||
multipler.Pow(dec_digits);
|
||||
guardian = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// there was a problem with locking, we store the result directly in 'result' object
|
||||
result = 10;
|
||||
result.Pow(dec_digits);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// automatically unlocking
|
||||
}
|
||||
|
||||
result = *pmultipler;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
an auxiliary method for converting from a string
|
||||
*/
|
||||
template<class char_type>
|
||||
uint FromStringBase(const char_type * s, const char_type ** after_source = 0, bool * value_read = 0)
|
||||
{
|
||||
UInt<value_size> multipler;
|
||||
const char_type * after;
|
||||
uint c = 0;
|
||||
info = 0;
|
||||
|
||||
Misc::SkipWhiteCharacters(s);
|
||||
|
||||
if( *s == '-' )
|
||||
{
|
||||
s += 1;
|
||||
SetSign();
|
||||
}
|
||||
else
|
||||
if( *s == '+' )
|
||||
{
|
||||
s += 1;
|
||||
}
|
||||
|
||||
c += value.FromString(s, 10, &after, value_read);
|
||||
|
||||
if( after_source )
|
||||
*after_source = after;
|
||||
|
||||
SetMultipler(multipler);
|
||||
c += value.Mul(multipler);
|
||||
|
||||
if( *after == '.' )
|
||||
c += FromStringBaseAfterComma(after+1, after_source);
|
||||
|
||||
if( c )
|
||||
SetInfoBit(TTMATH_DEC_NAN);
|
||||
|
||||
return (c==0)? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
template<class char_type>
|
||||
uint FromStringBaseAfterComma(const char_type * s, const char_type ** after_source = 0, bool * value_read = 0)
|
||||
{
|
||||
UInt<value_size> temp;
|
||||
UInt<value_size> multipler;
|
||||
sint z;
|
||||
uint c = 0;
|
||||
size_t i = dec_digits;
|
||||
|
||||
SetMultipler(multipler);
|
||||
|
||||
for( ; i>0 && (z=Misc::CharToDigit(*s, 10)) != -1 ; --i, ++s )
|
||||
{
|
||||
multipler.DivInt(10);
|
||||
temp.SetZero();
|
||||
|
||||
if( value_read )
|
||||
*value_read = true;
|
||||
|
||||
if( c == 0 )
|
||||
{
|
||||
temp.table[0] = z;
|
||||
c += temp.Mul(multipler);
|
||||
c += value.Add(temp);
|
||||
}
|
||||
}
|
||||
|
||||
if( i == 0 && (z=Misc::CharToDigit(*s, 10)) != -1 && z >= 5 )
|
||||
c += value.AddOne();
|
||||
|
||||
if( after_source )
|
||||
{
|
||||
while( (z=Misc::CharToDigit(*s, 10)) != -1 )
|
||||
s += 1;
|
||||
|
||||
*after_source = s;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class string_type>
|
||||
void ToStringBase(string_type & result) const
|
||||
{
|
||||
if( IsNan() )
|
||||
{
|
||||
result = "NaN";
|
||||
return;
|
||||
}
|
||||
|
||||
value.ToStringBase(result, 10, IsSign());
|
||||
|
||||
if( dec_digits > 0 )
|
||||
{
|
||||
size_t size = result.size();
|
||||
|
||||
if( IsSign() && size > 0 )
|
||||
size -= 1;
|
||||
|
||||
if( dec_digits >= size )
|
||||
{
|
||||
size_t zeroes = dec_digits - size + 1;
|
||||
size_t start = IsSign() ? 1 : 0;
|
||||
result.insert(start, zeroes, '0');
|
||||
}
|
||||
|
||||
result.insert(result.end() - dec_digits, '.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the 3-Clause BSD Licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2010, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||
* project may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef headerfilettmathmisc
|
||||
#define headerfilettmathmisc
|
||||
|
||||
|
||||
/*!
|
||||
\file ttmathmisc.h
|
||||
\brief some helpful functions
|
||||
*/
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace ttmath
|
||||
{
|
||||
|
||||
/*!
|
||||
some helpful functions
|
||||
*/
|
||||
class Misc
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* AssignString(result, str)
|
||||
* result = str
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
result = str
|
||||
*/
|
||||
static void AssignString(std::string & result, const char * str)
|
||||
{
|
||||
result = str;
|
||||
}
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
/*!
|
||||
result = str
|
||||
*/
|
||||
static void AssignString(std::wstring & result, const char * str)
|
||||
{
|
||||
result.clear();
|
||||
|
||||
for( ; *str ; ++str )
|
||||
result += *str;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
result = str
|
||||
*/
|
||||
static void AssignString(std::wstring & result, const std::string & str)
|
||||
{
|
||||
return AssignString(result, str.c_str());
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
result = str
|
||||
*/
|
||||
static void AssignString(std::string & result, const wchar_t * str)
|
||||
{
|
||||
result.clear();
|
||||
|
||||
for( ; *str ; ++str )
|
||||
result += static_cast<char>(*str);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
result = str
|
||||
*/
|
||||
static void AssignString(std::string & result, const std::wstring & str)
|
||||
{
|
||||
return AssignString(result, str.c_str());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* AddString(result, str)
|
||||
* result += str
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
result += str
|
||||
*/
|
||||
static void AddString(std::string & result, const char * str)
|
||||
{
|
||||
result += str;
|
||||
}
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
/*!
|
||||
result += str
|
||||
*/
|
||||
static void AddString(std::wstring & result, const char * str)
|
||||
{
|
||||
for( ; *str ; ++str )
|
||||
result += *str;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
this method omits any white characters from the string
|
||||
char_type is char or wchar_t
|
||||
*/
|
||||
template<class char_type>
|
||||
static void SkipWhiteCharacters(const char_type * & c)
|
||||
{
|
||||
// 13 is at the end in a DOS text file (\r\n)
|
||||
while( (*c==' ' ) || (*c=='\t') || (*c==13 ) || (*c=='\n') )
|
||||
++c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this static method converts one character into its value
|
||||
|
||||
for example:
|
||||
- 1 -> 1
|
||||
- 8 -> 8
|
||||
- A -> 10
|
||||
- f -> 15
|
||||
|
||||
this method don't check whether c is correct or not
|
||||
*/
|
||||
static uint CharToDigit(uint c)
|
||||
{
|
||||
if(c>='0' && c<='9')
|
||||
return c-'0';
|
||||
|
||||
if(c>='a' && c<='z')
|
||||
return c-'a'+10;
|
||||
|
||||
return c-'A'+10;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method changes a character 'c' into its value
|
||||
(if there can't be a correct value it returns -1)
|
||||
|
||||
for example:
|
||||
- c=2, base=10 -> function returns 2
|
||||
- c=A, base=10 -> function returns -1
|
||||
- c=A, base=16 -> function returns 10
|
||||
*/
|
||||
static sint CharToDigit(uint c, uint base)
|
||||
{
|
||||
if( c>='0' && c<='9' )
|
||||
c=c-'0';
|
||||
else
|
||||
if( c>='a' && c<='z' )
|
||||
c=c-'a'+10;
|
||||
else
|
||||
if( c>='A' && c<='Z' )
|
||||
c=c-'A'+10;
|
||||
else
|
||||
return -1;
|
||||
|
||||
|
||||
if( c >= base )
|
||||
return -1;
|
||||
|
||||
|
||||
return sint(c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this method converts a digit into a char
|
||||
digit should be from <0,F>
|
||||
(we don't have to get a base)
|
||||
|
||||
for example:
|
||||
- 1 -> 1
|
||||
- 8 -> 8
|
||||
- 10 -> A
|
||||
- 15 -> F
|
||||
*/
|
||||
static uint DigitToChar(uint digit)
|
||||
{
|
||||
if( digit < 10 )
|
||||
return digit + '0';
|
||||
|
||||
return digit - 10 + 'A';
|
||||
}
|
||||
|
||||
|
||||
}; // struct Misc
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* This file is a part of TTMath Mathematical Library
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* and is distributed under the 3-Clause BSD Licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||
* Copyright (c) 2006-2017, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -44,13 +44,13 @@
|
|||
\brief Mathematic functions.
|
||||
*/
|
||||
|
||||
#include "ttmathtypes.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include "ttmathtypes.h"
|
||||
#include "ttmathmisc.h"
|
||||
|
||||
|
||||
namespace ttmath
|
||||
|
@ -74,19 +74,19 @@ public:
|
|||
struct Item
|
||||
{
|
||||
// name of a variable of a function
|
||||
// (either std::string or std::wstring)
|
||||
tt_string value;
|
||||
// internally we store variables and funcions as std::string (not std::wstring even when wide characters are used)
|
||||
std::string value;
|
||||
|
||||
// number of parameters required by the function
|
||||
// (if there's a variable this 'param' is ignored)
|
||||
int param;
|
||||
|
||||
Item() {}
|
||||
Item(const tt_string & v, int p) : value(v), param(p) {}
|
||||
Item() { param = 0; }
|
||||
Item(const std::string & v, int p) : value(v), param(p) {}
|
||||
};
|
||||
|
||||
// 'Table' is the type of our table
|
||||
typedef std::map<tt_string, Item> Table;
|
||||
typedef std::map<std::string, Item> Table;
|
||||
typedef Table::iterator Iterator;
|
||||
typedef Table::const_iterator CIterator;
|
||||
|
||||
|
@ -114,7 +114,8 @@ public:
|
|||
/*!
|
||||
this method returns true if the name can be as a name of an object
|
||||
*/
|
||||
static bool IsNameCorrect(const tt_string & name)
|
||||
template<class string_type>
|
||||
static bool IsNameCorrect(const string_type & name)
|
||||
{
|
||||
if( name.empty() )
|
||||
return false;
|
||||
|
@ -122,7 +123,7 @@ public:
|
|||
if( !CorrectCharacter(name[0], false) )
|
||||
return false;
|
||||
|
||||
tt_string::const_iterator i=name.begin();
|
||||
typename string_type::const_iterator i = name.begin();
|
||||
|
||||
for(++i ; i!=name.end() ; ++i)
|
||||
if( !CorrectCharacter(*i, true) )
|
||||
|
@ -135,7 +136,7 @@ public:
|
|||
/*!
|
||||
this method returns true if such an object is defined (name exists)
|
||||
*/
|
||||
bool IsDefined(const tt_string & name)
|
||||
bool IsDefined(const std::string & name)
|
||||
{
|
||||
Iterator i = table.find(name);
|
||||
|
||||
|
@ -147,10 +148,31 @@ public:
|
|||
}
|
||||
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
/*!
|
||||
this method returns true if such an object is defined (name exists)
|
||||
*/
|
||||
bool IsDefined(const std::wstring & name)
|
||||
{
|
||||
// we should check whether the name (in wide characters) are correct
|
||||
// before calling AssignString() function
|
||||
if( !IsNameCorrect(name) )
|
||||
return false;
|
||||
|
||||
Misc::AssignString(str_tmp1, name);
|
||||
|
||||
return IsDefined(str_tmp1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
this method adds one object (variable of function) into the table
|
||||
*/
|
||||
ErrorCode Add(const tt_string & name, const tt_string & value, int param = 0)
|
||||
ErrorCode Add(const std::string & name, const std::string & value, int param = 0)
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
@ -167,6 +189,27 @@ public:
|
|||
}
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
/*!
|
||||
this method adds one object (variable of function) into the table
|
||||
*/
|
||||
ErrorCode Add(const std::wstring & name, const std::wstring & value, int param = 0)
|
||||
{
|
||||
// we should check whether the name (in wide characters) are correct
|
||||
// before calling AssignString() function
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
Misc::AssignString(str_tmp1, name);
|
||||
Misc::AssignString(str_tmp2, value);
|
||||
|
||||
return Add(str_tmp1, str_tmp2, param);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
this method returns 'true' if the table is empty
|
||||
*/
|
||||
|
@ -207,7 +250,7 @@ public:
|
|||
/*!
|
||||
this method changes the value and the number of parameters for a specific object
|
||||
*/
|
||||
ErrorCode EditValue(const tt_string & name, const tt_string & value, int param = 0)
|
||||
ErrorCode EditValue(const std::string & name, const std::string & value, int param = 0)
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
@ -224,10 +267,32 @@ public:
|
|||
}
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
|
||||
/*!
|
||||
this method changes the value and the number of parameters for a specific object
|
||||
*/
|
||||
ErrorCode EditValue(const std::wstring & name, const std::wstring & value, int param = 0)
|
||||
{
|
||||
// we should check whether the name (in wide characters) are correct
|
||||
// before calling AssignString() function
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
Misc::AssignString(str_tmp1, name);
|
||||
Misc::AssignString(str_tmp2, value);
|
||||
|
||||
return EditValue(str_tmp1, str_tmp2, param);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
this method changes the name of a specific object
|
||||
*/
|
||||
ErrorCode EditName(const tt_string & old_name, const tt_string & new_name)
|
||||
ErrorCode EditName(const std::string & old_name, const std::string & new_name)
|
||||
{
|
||||
if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
|
||||
return err_incorrect_name;
|
||||
|
@ -255,10 +320,33 @@ public:
|
|||
}
|
||||
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
|
||||
/*!
|
||||
this method changes the name of a specific object
|
||||
*/
|
||||
ErrorCode EditName(const std::wstring & old_name, const std::wstring & new_name)
|
||||
{
|
||||
// we should check whether the name (in wide characters) are correct
|
||||
// before calling AssignString() function
|
||||
if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
Misc::AssignString(str_tmp1, old_name);
|
||||
Misc::AssignString(str_tmp2, new_name);
|
||||
|
||||
return EditName(str_tmp1, str_tmp2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
this method deletes an object
|
||||
*/
|
||||
ErrorCode Delete(const tt_string & name)
|
||||
ErrorCode Delete(const std::string & name)
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
@ -274,10 +362,31 @@ public:
|
|||
}
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
|
||||
/*!
|
||||
this method deletes an object
|
||||
*/
|
||||
ErrorCode Delete(const std::wstring & name)
|
||||
{
|
||||
// we should check whether the name (in wide characters) are correct
|
||||
// before calling AssignString() function
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
Misc::AssignString(str_tmp1, name);
|
||||
|
||||
return Delete(str_tmp1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
this method gets the value of a specific object
|
||||
*/
|
||||
ErrorCode GetValue(const tt_string & name, tt_string & value) const
|
||||
ErrorCode GetValue(const std::string & name, std::string & value) const
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
@ -296,11 +405,33 @@ public:
|
|||
}
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
/*!
|
||||
this method gets the value of a specific object
|
||||
*/
|
||||
ErrorCode GetValue(const std::wstring & name, std::wstring & value)
|
||||
{
|
||||
// we should check whether the name (in wide characters) are correct
|
||||
// before calling AssignString() function
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
Misc::AssignString(str_tmp1, name);
|
||||
ErrorCode err = GetValue(str_tmp1, str_tmp2);
|
||||
Misc::AssignString(value, str_tmp2);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
this method gets the value of a specific object
|
||||
(this version is used for not copying the whole string)
|
||||
*/
|
||||
ErrorCode GetValue(const tt_string & name, const tt_char ** value) const
|
||||
ErrorCode GetValue(const std::string & name, const char ** value) const
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
@ -319,11 +450,32 @@ public:
|
|||
}
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
/*!
|
||||
this method gets the value of a specific object
|
||||
(this version is used for not copying the whole string)
|
||||
*/
|
||||
ErrorCode GetValue(const std::wstring & name, const char ** value)
|
||||
{
|
||||
// we should check whether the name (in wide characters) are correct
|
||||
// before calling AssignString() function
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
Misc::AssignString(str_tmp1, name);
|
||||
|
||||
return GetValue(str_tmp1, value);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
this method gets the value and the number of parameters
|
||||
of a specific object
|
||||
*/
|
||||
ErrorCode GetValueAndParam(const tt_string & name, tt_string & value, int * param) const
|
||||
ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
@ -332,7 +484,7 @@ public:
|
|||
|
||||
if( i == table.end() )
|
||||
{
|
||||
value.empty();
|
||||
value.clear();
|
||||
*param = 0;
|
||||
return err_unknown_object;
|
||||
}
|
||||
|
@ -344,12 +496,35 @@ public:
|
|||
}
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
/*!
|
||||
this method gets the value and the number of parameters
|
||||
of a specific object
|
||||
*/
|
||||
ErrorCode GetValueAndParam(const std::wstring & name, std::wstring & value, int * param)
|
||||
{
|
||||
// we should check whether the name (in wide characters) are correct
|
||||
// before calling AssignString() function
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
Misc::AssignString(str_tmp1, name);
|
||||
ErrorCode err = GetValueAndParam(str_tmp1, str_tmp2, param);
|
||||
Misc::AssignString(value, str_tmp2);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
this method sets the value and the number of parameters
|
||||
of a specific object
|
||||
(this version is used for not copying the whole string)
|
||||
*/
|
||||
ErrorCode GetValueAndParam(const tt_string & name, const tt_char ** value, int * param) const
|
||||
ErrorCode GetValueAndParam(const std::string & name, const char ** value, int * param) const
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
@ -370,6 +545,31 @@ public:
|
|||
}
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
|
||||
/*!
|
||||
this method sets the value and the number of parameters
|
||||
of a specific object
|
||||
(this version is used for not copying the whole string
|
||||
but in fact we make one copying during AssignString())
|
||||
*/
|
||||
ErrorCode GetValueAndParam(const std::wstring & name, const char ** value, int * param)
|
||||
{
|
||||
// we should check whether the name (in wide characters) are correct
|
||||
// before calling AssignString() function
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
Misc::AssignString(str_tmp1, name);
|
||||
|
||||
return GetValueAndParam(str_tmp1, value, param);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
this method returns a pointer into the table
|
||||
*/
|
||||
|
@ -382,6 +582,7 @@ public:
|
|||
private:
|
||||
|
||||
Table table;
|
||||
std::string str_tmp1, str_tmp2;
|
||||
|
||||
}; // end of class Objects
|
||||
|
||||
|
@ -428,7 +629,7 @@ public:
|
|||
|
||||
/*!
|
||||
default constructor
|
||||
default max size of the History's container is 10 items
|
||||
default max size of the History's container is 15 items
|
||||
*/
|
||||
History()
|
||||
{
|
||||
|
@ -522,14 +723,17 @@ public:
|
|||
|
||||
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.
|
||||
and you don't have to explicitly use it, e.g.
|
||||
|
||||
typedef Big<1, 3> MyBig;
|
||||
MyBig x = 123456;
|
||||
std::cout << Gamma(x);
|
||||
|
@ -591,8 +795,8 @@ struct CGamma
|
|||
you don't have to call this method, these coefficients will be automatically calculated
|
||||
when they are needed
|
||||
|
||||
you must note that calculating of the coefficients is a little time-consuming operation,
|
||||
(especially when the mantissa is large) and first called to Gamma() or Factorial()
|
||||
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
|
||||
*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the 3-Clause BSD Licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||
* project may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef headerfilettmaththreads
|
||||
#define headerfilettmaththreads
|
||||
|
||||
#include "ttmathtypes.h"
|
||||
|
||||
#ifdef TTMATH_WIN32_THREADS
|
||||
#include <windows.h>
|
||||
#include <cstdio>
|
||||
#endif
|
||||
|
||||
#ifdef TTMATH_POSIX_THREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\file ttmaththreads.h
|
||||
\brief Some objects used in multithreads environment
|
||||
*/
|
||||
|
||||
|
||||
namespace ttmath
|
||||
{
|
||||
|
||||
|
||||
#ifdef TTMATH_WIN32_THREADS
|
||||
|
||||
/*
|
||||
we use win32 threads
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
|
||||
somewhere in *.cpp file
|
||||
|
||||
(at the moment in win32 this macro does nothing)
|
||||
*/
|
||||
#define TTMATH_MULTITHREADS_HELPER
|
||||
|
||||
|
||||
/*!
|
||||
objects of this class are used to synchronize
|
||||
*/
|
||||
class ThreadLock
|
||||
{
|
||||
HANDLE mutex_handle;
|
||||
|
||||
|
||||
void CreateName(char * buffer) const
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4996)
|
||||
// warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead.
|
||||
#endif
|
||||
|
||||
sprintf(buffer, "TTMATH_LOCK_%ul", (unsigned long)GetCurrentProcessId());
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (default : 4996)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
bool Lock()
|
||||
{
|
||||
char buffer[50];
|
||||
|
||||
CreateName(buffer);
|
||||
mutex_handle = CreateMutexA(0, false, buffer);
|
||||
|
||||
if( mutex_handle == 0 )
|
||||
return false;
|
||||
|
||||
WaitForSingleObject(mutex_handle, INFINITE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
ThreadLock()
|
||||
{
|
||||
mutex_handle = 0;
|
||||
}
|
||||
|
||||
|
||||
~ThreadLock()
|
||||
{
|
||||
if( mutex_handle != 0 )
|
||||
{
|
||||
ReleaseMutex(mutex_handle);
|
||||
CloseHandle(mutex_handle);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifdef TTMATH_WIN32_THREADS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef TTMATH_POSIX_THREADS
|
||||
|
||||
/*
|
||||
we use posix threads
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
|
||||
somewhere in *.cpp file
|
||||
(this macro defines a pthread_mutex_t object used by TTMath library)
|
||||
*/
|
||||
#define TTMATH_MULTITHREADS_HELPER \
|
||||
namespace ttmath \
|
||||
{ \
|
||||
pthread_mutex_t ttmath_mutex = PTHREAD_MUTEX_INITIALIZER; \
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
ttmath_mutex will be defined by TTMATH_MULTITHREADS_HELPER macro
|
||||
*/
|
||||
extern pthread_mutex_t ttmath_mutex;
|
||||
|
||||
|
||||
/*!
|
||||
\brief objects of this class are used to synchronize
|
||||
|
||||
this is a simple skeleton of a program in multithreads environment:
|
||||
|
||||
#define TTMATH_MULTITHREADS
|
||||
#include<ttmath/ttmath.h>
|
||||
|
||||
TTMATH_MULTITHREADS_HELPER
|
||||
|
||||
int main()
|
||||
{
|
||||
[...]
|
||||
}
|
||||
|
||||
make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file)
|
||||
use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope)
|
||||
*/
|
||||
class ThreadLock
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
lock the current thread
|
||||
|
||||
it uses a global mutex created by TTMATH_MULTITHREADS_HELPER macro
|
||||
*/
|
||||
bool Lock()
|
||||
{
|
||||
if( pthread_mutex_lock(&ttmath_mutex) != 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
~ThreadLock()
|
||||
{
|
||||
pthread_mutex_unlock(&ttmath_mutex);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifdef TTMATH_POSIX_THREADS
|
||||
|
||||
|
||||
|
||||
|
||||
#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
|
||||
|
||||
/*!
|
||||
we don't use win32 and pthreads
|
||||
*/
|
||||
|
||||
/*!
|
||||
*/
|
||||
#define TTMATH_MULTITHREADS_HELPER
|
||||
|
||||
|
||||
/*!
|
||||
objects of this class are used to synchronize
|
||||
actually we don't synchronize, the method Lock() returns always 'false'
|
||||
*/
|
||||
class ThreadLock
|
||||
{
|
||||
public:
|
||||
|
||||
bool Lock()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // #if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* and is distributed under the 3-Clause BSD Licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||
* Copyright (c) 2006-2019, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -56,61 +56,121 @@
|
|||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
/*!
|
||||
the version of the library
|
||||
#ifndef _MSC_VER
|
||||
#include <stdint.h>
|
||||
// for uint64_t and int64_t on a 32 bit platform
|
||||
#endif
|
||||
|
||||
TTMATH_PRERELEASE_VER is either zero or one
|
||||
if zero that means this is the release version of the library
|
||||
|
||||
|
||||
/*!
|
||||
the major version of the library
|
||||
|
||||
the version present to the end user is constructed in this way:
|
||||
|
||||
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
|
||||
*/
|
||||
#define TTMATH_MAJOR_VER 0
|
||||
|
||||
/*!
|
||||
the minor version of the library
|
||||
|
||||
the version present to the end user is constructed in this way:
|
||||
|
||||
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
|
||||
*/
|
||||
#define TTMATH_MINOR_VER 9
|
||||
#define TTMATH_REVISION_VER 0
|
||||
|
||||
/*!
|
||||
the revision version of the library
|
||||
|
||||
the version present to the end user is constructed in this way:
|
||||
|
||||
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
|
||||
*/
|
||||
#define TTMATH_REVISION_VER 4
|
||||
|
||||
/*!
|
||||
TTMATH_PRERELEASE_VER is either zero or one
|
||||
zero means that this is the release version of the library
|
||||
(one means something like beta)
|
||||
|
||||
the version present to the end user is constructed in this way:
|
||||
|
||||
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
|
||||
*/
|
||||
#define TTMATH_PRERELEASE_VER 1
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
TTMATH_DEBUG
|
||||
this macro enables further testing during writing your code
|
||||
you don't have to define it in a release mode
|
||||
|
||||
if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
|
||||
are set as well and these macros can throw an exception if a condition in it
|
||||
is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
|
||||
|
||||
TTMATH_RELEASE
|
||||
if you are confident that your code is perfect you can define TTMATH_RELEASE
|
||||
macro for example by using -D option in gcc
|
||||
gcc -DTTMATH_RELEASE -o myprogram myprogram.cpp
|
||||
or by defining this macro in your code before using any header files of this library
|
||||
|
||||
if TTMATH_RELEASE is not set then TTMATH_DEBUG is set automatically
|
||||
you can define a platform explicitly by defining either
|
||||
TTMATH_PLATFORM32 or TTMATH_PLATFORM64 macro
|
||||
*/
|
||||
#ifndef TTMATH_RELEASE
|
||||
#define TTMATH_DEBUG
|
||||
#if !defined TTMATH_PLATFORM32 && !defined TTMATH_PLATFORM64
|
||||
|
||||
#if !defined _M_X64 && !defined __x86_64__
|
||||
|
||||
/*
|
||||
other platforms than x86 and amd64 are not recognized at the moment
|
||||
so you should set TTMATH_PLATFORMxx manually
|
||||
*/
|
||||
|
||||
// we're using a 32bit platform
|
||||
#define TTMATH_PLATFORM32
|
||||
|
||||
#else
|
||||
|
||||
// we're using a 64bit platform
|
||||
#define TTMATH_PLATFORM64
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
asm version of the library is available by default only for:
|
||||
x86 and amd64 platforms and for Microsoft Visual and GCC compilers
|
||||
|
||||
but you can force using asm version (the same asm as for Microsoft Visual)
|
||||
by defining TTMATH_FORCEASM macro
|
||||
you have to be sure that your compiler accept such an asm format
|
||||
*/
|
||||
#ifndef TTMATH_FORCEASM
|
||||
|
||||
#if !defined __i386__ && !defined _X86_ && !defined _M_IX86 && !defined __x86_64__ && !defined _M_X64
|
||||
/*!
|
||||
x86 architecture:
|
||||
__i386__ defined by GNU C
|
||||
_X86_ defined by MinGW32
|
||||
_M_IX86 defined by Visual Studio, Intel C/C++, Digital Mars and Watcom C/C++
|
||||
|
||||
amd64 architecture:
|
||||
__x86_64__ defined by GNU C, CLANG (LLVM) and Sun Studio
|
||||
_M_X64 defined by Visual Studio
|
||||
|
||||
asm version is available only for x86 or amd64 platforms
|
||||
*/
|
||||
#define TTMATH_NOASM
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if !defined _MSC_VER && !defined __GNUC__
|
||||
/*!
|
||||
another compilers than MS VC or GCC or CLANG (LLVM) by default use no asm version
|
||||
(CLANG defines __GNUC__ too)
|
||||
*/
|
||||
#define TTMATH_NOASM
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
namespace ttmath
|
||||
{
|
||||
|
||||
#if !defined _M_X64 && !defined __x86_64__
|
||||
|
||||
/*!
|
||||
we're using a 32bit platform
|
||||
*/
|
||||
#define TTMATH_PLATFORM32
|
||||
|
||||
#else
|
||||
|
||||
/*!
|
||||
we're using a 64bit platform
|
||||
*/
|
||||
#define TTMATH_PLATFORM64
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef TTMATH_PLATFORM32
|
||||
|
||||
|
@ -120,131 +180,120 @@ namespace ttmath
|
|||
typedef unsigned int uint;
|
||||
typedef signed int sint;
|
||||
|
||||
/*!
|
||||
on 32 bit platform ulint and slint will be equal 64 bits
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
// long long on MS Windows (Visual and GCC mingw compilers) have 64 bits
|
||||
// stdint.h is not available on Visual Studio prior to VS 2010 version
|
||||
typedef unsigned long long int ulint;
|
||||
typedef signed long long int slint;
|
||||
#else
|
||||
// we do not use 'long' here because there is a difference in unix and windows
|
||||
// environments: in unix 'long' has 64 bits but in windows it has only 32 bits
|
||||
typedef uint64_t ulint;
|
||||
typedef int64_t slint;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
this type is twice bigger than uint
|
||||
(64bit on a 32bit platforms)
|
||||
|
||||
although C++ Standard - ANSI ISO IEC 14882:2003 doesn't define such a type (long long)
|
||||
but it is defined in C99 and in upcoming C++0x /3.9.1 (2)/ and many compilers support it
|
||||
|
||||
this type is used in UInt::MulTwoWords and UInt::DivTwoWords when macro TTMATH_NOASM is defined
|
||||
how many bits there are in the uint type
|
||||
*/
|
||||
typedef unsigned long long int ulint;
|
||||
#define TTMATH_BITS_PER_UINT 32u
|
||||
|
||||
/*!
|
||||
the mask for the highest bit in the unsigned 32bit word (2^31)
|
||||
*/
|
||||
const uint TTMATH_UINT_HIGHEST_BIT = 0x80000000ul;
|
||||
#define TTMATH_UINT_HIGHEST_BIT 2147483648u
|
||||
|
||||
/*!
|
||||
the max value of the unsigned 32bit word (2^32 - 1)
|
||||
(all bits equal one)
|
||||
*/
|
||||
const uint TTMATH_UINT_MAX_VALUE = 0xfffffffful;
|
||||
#define TTMATH_UINT_MAX_VALUE 4294967295u
|
||||
|
||||
/*!
|
||||
the number of words (32bit words on 32bit platform)
|
||||
which are kept in built-in variables for a Big<> type
|
||||
(these variables are defined in ttmathbig.h)
|
||||
*/
|
||||
const uint 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
|
||||
|
||||
/*!
|
||||
on 64bit platforms one word (uint, sint) will be equal 64bits
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
#ifdef _MSC_VER
|
||||
/* in VC 'long' type has 32 bits, __int64 is VC extension */
|
||||
typedef unsigned __int64 uint;
|
||||
typedef signed __int64 sint;
|
||||
typedef signed __int64 sint;
|
||||
#else
|
||||
typedef unsigned long long uint;
|
||||
typedef signed long long sint;
|
||||
#endif
|
||||
/*!
|
||||
on 64bit platform we do not define ulint
|
||||
sizeof(long long) is 8 (64bit) but we need 128bit
|
||||
/*!
|
||||
on 64bit platforms one word (uint, sint) will be equal 64bits
|
||||
*/
|
||||
typedef uint64_t uint;
|
||||
|
||||
on 64 bit platform (when there is defined TTMATH_NOASM macro)
|
||||
methods UInt::MulTwoWords and UInt::DivTwoWords are using other algorithms than those on 32 bit
|
||||
/*!
|
||||
on 64bit platforms one word (uint, sint) will be equal 64bits
|
||||
*/
|
||||
typedef int64_t sint;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
on 64bit platforms we do not define ulint and slint
|
||||
*/
|
||||
//typedef unsigned long long int ulint;
|
||||
|
||||
/*!
|
||||
how many bits there are in the uint type
|
||||
*/
|
||||
#define TTMATH_BITS_PER_UINT 64ul
|
||||
|
||||
/*!
|
||||
the mask for the highest bit in the unsigned 64bit word (2^63)
|
||||
*/
|
||||
const uint TTMATH_UINT_HIGHEST_BIT = 0x8000000000000000ul;
|
||||
#define TTMATH_UINT_HIGHEST_BIT 9223372036854775808ul
|
||||
|
||||
/*!
|
||||
the max value of the unsigned 64bit word (2^64 - 1)
|
||||
(all bits equal one)
|
||||
*/
|
||||
const uint TTMATH_UINT_MAX_VALUE = 0xfffffffffffffffful;
|
||||
#define TTMATH_UINT_MAX_VALUE 18446744073709551615ul
|
||||
|
||||
/*!
|
||||
the number of words (64bit words on 64bit platforms)
|
||||
which are kept in built-in variables for a Big<> type
|
||||
(these variables are defined in ttmathbig.h)
|
||||
*/
|
||||
const uint 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
|
||||
|
||||
const uint TTMATH_BITS_PER_UINT = (sizeof(uint)*8);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if defined(UNICODE) || defined(_UNICODE)
|
||||
#define TTMATH_USE_WCHAR
|
||||
#if defined(TTMATH_MULTITHREADS) && !defined(TTMATH_MULTITHREADS_NOSYNC)
|
||||
#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define TTMATH_WIN32_THREADS
|
||||
#elif defined(unix) || defined(__unix__) || defined(__unix)
|
||||
#define TTMATH_POSIX_THREADS
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TTMATH_USE_WCHAR
|
||||
|
||||
typedef wchar_t tt_char;
|
||||
typedef std::wstring tt_string;
|
||||
typedef std::wostringstream tt_ostringstream;
|
||||
typedef std::wostream tt_ostream;
|
||||
typedef std::wistream tt_istream;
|
||||
#define TTMATH_TEXT_HELPER(txt) L##txt
|
||||
|
||||
#else
|
||||
|
||||
typedef char tt_char;
|
||||
typedef std::string tt_string;
|
||||
typedef std::ostringstream tt_ostringstream;
|
||||
typedef std::ostream tt_ostream;
|
||||
typedef std::istream tt_istream;
|
||||
#define TTMATH_TEXT_HELPER(txt) txt
|
||||
|
||||
#endif
|
||||
|
||||
#define TTMATH_TEXT(txt) TTMATH_TEXT_HELPER(txt)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
characters which represent the comma operator
|
||||
|
||||
TTMATH_COMMA_CHARACTER_1 is used in reading (parsing) and in writing (default, can be overwritten in ToString() function)
|
||||
TTMATH_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character
|
||||
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 ','
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this variable defines how many iterations are performed
|
||||
|
@ -267,10 +316,15 @@ namespace ttmath
|
|||
if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
|
||||
the Karatsuba algorithm will use standard schoolbook multiplication
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
|
||||
#ifdef TTMATH_DEBUG_LOG
|
||||
// if TTMATH_DEBUG_LOG is defined then we should use the same size regardless of the compiler
|
||||
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
|
||||
#else
|
||||
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
|
||||
#ifdef __GNUC__
|
||||
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
|
||||
#else
|
||||
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -286,9 +340,30 @@ 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
|
||||
*/
|
||||
|
@ -319,10 +394,142 @@ namespace ttmath
|
|||
err_object_exists,
|
||||
err_unknown_object,
|
||||
err_still_calculating,
|
||||
err_in_short_form_used_function
|
||||
err_in_short_form_used_function,
|
||||
err_percent_from,
|
||||
err_assignment_requires_variable
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
this struct is used when converting to/from a string
|
||||
/temporarily only in Big::ToString() and Big::FromString()/
|
||||
*/
|
||||
struct Conv
|
||||
{
|
||||
/*!
|
||||
base (radix) on which the value will be shown (or read)
|
||||
default: 10
|
||||
*/
|
||||
uint base;
|
||||
|
||||
|
||||
/*!
|
||||
used only in Big::ToString()
|
||||
if true the value will be always shown in the scientific mode, e.g: 123e+30
|
||||
default: false
|
||||
*/
|
||||
bool scient;
|
||||
|
||||
|
||||
/*!
|
||||
used only in Big::ToString()
|
||||
if scient is false then the value will be printed in the scientific mode
|
||||
only if the exponent is greater than scien_from
|
||||
default: 15
|
||||
*/
|
||||
sint scient_from;
|
||||
|
||||
|
||||
/*!
|
||||
if 'base_round' is true and 'base' is different from 2, 4, 8, or 16
|
||||
and the result value is not an integer then we make an additional rounding
|
||||
(after converting the last digit from the result is skipped)
|
||||
default: true
|
||||
|
||||
e.g.
|
||||
|
||||
Conv c;
|
||||
c.base_round = false;
|
||||
Big<1, 1> a = "0.1"; // decimal input
|
||||
std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999
|
||||
*/
|
||||
bool base_round;
|
||||
|
||||
|
||||
/*!
|
||||
used only in Big::ToString()
|
||||
tells how many digits after comma are possible
|
||||
default: -1 which means all digits are printed
|
||||
|
||||
set it to zero if you want integer value only
|
||||
|
||||
for example when the value is:
|
||||
12.345678 and 'round' is 4
|
||||
then the result will be
|
||||
12.3457 (the last digit was rounded)
|
||||
*/
|
||||
sint round;
|
||||
|
||||
|
||||
/*!
|
||||
if true that not mattered digits in the mantissa will be cut off
|
||||
(zero characters at the end -- after the comma operator)
|
||||
e.g. 1234,78000 will be: 1234,78
|
||||
default: true
|
||||
*/
|
||||
bool trim_zeroes;
|
||||
|
||||
|
||||
/*!
|
||||
the main comma operator (used when reading and writing)
|
||||
default is a dot '.'
|
||||
*/
|
||||
uint comma;
|
||||
|
||||
|
||||
/*!
|
||||
additional comma operator (used only when reading)
|
||||
if you don't want it just set it to zero
|
||||
default is a comma ','
|
||||
|
||||
this allowes you to convert from a value:
|
||||
123.45 as well as from 123,45
|
||||
*/
|
||||
uint comma2;
|
||||
|
||||
|
||||
/*!
|
||||
it sets the character which is used for grouping
|
||||
if group=' ' then: 1234,56789 will be printed as: 1 234,567 89
|
||||
|
||||
if you don't want grouping just set it to zero (which is default)
|
||||
*/
|
||||
uint group;
|
||||
|
||||
|
||||
/*!
|
||||
how many digits should be grouped (it is used if 'group' is non zero)
|
||||
default: 3
|
||||
*/
|
||||
uint group_digits;
|
||||
|
||||
|
||||
/*!
|
||||
*/
|
||||
uint group_exp; // not implemented yet
|
||||
|
||||
|
||||
|
||||
|
||||
Conv()
|
||||
{
|
||||
// default values
|
||||
base = 10;
|
||||
scient = false;
|
||||
scient_from = 15;
|
||||
base_round = true;
|
||||
round = -1;
|
||||
trim_zeroes = true;
|
||||
comma = '.';
|
||||
comma2 = ',';
|
||||
group = 0;
|
||||
group_digits = 3;
|
||||
group_exp = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this simple class can be used in multithreading model
|
||||
(you can write your own class derived from this one)
|
||||
|
@ -349,20 +556,20 @@ namespace ttmath
|
|||
*/
|
||||
class ExceptionInfo
|
||||
{
|
||||
const tt_char * file;
|
||||
const char * file;
|
||||
int line;
|
||||
|
||||
public:
|
||||
ExceptionInfo() : file(0), line(0) {}
|
||||
ExceptionInfo(const tt_char * f, int l) : file(f), line(l) {}
|
||||
ExceptionInfo(const char * f, int l) : file(f), line(l) {}
|
||||
|
||||
tt_string Where() const
|
||||
std::string Where() const
|
||||
{
|
||||
if( !file )
|
||||
return TTMATH_TEXT("unknown");
|
||||
return "unknown";
|
||||
|
||||
tt_ostringstream result;
|
||||
result << file << TTMATH_TEXT(":") << line;
|
||||
std::ostringstream result;
|
||||
result << file << ":" << line;
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
@ -375,41 +582,28 @@ namespace ttmath
|
|||
In the library is used macro TTMATH_REFERENCE_ASSERT which
|
||||
can throw an exception of this type
|
||||
|
||||
** from version 0.9.2 this macro is removed from all methods
|
||||
in public interface so you don't have to worry about it **
|
||||
|
||||
If you compile with gcc you can get a small benefit
|
||||
from using method Where() (it returns std::string (or std::wstring) with
|
||||
from using method Where() (it returns std::string) with
|
||||
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
|
||||
was used)
|
||||
|
||||
What is the 'reference' error?
|
||||
Some kind of methods use a reference as their argument to another object,
|
||||
and the another object not always can be the same which is calling, e.g.
|
||||
Big<1,2> foo(10);
|
||||
foo.Mul(foo); // this is incorrect
|
||||
above method Mul is making something more with 'this' object and
|
||||
'this' cannot be passed as the argument because the result will be undefined
|
||||
|
||||
macro TTMATH_REFERENCE_ASSERT helps us to solve the above problem
|
||||
|
||||
note! some methods can use 'this' object as the argument
|
||||
for example this code is correct:
|
||||
UInt<2> foo(10);
|
||||
foo.Add(foo);
|
||||
but there are only few methods which can do that
|
||||
*/
|
||||
class ReferenceError : public std::logic_error, public ExceptionInfo
|
||||
{
|
||||
public:
|
||||
|
||||
ReferenceError() : std::logic_error ("reference error")
|
||||
ReferenceError() : std::logic_error("reference error")
|
||||
{
|
||||
}
|
||||
|
||||
ReferenceError(const tt_char * f, int l) :
|
||||
std::logic_error ("reference error"), ExceptionInfo(f,l)
|
||||
ReferenceError(const char * f, int l) :
|
||||
std::logic_error("reference error"), ExceptionInfo(f,l)
|
||||
{
|
||||
}
|
||||
|
||||
tt_string Where() const
|
||||
std::string Where() const
|
||||
{
|
||||
return ExceptionInfo::Where();
|
||||
}
|
||||
|
@ -424,7 +618,7 @@ namespace ttmath
|
|||
of this type
|
||||
|
||||
if you compile with gcc you can get a small benefit
|
||||
from using method Where() (it returns std::string (or std::wstring) with
|
||||
from using method Where() (it returns std::string) with
|
||||
the name and the line of a file where the macro TTMATH_ASSERT
|
||||
was used)
|
||||
*/
|
||||
|
@ -432,16 +626,16 @@ namespace ttmath
|
|||
{
|
||||
public:
|
||||
|
||||
RuntimeError() : std::runtime_error ("internal error")
|
||||
RuntimeError() : std::runtime_error("internal error")
|
||||
{
|
||||
}
|
||||
|
||||
RuntimeError(const tt_char * f, int l) :
|
||||
std::runtime_error ("internal error"), ExceptionInfo(f,l)
|
||||
RuntimeError(const char * f, int l) :
|
||||
std::runtime_error("internal error"), ExceptionInfo(f,l)
|
||||
{
|
||||
}
|
||||
|
||||
tt_string Where() const
|
||||
std::string Where() const
|
||||
{
|
||||
return ExceptionInfo::Where();
|
||||
}
|
||||
|
@ -450,28 +644,30 @@ namespace ttmath
|
|||
|
||||
|
||||
/*!
|
||||
look at the description of macros TTMATH_RELEASE and TTMATH_DEBUG
|
||||
TTMATH_DEBUG
|
||||
this macro enables further testing during writing your code
|
||||
you don't have to define it in a release mode
|
||||
|
||||
if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
|
||||
are set as well and these macros can throw an exception if a condition in it
|
||||
is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
|
||||
|
||||
TTMATH_DEBUG is set automatically if DEBUG or _DEBUG are defined
|
||||
*/
|
||||
#if defined DEBUG || defined _DEBUG
|
||||
#define TTMATH_DEBUG
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TTMATH_DEBUG
|
||||
|
||||
#if defined(__FILE__) && defined(__LINE__)
|
||||
|
||||
#ifdef TTMATH_USE_WCHAR
|
||||
#define TTMATH_FILE_HELPER2(arg) L##arg
|
||||
#define TTMATH_FILE_HELPER(x) TTMATH_FILE_HELPER2(x)
|
||||
#define TTMATH_FILE TTMATH_FILE_HELPER(__FILE__)
|
||||
#else
|
||||
#define TTMATH_FILE __FILE__
|
||||
#endif
|
||||
|
||||
#define TTMATH_REFERENCE_ASSERT(expression) \
|
||||
if( &(expression) == this ) throw ttmath::ReferenceError(TTMATH_FILE, __LINE__);
|
||||
if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__);
|
||||
|
||||
#define TTMATH_ASSERT(expression) \
|
||||
if( !(expression) ) throw ttmath::RuntimeError(TTMATH_FILE, __LINE__);
|
||||
|
||||
#define TTMATH_VERIFY(expression) \
|
||||
if( !(expression) ) throw ttmath::RuntimeError(TTMATH_TEXT(__FILE__), __LINE__);
|
||||
if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -480,41 +676,30 @@ namespace ttmath
|
|||
|
||||
#define TTMATH_ASSERT(expression) \
|
||||
if( !(expression) ) throw RuntimeError();
|
||||
|
||||
#define TTMATH_VERIFY(expression) \
|
||||
if( !(expression) ) throw RuntimeError();
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define TTMATH_REFERENCE_ASSERT(expression)
|
||||
#define TTMATH_ASSERT(expression)
|
||||
#define TTMATH_VERIFY(expression) (void)(expression);
|
||||
#endif
|
||||
|
||||
#if !defined(LOG_PRINTF)
|
||||
#define LOG_PRINTF printf
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TTMATH_DEBUG_LOG
|
||||
|
||||
#ifdef TTMATH_USE_WCHAR
|
||||
#define TTMATH_LOG_HELPER(msg) \
|
||||
PrintLog(L##msg, std::wcout);
|
||||
#else
|
||||
#define TTMATH_LOG_HELPER(msg) \
|
||||
PrintLog(msg, std::cout);
|
||||
#endif
|
||||
|
||||
#define TTMATH_LOG(msg) TTMATH_LOG_HELPER(msg)
|
||||
|
||||
#define TTMATH_LOG(msg) PrintLog(msg, std::cout);
|
||||
#define TTMATH_LOGC(msg, carry) PrintLog(msg, carry, std::cout);
|
||||
#define TTMATH_VECTOR_LOG(msg, vector, len) PrintVectorLog(msg, std::cout, vector, len);
|
||||
#define TTMATH_VECTOR_LOGC(msg, carry, vector, len) PrintVectorLog(msg, carry, std::cout, vector, len);
|
||||
#else
|
||||
|
||||
#define TTMATH_LOG(msg)
|
||||
|
||||
#define TTMATH_LOGC(msg, carry)
|
||||
#define TTMATH_VECTOR_LOG(msg, vector, len)
|
||||
#define TTMATH_VECTOR_LOGC(msg, carry, vector, len)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
|
|
1685
ttmath/ttmathuint.h
1685
ttmath/ttmathuint.h
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* and is distributed under the 3-Clause BSD Licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||
* Copyright (c) 2006-2010, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -39,20 +39,69 @@
|
|||
#define headerfilettmathuint_noasm
|
||||
|
||||
|
||||
#ifdef TTMATH_NOASM
|
||||
|
||||
#pragma message("TTMATH_NOASM")
|
||||
|
||||
/*!
|
||||
\file ttmathuint_noasm.h
|
||||
\brief template class UInt<uint> with methods without any assembler code
|
||||
\brief template class UInt<uint> with methods without any assembler code (used for no-asm version of ttmath)
|
||||
|
||||
this file is included at the end of ttmathuint.h
|
||||
*/
|
||||
|
||||
#ifdef TTMATH_NOASM
|
||||
|
||||
|
||||
|
||||
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>
|
||||
uint UInt<value_size>::AddTwoWords(uint a, uint b, uint carry, uint * result)
|
||||
{
|
||||
|
@ -97,7 +146,7 @@ namespace ttmath
|
|||
for(i=0 ; i<value_size ; ++i)
|
||||
c = AddTwoWords(table[i], ss2.table[i], c, &table[i]);
|
||||
|
||||
TTMATH_LOG("UInt::Add")
|
||||
TTMATH_LOGC("UInt::Add", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -108,12 +157,17 @@ namespace ttmath
|
|||
and returns a carry (if it was)
|
||||
|
||||
if we've got (value_size=3):
|
||||
|
||||
table[0] = 10;
|
||||
table[1] = 30;
|
||||
table[2] = 5;
|
||||
|
||||
and we call:
|
||||
|
||||
AddInt(2,1)
|
||||
|
||||
then it'll be:
|
||||
|
||||
table[0] = 10;
|
||||
table[1] = 30 + 2;
|
||||
table[2] = 5;
|
||||
|
@ -133,7 +187,7 @@ namespace ttmath
|
|||
for(i=index+1 ; i<value_size && c ; ++i)
|
||||
c = AddTwoWords(table[i], 0, c, &table[i]);
|
||||
|
||||
TTMATH_LOG("UInt::AddInt")
|
||||
TTMATH_LOGC("UInt::AddInt", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -151,17 +205,23 @@ namespace ttmath
|
|||
x1 - lower word, x2 - higher word
|
||||
|
||||
for example if we've got value_size equal 4 and:
|
||||
|
||||
table[0] = 3
|
||||
table[1] = 4
|
||||
table[2] = 5
|
||||
table[3] = 6
|
||||
|
||||
then let
|
||||
|
||||
x1 = 10
|
||||
x2 = 20
|
||||
|
||||
and
|
||||
|
||||
index = 1
|
||||
|
||||
the result of this method will be:
|
||||
|
||||
table[0] = 3
|
||||
table[1] = 4 + x1 = 14
|
||||
table[2] = 5 + x2 = 25
|
||||
|
@ -186,7 +246,7 @@ namespace ttmath
|
|||
for(i=index+2 ; i<value_size && c ; ++i)
|
||||
c = AddTwoWords(table[i], 0, c, &table[i]);
|
||||
|
||||
TTMATH_LOG("UInt::AddTwoInts")
|
||||
TTMATH_LOGC("UInt::AddTwoInts", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -197,19 +257,20 @@ namespace ttmath
|
|||
this static method addes one vector to the other
|
||||
'ss1' is larger in size or equal to 'ss2'
|
||||
|
||||
ss1 points to the first (larger) vector
|
||||
ss2 points to the second vector
|
||||
ss1_size - size of the ss1 (and size of the result too)
|
||||
ss2_size - size of the ss2
|
||||
result - is the result vector (which has size the same as ss1: ss1_size)
|
||||
- ss1 points to the first (larger) vector
|
||||
- ss2 points to the second vector
|
||||
- ss1_size - size of the ss1 (and size of the result too)
|
||||
- ss2_size - size of the ss2
|
||||
- result - is the result vector (which has size the same as ss1: ss1_size)
|
||||
|
||||
Example: ss1_size is 5, ss2_size is 3
|
||||
ss1: ss2: result (output):
|
||||
5 1 5+1
|
||||
4 3 4+3
|
||||
2 7 2+7
|
||||
6 6
|
||||
9 9
|
||||
|
||||
Example: ss1_size is 5, ss2_size is 3
|
||||
ss1: ss2: result (output):
|
||||
5 1 5+1
|
||||
4 3 4+3
|
||||
2 7 2+7
|
||||
6 6
|
||||
9 9
|
||||
of course the carry is propagated and will be returned from the last item
|
||||
(this method is used by the Karatsuba multiplication algorithm)
|
||||
*/
|
||||
|
@ -226,7 +287,7 @@ namespace ttmath
|
|||
for( ; i<ss1_size ; ++i)
|
||||
c = AddTwoWords(ss1[i], 0, c, &result[i]);
|
||||
|
||||
TTMATH_LOG("UInt::AddVector")
|
||||
TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -234,6 +295,12 @@ 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>
|
||||
uint UInt<value_size>::SubTwoWords(uint a, uint b, uint carry, uint * result)
|
||||
{
|
||||
|
@ -275,7 +342,7 @@ namespace ttmath
|
|||
for(i=0 ; i<value_size ; ++i)
|
||||
c = SubTwoWords(table[i], ss2.table[i], c, &table[i]);
|
||||
|
||||
TTMATH_LOG("UInt::Sub")
|
||||
TTMATH_LOGC("UInt::Sub", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -288,12 +355,17 @@ namespace ttmath
|
|||
and returns a carry (if it was)
|
||||
|
||||
if we've got (value_size=3):
|
||||
|
||||
table[0] = 10;
|
||||
table[1] = 30;
|
||||
table[2] = 5;
|
||||
|
||||
and we call:
|
||||
|
||||
SubInt(2,1)
|
||||
|
||||
then it'll be:
|
||||
|
||||
table[0] = 10;
|
||||
table[1] = 30 - 2;
|
||||
table[2] = 5;
|
||||
|
@ -313,7 +385,7 @@ namespace ttmath
|
|||
for(i=index+1 ; i<value_size && c ; ++i)
|
||||
c = SubTwoWords(table[i], 0, c, &table[i]);
|
||||
|
||||
TTMATH_LOG("UInt::SubInt")
|
||||
TTMATH_LOGC("UInt::SubInt", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -323,19 +395,19 @@ namespace ttmath
|
|||
this static method subtractes one vector from the other
|
||||
'ss1' is larger in size or equal to 'ss2'
|
||||
|
||||
ss1 points to the first (larger) vector
|
||||
ss2 points to the second vector
|
||||
ss1_size - size of the ss1 (and size of the result too)
|
||||
ss2_size - size of the ss2
|
||||
result - is the result vector (which has size the same as ss1: ss1_size)
|
||||
- ss1 points to the first (larger) vector
|
||||
- ss2 points to the second vector
|
||||
- ss1_size - size of the ss1 (and size of the result too)
|
||||
- ss2_size - size of the ss2
|
||||
- result - is the result vector (which has size the same as ss1: ss1_size)
|
||||
|
||||
Example: ss1_size is 5, ss2_size is 3
|
||||
ss1: ss2: result (output):
|
||||
5 1 5-1
|
||||
4 3 4-3
|
||||
2 7 2-7
|
||||
6 6-1 (the borrow from previous item)
|
||||
9 9
|
||||
Example: ss1_size is 5, ss2_size is 3
|
||||
ss1: ss2: result (output):
|
||||
5 1 5-1
|
||||
4 3 4-3
|
||||
2 7 2-7
|
||||
6 6-1 (the borrow from previous item)
|
||||
9 9
|
||||
return (carry): 0
|
||||
of course the carry (borrow) is propagated and will be returned from the last item
|
||||
(this method is used by the Karatsuba multiplication algorithm)
|
||||
|
@ -353,7 +425,7 @@ namespace ttmath
|
|||
for( ; i<ss1_size ; ++i)
|
||||
c = SubTwoWords(ss1[i], 0, c, &result[i]);
|
||||
|
||||
TTMATH_LOG("UInt::SubVector")
|
||||
TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -387,7 +459,7 @@ namespace ttmath
|
|||
c = new_c;
|
||||
}
|
||||
|
||||
TTMATH_LOG("UInt::Rcl2_one")
|
||||
TTMATH_LOGC("UInt::Rcl2_one", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -426,7 +498,9 @@ namespace ttmath
|
|||
c = new_c;
|
||||
}
|
||||
|
||||
TTMATH_LOG("UInt::Rcr2_one")
|
||||
c = (c != 0)? 1 : 0;
|
||||
|
||||
TTMATH_LOGC("UInt::Rcr2_one", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -464,7 +538,7 @@ namespace ttmath
|
|||
c = new_c;
|
||||
}
|
||||
|
||||
TTMATH_LOG("UInt::Rcl2")
|
||||
TTMATH_LOGC("UInt::Rcl2", (c & 1))
|
||||
|
||||
return (c & 1);
|
||||
}
|
||||
|
@ -503,18 +577,19 @@ namespace ttmath
|
|||
c = new_c;
|
||||
}
|
||||
|
||||
TTMATH_LOG("UInt::Rcr2")
|
||||
c = (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
|
||||
|
||||
return (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
|
||||
TTMATH_LOGC("UInt::Rcr2", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/*!
|
||||
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>::FindLeadingBitInWord(uint x)
|
||||
|
@ -535,18 +610,41 @@ 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'
|
||||
and returns the last state of the bit (zero or one)
|
||||
|
||||
bit is from <0,63>
|
||||
bit is from <0,TTMATH_BITS_PER_UINT-1>
|
||||
|
||||
e.g.
|
||||
uint x = 100;
|
||||
uint bit = SetBitInWord(x, 3);
|
||||
now: x = 108 and bit = 0
|
||||
|
||||
uint x = 100;
|
||||
uint bit = SetBitInWord(x, 3);
|
||||
|
||||
now: x = 108 and bit = 0
|
||||
*/
|
||||
template<uint value_size>
|
||||
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
||||
|
@ -555,7 +653,7 @@ namespace ttmath
|
|||
|
||||
uint mask = 1;
|
||||
|
||||
if( bit > 1 )
|
||||
if( bit > 0 )
|
||||
mask = mask << bit;
|
||||
|
||||
uint last = value & mask;
|
||||
|
@ -579,10 +677,11 @@ namespace ttmath
|
|||
|
||||
/*!
|
||||
multiplication: result_high:result_low = a * b
|
||||
result_high - higher word of the result
|
||||
result_low - lower word of the result
|
||||
- result_high - higher word of the result
|
||||
- result_low - lower word of the result
|
||||
|
||||
this methos never returns a carry
|
||||
|
||||
this method is used in the second version of the multiplication algorithms
|
||||
*/
|
||||
template<uint value_size>
|
||||
|
@ -743,11 +842,11 @@ namespace ttmath
|
|||
temp1.u_.high = a_.u_.low;
|
||||
temp1.u_.low = b_.u_.high;
|
||||
|
||||
res_.u_.high = temp1.u / c;
|
||||
temp2.u_.high = temp1.u % c;
|
||||
res_.u_.high = (unsigned int)(temp1.u / c);
|
||||
temp2.u_.high = (unsigned int)(temp1.u % c);
|
||||
temp2.u_.low = b_.u_.low;
|
||||
|
||||
res_.u_.low = temp2.u / c;
|
||||
res_.u_.low = (unsigned int)(temp2.u / c);
|
||||
*rest = temp2.u % c;
|
||||
|
||||
*r = res_.u;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* and is distributed under the 3-Clause BSD Licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
|
@ -35,14 +35,9 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef headerfilettmathuint_x86
|
||||
#define headerfilettmathuint_x86
|
||||
|
||||
#ifndef TTMATH_NOASM
|
||||
#ifdef TTMATH_PLATFORM32
|
||||
|
||||
#pragma message("TTMATH_ASM32")
|
||||
|
||||
/*!
|
||||
\file ttmathuint_x86.h
|
||||
|
@ -52,6 +47,12 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef TTMATH_NOASM
|
||||
#ifdef TTMATH_PLATFORM32
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief a namespace for the TTMath library
|
||||
|
@ -59,12 +60,58 @@
|
|||
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
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
adding ss2 to the this and adding carry if it's defined
|
||||
(this = this + ss2 + c)
|
||||
|
@ -83,31 +130,46 @@ namespace ttmath
|
|||
// this algorithm doesn't require it
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
||||
// this part might be compiled with for example visual c
|
||||
|
||||
__asm
|
||||
{
|
||||
xor eax,eax // eax=0
|
||||
xor edx,edx // edx=0
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
|
||||
mov ecx,[b]
|
||||
|
||||
mov ebx,[p1]
|
||||
mov esi,[p2]
|
||||
|
||||
sub eax,[c] // CF=c
|
||||
xor edx,edx // edx=0
|
||||
mov eax,[c]
|
||||
neg eax // CF=1 if rax!=0 , CF=0 if rax==0
|
||||
|
||||
ALIGN 16
|
||||
ttmath_loop:
|
||||
mov eax,[esi+edx*4+0]
|
||||
adc [ebx+edx*4+0],eax
|
||||
mov eax,[esi+edx*4]
|
||||
adc [ebx+edx*4],eax
|
||||
|
||||
lea edx, [edx+1] // inc edx, but faster (no flags dependencies)
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz ttmath_loop
|
||||
|
||||
setc al
|
||||
movzx eax, al
|
||||
mov [c], eax
|
||||
adc ecx, ecx
|
||||
mov [c], ecx
|
||||
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -135,9 +197,9 @@ namespace ttmath
|
|||
: "cc", "memory" );
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::Add")
|
||||
TTMATH_LOGC("UInt::Add", c)
|
||||
|
||||
return c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
@ -149,12 +211,17 @@ namespace ttmath
|
|||
e.g.
|
||||
|
||||
if we've got (value_size=3):
|
||||
|
||||
table[0] = 10;
|
||||
table[1] = 30;
|
||||
table[2] = 5;
|
||||
|
||||
and we call:
|
||||
|
||||
AddInt(2,1)
|
||||
|
||||
then it'll be:
|
||||
|
||||
table[0] = 10;
|
||||
table[1] = 30 + 2;
|
||||
table[2] = 5;
|
||||
|
@ -171,8 +238,14 @@ namespace ttmath
|
|||
TTMATH_ASSERT( index < value_size )
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
mov ecx, [b]
|
||||
sub ecx, [index]
|
||||
|
||||
|
@ -181,21 +254,26 @@ namespace ttmath
|
|||
|
||||
mov eax, [value]
|
||||
|
||||
ALIGN 16
|
||||
ttmath_loop:
|
||||
add [ebx+edx*4], eax
|
||||
jnc ttmath_end
|
||||
|
||||
mov eax, 1
|
||||
lea edx, [edx+1] // inc edx, but faster (no flags dependencies)
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz ttmath_loop
|
||||
|
||||
ttmath_end:
|
||||
setc al
|
||||
movzx eax, al
|
||||
mov [c], eax
|
||||
setc al
|
||||
movzx edx, al
|
||||
mov [c], edx
|
||||
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -225,9 +303,9 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::AddInt")
|
||||
TTMATH_LOGC("UInt::AddInt", c)
|
||||
|
||||
return c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
@ -242,17 +320,23 @@ namespace ttmath
|
|||
x1 - lower word, x2 - higher word
|
||||
|
||||
for example if we've got value_size equal 4 and:
|
||||
|
||||
table[0] = 3
|
||||
table[1] = 4
|
||||
table[2] = 5
|
||||
table[3] = 6
|
||||
|
||||
then let
|
||||
|
||||
x1 = 10
|
||||
x2 = 20
|
||||
|
||||
and
|
||||
|
||||
index = 1
|
||||
|
||||
the result of this method will be:
|
||||
|
||||
table[0] = 3
|
||||
table[1] = 4 + x1 = 14
|
||||
table[2] = 5 + x2 = 25
|
||||
|
@ -268,46 +352,58 @@ namespace ttmath
|
|||
{
|
||||
uint b = value_size;
|
||||
uint * p1 = table;
|
||||
uint c;
|
||||
uint c;
|
||||
|
||||
TTMATH_ASSERT( index < value_size - 1 )
|
||||
|
||||
#ifndef __GNUC__
|
||||
__asm
|
||||
{
|
||||
mov ecx, [b]
|
||||
mov edx, [index]
|
||||
mov ebx, [p1]
|
||||
mov eax, [x1]
|
||||
sub ecx, edx // max uints to add (value_size - index)
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
mov ecx, [b]
|
||||
sub ecx, [index]
|
||||
|
||||
mov ebx, [p1]
|
||||
mov edx, [index]
|
||||
|
||||
mov eax, [x1]
|
||||
add [ebx+edx*4], eax
|
||||
lea ecx, [ecx-1]
|
||||
inc edx
|
||||
dec ecx
|
||||
|
||||
mov eax, [x2]
|
||||
|
||||
ALIGN 16
|
||||
ttmath_loop:
|
||||
adc [ebx+edx*4+4], eax
|
||||
adc [ebx+edx*4], eax
|
||||
jnc ttmath_end
|
||||
|
||||
mov eax, 0
|
||||
lea edx, [edx+1] // inc edx, but faster (no flags dependencies)
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz ttmath_loop
|
||||
|
||||
ttmath_end:
|
||||
setc al
|
||||
movzx eax, al
|
||||
mov [c], eax
|
||||
setc al
|
||||
movzx edx, al
|
||||
mov [c], edx
|
||||
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
__asm__ __volatile__(
|
||||
|
||||
"push %%ecx \n"
|
||||
"push %%edx \n"
|
||||
#ifdef __GNUC__
|
||||
uint dummy, dummy2;
|
||||
|
||||
__asm__ __volatile__(
|
||||
|
||||
"subl %%edx, %%ecx \n"
|
||||
|
||||
|
@ -334,9 +430,9 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::AddTwoInts")
|
||||
TTMATH_LOGC("UInt::AddTwoInts", c)
|
||||
|
||||
return c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
@ -374,19 +470,21 @@ namespace ttmath
|
|||
// this part might be compiled with for example visual c
|
||||
__asm
|
||||
{
|
||||
pushad
|
||||
|
||||
mov ecx, [ss2_size]
|
||||
xor edx, edx // edx = 0, cf = 0
|
||||
|
||||
mov esi, [ss1]
|
||||
mov ebx, [ss2]
|
||||
mov edi, [result]
|
||||
ALIGN 16
|
||||
|
||||
ttmath_loop:
|
||||
mov eax, [esi+edx*4]
|
||||
adc eax, [ebx+edx*4]
|
||||
mov [edi+edx*4], eax
|
||||
|
||||
lea edx, [edx+1] // inc edx, but faster (no flags dependencies)
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz ttmath_loop
|
||||
|
||||
|
@ -405,7 +503,7 @@ namespace ttmath
|
|||
adc eax, ebx
|
||||
mov [edi+edx*4], eax
|
||||
|
||||
lea edx, [edx+1] // inc edx, but faster (no flags dependencies)
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz ttmath_loop2
|
||||
|
||||
|
@ -413,6 +511,8 @@ namespace ttmath
|
|||
|
||||
ttmath_end:
|
||||
mov [c], ecx
|
||||
|
||||
popad
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -462,6 +562,8 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -485,30 +587,40 @@ namespace ttmath
|
|||
// this algorithm doesn't require it
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
|
||||
mov ecx,[b]
|
||||
|
||||
mov ebx,[p1]
|
||||
mov esi,[p2]
|
||||
|
||||
xor eax, eax
|
||||
mov edx, eax
|
||||
xor edx,edx // edx=0
|
||||
mov eax,[c]
|
||||
neg eax // CF=1 if rax!=0 , CF=0 if rax==0
|
||||
|
||||
sub eax, [c]
|
||||
|
||||
ALIGN 16
|
||||
ttmath_loop:
|
||||
mov eax, [esi+edx*4]
|
||||
sbb [ebx+edx*4], eax
|
||||
mov eax,[esi+edx*4]
|
||||
sbb [ebx+edx*4],eax
|
||||
|
||||
lea edx, [edx+1] // inc edx, but faster (no flags dependencies)
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz ttmath_loop
|
||||
|
||||
setc al
|
||||
movzx eax, al
|
||||
mov [c], eax
|
||||
adc ecx, ecx
|
||||
mov [c], ecx
|
||||
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -538,9 +650,9 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::Sub")
|
||||
TTMATH_LOGC("UInt::Sub", c)
|
||||
|
||||
return c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
@ -553,12 +665,17 @@ namespace ttmath
|
|||
e.g.
|
||||
|
||||
if we've got (value_size=3):
|
||||
|
||||
table[0] = 10;
|
||||
table[1] = 30;
|
||||
table[2] = 5;
|
||||
|
||||
and we call:
|
||||
|
||||
SubInt(2,1)
|
||||
|
||||
then it'll be:
|
||||
|
||||
table[0] = 10;
|
||||
table[1] = 30 - 2;
|
||||
table[2] = 5;
|
||||
|
@ -575,8 +692,14 @@ namespace ttmath
|
|||
TTMATH_ASSERT( index < value_size )
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
mov ecx, [b]
|
||||
sub ecx, [index]
|
||||
|
||||
|
@ -585,21 +708,26 @@ namespace ttmath
|
|||
|
||||
mov eax, [value]
|
||||
|
||||
ALIGN 16
|
||||
ttmath_loop:
|
||||
sub [ebx+edx*4], eax
|
||||
jnc ttmath_end
|
||||
|
||||
mov eax, 1
|
||||
lea edx, [edx+1] // inc edx, but faster (no flags dependencies)
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz ttmath_loop
|
||||
|
||||
ttmath_end:
|
||||
setc al
|
||||
movzx eax, al
|
||||
mov [c], eax
|
||||
setc al
|
||||
movzx edx, al
|
||||
mov [c], edx
|
||||
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -629,7 +757,7 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::SubInt")
|
||||
TTMATH_LOGC("UInt::SubInt", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -675,6 +803,7 @@ namespace ttmath
|
|||
*/
|
||||
__asm
|
||||
{
|
||||
pushad
|
||||
|
||||
mov ecx, [ss2_size]
|
||||
xor edx, edx // edx = 0, cf = 0
|
||||
|
@ -688,7 +817,7 @@ namespace ttmath
|
|||
sbb eax, [ebx+edx*4]
|
||||
mov [edi+edx*4], eax
|
||||
|
||||
lea edx, [edx+1]
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz ttmath_loop
|
||||
|
||||
|
@ -707,7 +836,7 @@ namespace ttmath
|
|||
sbb eax, ebx
|
||||
mov [edi+edx*4], eax
|
||||
|
||||
lea edx, [edx+1]
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz ttmath_loop2
|
||||
|
||||
|
@ -715,6 +844,8 @@ namespace ttmath
|
|||
|
||||
ttmath_end:
|
||||
mov [c], ecx
|
||||
|
||||
popad
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -764,6 +895,8 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -790,25 +923,29 @@ namespace ttmath
|
|||
#ifndef __GNUC__
|
||||
__asm
|
||||
{
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
mov ebx, [p1]
|
||||
|
||||
xor edx, edx
|
||||
mov ecx, edx
|
||||
sub ecx, [c]
|
||||
|
||||
mov ecx, [c]
|
||||
neg ecx
|
||||
mov ecx, [b]
|
||||
|
||||
ALIGN 16
|
||||
ttmath_loop:
|
||||
rcl dword ptr [ebx+edx*4], 1
|
||||
|
||||
lea edx, [edx+1] // inc edx, but faster (no flags dependencies)
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz ttmath_loop
|
||||
|
||||
setc al
|
||||
movzx eax, al
|
||||
mov [c], eax
|
||||
adc ecx, ecx
|
||||
mov [c], ecx
|
||||
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -836,7 +973,7 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::Rcl2_one")
|
||||
TTMATH_LOGC("UInt::Rcl2_one", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -864,22 +1001,25 @@ namespace ttmath
|
|||
#ifndef __GNUC__
|
||||
__asm
|
||||
{
|
||||
xor ecx, ecx
|
||||
sub ecx, [c]
|
||||
push ebx
|
||||
push ecx
|
||||
|
||||
mov ebx, [p1]
|
||||
mov ecx, [c]
|
||||
neg ecx
|
||||
mov ecx, [b]
|
||||
|
||||
ALIGN 16
|
||||
ttmath_loop:
|
||||
rcr dword ptr [ebx+ecx*4-4], 1
|
||||
|
||||
dec ecx
|
||||
jnz ttmath_loop
|
||||
|
||||
setc al
|
||||
movzx eax, al
|
||||
mov [c], eax
|
||||
adc ecx, ecx
|
||||
mov [c], ecx
|
||||
|
||||
pop ecx
|
||||
pop ebx
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -905,13 +1045,20 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::Rcr2_one")
|
||||
TTMATH_LOGC("UInt::Rcr2_one", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4731)
|
||||
//warning C4731: frame pointer register 'ebp' modified by inline assembly code
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this method moves all bits into the left hand side
|
||||
return value <- this <- c
|
||||
|
@ -929,47 +1076,62 @@ namespace ttmath
|
|||
{
|
||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||
|
||||
register sint b = value_size;
|
||||
register uint * p1 = table;
|
||||
register uint mask;
|
||||
uint b = value_size;
|
||||
uint * p1 = table;
|
||||
|
||||
#ifndef __GNUC__
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
push ebp
|
||||
|
||||
mov edi, [b]
|
||||
|
||||
mov ecx, 32
|
||||
sub ecx, [bits]
|
||||
mov edx, -1
|
||||
shr edx, cl
|
||||
mov [mask], edx
|
||||
|
||||
mov ecx, [bits]
|
||||
mov ebx, [p1]
|
||||
|
||||
xor edx, edx // edx = 0
|
||||
mov esi, edx // old value = 0
|
||||
|
||||
mov eax, [c]
|
||||
or eax, eax
|
||||
cmovnz esi, [mask] // if c then old value = mask
|
||||
|
||||
ALIGN 16
|
||||
mov ebp, edx // ebp = mask (modified ebp - don't read/write to variables)
|
||||
|
||||
xor edx, edx // edx = 0
|
||||
mov esi, edx
|
||||
or eax, eax
|
||||
cmovnz esi, ebp // if(c) esi=mask else esi=0
|
||||
|
||||
ttmath_loop:
|
||||
rol dword ptr [ebx+edx*4], cl
|
||||
|
||||
mov eax, [ebx+edx*4]
|
||||
and eax, [mask]
|
||||
and eax, ebp
|
||||
xor [ebx+edx*4], eax // clearing bits
|
||||
or [ebx+edx*4], esi // saving old value
|
||||
mov esi, eax
|
||||
|
||||
lea edx, [edx+1] // inc edx, but faster (no flags dependencies)
|
||||
inc edx
|
||||
dec edi
|
||||
jnz ttmath_loop
|
||||
|
||||
pop ebp // restoring ebp
|
||||
|
||||
and eax, 1
|
||||
mov dword ptr [c], eax
|
||||
mov [c], eax
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1017,9 +1179,9 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::Rcl2")
|
||||
TTMATH_LOGC("UInt::Rcl2", c)
|
||||
|
||||
return c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1044,37 +1206,43 @@ namespace ttmath
|
|||
|
||||
uint b = value_size;
|
||||
uint * p1 = table;
|
||||
uint mask;
|
||||
|
||||
#ifndef __GNUC__
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
push ebp
|
||||
|
||||
mov edi, [b]
|
||||
|
||||
mov ecx, 32
|
||||
sub ecx, [bits]
|
||||
mov edx, -1
|
||||
shl edx, cl
|
||||
mov [mask], edx
|
||||
|
||||
mov ecx, [bits]
|
||||
mov ebx, [p1]
|
||||
|
||||
xor edx, edx // edx = 0
|
||||
mov esi, edx // old value = 0
|
||||
add edx, edi
|
||||
dec edx // edx - is pointing at the last word
|
||||
|
||||
mov eax, [c]
|
||||
or eax, eax
|
||||
cmovnz esi, [mask] // if c then old value = mask
|
||||
|
||||
ALIGN 16
|
||||
mov ebp, edx // ebp = mask (modified ebp - don't read/write to variables)
|
||||
|
||||
xor edx, edx // edx = 0
|
||||
mov esi, edx
|
||||
add edx, edi
|
||||
dec edx // edx is pointing at the end of the table (on last word)
|
||||
or eax, eax
|
||||
cmovnz esi, ebp // if(c) esi=mask else esi=0
|
||||
|
||||
ttmath_loop:
|
||||
ror dword ptr [ebx+edx*4], cl
|
||||
|
||||
mov eax, [ebx+edx*4]
|
||||
and eax, [mask]
|
||||
and eax, ebp
|
||||
xor [ebx+edx*4], eax // clearing bits
|
||||
or [ebx+edx*4], esi // saving old value
|
||||
mov esi, eax
|
||||
|
@ -1083,10 +1251,18 @@ namespace ttmath
|
|||
dec edi
|
||||
jnz ttmath_loop
|
||||
|
||||
rol eax, 1 // bit 31 will be bit 0
|
||||
and eax, 1
|
||||
pop ebp // restoring ebp
|
||||
|
||||
mov dword ptr [c], eax
|
||||
rol eax, 1 // 31bit will be first
|
||||
and eax, 1
|
||||
mov [c], eax
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1137,12 +1313,16 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::Rcr2")
|
||||
TTMATH_LOGC("UInt::Rcr2", c)
|
||||
|
||||
return c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (default : 4731)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
this method returns the number of the highest set bit in one 32-bit word
|
||||
|
@ -1156,11 +1336,16 @@ namespace ttmath
|
|||
#ifndef __GNUC__
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push edx
|
||||
|
||||
mov edx,-1
|
||||
bsr eax,[x]
|
||||
cmovz eax,edx
|
||||
|
||||
mov [result], eax
|
||||
|
||||
pop edx
|
||||
pop eax
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1185,6 +1370,50 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -1193,9 +1422,10 @@ namespace ttmath
|
|||
|
||||
bit is from <0,31>
|
||||
e.g.
|
||||
uint x = 100;
|
||||
uint bit = SetBitInWord(x, 3);
|
||||
now: x = 108 and bit = 0
|
||||
|
||||
uint x = 100;
|
||||
uint bit = SetBitInWord(x, 3);
|
||||
now: x = 108 and bit = 0
|
||||
*/
|
||||
template<uint value_size>
|
||||
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
||||
|
@ -1208,14 +1438,20 @@ namespace ttmath
|
|||
#ifndef __GNUC__
|
||||
__asm
|
||||
{
|
||||
mov eax, [v]
|
||||
mov ebx, [bit]
|
||||
bts eax, ebx
|
||||
mov [v], eax
|
||||
push ebx
|
||||
push eax
|
||||
|
||||
setc bl
|
||||
movzx ebx, bl
|
||||
mov [old_bit], ebx
|
||||
mov eax, [v]
|
||||
mov ebx, [bit]
|
||||
bts eax, ebx
|
||||
mov [v], eax
|
||||
|
||||
setc bl
|
||||
movzx ebx, bl
|
||||
mov [old_bit], ebx
|
||||
|
||||
pop eax
|
||||
pop ebx
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1234,7 +1470,8 @@ namespace ttmath
|
|||
#endif
|
||||
|
||||
value = v;
|
||||
return old_bit;
|
||||
|
||||
return old_bit;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1265,11 +1502,17 @@ namespace ttmath
|
|||
|
||||
__asm
|
||||
{
|
||||
mov eax, [a]
|
||||
mul dword ptr [b]
|
||||
push eax
|
||||
push edx
|
||||
|
||||
mov [result2_], edx
|
||||
mov [result1_], eax
|
||||
mov eax, [a]
|
||||
mul dword ptr [b]
|
||||
|
||||
mov [result2_], edx
|
||||
mov [result1_], eax
|
||||
|
||||
pop edx
|
||||
pop eax
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1332,12 +1575,18 @@ namespace ttmath
|
|||
#ifndef __GNUC__
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push edx
|
||||
|
||||
mov edx, [a]
|
||||
mov eax, [b]
|
||||
div dword ptr [c]
|
||||
|
||||
mov [r_], eax
|
||||
mov [rest_], edx
|
||||
|
||||
pop edx
|
||||
pop eax
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* and is distributed under the 3-Clause BSD Licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||
* Copyright (c) 2006-2010, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -39,10 +39,11 @@
|
|||
#ifndef headerfilettmathuint_x86_64
|
||||
#define headerfilettmathuint_x86_64
|
||||
|
||||
|
||||
#ifndef TTMATH_NOASM
|
||||
#ifdef TTMATH_PLATFORM64
|
||||
|
||||
#pragma message("TTMATH_ASM64")
|
||||
|
||||
/*!
|
||||
\file ttmathuint_x86_64.h
|
||||
\brief template class UInt<uint> with assembler code for 64bit x86_64 processors
|
||||
|
@ -50,31 +51,92 @@
|
|||
this file is included at the end of ttmathuint.h
|
||||
*/
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
/*!
|
||||
\file ttmathuint_x86_64_msvc.asm
|
||||
\brief some asm routines for x86_64 when using Microsoft compiler
|
||||
|
||||
this file should be first compiled:
|
||||
- compile with debug info: ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
|
||||
- compile without debug info: ml64.exe /c ttmathuint_x86_64_msvc.asm
|
||||
|
||||
this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program
|
||||
|
||||
(you can use win64_assemble.bat file from ttmath subdirectory)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GNUC__
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace ttmath
|
||||
{
|
||||
|
||||
#if defined(_M_X64)
|
||||
#include <intrin.h>
|
||||
#ifndef __GNUC__
|
||||
|
||||
extern "C"
|
||||
{
|
||||
uint __fastcall adc_x64(uint* p1, const uint* p2, uint nSize, uint c);
|
||||
uint __fastcall addindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue);
|
||||
uint __fastcall addindexed2_x64(uint* p1, uint nSize, uint nPos, uint nValue1, uint nValue2);
|
||||
uint __fastcall sbb_x64(uint* p1, const uint* p2, uint nSize, uint c);
|
||||
uint __fastcall subindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue);
|
||||
uint __fastcall rcl_x64(uint* p1, uint nSize, uint nLowestBit);
|
||||
uint __fastcall rcr_x64(uint* p1, uint nSize, uint nLowestBit);
|
||||
uint __fastcall div_x64(uint* pnValHi, uint* pnValLo, uint nDiv);
|
||||
uint __fastcall rcl2_x64(uint* p1, uint nSize, uint nBits, uint c);
|
||||
uint __fastcall rcr2_x64(uint* p1, uint nSize, uint nBits, uint 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()
|
||||
{
|
||||
#ifndef __GNUC__
|
||||
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()
|
||||
{
|
||||
#ifndef __GNUC__
|
||||
LibTypeCode info = asm_vc_64;
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
LibTypeCode info = asm_gcc_64;
|
||||
#endif
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
*
|
||||
* basic mathematic functions
|
||||
|
@ -103,15 +165,12 @@ namespace ttmath
|
|||
// this algorithm doesn't require it
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined(_M_X64)
|
||||
c = adc_x64(p1,p2,b,c);
|
||||
#else
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
c = ttmath_adc_x64(p1,p2,b,c);
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
uint dummy, dummy2;
|
||||
uint dummy, dummy2;
|
||||
|
||||
/*
|
||||
this part should be compiled with gcc
|
||||
*/
|
||||
|
@ -131,12 +190,12 @@ namespace ttmath
|
|||
"adcq %%rcx, %%rcx \n"
|
||||
|
||||
: "=c" (c), "=a" (dummy), "=d" (dummy2)
|
||||
: "0" (b), "1" (c), "b" (p1), "S" (p2)
|
||||
: "0" (b), "1" (c), "b" (p1), "S" (p2)
|
||||
: "cc", "memory" );
|
||||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::Add")
|
||||
TTMATH_LOGC("UInt::Add", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -151,12 +210,17 @@ namespace ttmath
|
|||
|
||||
|
||||
if we've got (value_size=3):
|
||||
|
||||
table[0] = 10;
|
||||
table[1] = 30;
|
||||
table[2] = 5;
|
||||
|
||||
and we call:
|
||||
|
||||
AddInt(2,1)
|
||||
|
||||
then it'll be:
|
||||
|
||||
table[0] = 10;
|
||||
table[1] = 30 + 2;
|
||||
table[2] = 5;
|
||||
|
@ -173,15 +237,12 @@ namespace ttmath
|
|||
TTMATH_ASSERT( index < value_size )
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined(_M_X64)
|
||||
c = addindexed_x64(p1,b,index,value);
|
||||
#else
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
c = ttmath_addindexed_x64(p1,b,index,value);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
uint dummy, dummy2;
|
||||
uint dummy, dummy2;
|
||||
|
||||
__asm__ __volatile__(
|
||||
|
||||
|
@ -200,13 +261,13 @@ namespace ttmath
|
|||
"setc %%al \n"
|
||||
"movzx %%al, %%rdx \n"
|
||||
|
||||
: "=d" (c), "=a" (dummy), "=c" (dummy2)
|
||||
: "=d" (c), "=a" (dummy), "=c" (dummy2)
|
||||
: "0" (index), "1" (value), "2" (b), "b" (p1)
|
||||
: "cc", "memory" );
|
||||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::AddInt")
|
||||
TTMATH_LOGC("UInt::AddInt", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -224,17 +285,23 @@ namespace ttmath
|
|||
x1 - lower word, x2 - higher word
|
||||
|
||||
for example if we've got value_size equal 4 and:
|
||||
|
||||
table[0] = 3
|
||||
table[1] = 4
|
||||
table[2] = 5
|
||||
table[3] = 6
|
||||
|
||||
then let
|
||||
|
||||
x1 = 10
|
||||
x2 = 20
|
||||
|
||||
and
|
||||
|
||||
index = 1
|
||||
|
||||
the result of this method will be:
|
||||
|
||||
table[0] = 3
|
||||
table[1] = 4 + x1 = 14
|
||||
table[2] = 5 + x2 = 25
|
||||
|
@ -247,30 +314,6 @@ namespace ttmath
|
|||
*/
|
||||
template<uint value_size>
|
||||
uint UInt<value_size>::AddTwoInts(uint x2, uint x1, uint index)
|
||||
#if 0
|
||||
{
|
||||
uint i, c;
|
||||
|
||||
TTMATH_ASSERT( index < value_size )
|
||||
|
||||
printf("add %Id + %Id\n",x1,x2);
|
||||
for(int i=index ; i<value_size ; ++i)
|
||||
printf("%d: %Id\n",i,table[i]);
|
||||
|
||||
c = AddTwoWords(table[index], x1, 0, &table[index]);
|
||||
c = AddTwoWords(table[index+1], x2, c, &table[index+1]);
|
||||
|
||||
for(i=index+2 ; i<value_size && c ; ++i)
|
||||
c = AddTwoWords(table[i], 0, c, &table[i]);
|
||||
for(i=index ; i<value_size ; ++i)
|
||||
printf("%d: %Id\n",i,table[i]);
|
||||
printf(" -> %d\n",c);
|
||||
|
||||
TTMATH_LOG("UInt::AddTwoInts")
|
||||
|
||||
return c;
|
||||
}
|
||||
#else
|
||||
{
|
||||
uint b = value_size;
|
||||
uint * p1 = table;
|
||||
|
@ -279,22 +322,12 @@ namespace ttmath
|
|||
TTMATH_ASSERT( index < value_size - 1 )
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined(_M_X64)
|
||||
//printf("add %Id + %Id\n",x1,x2);
|
||||
//for(int i=index ; i<value_size ; ++i)
|
||||
// printf("%d: %Id\n",i,table[i]);
|
||||
//if (table[0] == 1265784741359897913) DebugBreak();
|
||||
c = addindexed2_x64(p1,b,index,x1,x2);
|
||||
//for(int i=index ; i<value_size ; ++i)
|
||||
// printf("%d: %Id\n",i,table[i]);
|
||||
//printf(" -> %d\n",c);
|
||||
#else
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
c = ttmath_addindexed2_x64(p1,b,index,x1,x2);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
uint dummy, dummy2;
|
||||
uint dummy, dummy2;
|
||||
|
||||
__asm__ __volatile__(
|
||||
|
||||
|
@ -323,14 +356,94 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::AddTwoInts")
|
||||
TTMATH_LOGC("UInt::AddTwoInts", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this static method addes one vector to the other
|
||||
'ss1' is larger in size or equal to 'ss2'
|
||||
|
||||
- ss1 points to the first (larger) vector
|
||||
- ss2 points to the second vector
|
||||
- ss1_size - size of the ss1 (and size of the result too)
|
||||
- ss2_size - size of the ss2
|
||||
- result - is the result vector (which has size the same as ss1: ss1_size)
|
||||
|
||||
Example: ss1_size is 5, ss2_size is 3
|
||||
ss1: ss2: result (output):
|
||||
5 1 5+1
|
||||
4 3 4+3
|
||||
2 7 2+7
|
||||
6 6
|
||||
9 9
|
||||
of course the carry is propagated and will be returned from the last item
|
||||
(this method is used by the Karatsuba multiplication algorithm)
|
||||
*/
|
||||
template<uint value_size>
|
||||
uint UInt<value_size>::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
|
||||
{
|
||||
TTMATH_ASSERT( ss1_size >= ss2_size )
|
||||
|
||||
uint c;
|
||||
|
||||
#ifndef __GNUC__
|
||||
c = ttmath_addvector_x64(ss1, ss2, ss1_size, ss2_size, result);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
uint dummy1, dummy2, dummy3;
|
||||
uint rest = ss1_size - ss2_size;
|
||||
|
||||
// this part should be compiled with gcc
|
||||
|
||||
__asm__ __volatile__(
|
||||
"mov %%rdx, %%r8 \n"
|
||||
"xor %%rdx, %%rdx \n" // rdx = 0, cf = 0
|
||||
"1: \n"
|
||||
"mov (%%rsi,%%rdx,8), %%rax \n"
|
||||
"adc (%%rbx,%%rdx,8), %%rax \n"
|
||||
"mov %%rax, (%%rdi,%%rdx,8) \n"
|
||||
|
||||
"inc %%rdx \n"
|
||||
"dec %%rcx \n"
|
||||
"jnz 1b \n"
|
||||
|
||||
"adc %%rcx, %%rcx \n" // rcx has the cf state
|
||||
|
||||
"or %%r8, %%r8 \n"
|
||||
"jz 3f \n"
|
||||
|
||||
"xor %%rbx, %%rbx \n" // ebx = 0
|
||||
"neg %%rcx \n" // setting cf from rcx
|
||||
"mov %%r8, %%rcx \n" // rcx=rest and is != 0
|
||||
"2: \n"
|
||||
"mov (%%rsi, %%rdx, 8), %%rax \n"
|
||||
"adc %%rbx, %%rax \n"
|
||||
"mov %%rax, (%%rdi, %%rdx, 8) \n"
|
||||
|
||||
"inc %%rdx \n"
|
||||
"dec %%rcx \n"
|
||||
"jnz 2b \n"
|
||||
|
||||
"adc %%rcx, %%rcx \n"
|
||||
"3: \n"
|
||||
|
||||
: "=a" (dummy1), "=b" (dummy2), "=c" (c), "=d" (dummy3)
|
||||
: "1" (ss2), "2" (ss2_size), "3" (rest), "S" (ss1), "D" (result)
|
||||
: "%r8", "cc", "memory" );
|
||||
|
||||
#endif
|
||||
|
||||
TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -354,15 +467,12 @@ namespace ttmath
|
|||
// this algorithm doesn't require it
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined(_M_X64)
|
||||
c = sbb_x64(p1,p2,b,c);
|
||||
#else
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
c = ttmath_sbb_x64(p1,p2,b,c);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
uint dummy, dummy2;
|
||||
uint dummy, dummy2;
|
||||
|
||||
__asm__ __volatile__(
|
||||
|
||||
|
@ -380,18 +490,18 @@ namespace ttmath
|
|||
"adcq %%rcx, %%rcx \n"
|
||||
|
||||
: "=c" (c), "=a" (dummy), "=d" (dummy2)
|
||||
: "0" (b), "1" (c), "b" (p1), "S" (p2)
|
||||
: "0" (b), "1" (c), "b" (p1), "S" (p2)
|
||||
: "cc", "memory" );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::Sub")
|
||||
TTMATH_LOGC("UInt::Sub", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this method subtracts one word (at a specific position)
|
||||
and returns a carry (if it was)
|
||||
|
@ -399,12 +509,17 @@ namespace ttmath
|
|||
***this method is created only on a 64bit platform***
|
||||
|
||||
if we've got (value_size=3):
|
||||
|
||||
table[0] = 10;
|
||||
table[1] = 30;
|
||||
table[2] = 5;
|
||||
|
||||
and we call:
|
||||
|
||||
SubInt(2,1)
|
||||
|
||||
then it'll be:
|
||||
|
||||
table[0] = 10;
|
||||
table[1] = 30 - 2;
|
||||
table[2] = 5;
|
||||
|
@ -421,13 +536,10 @@ namespace ttmath
|
|||
TTMATH_ASSERT( index < value_size )
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined(_M_X64)
|
||||
c = subindexed_x64(p1,b,index,value);
|
||||
#else
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
c = ttmath_subindexed_x64(p1,b,index,value);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
uint dummy, dummy2;
|
||||
|
||||
|
@ -454,7 +566,92 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt64::SubInt")
|
||||
TTMATH_LOGC("UInt::SubInt", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this static method subtractes one vector from the other
|
||||
'ss1' is larger in size or equal to 'ss2'
|
||||
|
||||
- ss1 points to the first (larger) vector
|
||||
- ss2 points to the second vector
|
||||
- ss1_size - size of the ss1 (and size of the result too)
|
||||
- ss2_size - size of the ss2
|
||||
- result - is the result vector (which has size the same as ss1: ss1_size)
|
||||
|
||||
Example: ss1_size is 5, ss2_size is 3
|
||||
ss1: ss2: result (output):
|
||||
5 1 5-1
|
||||
4 3 4-3
|
||||
2 7 2-7
|
||||
6 6-1 (the borrow from previous item)
|
||||
9 9
|
||||
return (carry): 0
|
||||
of course the carry (borrow) is propagated and will be returned from the last item
|
||||
(this method is used by the Karatsuba multiplication algorithm)
|
||||
*/
|
||||
template<uint value_size>
|
||||
uint UInt<value_size>::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
|
||||
{
|
||||
TTMATH_ASSERT( ss1_size >= ss2_size )
|
||||
|
||||
uint c;
|
||||
|
||||
#ifndef __GNUC__
|
||||
c = ttmath_subvector_x64(ss1, ss2, ss1_size, ss2_size, result);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
// the asm code is nearly the same as in AddVector
|
||||
// only two instructions 'adc' are changed to 'sbb'
|
||||
|
||||
uint dummy1, dummy2, dummy3;
|
||||
uint rest = ss1_size - ss2_size;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"mov %%rdx, %%r8 \n"
|
||||
"xor %%rdx, %%rdx \n" // rdx = 0, cf = 0
|
||||
"1: \n"
|
||||
"mov (%%rsi,%%rdx,8), %%rax \n"
|
||||
"sbb (%%rbx,%%rdx,8), %%rax \n"
|
||||
"mov %%rax, (%%rdi,%%rdx,8) \n"
|
||||
|
||||
"inc %%rdx \n"
|
||||
"dec %%rcx \n"
|
||||
"jnz 1b \n"
|
||||
|
||||
"adc %%rcx, %%rcx \n" // rcx has the cf state
|
||||
|
||||
"or %%r8, %%r8 \n"
|
||||
"jz 3f \n"
|
||||
|
||||
"xor %%rbx, %%rbx \n" // ebx = 0
|
||||
"neg %%rcx \n" // setting cf from rcx
|
||||
"mov %%r8, %%rcx \n" // rcx=rest and is != 0
|
||||
"2: \n"
|
||||
"mov (%%rsi, %%rdx, 8), %%rax \n"
|
||||
"sbb %%rbx, %%rax \n"
|
||||
"mov %%rax, (%%rdi, %%rdx, 8) \n"
|
||||
|
||||
"inc %%rdx \n"
|
||||
"dec %%rcx \n"
|
||||
"jnz 2b \n"
|
||||
|
||||
"adc %%rcx, %%rcx \n"
|
||||
"3: \n"
|
||||
|
||||
: "=a" (dummy1), "=b" (dummy2), "=c" (c), "=d" (dummy3)
|
||||
: "1" (ss2), "2" (ss2_size), "3" (rest), "S" (ss1), "D" (result)
|
||||
: "%r8", "cc", "memory" );
|
||||
|
||||
#endif
|
||||
|
||||
TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -480,14 +677,12 @@ namespace ttmath
|
|||
sint b = value_size;
|
||||
uint * p1 = table;
|
||||
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined(_M_X64)
|
||||
c = rcl_x64(p1,b,c);
|
||||
#else
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
c = ttmath_rcl_x64(p1,b,c);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
uint dummy, dummy2;
|
||||
|
||||
|
@ -511,7 +706,7 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::Rcl2_one")
|
||||
TTMATH_LOGC("UInt::Rcl2_one", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -537,14 +732,12 @@ namespace ttmath
|
|||
sint b = value_size;
|
||||
uint * p1 = table;
|
||||
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined(_M_X64)
|
||||
c = rcr_x64(p1,b,c);
|
||||
#else
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
c = ttmath_rcr_x64(p1,b,c);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
uint dummy;
|
||||
|
||||
|
@ -566,7 +759,7 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::Rcr2_one")
|
||||
TTMATH_LOGC("UInt::Rcr2_one", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -595,14 +788,12 @@ namespace ttmath
|
|||
uint b = value_size;
|
||||
uint * p1 = table;
|
||||
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined(_M_X64)
|
||||
c = rcl2_x64(p1,b,bits,c);
|
||||
#else
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
c = ttmath_rcl2_x64(p1,b,bits,c);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
uint dummy, dummy2, dummy3;
|
||||
|
||||
|
@ -618,7 +809,6 @@ namespace ttmath
|
|||
|
||||
"xorq %%rdx, %%rdx \n"
|
||||
"movq %%rdx, %%rsi \n"
|
||||
|
||||
"orq %%rax, %%rax \n"
|
||||
"cmovnz %%r8, %%rsi \n"
|
||||
|
||||
|
@ -638,12 +828,12 @@ namespace ttmath
|
|||
"and $1, %%rax \n"
|
||||
|
||||
: "=a" (c), "=D" (dummy), "=S" (dummy2), "=d" (dummy3)
|
||||
: "0" (c), "1" (b), "b" (p1), "c" (bits)
|
||||
: "0" (c), "1" (b), "b" (p1), "c" (bits)
|
||||
: "%r8", "cc", "memory" );
|
||||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::Rcl2")
|
||||
TTMATH_LOGC("UInt::Rcl2", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -671,12 +861,9 @@ namespace ttmath
|
|||
sint b = value_size;
|
||||
uint * p1 = table;
|
||||
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined(_M_X64)
|
||||
c = rcr2_x64(p1,b,bits,c);
|
||||
#else
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
c = ttmath_rcr2_x64(p1,b,bits,c);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -697,7 +884,6 @@ namespace ttmath
|
|||
"movq %%rdx, %%rsi \n"
|
||||
"addq %%rdi, %%rdx \n"
|
||||
"decq %%rdx \n"
|
||||
|
||||
"orq %%rax, %%rax \n"
|
||||
"cmovnz %%R8, %%rsi \n"
|
||||
|
||||
|
@ -705,7 +891,7 @@ namespace ttmath
|
|||
"rorq %%cl, (%%rbx,%%rdx,8) \n"
|
||||
|
||||
"movq (%%rbx,%%rdx,8), %%rax \n"
|
||||
"andq %%R8, %%rax \n"
|
||||
"andq %%R8, %%rax \n"
|
||||
"xorq %%rax, (%%rbx,%%rdx,8) \n"
|
||||
"orq %%rsi, (%%rbx,%%rdx,8) \n"
|
||||
"movq %%rax, %%rsi \n"
|
||||
|
@ -723,7 +909,7 @@ namespace ttmath
|
|||
|
||||
#endif
|
||||
|
||||
TTMATH_LOG("UInt::Rcr2")
|
||||
TTMATH_LOGC("UInt::Rcr2", c)
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -738,21 +924,21 @@ namespace ttmath
|
|||
template<uint value_size>
|
||||
sint UInt<value_size>::FindLeadingBitInWord(uint x)
|
||||
{
|
||||
register sint result;
|
||||
sint result;
|
||||
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined(_MSC_VER)
|
||||
unsigned long nIndex(0);
|
||||
|
||||
if (_BitScanReverse64(&nIndex,x) == 0)
|
||||
result = -1;
|
||||
else
|
||||
result = nIndex;
|
||||
#else
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
unsigned long nIndex = 0;
|
||||
|
||||
if( _BitScanReverse64(&nIndex,x) == 0 )
|
||||
result = -1;
|
||||
else
|
||||
result = nIndex;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
uint dummy;
|
||||
|
||||
|
@ -773,6 +959,50 @@ 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;
|
||||
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
||||
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'
|
||||
and returns the last state of the bit (zero or one)
|
||||
|
@ -796,17 +1026,10 @@ namespace ttmath
|
|||
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(TTMATH_PLATFORM64)
|
||||
old_bit = _bittestandset64((__int64*)&value,bit) != 0;
|
||||
#else
|
||||
old_bit = _bittestandset((long*)&value,bit) != 0;
|
||||
#endif
|
||||
#else
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
old_bit = _bittestandset64((__int64*)&value,bit) != 0;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
__asm__ (
|
||||
|
@ -837,8 +1060,8 @@ namespace ttmath
|
|||
|
||||
/*!
|
||||
multiplication: result_high:result_low = a * b
|
||||
result_high - higher word of the result
|
||||
result_low - lower word of the result
|
||||
- result_high - higher word of the result
|
||||
- result_low - lower word of the result
|
||||
|
||||
this methos never returns a carry
|
||||
this method is used in the second version of the multiplication algorithms
|
||||
|
@ -858,14 +1081,12 @@ namespace ttmath
|
|||
uint result1_;
|
||||
uint result2_;
|
||||
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined(_MSC_VER)
|
||||
result1_ = _umul128(a,b,&result2_);
|
||||
#else
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
result1_ = _umul128(a,b,&result2_);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
__asm__ (
|
||||
|
@ -893,7 +1114,6 @@ namespace ttmath
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
||||
/*!
|
||||
this method calculates 64bits word a:b / 32bits c (a higher, b lower word)
|
||||
|
@ -920,16 +1140,16 @@ namespace ttmath
|
|||
|
||||
TTMATH_ASSERT( c != 0 )
|
||||
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined(_MSC_VER)
|
||||
div_x64(&a,&b,c);
|
||||
r_ = a;
|
||||
rest_ = b;
|
||||
#else
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
|
||||
ttmath_div_x64(&a,&b,c);
|
||||
r_ = a;
|
||||
rest_ = b;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
__asm__ (
|
||||
|
@ -947,133 +1167,6 @@ namespace ttmath
|
|||
*rest = rest_;
|
||||
}
|
||||
|
||||
template<uint value_size>
|
||||
uint UInt<value_size>::AddTwoWords(uint a, uint b, uint carry, uint * result)
|
||||
{
|
||||
uint temp;
|
||||
|
||||
if( carry == 0 )
|
||||
{
|
||||
temp = a + b;
|
||||
|
||||
if( temp < a )
|
||||
carry = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
carry = 1;
|
||||
temp = a + b + carry;
|
||||
|
||||
if( temp > a ) // !(temp<=a)
|
||||
carry = 0;
|
||||
}
|
||||
|
||||
*result = temp;
|
||||
|
||||
return carry;
|
||||
}
|
||||
|
||||
template<uint value_size>
|
||||
uint UInt<value_size>::SubTwoWords(uint a, uint b, uint carry, uint * result)
|
||||
{
|
||||
if( carry == 0 )
|
||||
{
|
||||
*result = a - b;
|
||||
|
||||
if( a < b )
|
||||
carry = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
carry = 1;
|
||||
*result = a - b - carry;
|
||||
|
||||
if( a > b ) // !(a <= b )
|
||||
carry = 0;
|
||||
}
|
||||
|
||||
return carry;
|
||||
}
|
||||
|
||||
/*!
|
||||
this static method addes one vector to the other
|
||||
'ss1' is larger in size or equal to 'ss2'
|
||||
|
||||
ss1 points to the first (larger) vector
|
||||
ss2 points to the second vector
|
||||
ss1_size - size of the ss1 (and size of the result too)
|
||||
ss2_size - size of the ss2
|
||||
result - is the result vector (which has size the same as ss1: ss1_size)
|
||||
|
||||
Example: ss1_size is 5, ss2_size is 3
|
||||
ss1: ss2: result (output):
|
||||
5 1 5+1
|
||||
4 3 4+3
|
||||
2 7 2+7
|
||||
6 6
|
||||
9 9
|
||||
of course the carry is propagated and will be returned from the last item
|
||||
(this method is used by the Karatsuba multiplication algorithm)
|
||||
*/
|
||||
template<uint value_size>
|
||||
uint UInt<value_size>::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
|
||||
{
|
||||
uint i, c = 0;
|
||||
|
||||
TTMATH_ASSERT( ss1_size >= ss2_size )
|
||||
|
||||
for(i=0 ; i<ss2_size ; ++i)
|
||||
c = AddTwoWords(ss1[i], ss2[i], c, &result[i]);
|
||||
|
||||
for( ; i<ss1_size ; ++i)
|
||||
c = AddTwoWords(ss1[i], 0, c, &result[i]);
|
||||
|
||||
TTMATH_LOG("UInt::AddVector")
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/*!
|
||||
this static method subtractes one vector from the other
|
||||
'ss1' is larger in size or equal to 'ss2'
|
||||
|
||||
ss1 points to the first (larger) vector
|
||||
ss2 points to the second vector
|
||||
ss1_size - size of the ss1 (and size of the result too)
|
||||
ss2_size - size of the ss2
|
||||
result - is the result vector (which has size the same as ss1: ss1_size)
|
||||
|
||||
Example: ss1_size is 5, ss2_size is 3
|
||||
ss1: ss2: result (output):
|
||||
5 1 5-1
|
||||
4 3 4-3
|
||||
2 7 2-7
|
||||
6 6-1 (the borrow from previous item)
|
||||
9 9
|
||||
return (carry): 0
|
||||
of course the carry (borrow) is propagated and will be returned from the last item
|
||||
(this method is used by the Karatsuba multiplication algorithm)
|
||||
*/
|
||||
template<uint value_size>
|
||||
uint UInt<value_size>::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
|
||||
{
|
||||
uint i, c = 0;
|
||||
|
||||
TTMATH_ASSERT( ss1_size >= ss2_size )
|
||||
|
||||
for(i=0 ; i<ss2_size ; ++i)
|
||||
c = SubTwoWords(ss1[i], ss2[i], c, &result[i]);
|
||||
|
||||
for( ; i<ss1_size ; ++i)
|
||||
c = SubTwoWords(ss1[i], 0, c, &result[i]);
|
||||
|
||||
TTMATH_LOG("UInt::SubVector")
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif // #ifndef __GNUC__
|
||||
|
||||
} //namespace
|
||||
|
||||
|
||||
|
|
|
@ -1,30 +1,82 @@
|
|||
PUBLIC adc_x64
|
||||
PUBLIC addindexed_x64
|
||||
PUBLIC addindexed2_x64
|
||||
;
|
||||
; This file is a part of TTMath Bignum Library
|
||||
; and is distributed under the 3-Clause BSD Licence.
|
||||
; Author: Christian Kaiser <chk@online.de>, Tomasz Sowa <t.sowa@ttmath.org>
|
||||
;
|
||||
|
||||
PUBLIC sbb_x64
|
||||
PUBLIC subindexed_x64
|
||||
;
|
||||
; Copyright (c) 2009-2017, Christian Kaiser, Tomasz Sowa
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
;
|
||||
; * Redistributions of source code must retain the above copyright notice,
|
||||
; this list of conditions and the following disclaimer.
|
||||
;
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
;
|
||||
; * Neither the name Christian Kaiser nor the names of contributors to this
|
||||
; project may be used to endorse or promote products derived
|
||||
; from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
; THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;
|
||||
|
||||
PUBLIC rcl_x64
|
||||
PUBLIC rcr_x64
|
||||
;
|
||||
; compile with debug info: ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
|
||||
; compile without debug info: ml64.exe /c ttmathuint_x86_64_msvc.asm
|
||||
; this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program
|
||||
;
|
||||
|
||||
PUBLIC rcl2_x64
|
||||
PUBLIC rcr2_x64
|
||||
; doxygen info is put to ttmathuint_x86_64.h file
|
||||
|
||||
PUBLIC div_x64
|
||||
|
||||
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
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
adc_x64 PROC
|
||||
ttmath_adc_x64 PROC
|
||||
; rcx = p1
|
||||
; rdx = p2
|
||||
; r8 = nSize
|
||||
|
@ -47,7 +99,7 @@ adc_x64 PROC
|
|||
|
||||
ret
|
||||
|
||||
adc_x64 ENDP
|
||||
ttmath_adc_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
|
@ -55,7 +107,7 @@ adc_x64 ENDP
|
|||
|
||||
;----------------------------------------
|
||||
|
||||
addindexed_x64 PROC
|
||||
ttmath_addindexed_x64 PROC
|
||||
|
||||
; rcx = p1
|
||||
; rdx = nSize
|
||||
|
@ -88,7 +140,7 @@ done_with_cy:
|
|||
|
||||
ret
|
||||
|
||||
addindexed_x64 ENDP
|
||||
ttmath_addindexed_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
|
@ -96,18 +148,18 @@ addindexed_x64 ENDP
|
|||
|
||||
;----------------------------------------
|
||||
|
||||
addindexed2_x64 PROC
|
||||
ttmath_addindexed2_x64 PROC
|
||||
|
||||
; rcx = p1 (pointer)
|
||||
; rdx = b (value size)
|
||||
; r8 = nPos
|
||||
; r9 = nValue1
|
||||
; [esp+0x28] = nValue2
|
||||
; [rsp+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
|
||||
mov r10, [rsp+028h] ; r10 = nValue2
|
||||
|
||||
add qword ptr [r11 + r8 * 8], r9
|
||||
lea r8, [r8+1]
|
||||
|
@ -129,7 +181,9 @@ next:
|
|||
lea rax, [rax+1]
|
||||
ret
|
||||
|
||||
addindexed2_x64 ENDP
|
||||
ttmath_addindexed2_x64 ENDP
|
||||
|
||||
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
|
@ -137,7 +191,61 @@ addindexed2_x64 ENDP
|
|||
|
||||
;----------------------------------------
|
||||
|
||||
sbb_x64 PROC
|
||||
|
||||
ttmath_addvector_x64 PROC
|
||||
; rcx = ss1
|
||||
; rdx = ss2
|
||||
; r8 = ss1_size
|
||||
; r9 = ss2_size
|
||||
; [rsp+0x28] = result
|
||||
|
||||
mov r10, [rsp+028h]
|
||||
sub r8, r9
|
||||
xor r11, r11 ; r11=0, cf=0
|
||||
|
||||
ALIGN 16
|
||||
loop1:
|
||||
mov rax, qword ptr [rcx + r11 * 8]
|
||||
adc rax, qword ptr [rdx + r11 * 8]
|
||||
mov qword ptr [r10 + r11 * 8], rax
|
||||
inc r11
|
||||
dec r9
|
||||
jnz loop1
|
||||
|
||||
adc r9, r9 ; r9 has the cf state
|
||||
|
||||
or r8, r8
|
||||
jz done
|
||||
|
||||
neg r9 ; setting cf from r9
|
||||
mov r9, 0 ; don't use xor here (cf is used)
|
||||
loop2:
|
||||
mov rax, qword ptr [rcx + r11 * 8]
|
||||
adc rax, r9
|
||||
mov qword ptr [r10 + r11 * 8], rax
|
||||
inc r11
|
||||
dec r8
|
||||
jnz loop2
|
||||
|
||||
adc r8, r8
|
||||
mov rax, r8
|
||||
|
||||
ret
|
||||
|
||||
done:
|
||||
mov rax, r9
|
||||
ret
|
||||
|
||||
ttmath_addvector_x64 ENDP
|
||||
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ttmath_sbb_x64 PROC
|
||||
|
||||
; rcx = p1
|
||||
; rdx = p2
|
||||
|
@ -161,7 +269,7 @@ sbb_x64 PROC
|
|||
|
||||
ret
|
||||
|
||||
sbb_x64 ENDP
|
||||
ttmath_sbb_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
|
@ -169,7 +277,7 @@ sbb_x64 ENDP
|
|||
|
||||
;----------------------------------------
|
||||
|
||||
subindexed_x64 PROC
|
||||
ttmath_subindexed_x64 PROC
|
||||
; rcx = p1
|
||||
; rdx = nSize
|
||||
; r8 = nPos
|
||||
|
@ -186,17 +294,17 @@ loop1:
|
|||
mov r9, 1
|
||||
dec rdx
|
||||
jnz loop1
|
||||
jc return_1 ; most of the times, there will be NO carry (I hope)
|
||||
|
||||
mov rax, 1
|
||||
ret
|
||||
|
||||
done:
|
||||
xor rax, rax
|
||||
ret
|
||||
|
||||
return_1:
|
||||
mov rax, 1
|
||||
ret
|
||||
ttmath_subindexed_x64 ENDP
|
||||
|
||||
|
||||
subindexed_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
|
@ -204,7 +312,64 @@ subindexed_x64 ENDP
|
|||
|
||||
;----------------------------------------
|
||||
|
||||
rcl_x64 PROC
|
||||
; the same asm code as in addvector_x64 only two instructions 'adc' changed to 'sbb'
|
||||
|
||||
ttmath_subvector_x64 PROC
|
||||
; rcx = ss1
|
||||
; rdx = ss2
|
||||
; r8 = ss1_size
|
||||
; r9 = ss2_size
|
||||
; [rsp+0x28] = result
|
||||
|
||||
mov r10, [rsp+028h]
|
||||
sub r8, r9
|
||||
xor r11, r11 ; r11=0, cf=0
|
||||
|
||||
ALIGN 16
|
||||
loop1:
|
||||
mov rax, qword ptr [rcx + r11 * 8]
|
||||
sbb rax, qword ptr [rdx + r11 * 8]
|
||||
mov qword ptr [r10 + r11 * 8], rax
|
||||
inc r11
|
||||
dec r9
|
||||
jnz loop1
|
||||
|
||||
adc r9, r9 ; r9 has the cf state
|
||||
|
||||
or r8, r8
|
||||
jz done
|
||||
|
||||
neg r9 ; setting cf from r9
|
||||
mov r9, 0 ; don't use xor here (cf is used)
|
||||
loop2:
|
||||
mov rax, qword ptr [rcx + r11 * 8]
|
||||
sbb rax, r9
|
||||
mov qword ptr [r10 + r11 * 8], rax
|
||||
inc r11
|
||||
dec r8
|
||||
jnz loop2
|
||||
|
||||
adc r8, r8
|
||||
mov rax, r8
|
||||
|
||||
ret
|
||||
|
||||
done:
|
||||
mov rax, r9
|
||||
ret
|
||||
|
||||
ttmath_subvector_x64 ENDP
|
||||
|
||||
|
||||
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ttmath_rcl_x64 PROC
|
||||
; rcx = p1
|
||||
; rdx = b
|
||||
; r8 = nLowestBit
|
||||
|
@ -225,7 +390,7 @@ loop1:
|
|||
|
||||
ret
|
||||
|
||||
rcl_x64 ENDP
|
||||
ttmath_rcl_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
|
@ -233,7 +398,7 @@ rcl_x64 ENDP
|
|||
|
||||
;----------------------------------------
|
||||
|
||||
rcr_x64 PROC
|
||||
ttmath_rcr_x64 PROC
|
||||
; rcx = p1
|
||||
; rdx = nSize
|
||||
; r8 = nLowestBit
|
||||
|
@ -252,7 +417,7 @@ loop1:
|
|||
|
||||
ret
|
||||
|
||||
rcr_x64 ENDP
|
||||
ttmath_rcr_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
|
@ -260,7 +425,7 @@ rcr_x64 ENDP
|
|||
|
||||
;----------------------------------------
|
||||
|
||||
div_x64 PROC
|
||||
ttmath_div_x64 PROC
|
||||
|
||||
; rcx = &Hi
|
||||
; rdx = &Lo
|
||||
|
@ -277,7 +442,7 @@ div_x64 PROC
|
|||
|
||||
ret
|
||||
|
||||
div_x64 ENDP
|
||||
ttmath_div_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
|
@ -285,7 +450,7 @@ div_x64 ENDP
|
|||
|
||||
;----------------------------------------
|
||||
|
||||
rcl2_x64 PROC
|
||||
ttmath_rcl2_x64 PROC
|
||||
; rcx = p1
|
||||
; rdx = nSize
|
||||
; r8 = bits
|
||||
|
@ -328,7 +493,7 @@ loop1:
|
|||
pop rbx
|
||||
ret
|
||||
|
||||
rcl2_x64 ENDP
|
||||
ttmath_rcl2_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
|
@ -336,7 +501,7 @@ rcl2_x64 ENDP
|
|||
|
||||
;----------------------------------------
|
||||
|
||||
rcr2_x64 PROC
|
||||
ttmath_rcr2_x64 PROC
|
||||
; rcx = p1
|
||||
; rdx = nSize
|
||||
; r8 = bits
|
||||
|
@ -381,6 +546,6 @@ loop1:
|
|||
|
||||
ret
|
||||
|
||||
rcr2_x64 ENDP
|
||||
ttmath_rcr2_x64 ENDP
|
||||
|
||||
END
|
|
@ -0,0 +1,9 @@
|
|||
rem make sure this is a proper path to the 64 bit assembler
|
||||
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\ml64.exe" /c ttmathuint_x86_64_msvc.asm
|
||||
rem ml64.exe will produce ttmathuint_x86_64_msvc.obj which should be added (linked) to your project
|
||||
|
||||
rem or you can assemble with debug info
|
||||
rem ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
|
||||
|
||||
rem be nice, most Windows users just click on the file
|
||||
pause
|
Loading…
Reference in New Issue