First commit
This commit is contained in:
commit
1dd3d37a9c
|
@ -0,0 +1,2 @@
|
|||
nimcache/
|
||||
build/
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,5 @@
|
|||
# nim-ttmath
|
||||
|
||||
A Nim wrapper for [ttmath library](https://www.ttmath.org/), a c++ template library for operating with
|
||||
big integers and floats with fixed sizes.
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import ttmath
|
||||
|
||||
var a = 2.i256
|
||||
var b = 2.i256
|
||||
|
||||
echo a + b
|
||||
echo a - b
|
||||
echo a * b
|
||||
echo a / b
|
||||
|
||||
echo a < b
|
||||
echo a > b
|
||||
echo 3.i256 > b
|
||||
echo a < 3.i256
|
||||
echo a <= b
|
||||
echo a >= b
|
||||
a += b
|
||||
echo a
|
||||
a *= b
|
||||
echo a
|
||||
a -= b
|
||||
echo a
|
||||
a /= b
|
||||
echo a
|
||||
echo a mod b
|
||||
echo a div b
|
||||
echo a and b
|
||||
echo a or b
|
||||
echo a xor b
|
||||
echo pow(a, 2)
|
||||
echo a shl 2
|
||||
echo a shr 2
|
||||
echo a.getInt
|
||||
echo -a
|
||||
echo "02".i256
|
|
@ -0,0 +1 @@
|
|||
--p:"../src"
|
|
@ -0,0 +1,28 @@
|
|||
Copyright (c) 2006-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.
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the (new) 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 (new) BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2010, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||
* project may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef headerfilettmathmisc
|
||||
#define headerfilettmathmisc
|
||||
|
||||
|
||||
/*!
|
||||
\file ttmathmisc.h
|
||||
\brief some helpful functions
|
||||
*/
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace ttmath
|
||||
{
|
||||
|
||||
/*!
|
||||
some helpful functions
|
||||
*/
|
||||
class Misc
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* AssignString(result, str)
|
||||
* result = str
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
result = str
|
||||
*/
|
||||
static void AssignString(std::string & result, const char * str)
|
||||
{
|
||||
result = str;
|
||||
}
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
/*!
|
||||
result = str
|
||||
*/
|
||||
static void AssignString(std::wstring & result, const char * str)
|
||||
{
|
||||
result.clear();
|
||||
|
||||
for( ; *str ; ++str )
|
||||
result += *str;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
result = str
|
||||
*/
|
||||
static void AssignString(std::wstring & result, const std::string & str)
|
||||
{
|
||||
return AssignString(result, str.c_str());
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
result = str
|
||||
*/
|
||||
static void AssignString(std::string & result, const wchar_t * str)
|
||||
{
|
||||
result.clear();
|
||||
|
||||
for( ; *str ; ++str )
|
||||
result += static_cast<char>(*str);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
result = str
|
||||
*/
|
||||
static void AssignString(std::string & result, const std::wstring & str)
|
||||
{
|
||||
return AssignString(result, str.c_str());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* AddString(result, str)
|
||||
* result += str
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
result += str
|
||||
*/
|
||||
static void AddString(std::string & result, const char * str)
|
||||
{
|
||||
result += str;
|
||||
}
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
/*!
|
||||
result += str
|
||||
*/
|
||||
static void AddString(std::wstring & result, const char * str)
|
||||
{
|
||||
for( ; *str ; ++str )
|
||||
result += *str;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
this method omits any white characters from the string
|
||||
char_type is char or wchar_t
|
||||
*/
|
||||
template<class char_type>
|
||||
static void SkipWhiteCharacters(const char_type * & c)
|
||||
{
|
||||
// 13 is at the end in a DOS text file (\r\n)
|
||||
while( (*c==' ' ) || (*c=='\t') || (*c==13 ) || (*c=='\n') )
|
||||
++c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this static method converts one character into its value
|
||||
|
||||
for example:
|
||||
1 -> 1
|
||||
8 -> 8
|
||||
A -> 10
|
||||
f -> 15
|
||||
|
||||
this method don't check whether c is correct or not
|
||||
*/
|
||||
static uint CharToDigit(uint c)
|
||||
{
|
||||
if(c>='0' && c<='9')
|
||||
return c-'0';
|
||||
|
||||
if(c>='a' && c<='z')
|
||||
return c-'a'+10;
|
||||
|
||||
return c-'A'+10;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method changes a character 'c' into its value
|
||||
(if there can't be a correct value it returns -1)
|
||||
|
||||
for example:
|
||||
c=2, base=10 -> function returns 2
|
||||
c=A, base=10 -> function returns -1
|
||||
c=A, base=16 -> function returns 10
|
||||
*/
|
||||
static sint CharToDigit(uint c, uint base)
|
||||
{
|
||||
if( c>='0' && c<='9' )
|
||||
c=c-'0';
|
||||
else
|
||||
if( c>='a' && c<='z' )
|
||||
c=c-'a'+10;
|
||||
else
|
||||
if( c>='A' && c<='Z' )
|
||||
c=c-'A'+10;
|
||||
else
|
||||
return -1;
|
||||
|
||||
|
||||
if( c >= base )
|
||||
return -1;
|
||||
|
||||
|
||||
return sint(c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this method converts a digit into a char
|
||||
digit should be from <0,F>
|
||||
(we don't have to get a base)
|
||||
|
||||
for example:
|
||||
1 -> 1
|
||||
8 -> 8
|
||||
10 -> A
|
||||
15 -> F
|
||||
*/
|
||||
static uint DigitToChar(uint digit)
|
||||
{
|
||||
if( digit < 10 )
|
||||
return digit + '0';
|
||||
|
||||
return digit - 10 + 'A';
|
||||
}
|
||||
|
||||
|
||||
}; // struct Misc
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,809 @@
|
|||
/*
|
||||
* This file is a part of TTMath Mathematical Library
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2010, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||
* project may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef headerfilettmathobject
|
||||
#define headerfilettmathobject
|
||||
|
||||
/*!
|
||||
\file ttmathobjects.h
|
||||
\brief Mathematic functions.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include "ttmathtypes.h"
|
||||
#include "ttmathmisc.h"
|
||||
|
||||
|
||||
namespace ttmath
|
||||
{
|
||||
|
||||
/*!
|
||||
objects of this class are used with the mathematical parser
|
||||
they hold variables or functions defined by a user
|
||||
|
||||
each object has its own table in which we're keeping variables or functions
|
||||
*/
|
||||
class Objects
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
/*!
|
||||
one item (variable or function)
|
||||
'items' will be on the table
|
||||
*/
|
||||
struct Item
|
||||
{
|
||||
// name of a variable of a function
|
||||
// internally we store variables and funcions as std::string (not std::wstring even when wide characters are used)
|
||||
std::string value;
|
||||
|
||||
// number of parameters required by the function
|
||||
// (if there's a variable this 'param' is ignored)
|
||||
int param;
|
||||
|
||||
Item() {}
|
||||
Item(const std::string & v, int p) : value(v), param(p) {}
|
||||
};
|
||||
|
||||
// 'Table' is the type of our table
|
||||
typedef std::map<std::string, Item> Table;
|
||||
typedef Table::iterator Iterator;
|
||||
typedef Table::const_iterator CIterator;
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this method returns true if a character 'c' is a character
|
||||
which can be in a name
|
||||
|
||||
if 'can_be_digit' is true that means when the 'c' is a digit this
|
||||
method returns true otherwise it returns false
|
||||
*/
|
||||
static bool CorrectCharacter(int c, bool can_be_digit)
|
||||
{
|
||||
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
|
||||
return true;
|
||||
|
||||
if( can_be_digit && ((c>='0' && c<='9') || c=='_') )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method returns true if the name can be as a name of an object
|
||||
*/
|
||||
template<class string_type>
|
||||
static bool IsNameCorrect(const string_type & name)
|
||||
{
|
||||
if( name.empty() )
|
||||
return false;
|
||||
|
||||
if( !CorrectCharacter(name[0], false) )
|
||||
return false;
|
||||
|
||||
typename string_type::const_iterator i = name.begin();
|
||||
|
||||
for(++i ; i!=name.end() ; ++i)
|
||||
if( !CorrectCharacter(*i, true) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method returns true if such an object is defined (name exists)
|
||||
*/
|
||||
bool IsDefined(const std::string & name)
|
||||
{
|
||||
Iterator i = table.find(name);
|
||||
|
||||
if( i != table.end() )
|
||||
// we have this object in our table
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef TTMATH_DONT_USE_WCHAR
|
||||
|
||||
/*!
|
||||
this method returns true if such an object is defined (name exists)
|
||||
*/
|
||||
bool IsDefined(const std::wstring & name)
|
||||
{
|
||||
// we should check whether the name (in wide characters) are correct
|
||||
// before calling AssignString() function
|
||||
if( !IsNameCorrect(name) )
|
||||
return false;
|
||||
|
||||
Misc::AssignString(str_tmp1, name);
|
||||
|
||||
return IsDefined(str_tmp1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
this method adds one object (variable of function) into the table
|
||||
*/
|
||||
ErrorCode Add(const std::string & name, const std::string & value, int param = 0)
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
Iterator i = table.find(name);
|
||||
|
||||
if( i != table.end() )
|
||||
// we have this object in our table
|
||||
return err_object_exists;
|
||||
|
||||
table.insert( std::make_pair(name, Item(value, param)) );
|
||||
|
||||
return err_ok;
|
||||
}
|
||||
|
||||
|
||||
#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
|
||||
*/
|
||||
bool Empty() const
|
||||
{
|
||||
return table.empty();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method clears the table
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
return table.clear();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method returns 'const_iterator' on the first item on the table
|
||||
*/
|
||||
CIterator Begin() const
|
||||
{
|
||||
return table.begin();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method returns 'const_iterator' pointing at the space after last item
|
||||
(returns table.end())
|
||||
*/
|
||||
CIterator End() const
|
||||
{
|
||||
return table.end();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method changes the value and the number of parameters for a specific object
|
||||
*/
|
||||
ErrorCode EditValue(const std::string & name, const std::string & value, int param = 0)
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
Iterator i = table.find(name);
|
||||
|
||||
if( i == table.end() )
|
||||
return err_unknown_object;
|
||||
|
||||
i->second.value = value;
|
||||
i->second.param = param;
|
||||
|
||||
return err_ok;
|
||||
}
|
||||
|
||||
|
||||
#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 std::string & old_name, const std::string & new_name)
|
||||
{
|
||||
if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
Iterator old_i = table.find(old_name);
|
||||
if( old_i == table.end() )
|
||||
return err_unknown_object;
|
||||
|
||||
if( old_name == new_name )
|
||||
// the new name is the same as the old one
|
||||
// we treat it as a normal situation
|
||||
return err_ok;
|
||||
|
||||
ErrorCode err = Add(new_name, old_i->second.value, old_i->second.param);
|
||||
|
||||
if( err == err_ok )
|
||||
{
|
||||
old_i = table.find(old_name);
|
||||
TTMATH_ASSERT( old_i != table.end() )
|
||||
|
||||
table.erase(old_i);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#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 std::string & name)
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
Iterator i = table.find(name);
|
||||
|
||||
if( i == table.end() )
|
||||
return err_unknown_object;
|
||||
|
||||
table.erase( i );
|
||||
|
||||
return err_ok;
|
||||
}
|
||||
|
||||
|
||||
#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 std::string & name, std::string & value) const
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
CIterator i = table.find(name);
|
||||
|
||||
if( i == table.end() )
|
||||
{
|
||||
value.clear();
|
||||
return err_unknown_object;
|
||||
}
|
||||
|
||||
value = i->second.value;
|
||||
|
||||
return err_ok;
|
||||
}
|
||||
|
||||
|
||||
#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 std::string & name, const char ** value) const
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
CIterator i = table.find(name);
|
||||
|
||||
if( i == table.end() )
|
||||
{
|
||||
*value = 0;
|
||||
return err_unknown_object;
|
||||
}
|
||||
|
||||
*value = i->second.value.c_str();
|
||||
|
||||
return err_ok;
|
||||
}
|
||||
|
||||
|
||||
#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 std::string & name, std::string & value, int * param) const
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
CIterator i = table.find(name);
|
||||
|
||||
if( i == table.end() )
|
||||
{
|
||||
value.empty();
|
||||
*param = 0;
|
||||
return err_unknown_object;
|
||||
}
|
||||
|
||||
value = i->second.value;
|
||||
*param = i->second.param;
|
||||
|
||||
return err_ok;
|
||||
}
|
||||
|
||||
|
||||
#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 std::string & name, const char ** value, int * param) const
|
||||
{
|
||||
if( !IsNameCorrect(name) )
|
||||
return err_incorrect_name;
|
||||
|
||||
CIterator i = table.find(name);
|
||||
|
||||
if( i == table.end() )
|
||||
{
|
||||
*value = 0;
|
||||
*param = 0;
|
||||
return err_unknown_object;
|
||||
}
|
||||
|
||||
*value = i->second.value.c_str();
|
||||
*param = i->second.param;
|
||||
|
||||
return err_ok;
|
||||
}
|
||||
|
||||
|
||||
#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
|
||||
*/
|
||||
Table * GetTable()
|
||||
{
|
||||
return &table;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Table table;
|
||||
std::string str_tmp1, str_tmp2;
|
||||
|
||||
}; // end of class Objects
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
objects of the class History are used to keep values in functions
|
||||
which take a lot of time during calculating, for instance in the
|
||||
function Factorial(x)
|
||||
|
||||
it means that when we're calculating e.g. Factorial(1000) and the
|
||||
Factorial finds that we have calculated it before, the value (result)
|
||||
is taken from the history
|
||||
*/
|
||||
template<class ValueType>
|
||||
class History
|
||||
{
|
||||
/*!
|
||||
one item in the History's object holds a key, a value for the key
|
||||
and a corresponding error code
|
||||
*/
|
||||
struct Item
|
||||
{
|
||||
ValueType key, value;
|
||||
ErrorCode err;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
we use std::list for simply deleting the first item
|
||||
but because we're searching through the whole container
|
||||
(in the method Get) the container should not be too big
|
||||
(linear time of searching)
|
||||
*/
|
||||
typedef std::list<Item> buffer_type;
|
||||
buffer_type buffer;
|
||||
typename buffer_type::size_type buffer_max_size;
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
default constructor
|
||||
default max size of the History's container is 15 items
|
||||
*/
|
||||
History()
|
||||
{
|
||||
buffer_max_size = 15;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
a constructor which takes another value of the max size
|
||||
of the History's container
|
||||
*/
|
||||
History(typename buffer_type::size_type new_size)
|
||||
{
|
||||
buffer_max_size = new_size;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method adds one item into the History
|
||||
if the size of the container is greater than buffer_max_size
|
||||
the first item will be removed
|
||||
*/
|
||||
void Add(const ValueType & key, const ValueType & value, ErrorCode err)
|
||||
{
|
||||
Item item;
|
||||
item.key = key;
|
||||
item.value = value;
|
||||
item.err = err;
|
||||
|
||||
buffer.insert( buffer.end(), item );
|
||||
|
||||
if( buffer.size() > buffer_max_size )
|
||||
buffer.erase(buffer.begin());
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this method checks whether we have an item which has the key equal 'key'
|
||||
|
||||
if there's such item the method sets the 'value' and the 'err'
|
||||
and returns true otherwise it returns false and 'value' and 'err'
|
||||
remain unchanged
|
||||
*/
|
||||
bool Get(const ValueType & key, ValueType & value, ErrorCode & err)
|
||||
{
|
||||
typename buffer_type::iterator i = buffer.begin();
|
||||
|
||||
for( ; i != buffer.end() ; ++i )
|
||||
{
|
||||
if( i->key == key )
|
||||
{
|
||||
value = i->value;
|
||||
err = i->err;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this methods deletes an item
|
||||
|
||||
we assume that there is only one item with the 'key'
|
||||
(this methods removes the first one)
|
||||
*/
|
||||
bool Remove(const ValueType & key)
|
||||
{
|
||||
typename buffer_type::iterator i = buffer.begin();
|
||||
|
||||
for( ; i != buffer.end() ; ++i )
|
||||
{
|
||||
if( i->key == key )
|
||||
{
|
||||
buffer.erase(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}; // end of class History
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this is an auxiliary class used when calculating Gamma() or Factorial()
|
||||
|
||||
in multithreaded environment you can provide an object of this class to
|
||||
the Gamma() or Factorial() function, e.g;
|
||||
typedef Big<1, 3> MyBig;
|
||||
MyBig x = 123456;
|
||||
CGamma<MyBig> cgamma;
|
||||
std::cout << Gamma(x, cgamma);
|
||||
each thread should have its own CGamma<> object
|
||||
|
||||
in a single-thread environment a CGamma<> object is a static variable
|
||||
in a second version of Gamma() and you don't have to explicitly use it, e.g.
|
||||
typedef Big<1, 3> MyBig;
|
||||
MyBig x = 123456;
|
||||
std::cout << Gamma(x);
|
||||
*/
|
||||
template<class ValueType>
|
||||
struct CGamma
|
||||
{
|
||||
/*!
|
||||
this table holds factorials
|
||||
1
|
||||
1
|
||||
2
|
||||
6
|
||||
24
|
||||
120
|
||||
720
|
||||
.......
|
||||
*/
|
||||
std::vector<ValueType> fact;
|
||||
|
||||
|
||||
/*!
|
||||
this table holds Bernoulli numbers
|
||||
1
|
||||
-0.5
|
||||
0.166666666666666666666666667
|
||||
0
|
||||
-0.0333333333333333333333333333
|
||||
0
|
||||
0.0238095238095238095238095238
|
||||
0
|
||||
-0.0333333333333333333333333333
|
||||
0
|
||||
0.075757575757575757575757576
|
||||
.....
|
||||
*/
|
||||
std::vector<ValueType> bern;
|
||||
|
||||
|
||||
/*!
|
||||
here we store some calculated values
|
||||
(this is for speeding up, if the next argument of Gamma() or Factorial()
|
||||
is in the 'history' then the result we are not calculating but simply
|
||||
return from the 'history' object)
|
||||
*/
|
||||
History<ValueType> history;
|
||||
|
||||
|
||||
/*!
|
||||
this method prepares some coefficients: factorials and Bernoulli numbers
|
||||
stored in 'fact' and 'bern' objects
|
||||
|
||||
how many values should be depends on the size of the mantissa - if
|
||||
the mantissa is larger then we must calculate more values
|
||||
for a mantissa which consists of 256 bits (8 words on a 32bit platform)
|
||||
we have to calculate about 30 values (the size of fact and bern will be 30),
|
||||
and for a 2048 bits mantissa we have to calculate 306 coefficients
|
||||
|
||||
you don't have to call this method, these coefficients will be automatically calculated
|
||||
when they are needed
|
||||
|
||||
you must note that calculating these coefficients is a little time-consuming operation,
|
||||
(especially when the mantissa is large) and first call to Gamma() or Factorial()
|
||||
can take more time than next calls, and in the end this is the point when InitAll()
|
||||
comes in handy: you can call this method somewhere at the beginning of your program
|
||||
*/
|
||||
void InitAll();
|
||||
// definition is in ttmath.h
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#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 (new) BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||
* project may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef headerfilettmaththreads
|
||||
#define headerfilettmaththreads
|
||||
|
||||
#include "ttmathtypes.h"
|
||||
|
||||
#ifdef TTMATH_WIN32_THREADS
|
||||
#include <windows.h>
|
||||
#include <cstdio>
|
||||
#endif
|
||||
|
||||
#ifdef TTMATH_POSIX_THREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\file ttmaththreads.h
|
||||
\brief Some objects used in multithreads environment
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
this is a simple skeleton of a program in multithreads environment:
|
||||
|
||||
#define TTMATH_MULTITHREADS
|
||||
#include<ttmath/ttmath.h>
|
||||
|
||||
TTMATH_MULTITHREADS_HELPER
|
||||
|
||||
int main()
|
||||
{
|
||||
[...]
|
||||
}
|
||||
|
||||
make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file)
|
||||
use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope)
|
||||
*/
|
||||
|
||||
|
||||
namespace ttmath
|
||||
{
|
||||
|
||||
|
||||
#ifdef TTMATH_WIN32_THREADS
|
||||
|
||||
/*
|
||||
we use win32 threads
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
|
||||
somewhere in *.cpp file
|
||||
|
||||
(at the moment in win32 this macro does nothing)
|
||||
*/
|
||||
#define TTMATH_MULTITHREADS_HELPER
|
||||
|
||||
|
||||
/*!
|
||||
objects of this class are used to synchronize
|
||||
*/
|
||||
class ThreadLock
|
||||
{
|
||||
HANDLE mutex_handle;
|
||||
|
||||
|
||||
void CreateName(char * buffer) const
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4996)
|
||||
// warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead.
|
||||
#endif
|
||||
|
||||
sprintf(buffer, "TTMATH_LOCK_%ul", (unsigned long)GetCurrentProcessId());
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (default : 4996)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
bool Lock()
|
||||
{
|
||||
char buffer[50];
|
||||
|
||||
CreateName(buffer);
|
||||
mutex_handle = CreateMutexA(0, false, buffer);
|
||||
|
||||
if( mutex_handle == 0 )
|
||||
return false;
|
||||
|
||||
WaitForSingleObject(mutex_handle, INFINITE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
ThreadLock()
|
||||
{
|
||||
mutex_handle = 0;
|
||||
}
|
||||
|
||||
|
||||
~ThreadLock()
|
||||
{
|
||||
if( mutex_handle != 0 )
|
||||
{
|
||||
ReleaseMutex(mutex_handle);
|
||||
CloseHandle(mutex_handle);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifdef TTMATH_WIN32_THREADS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef TTMATH_POSIX_THREADS
|
||||
|
||||
/*
|
||||
we use posix threads
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
|
||||
somewhere in *.cpp file
|
||||
(this macro defines a pthread_mutex_t object used by TTMath library)
|
||||
*/
|
||||
#define TTMATH_MULTITHREADS_HELPER \
|
||||
namespace ttmath \
|
||||
{ \
|
||||
pthread_mutex_t ttmath_mutex = PTHREAD_MUTEX_INITIALIZER; \
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
ttmath_mutex will be defined by TTMATH_MULTITHREADS_HELPER macro
|
||||
*/
|
||||
extern pthread_mutex_t ttmath_mutex;
|
||||
|
||||
|
||||
/*!
|
||||
objects of this class are used to synchronize
|
||||
*/
|
||||
class ThreadLock
|
||||
{
|
||||
public:
|
||||
|
||||
bool Lock()
|
||||
{
|
||||
if( pthread_mutex_lock(&ttmath_mutex) != 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
~ThreadLock()
|
||||
{
|
||||
pthread_mutex_unlock(&ttmath_mutex);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifdef TTMATH_POSIX_THREADS
|
||||
|
||||
|
||||
|
||||
|
||||
#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
|
||||
|
||||
/*!
|
||||
we don't use win32 and pthreads
|
||||
*/
|
||||
|
||||
/*!
|
||||
*/
|
||||
#define TTMATH_MULTITHREADS_HELPER
|
||||
|
||||
|
||||
/*!
|
||||
objects of this class are used to synchronize
|
||||
actually we don't synchronize, the method Lock() returns always 'false'
|
||||
*/
|
||||
class ThreadLock
|
||||
{
|
||||
public:
|
||||
|
||||
bool Lock()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // #if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,676 @@
|
|||
/*
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-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 headerfilettmathtypes
|
||||
#define headerfilettmathtypes
|
||||
|
||||
/*!
|
||||
\file ttmathtypes.h
|
||||
\brief constants used in the library
|
||||
|
||||
As our library is written in header files (templates) we cannot use
|
||||
constants like 'const int' etc. because we should have some source files
|
||||
*.cpp to define this variables. Only what we can have are constants
|
||||
defined by #define preprocessor macros.
|
||||
|
||||
All macros are preceded by TTMATH_ prefix
|
||||
*/
|
||||
|
||||
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <stdint.h>
|
||||
// for uint64_t and int64_t on a 32 bit platform
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
the version of the library
|
||||
|
||||
TTMATH_PRERELEASE_VER is either zero or one
|
||||
zero means that this is the release version of the library
|
||||
(one means something like beta)
|
||||
*/
|
||||
#define TTMATH_MAJOR_VER 0
|
||||
#define TTMATH_MINOR_VER 9
|
||||
#define TTMATH_REVISION_VER 3
|
||||
|
||||
#define TTMATH_PRERELEASE_VER 0
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
you can define a platform explicitly by defining either
|
||||
TTMATH_PLATFORM32 or TTMATH_PLATFORM64 macro
|
||||
*/
|
||||
#if !defined TTMATH_PLATFORM32 && !defined TTMATH_PLATFORM64
|
||||
|
||||
#if !defined _M_X64 && !defined __x86_64__
|
||||
|
||||
/*
|
||||
other platforms than x86 and amd64 are not recognized at the moment
|
||||
so you should set TTMATH_PLATFORMxx manually
|
||||
*/
|
||||
|
||||
// we're using a 32bit platform
|
||||
#define TTMATH_PLATFORM32
|
||||
|
||||
#else
|
||||
|
||||
// we're using a 64bit platform
|
||||
#define TTMATH_PLATFORM64
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
asm version of the library is available by default only for:
|
||||
x86 and amd64 platforms and for Microsoft Visual and GCC compilers
|
||||
|
||||
but you can force using asm version (the same asm as for Microsoft Visual)
|
||||
by defining TTMATH_FORCEASM macro
|
||||
you have to be sure that your compiler accept such an asm format
|
||||
*/
|
||||
#ifndef TTMATH_FORCEASM
|
||||
|
||||
#if !defined __i386__ && !defined _X86_ && !defined _M_IX86 && !defined __x86_64__ && !defined _M_X64
|
||||
/*!
|
||||
x86 architecture:
|
||||
__i386__ defined by GNU C
|
||||
_X86_ defined by MinGW32
|
||||
_M_IX86 defined by Visual Studio, Intel C/C++, Digital Mars and Watcom C/C++
|
||||
|
||||
amd64 architecture:
|
||||
__x86_64__ defined by GNU C, CLANG (LLVM) and Sun Studio
|
||||
_M_X64 defined by Visual Studio
|
||||
|
||||
asm version is available only for x86 or amd64 platforms
|
||||
*/
|
||||
#define TTMATH_NOASM
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if !defined _MSC_VER && !defined __GNUC__
|
||||
/*!
|
||||
another compilers than MS VC or GCC or CLANG (LLVM) by default use no asm version
|
||||
(CLANG defines __GNUC__ too)
|
||||
*/
|
||||
#define TTMATH_NOASM
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
namespace ttmath
|
||||
{
|
||||
|
||||
|
||||
#ifdef TTMATH_PLATFORM32
|
||||
|
||||
/*!
|
||||
on 32bit platforms one word (uint, sint) will be equal 32bits
|
||||
*/
|
||||
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
|
||||
|
||||
/*!
|
||||
how many bits there are in the uint type
|
||||
*/
|
||||
#define TTMATH_BITS_PER_UINT 32u
|
||||
|
||||
/*!
|
||||
the mask for the highest bit in the unsigned 32bit word (2^31)
|
||||
*/
|
||||
#define TTMATH_UINT_HIGHEST_BIT 2147483648u
|
||||
|
||||
/*!
|
||||
the max value of the unsigned 32bit word (2^32 - 1)
|
||||
(all bits equal one)
|
||||
*/
|
||||
#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)
|
||||
*/
|
||||
#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
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
/* in VC 'long' type has 32 bits, __int64 is VC extension */
|
||||
typedef unsigned __int64 uint;
|
||||
typedef signed __int64 sint;
|
||||
#else
|
||||
typedef unsigned long uint;
|
||||
typedef signed long sint;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
on 64bit platforms we do not define ulint and slint
|
||||
*/
|
||||
|
||||
/*!
|
||||
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)
|
||||
*/
|
||||
#define TTMATH_UINT_HIGHEST_BIT 9223372036854775808ul
|
||||
|
||||
/*!
|
||||
the max value of the unsigned 64bit word (2^64 - 1)
|
||||
(all bits equal one)
|
||||
*/
|
||||
#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)
|
||||
*/
|
||||
#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
|
||||
}
|
||||
|
||||
|
||||
#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
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this variable defines how many iterations are performed
|
||||
during some kind of calculating when we're making any long formulas
|
||||
(for example Taylor series)
|
||||
|
||||
it's used in ExpSurrounding0(...), LnSurrounding1(...), Sin0pi05(...), etc.
|
||||
|
||||
note! there'll not be so many iterations, iterations are stopped when
|
||||
there is no sense to continue calculating (for example when the result
|
||||
still remains unchanged after adding next series and we know that the next
|
||||
series are smaller than previous ones)
|
||||
*/
|
||||
#define TTMATH_ARITHMETIC_MAX_LOOP 10000
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this is a limit when calculating Karatsuba multiplication
|
||||
if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
|
||||
the Karatsuba algorithm will use standard schoolbook multiplication
|
||||
*/
|
||||
#ifdef TTMATH_DEBUG_LOG
|
||||
// if TTMATH_DEBUG_LOG is defined then we should use the same size regardless of the compiler
|
||||
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
|
||||
#else
|
||||
#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
this is a special value used when calculating the Gamma(x) function
|
||||
if x is greater than this value then the Gamma(x) will be calculated using
|
||||
some kind of series
|
||||
|
||||
don't use smaller values than about 100
|
||||
*/
|
||||
#define TTMATH_GAMMA_BOUNDARY 2000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace ttmath
|
||||
{
|
||||
|
||||
/*!
|
||||
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
|
||||
*/
|
||||
enum ErrorCode
|
||||
{
|
||||
err_ok = 0,
|
||||
err_nothing_has_read,
|
||||
err_unknown_character,
|
||||
err_unexpected_final_bracket,
|
||||
err_stack_not_clear,
|
||||
err_unknown_variable,
|
||||
err_division_by_zero,
|
||||
err_interrupt,
|
||||
err_overflow,
|
||||
err_unknown_function,
|
||||
err_unknown_operator,
|
||||
err_unexpected_semicolon_operator,
|
||||
err_improper_amount_of_arguments,
|
||||
err_improper_argument,
|
||||
err_unexpected_end,
|
||||
err_internal_error,
|
||||
err_incorrect_name,
|
||||
err_incorrect_value,
|
||||
err_variable_exists,
|
||||
err_variable_loop,
|
||||
err_functions_loop,
|
||||
err_must_be_only_one_value,
|
||||
err_object_exists,
|
||||
err_unknown_object,
|
||||
err_still_calculating,
|
||||
err_in_short_form_used_function,
|
||||
err_percent_from
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
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)
|
||||
|
||||
for example: in some functions like Factorial()
|
||||
/at the moment only Factorial/ you can give a pointer to
|
||||
the 'stop object', if the method WasStopSignal() of this
|
||||
object returns true that means we should break the calculating
|
||||
and return
|
||||
*/
|
||||
class StopCalculating
|
||||
{
|
||||
public:
|
||||
virtual bool WasStopSignal() const volatile { return false; }
|
||||
virtual ~StopCalculating(){}
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
a small class which is useful when compiling with gcc
|
||||
|
||||
object of this type holds the name and the line of a file
|
||||
in which the macro TTMATH_ASSERT or TTMATH_REFERENCE_ASSERT was used
|
||||
*/
|
||||
class ExceptionInfo
|
||||
{
|
||||
const char * file;
|
||||
int line;
|
||||
|
||||
public:
|
||||
ExceptionInfo() : file(0), line(0) {}
|
||||
ExceptionInfo(const char * f, int l) : file(f), line(l) {}
|
||||
|
||||
std::string Where() const
|
||||
{
|
||||
if( !file )
|
||||
return "unknown";
|
||||
|
||||
std::ostringstream result;
|
||||
result << file << ":" << line;
|
||||
|
||||
return result.str();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
A small class used for reporting 'reference' errors
|
||||
|
||||
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) with
|
||||
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
|
||||
was used)
|
||||
*/
|
||||
class ReferenceError : public std::logic_error, public ExceptionInfo
|
||||
{
|
||||
public:
|
||||
|
||||
ReferenceError() : std::logic_error("reference error")
|
||||
{
|
||||
}
|
||||
|
||||
ReferenceError(const char * f, int l) :
|
||||
std::logic_error("reference error"), ExceptionInfo(f,l)
|
||||
{
|
||||
}
|
||||
|
||||
std::string Where() const
|
||||
{
|
||||
return ExceptionInfo::Where();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
a small class used for reporting errors
|
||||
|
||||
in the library is used macro TTMATH_ASSERT which
|
||||
(if the condition in it is false) throw an exception
|
||||
of this type
|
||||
|
||||
if you compile with gcc you can get a small benefit
|
||||
from using method Where() (it returns std::string) with
|
||||
the name and the line of a file where the macro TTMATH_ASSERT
|
||||
was used)
|
||||
*/
|
||||
class RuntimeError : public std::runtime_error, public ExceptionInfo
|
||||
{
|
||||
public:
|
||||
|
||||
RuntimeError() : std::runtime_error("internal error")
|
||||
{
|
||||
}
|
||||
|
||||
RuntimeError(const char * f, int l) :
|
||||
std::runtime_error("internal error"), ExceptionInfo(f,l)
|
||||
{
|
||||
}
|
||||
|
||||
std::string Where() const
|
||||
{
|
||||
return ExceptionInfo::Where();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
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__)
|
||||
|
||||
#define TTMATH_REFERENCE_ASSERT(expression) \
|
||||
if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__);
|
||||
|
||||
#define TTMATH_ASSERT(expression) \
|
||||
if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__);
|
||||
|
||||
#else
|
||||
|
||||
#define TTMATH_REFERENCE_ASSERT(expression) \
|
||||
if( &(expression) == this ) throw ReferenceError();
|
||||
|
||||
#define TTMATH_ASSERT(expression) \
|
||||
if( !(expression) ) throw RuntimeError();
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define TTMATH_REFERENCE_ASSERT(expression)
|
||||
#define TTMATH_ASSERT(expression)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef TTMATH_DEBUG_LOG
|
||||
#define TTMATH_LOG(msg) PrintLog(msg, std::cout);
|
||||
#define TTMATH_LOGC(msg, carry) PrintLog(msg, carry, std::cout);
|
||||
#define TTMATH_VECTOR_LOG(msg, vector, len) PrintVectorLog(msg, std::cout, vector, len);
|
||||
#define TTMATH_VECTOR_LOGC(msg, carry, vector, len) PrintVectorLog(msg, carry, std::cout, vector, len);
|
||||
#else
|
||||
#define TTMATH_LOG(msg)
|
||||
#define TTMATH_LOGC(msg, carry)
|
||||
#define TTMATH_VECTOR_LOG(msg, vector, len)
|
||||
#define TTMATH_VECTOR_LOGC(msg, carry, vector, len)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,548 @@
|
|||
;
|
||||
; This file is a part of TTMath Bignum Library
|
||||
; and is distributed under the (new) BSD licence.
|
||||
; Author: Christian Kaiser <chk@online.de>
|
||||
;
|
||||
|
||||
;
|
||||
; Copyright (c) 2009, Christian Kaiser
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
;
|
||||
; * Redistributions of source code must retain the above copyright notice,
|
||||
; this list of conditions and the following disclaimer.
|
||||
;
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
;
|
||||
; * Neither the name Christian Kaiser nor the names of contributors to this
|
||||
; project may be used to endorse or promote products derived
|
||||
; from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
; THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;
|
||||
|
||||
;
|
||||
; compile with debug info: ml64.exe /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 ttmath_adc_x64
|
||||
PUBLIC ttmath_addindexed_x64
|
||||
PUBLIC ttmath_addindexed2_x64
|
||||
PUBLIC ttmath_addvector_x64
|
||||
|
||||
PUBLIC ttmath_sbb_x64
|
||||
PUBLIC ttmath_subindexed_x64
|
||||
PUBLIC ttmath_subvector_x64
|
||||
|
||||
PUBLIC ttmath_rcl_x64
|
||||
PUBLIC ttmath_rcr_x64
|
||||
|
||||
PUBLIC ttmath_rcl2_x64
|
||||
PUBLIC ttmath_rcr2_x64
|
||||
|
||||
PUBLIC ttmath_div_x64
|
||||
|
||||
;
|
||||
; Microsoft x86_64 convention: http://msdn.microsoft.com/en-us/library/9b372w95.aspx
|
||||
;
|
||||
; "rax, rcx, rdx, r8-r11 are volatile."
|
||||
; "rbx, rbp, rdi, rsi, r12-r15 are nonvolatile."
|
||||
;
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ttmath_adc_x64 PROC
|
||||
; rcx = p1
|
||||
; rdx = p2
|
||||
; r8 = nSize
|
||||
; r9 = nCarry
|
||||
|
||||
xor rax, rax
|
||||
xor r11, r11
|
||||
sub rax, r9 ; sets CARRY if r9 != 0
|
||||
|
||||
ALIGN 16
|
||||
loop1:
|
||||
mov rax,qword ptr [rdx + r11 * 8]
|
||||
adc qword ptr [rcx + r11 * 8], rax
|
||||
lea r11, [r11+1]
|
||||
dec r8
|
||||
jnz loop1
|
||||
|
||||
setc al
|
||||
movzx rax, al
|
||||
|
||||
ret
|
||||
|
||||
ttmath_adc_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ttmath_addindexed_x64 PROC
|
||||
|
||||
; rcx = p1
|
||||
; rdx = nSize
|
||||
; r8 = nPos
|
||||
; r9 = nValue
|
||||
|
||||
xor rax, rax ; rax = result
|
||||
sub rdx, r8 ; rdx = remaining count of uints
|
||||
|
||||
add qword ptr [rcx + r8 * 8], r9
|
||||
jc next1
|
||||
|
||||
ret
|
||||
|
||||
next1:
|
||||
mov r9, 1
|
||||
|
||||
ALIGN 16
|
||||
loop1:
|
||||
dec rdx
|
||||
jz done_with_cy
|
||||
lea r8, [r8+1]
|
||||
add qword ptr [rcx + r8 * 8], r9
|
||||
jc loop1
|
||||
|
||||
ret
|
||||
|
||||
done_with_cy:
|
||||
lea rax, [rax+1] ; rax = 1
|
||||
|
||||
ret
|
||||
|
||||
ttmath_addindexed_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ttmath_addindexed2_x64 PROC
|
||||
|
||||
; rcx = p1 (pointer)
|
||||
; rdx = b (value size)
|
||||
; r8 = nPos
|
||||
; r9 = nValue1
|
||||
; [esp+0x28] = nValue2
|
||||
|
||||
xor rax, rax ; return value
|
||||
mov r11, rcx ; table
|
||||
sub rdx, r8 ; rdx = remaining count of uints
|
||||
mov r10, [esp+028h] ; r10 = nValue2
|
||||
|
||||
add qword ptr [r11 + r8 * 8], r9
|
||||
lea r8, [r8+1]
|
||||
lea rdx, [rdx-1]
|
||||
adc qword ptr [r11 + r8 * 8], r10
|
||||
jc next
|
||||
ret
|
||||
|
||||
ALIGN 16
|
||||
loop1:
|
||||
lea r8, [r8+1]
|
||||
add qword ptr [r11 + r8 * 8], 1
|
||||
jc next
|
||||
ret
|
||||
|
||||
next:
|
||||
dec rdx ; does not modify CY too...
|
||||
jnz loop1
|
||||
lea rax, [rax+1]
|
||||
ret
|
||||
|
||||
ttmath_addindexed2_x64 ENDP
|
||||
|
||||
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
|
||||
ttmath_addvector_x64 PROC
|
||||
; rcx = ss1
|
||||
; rdx = ss2
|
||||
; r8 = ss1_size
|
||||
; r9 = ss2_size
|
||||
; [esp+0x28] = result
|
||||
|
||||
mov r10, [esp+028h]
|
||||
sub r8, r9
|
||||
xor r11, r11 ; r11=0, cf=0
|
||||
|
||||
ALIGN 16
|
||||
loop1:
|
||||
mov rax, qword ptr [rcx + r11 * 8]
|
||||
adc rax, qword ptr [rdx + r11 * 8]
|
||||
mov qword ptr [r10 + r11 * 8], rax
|
||||
inc r11
|
||||
dec r9
|
||||
jnz loop1
|
||||
|
||||
adc r9, r9 ; r9 has the cf state
|
||||
|
||||
or r8, r8
|
||||
jz done
|
||||
|
||||
neg r9 ; setting cf from r9
|
||||
mov r9, 0 ; don't use xor here (cf is used)
|
||||
loop2:
|
||||
mov rax, qword ptr [rcx + r11 * 8]
|
||||
adc rax, r9
|
||||
mov qword ptr [r10 + r11 * 8], rax
|
||||
inc r11
|
||||
dec r8
|
||||
jnz loop2
|
||||
|
||||
adc r8, r8
|
||||
mov rax, r8
|
||||
|
||||
ret
|
||||
|
||||
done:
|
||||
mov rax, r9
|
||||
ret
|
||||
|
||||
ttmath_addvector_x64 ENDP
|
||||
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ttmath_sbb_x64 PROC
|
||||
|
||||
; rcx = p1
|
||||
; rdx = p2
|
||||
; r8 = nCount
|
||||
; r9 = nCarry
|
||||
|
||||
xor rax, rax
|
||||
xor r11, r11
|
||||
sub rax, r9 ; sets CARRY if r9 != 0
|
||||
|
||||
ALIGN 16
|
||||
loop1:
|
||||
mov rax,qword ptr [rdx + r11 * 8]
|
||||
sbb qword ptr [rcx + r11 * 8], rax
|
||||
lea r11, [r11+1]
|
||||
dec r8
|
||||
jnz loop1
|
||||
|
||||
setc al
|
||||
movzx rax, al
|
||||
|
||||
ret
|
||||
|
||||
ttmath_sbb_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ttmath_subindexed_x64 PROC
|
||||
; rcx = p1
|
||||
; rdx = nSize
|
||||
; r8 = nPos
|
||||
; r9 = nValue
|
||||
|
||||
sub rdx, r8 ; rdx = remaining count of uints
|
||||
|
||||
ALIGN 16
|
||||
loop1:
|
||||
sub qword ptr [rcx + r8 * 8], r9
|
||||
jnc done
|
||||
|
||||
lea r8, [r8+1]
|
||||
mov r9, 1
|
||||
dec rdx
|
||||
jnz loop1
|
||||
|
||||
mov rax, 1
|
||||
ret
|
||||
|
||||
done:
|
||||
xor rax, rax
|
||||
ret
|
||||
|
||||
ttmath_subindexed_x64 ENDP
|
||||
|
||||
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
; the same asm code as in addvector_x64 only two instructions 'adc' changed to 'sbb'
|
||||
|
||||
ttmath_subvector_x64 PROC
|
||||
; rcx = ss1
|
||||
; rdx = ss2
|
||||
; r8 = ss1_size
|
||||
; r9 = ss2_size
|
||||
; [esp+0x28] = result
|
||||
|
||||
mov r10, [esp+028h]
|
||||
sub r8, r9
|
||||
xor r11, r11 ; r11=0, cf=0
|
||||
|
||||
ALIGN 16
|
||||
loop1:
|
||||
mov rax, qword ptr [rcx + r11 * 8]
|
||||
sbb rax, qword ptr [rdx + r11 * 8]
|
||||
mov qword ptr [r10 + r11 * 8], rax
|
||||
inc r11
|
||||
dec r9
|
||||
jnz loop1
|
||||
|
||||
adc r9, r9 ; r9 has the cf state
|
||||
|
||||
or r8, r8
|
||||
jz done
|
||||
|
||||
neg r9 ; setting cf from r9
|
||||
mov r9, 0 ; don't use xor here (cf is used)
|
||||
loop2:
|
||||
mov rax, qword ptr [rcx + r11 * 8]
|
||||
sbb rax, r9
|
||||
mov qword ptr [r10 + r11 * 8], rax
|
||||
inc r11
|
||||
dec r8
|
||||
jnz loop2
|
||||
|
||||
adc r8, r8
|
||||
mov rax, r8
|
||||
|
||||
ret
|
||||
|
||||
done:
|
||||
mov rax, r9
|
||||
ret
|
||||
|
||||
ttmath_subvector_x64 ENDP
|
||||
|
||||
|
||||
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ttmath_rcl_x64 PROC
|
||||
; rcx = p1
|
||||
; rdx = b
|
||||
; r8 = nLowestBit
|
||||
|
||||
mov r11, rcx ; table
|
||||
xor r10, r10
|
||||
neg r8 ; CY set if r8 <> 0
|
||||
|
||||
ALIGN 16
|
||||
loop1:
|
||||
rcl qword ptr [r11 + r10 * 8], 1
|
||||
lea r10, [r10+1]
|
||||
dec rdx
|
||||
jnz loop1
|
||||
|
||||
setc al
|
||||
movzx rax, al
|
||||
|
||||
ret
|
||||
|
||||
ttmath_rcl_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ttmath_rcr_x64 PROC
|
||||
; rcx = p1
|
||||
; rdx = nSize
|
||||
; r8 = nLowestBit
|
||||
|
||||
xor r10, r10
|
||||
neg r8 ; CY set if r8 <> 0
|
||||
|
||||
ALIGN 16
|
||||
loop1:
|
||||
rcr qword ptr -8[rcx + rdx * 8], 1
|
||||
dec rdx
|
||||
jnz loop1
|
||||
|
||||
setc al
|
||||
movzx rax, al
|
||||
|
||||
ret
|
||||
|
||||
ttmath_rcr_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ttmath_div_x64 PROC
|
||||
|
||||
; rcx = &Hi
|
||||
; rdx = &Lo
|
||||
; r8 = nDiv
|
||||
|
||||
mov r11, rcx
|
||||
mov r10, rdx
|
||||
|
||||
mov rdx, qword ptr [r11]
|
||||
mov rax, qword ptr [r10]
|
||||
div r8
|
||||
mov qword ptr [r10], rdx ; remainder
|
||||
mov qword ptr [r11], rax ; value
|
||||
|
||||
ret
|
||||
|
||||
ttmath_div_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ttmath_rcl2_x64 PROC
|
||||
; rcx = p1
|
||||
; rdx = nSize
|
||||
; r8 = bits
|
||||
; r9 = c
|
||||
|
||||
push rbx
|
||||
|
||||
mov r10, rcx ; r10 = p1
|
||||
xor rax, rax
|
||||
|
||||
mov rcx, 64
|
||||
sub rcx, r8
|
||||
|
||||
mov r11, -1
|
||||
shr r11, cl ; r11 = mask
|
||||
|
||||
mov rcx, r8 ; rcx = count of bits
|
||||
|
||||
mov rbx, rax ; rbx = old value = 0
|
||||
or r9, r9
|
||||
cmovnz rbx, r11 ; if (c) then old value = mask
|
||||
|
||||
mov r9, rax ; r9 = index (0..nSize-1)
|
||||
|
||||
ALIGN 16
|
||||
loop1:
|
||||
rol qword ptr [r10+r9*8], cl
|
||||
mov rax, qword ptr [r10+r9*8]
|
||||
and rax, r11
|
||||
xor qword ptr [r10+r9*8], rax
|
||||
or qword ptr [r10+r9*8], rbx
|
||||
mov rbx, rax
|
||||
|
||||
lea r9, [r9+1]
|
||||
dec rdx
|
||||
|
||||
jnz loop1
|
||||
|
||||
and rax, 1
|
||||
pop rbx
|
||||
ret
|
||||
|
||||
ttmath_rcl2_x64 ENDP
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ALIGN 8
|
||||
|
||||
;----------------------------------------
|
||||
|
||||
ttmath_rcr2_x64 PROC
|
||||
; rcx = p1
|
||||
; rdx = nSize
|
||||
; r8 = bits
|
||||
; r9 = c
|
||||
|
||||
push rbx
|
||||
mov r10, rcx ; r10 = p1
|
||||
xor rax, rax
|
||||
|
||||
mov rcx, 64
|
||||
sub rcx, r8
|
||||
|
||||
mov r11, -1
|
||||
shl r11, cl ; r11 = mask
|
||||
|
||||
mov rcx, r8 ; rcx = count of bits
|
||||
|
||||
mov rbx, rax ; rbx = old value = 0
|
||||
or r9, r9
|
||||
cmovnz rbx, r11 ; if (c) then old value = mask
|
||||
|
||||
mov r9, rdx ; r9 = index (0..nSize-1)
|
||||
lea r9, [r9-1]
|
||||
|
||||
ALIGN 16
|
||||
loop1:
|
||||
ror qword ptr [r10+r9*8], cl
|
||||
mov rax, qword ptr [r10+r9*8]
|
||||
and rax, r11
|
||||
xor qword ptr [r10+r9*8], rax
|
||||
or qword ptr [r10+r9*8], rbx
|
||||
mov rbx, rax
|
||||
|
||||
lea r9, [r9-1]
|
||||
dec rdx
|
||||
|
||||
jnz loop1
|
||||
|
||||
rol rax, 1
|
||||
and rax, 1
|
||||
pop rbx
|
||||
|
||||
ret
|
||||
|
||||
ttmath_rcr2_x64 ENDP
|
||||
|
||||
END
|
|
@ -0,0 +1,90 @@
|
|||
const TTMATH_HEADER = "headers/ttmath.h"
|
||||
|
||||
type
|
||||
Int256* {.importc: "ttmath::Int<4>", header: TTMATH_HEADER.} = object
|
||||
table: array[4, int]
|
||||
|
||||
stdString {.importc: "std::string", header: "<string.h>".} = object
|
||||
|
||||
#var tmp256* {.exportc: "tmp256".}: Int256
|
||||
|
||||
# var tmpString256* {.exportc: "tmpString256", importcpp: "(char*)malloc(sizeof(char) * 256)".}: cstring
|
||||
|
||||
proc `+`*(a: Int256, b: Int256): Int256 {.importcpp: "(# + #)".}
|
||||
|
||||
proc `-`*(a: Int256, b: Int256): Int256 {.importcpp: "(# - #)".}
|
||||
|
||||
proc `*`*(a: Int256, b: Int256): Int256 {.importcpp: "(# * #)".}
|
||||
|
||||
proc `/`*(a: Int256, b: Int256): Int256 {.importcpp: "(# / #)".}
|
||||
|
||||
proc `div`*(a: Int256, b: Int256): Int256 {.importcpp: "(# / #)".}
|
||||
|
||||
proc `==`*(a: Int256, b: Int256): bool {.importcpp: "(# == #)".}
|
||||
|
||||
proc `<`*(a: Int256, b: Int256): bool {.importcpp: "(# < #)".}
|
||||
|
||||
proc `<=`*(a: Int256, b: Int256): bool {.importcpp: "(# <= #)".}
|
||||
|
||||
proc `+=`*(a: var Int256, b: Int256) {.importcpp: "# += #".}
|
||||
|
||||
proc `-=`*(a: var Int256, b: Int256) {.importcpp: "# -= #".}
|
||||
|
||||
proc `*=`*(a: var Int256, b: Int256) {.importcpp: "# *= #".}
|
||||
|
||||
proc `/=`*(a: var Int256, b: Int256) {.importcpp: "# /= #".}
|
||||
|
||||
template `-`*(a: Int256): Int256 =
|
||||
0.i256 - a
|
||||
|
||||
proc `and`*(a: Int256, b: Int256): Int256 {.importcpp: "(# & #)".}
|
||||
|
||||
proc `or`*(a: Int256, b: Int256): Int256 {.importcpp: "(# | #)".}
|
||||
|
||||
proc `xor`*(a: Int256, b: Int256): Int256 {.importcpp: "(# ^ #)".}
|
||||
|
||||
proc i256*(a: int): Int256 {.importcpp: "ttmath::Int<4>((int)#)".}
|
||||
|
||||
proc i256*(a: cstring): Int256 {.importcpp: "ttmath::Int<4>(#)".}
|
||||
|
||||
proc i256*(a: string): Int256 =
|
||||
cstring(a).i256
|
||||
|
||||
proc inplacePow(a: var Int256, b: Int256) {.importcpp: "(#.Pow(#))".}
|
||||
|
||||
proc inplaceDiv(a: var Int256, b: Int256, c: var Int256) {.importcpp: "(#.Div(#, #))".}
|
||||
|
||||
proc pow*(a: Int256, b: int): Int256 =
|
||||
var tmp = a
|
||||
tmp.inplacePow(b.i256)
|
||||
result = tmp
|
||||
|
||||
proc `mod`*(a: Int256, b: Int256): Int256 =
|
||||
var tmp = a
|
||||
tmp.inplaceDiv(b, result)
|
||||
|
||||
proc ToString(a: Int256, s: stdString | cstring) {.importcpp: "#.ToString(#)", header: TTMATH_HEADER.}
|
||||
|
||||
proc strcpy(c: cstring, s: cstring) {.importc: "strcpy", header: "<cstring>".}
|
||||
|
||||
proc c_str(s: stdString): cstring {.importcpp: "#.c_str()", header: "<string.h>".}
|
||||
|
||||
#proc toCString*(a: Int256): cstring =
|
||||
|
||||
proc `shl`*(a: Int256, b: int): Int256 {.importcpp: "(# << #)".}
|
||||
|
||||
proc `shr`*(a: Int256, b: int): Int256 {.importcpp: "(# >> #)".}
|
||||
|
||||
proc getInt*(a: Int256): int =
|
||||
a.table[0]
|
||||
|
||||
proc `$`*(a: Int256): string =
|
||||
var tmp: stdString
|
||||
# TODO: something smarter
|
||||
{.emit: "tmp = \" \";".}
|
||||
var s: cstring
|
||||
{.emit: "s = new char[256];".}
|
||||
a.ToString(tmp)
|
||||
strcpy(s, tmp.c_str())
|
||||
result = $s
|
||||
{.emit: "delete[] s;".}
|
|
@ -0,0 +1,10 @@
|
|||
packageName = "ttmath"
|
||||
version = "0.1.0"
|
||||
author = "Status Research & Development GmbH"
|
||||
description = "A Nim wrapper for ttmath: big numbers with fixed size"
|
||||
license = "Apache License 2.0"
|
||||
srcDir = "src"
|
||||
|
||||
### Dependencies
|
||||
requires "nim >= 0.17.2"
|
||||
|
Loading…
Reference in New Issue