mirror of
https://github.com/status-im/nim-ttmath.git
synced 2025-02-23 09:48:08 +00:00
First commit
This commit is contained in:
commit
1dd3d37a9c
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
nimcache/
|
||||
build/
|
201
LICENSE
Normal file
201
LICENSE
Normal file
@ -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.
|
5
README.md
Normal file
5
README.md
Normal file
@ -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.
|
||||
|
35
examples/example.nim
Normal file
35
examples/example.nim
Normal file
@ -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
|
1
examples/nim.cfg
Normal file
1
examples/nim.cfg
Normal file
@ -0,0 +1 @@
|
||||
--p:"../src"
|
28
headers/COPYRIGHT
Normal file
28
headers/COPYRIGHT
Normal file
@ -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.
|
2853
headers/ttmath.h
Normal file
2853
headers/ttmath.h
Normal file
File diff suppressed because it is too large
Load Diff
6045
headers/ttmathbig.h
Normal file
6045
headers/ttmathbig.h
Normal file
File diff suppressed because it is too large
Load Diff
419
headers/ttmathdec.h
Normal file
419
headers/ttmathdec.h
Normal file
@ -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
|
1922
headers/ttmathint.h
Normal file
1922
headers/ttmathint.h
Normal file
File diff suppressed because it is too large
Load Diff
250
headers/ttmathmisc.h
Normal file
250
headers/ttmathmisc.h
Normal file
@ -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
|
809
headers/ttmathobjects.h
Normal file
809
headers/ttmathobjects.h
Normal file
@ -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
|
2777
headers/ttmathparser.h
Normal file
2777
headers/ttmathparser.h
Normal file
File diff suppressed because it is too large
Load Diff
250
headers/ttmaththreads.h
Normal file
250
headers/ttmaththreads.h
Normal file
@ -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
|
||||
|
676
headers/ttmathtypes.h
Normal file
676
headers/ttmathtypes.h
Normal file
@ -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
|
||||
|
4165
headers/ttmathuint.h
Normal file
4165
headers/ttmathuint.h
Normal file
File diff suppressed because it is too large
Load Diff
1017
headers/ttmathuint_noasm.h
Normal file
1017
headers/ttmathuint_noasm.h
Normal file
File diff suppressed because it is too large
Load Diff
1602
headers/ttmathuint_x86.h
Normal file
1602
headers/ttmathuint_x86.h
Normal file
File diff suppressed because it is too large
Load Diff
1146
headers/ttmathuint_x86_64.h
Normal file
1146
headers/ttmathuint_x86_64.h
Normal file
File diff suppressed because it is too large
Load Diff
548
headers/ttmathuint_x86_64_msvc.asm
Normal file
548
headers/ttmathuint_x86_64_msvc.asm
Normal file
@ -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
|
90
src/ttmath.nim
Normal file
90
src/ttmath.nim
Normal file
@ -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;".}
|
10
ttmath.nimble
Normal file
10
ttmath.nimble
Normal file
@ -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…
x
Reference in New Issue
Block a user