Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
506840787a | |||
e58253a078 | |||
6862321fad | |||
2e192969b0 | |||
e8daa77d75 | |||
231164f6ea | |||
c51b2fdcc9 | |||
84f34ebe52 | |||
3190f3011f | |||
a34cf55155 | |||
648de47400 | |||
362207e2f1 | |||
a40e951923 | |||
b028896118 | |||
a67a088e3a | |||
996fac15f1 | |||
1e268f1808 | |||
90674c9505 | |||
b6fe168e3c | |||
ae61b302a8 | |||
a1c41c02db | |||
69f065245e | |||
c65dac524a | |||
b3c3dd8c3f | |||
1b7e13a9fd |
103
CHANGELOG
103
CHANGELOG
@@ -1,3 +1,106 @@
|
|||||||
|
Version 0.9.3 (2012.12.28):
|
||||||
|
* fixed: in Big::FromDouble(double value) (only 32 bit version)
|
||||||
|
buffer overflow in referencing to UInt<2>
|
||||||
|
this was used when 'value' was in so called "unnormalized" state
|
||||||
|
(E=0 and F is nonzero)
|
||||||
|
it produced incorrect mantissa (on about 8th decimal digit up)
|
||||||
|
* added: Parser::InitCGamma()
|
||||||
|
initializing coefficients used when calculating the gamma (or factorial) function
|
||||||
|
this speed up the next calculations
|
||||||
|
you don't have to call this method explicitly
|
||||||
|
these coefficients will be calculated when needed
|
||||||
|
* added: option 'group_digits' to Conv struct
|
||||||
|
you can set how many digits should be grouped
|
||||||
|
* changed: small optimizations in UInt::ToString() and Big::FromString()
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.9.2 (2010.09.23):
|
||||||
|
* fixed: Big::Add() sometimes incorrectly rounded the last bit from its mantissa
|
||||||
|
* fixed: Big::BigAnd() Big::BigOr() Big::BigXor() should have set NaN
|
||||||
|
when the argument was negative (they only returned 2)
|
||||||
|
* fixed: recurrence calling in Big::FromString(const std::string &, uint, const wchar_t **, bool *)
|
||||||
|
it should have the signature: Big::FromString(const std::string &, uint, const char **, bool *)
|
||||||
|
* fixed: Big::ToString method
|
||||||
|
in some cases when in the output string the exponent should be equal zero
|
||||||
|
the method changes the exponent to one so the last digit from the mantissa
|
||||||
|
was lost
|
||||||
|
* fixed: Big::ToDouble(double &) set always +INF (infinity)
|
||||||
|
when the value was too large (even for negative values)
|
||||||
|
(it should set -INF in such a case)
|
||||||
|
* added: some missing operators
|
||||||
|
UInt::operator~() /* bitwise neg */
|
||||||
|
UInt::operator&() /* bitwise and */
|
||||||
|
UInt::operator&=()
|
||||||
|
UInt::operator|() /* bitwise or */
|
||||||
|
UInt::operator|=()
|
||||||
|
UInt::operator^() /* bitwise xor */
|
||||||
|
UInt::operator^=()
|
||||||
|
Big::operator&()
|
||||||
|
Big::operator&=()
|
||||||
|
Big::operator|()
|
||||||
|
Big::operator|=()
|
||||||
|
Big::operator^()
|
||||||
|
Big::operator^=()
|
||||||
|
for Big<> we do not define bitwise neg
|
||||||
|
Big::operator++()
|
||||||
|
Big::operator++(int)
|
||||||
|
Big::operator--()
|
||||||
|
Big::operator--(int)
|
||||||
|
* added: macro TTMATH_DONT_USE_WCHAR
|
||||||
|
if defined then the library does not use wide characters
|
||||||
|
(wchar_t, std::wstring, ...) this is a workaround for some compilers
|
||||||
|
* added: bool UInt::IsOnlyTheHighestBitSet()
|
||||||
|
bool UInt::IsOnlyTheLowestBitSet()
|
||||||
|
returning true if only the highest/lowest bit is set
|
||||||
|
* added: uint Int::MulInt(sint ss2)
|
||||||
|
* added: void UInt::Swap(UInt<value_size> & ss2)
|
||||||
|
void Big::Swap(UInt<value_size> & ss2)
|
||||||
|
method for swapping this for an argument
|
||||||
|
* added: macro TTMATH_BIG_DEFAULT_CLEAR
|
||||||
|
when defined the default constructor from Big<> clears its mantissa and exponent
|
||||||
|
Big<1, 2> var;
|
||||||
|
var.mantissa and var.exponent will be set to zero
|
||||||
|
(but var has the NaN flag set too - it is not zero value, this is mainly for debug purposes)
|
||||||
|
* added: only on 32bit platforms:
|
||||||
|
uint UInt::FromUInt(uint64_t n)
|
||||||
|
uint Int::FromInt(int64_t n)
|
||||||
|
void Big::FromUInt(uint64_t n)
|
||||||
|
void Big::FromInt(int64_t n)
|
||||||
|
and appropriate constructors and operators
|
||||||
|
* added: TTMATH_FORCEASM macro
|
||||||
|
asm version of the library is available by default only for:
|
||||||
|
x86 and amd64 platforms and for Microsoft Visual and GCC compilers,
|
||||||
|
but you can force using asm version (the same asm as for Microsoft Visual)
|
||||||
|
by defining TTMATH_FORCEASM macro
|
||||||
|
you have to be sure that your compiler accept such an asm format
|
||||||
|
* added: some missing methods for converting
|
||||||
|
for UInt<>, Int<> and Big<> classes:
|
||||||
|
uint ToUInt()
|
||||||
|
sint ToInt()
|
||||||
|
ToUInt(uint32_t &)
|
||||||
|
ToInt(uint32_t &)
|
||||||
|
ToInt(int32_t &)
|
||||||
|
ToUInt(uint64_t &)
|
||||||
|
ToInt(uint64_t &)
|
||||||
|
ToInt(int64_t &)
|
||||||
|
FromUInt(uint32_t &)
|
||||||
|
FromInt(uint32_t &)
|
||||||
|
FromInt(int32_t &)
|
||||||
|
FromUInt(uint64_t &)
|
||||||
|
FromInt(uint64_t &)
|
||||||
|
FromInt(int64_t &)
|
||||||
|
and appropriate constructors and operators
|
||||||
|
* added: double Big::ToDouble() /there was only Big::ToDouble(double &) /
|
||||||
|
uint Big::ToFloat(float &)
|
||||||
|
float Big::ToFloat()
|
||||||
|
* changed: now asm version is available only on x86 and amd64
|
||||||
|
(and only for GCC and MS VC compilers)
|
||||||
|
* removed: macro TTMATH_RELEASE (now the 'release' version is default)
|
||||||
|
for debug version define TTMATH_DEBUG macro
|
||||||
|
TTMATH_DEBUG is also automatically defined when DEBUG or _DEBUG is set
|
||||||
|
* removed: macro TTMATH_REFERENCE_ASSERT from all methods in public interface
|
||||||
|
|
||||||
|
|
||||||
Version 0.9.1 (2010.02.07):
|
Version 0.9.1 (2010.02.07):
|
||||||
* fixed: the parser didn't use characters for changing the base (# and &)
|
* fixed: the parser didn't use characters for changing the base (# and &)
|
||||||
those characters were skipped
|
those characters were skipped
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2006-2010, Tomasz Sowa
|
Copyright (c) 2006-2012, Tomasz Sowa
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@@ -31,7 +31,7 @@ PROJECT_NAME = TTMath
|
|||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# if some version control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 0.8.2
|
PROJECT_NUMBER = 0.9.2
|
||||||
|
|
||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||||
# base path where the generated documentation will be put.
|
# base path where the generated documentation will be put.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
CC = g++
|
CC = g++
|
||||||
CFLAGS = -Wall -pedantic -s -O2 -I..
|
CFLAGS = -Wall -pedantic -s -O2 -I.. -DTTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
.SUFFIXES: .cpp .o
|
.SUFFIXES: .cpp .o
|
||||||
|
@@ -88,13 +88,13 @@ a = 123456.543456
|
|||||||
b = 98767878.124322
|
b = 98767878.124322
|
||||||
a + b = 98891334.667778
|
a + b = 98891334.667778
|
||||||
a - b = -98644421.580866
|
a - b = -98644421.580866
|
||||||
a * b = 12193540837712.2708
|
a * b = 12193540837712.27076
|
||||||
a / b = 0.00124996654580957646
|
a / b = 0.00124996654580957646
|
||||||
Calculating with a carry
|
Calculating with a carry
|
||||||
a = 1.624801256066640878e+646457012
|
a = 1.6248012560666408782e+646457012
|
||||||
b = 456.319999999999993
|
b = 456.319999999999993
|
||||||
a + b = 1.624801256066640878e+646457012
|
a + b = 1.6248012560666408782e+646457012
|
||||||
a - b = 1.624801256066640878e+646457012
|
a - b = 1.6248012560666408782e+646457012
|
||||||
a * b = (carry)
|
a * b = (carry)
|
||||||
a / b = 3.560661939136222174e+646457009
|
a / b = 3.560661939136222174e+646457009
|
||||||
*/
|
*/
|
||||||
|
@@ -102,12 +102,12 @@ b = 98767878.124322
|
|||||||
a + b = 98891334.667778
|
a + b = 98891334.667778
|
||||||
a - b = -98644421.580866
|
a - b = -98644421.580866
|
||||||
a * b = 12193540837712.270763536832
|
a * b = 12193540837712.270763536832
|
||||||
a / b = 0.001249966545809576460596448526166860913
|
a / b = 0.0012499665458095764605964485261668609133
|
||||||
Calculating with a carry
|
Calculating with a carry
|
||||||
a = 2.3495345545711177736883282090959505003e+2776511644261678604
|
a = 2.34953455457111777368832820909595050034e+2776511644261678604
|
||||||
b = 456.3199999999999931787897367030382156
|
b = 456.3199999999999931787897367030382156
|
||||||
a + b = 2.3495345545711177736883282090959505003e+2776511644261678604
|
a + b = 2.34953455457111777368832820909595050034e+2776511644261678604
|
||||||
a - b = 2.3495345545711177736883282090959505003e+2776511644261678604
|
a - b = 2.34953455457111777368832820909595050034e+2776511644261678604
|
||||||
a * b = (carry)
|
a * b = (carry)
|
||||||
a / b = 5.1488748127873374141170361292780486452e+2776511644261678601
|
a / b = 5.1488748127873374141170361292780486452e+2776511644261678601
|
||||||
*/
|
*/
|
||||||
|
@@ -29,7 +29,7 @@ const char equation[] = " (34 + 24) * 123 - 34.32 ^ 6 * sin(2.56) - atan(10)";
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
the result (on 32 bit platform):
|
the result (on 32 bit platform):
|
||||||
-897705014.52573107
|
-897705014.525731067
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
* Copyright (c) 2006-2012, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -273,12 +273,16 @@ namespace ttmath
|
|||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Log(const ValueType & x, const ValueType & base, ErrorCode * err = 0)
|
ValueType Log(const ValueType & x, const ValueType & base, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() || base.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err ) *err = err_improper_argument;
|
||||||
*err = err_improper_argument;
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
return ValueType(); // default NaN
|
if( base.IsNan() )
|
||||||
|
{
|
||||||
|
if( err ) *err = err_improper_argument;
|
||||||
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType result;
|
ValueType result;
|
||||||
@@ -523,7 +527,7 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( err )
|
if( err )
|
||||||
@@ -854,7 +858,7 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( x.GreaterWithoutSignThan(one) )
|
if( x.GreaterWithoutSignThan(one) )
|
||||||
@@ -1080,7 +1084,7 @@ namespace ttmath
|
|||||||
bool change_sign = false;
|
bool change_sign = false;
|
||||||
|
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
|
|
||||||
// if x is negative we're using the formula:
|
// if x is negative we're using the formula:
|
||||||
// atan(-x) = -atan(x)
|
// atan(-x) = -atan(x)
|
||||||
@@ -1548,7 +1552,7 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = x;
|
result = x;
|
||||||
@@ -1584,7 +1588,7 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = 180;
|
result = 180;
|
||||||
@@ -1629,7 +1633,9 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return delimiter ; // NaN is set by default
|
delimiter.SetZeroNan(); // not needed, only to get rid of GCC warning about an uninitialized variable
|
||||||
|
|
||||||
|
return delimiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
multipler = 60;
|
multipler = 60;
|
||||||
@@ -1683,7 +1689,7 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = x;
|
result = x;
|
||||||
@@ -1719,7 +1725,7 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = 200;
|
result = 200;
|
||||||
@@ -1751,7 +1757,7 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = x;
|
result = x;
|
||||||
@@ -1801,7 +1807,7 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = x;
|
result = x;
|
||||||
@@ -1842,7 +1848,9 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return ValueType(); // NaN is set by default
|
x.SetNan();
|
||||||
|
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint c = x.Sqrt();
|
uint c = x.Sqrt();
|
||||||
@@ -2065,7 +2073,9 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return ValueType(); // NaN is set by default
|
x.SetNan();
|
||||||
|
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( RootCheckIndexSign(x, index, err) ) return x;
|
if( RootCheckIndexSign(x, index, err) ) return x;
|
||||||
@@ -2154,7 +2164,9 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return ValueType(); // NaN is set by default
|
a.SetNan();
|
||||||
|
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint c = a.Mod(b);
|
uint c = a.Mod(b);
|
||||||
@@ -2652,7 +2664,7 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( cgamma.history.Get(n, result, err_tmp) )
|
if( cgamma.history.Get(n, result, err_tmp) )
|
||||||
@@ -2731,7 +2743,9 @@ namespace ttmath
|
|||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN set by default
|
x.SetNan();
|
||||||
|
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
one.SetOne();
|
one.SetOne();
|
||||||
@@ -2818,10 +2832,14 @@ namespace ttmath
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
this is for convenience for the user
|
this is for convenience for the user
|
||||||
he can only use '#include <ttmath/ttmath.h>' even if he uses the parser
|
he can only use '#include <ttmath/ttmath.h>'
|
||||||
*/
|
*/
|
||||||
#include "ttmathparser.h"
|
#include "ttmathparser.h"
|
||||||
|
|
||||||
|
// Dec is not finished yet
|
||||||
|
//#include "ttmathdec.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
//warning C4127: conditional expression is constant
|
//warning C4127: conditional expression is constant
|
||||||
|
1521
ttmath/ttmathbig.h
1521
ttmath/ttmathbig.h
File diff suppressed because it is too large
Load Diff
419
ttmath/ttmathdec.h
Normal file
419
ttmath/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
|
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
* Copyright (c) 2006-2011, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -104,13 +104,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
uint ChangeSign()
|
uint ChangeSign()
|
||||||
{
|
{
|
||||||
Int<value_size> temp;
|
|
||||||
|
|
||||||
temp.SetMin();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if the value is equal that one which has been returned from SetMin
|
if the value is equal that one which has been returned from SetMin
|
||||||
that means we can't change sign because the value is too big (bigger about one)
|
(only the highest bit is set) that means we can't change sign
|
||||||
|
because the value is too big (bigger about one)
|
||||||
|
|
||||||
e.g. when value_size = 1 and value is -2147483648 we can't change it to the
|
e.g. when value_size = 1 and value is -2147483648 we can't change it to the
|
||||||
2147483648 because the max value which can be held is 2147483647
|
2147483648 because the max value which can be held is 2147483647
|
||||||
@@ -119,13 +116,12 @@ public:
|
|||||||
(if we look on our value without the sign we get the correct value
|
(if we look on our value without the sign we get the correct value
|
||||||
eg. -2147483648 in Int<1> will be 2147483648 on the UInt<1> type)
|
eg. -2147483648 in Int<1> will be 2147483648 on the UInt<1> type)
|
||||||
*/
|
*/
|
||||||
if( operator==(temp) )
|
if( UInt<value_size>::IsOnlyTheHighestBitSet() )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
temp.SetZero();
|
UInt<value_size> temp(*this);
|
||||||
temp.UInt<value_size>::Sub(*this);
|
UInt<value_size>::SetZero();
|
||||||
|
UInt<value_size>::Sub(temp);
|
||||||
operator=(temp);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -350,33 +346,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
/*!
|
|
||||||
multiplication this = this * ss2
|
|
||||||
|
|
||||||
it returns carry if the result is too big
|
uint CheckMinCarry(bool ss1_is_sign, bool ss2_is_sign)
|
||||||
(we're using the method from the base class but we have to make
|
|
||||||
one correction in account of signs)
|
|
||||||
*/
|
|
||||||
uint Mul(Int<value_size> ss2)
|
|
||||||
{
|
{
|
||||||
bool ss1_is_sign, ss2_is_sign;
|
|
||||||
|
|
||||||
ss1_is_sign = IsSign();
|
|
||||||
ss2_is_sign = ss2.IsSign();
|
|
||||||
|
|
||||||
/*
|
|
||||||
we don't have to check the carry from Abs (values will be correct
|
|
||||||
because next we're using the method Mul from the base class UInt
|
|
||||||
which is without a sign)
|
|
||||||
*/
|
|
||||||
Abs();
|
|
||||||
ss2.Abs();
|
|
||||||
|
|
||||||
if( UInt<value_size>::Mul(ss2) )
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
we have to examine the sign of the result now
|
we have to examine the sign of the result now
|
||||||
but if the result is with the sign then:
|
but if the result is with the sign then:
|
||||||
@@ -391,36 +365,100 @@ public:
|
|||||||
*/
|
*/
|
||||||
if( IsSign() )
|
if( IsSign() )
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
there can be one case where signs are different and
|
|
||||||
the result will be equal the value from SetMin()
|
|
||||||
(this situation is ok)
|
|
||||||
*/
|
|
||||||
if( ss1_is_sign != ss2_is_sign )
|
if( ss1_is_sign != ss2_is_sign )
|
||||||
{
|
{
|
||||||
Int<value_size> temp;
|
|
||||||
temp.SetMin();
|
|
||||||
|
|
||||||
if( operator!=(temp) )
|
|
||||||
/*
|
/*
|
||||||
the result is too big
|
there can be one case where signs are different and
|
||||||
|
the result will be equal the value from SetMin() (only the highest bit is set)
|
||||||
|
(this situation is ok)
|
||||||
*/
|
*/
|
||||||
|
if( !UInt<value_size>::IsOnlyTheHighestBitSet() )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
// signs were the same
|
||||||
the result is too big
|
|
||||||
*/
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
multiplication: this = this * ss2
|
||||||
|
|
||||||
|
it can return a carry
|
||||||
|
*/
|
||||||
|
uint MulInt(sint ss2)
|
||||||
|
{
|
||||||
|
bool ss1_is_sign, ss2_is_sign;
|
||||||
|
uint c;
|
||||||
|
|
||||||
|
ss1_is_sign = IsSign();
|
||||||
|
|
||||||
|
/*
|
||||||
|
we don't have to check the carry from Abs (values will be correct
|
||||||
|
because next we're using the method MulInt from the base class UInt
|
||||||
|
which is without a sign)
|
||||||
|
*/
|
||||||
|
Abs();
|
||||||
|
|
||||||
|
if( ss2 < 0 )
|
||||||
|
{
|
||||||
|
ss2 = -ss2;
|
||||||
|
ss2_is_sign = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss2_is_sign = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = UInt<value_size>::MulInt((uint)ss2);
|
||||||
|
c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
|
||||||
|
|
||||||
if( ss1_is_sign != ss2_is_sign )
|
if( ss1_is_sign != ss2_is_sign )
|
||||||
SetSign();
|
SetSign();
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
multiplication this = this * ss2
|
||||||
|
|
||||||
|
it returns carry if the result is too big
|
||||||
|
(we're using the method from the base class but we have to make
|
||||||
|
one correction in account of signs)
|
||||||
|
*/
|
||||||
|
uint Mul(Int<value_size> ss2)
|
||||||
|
{
|
||||||
|
bool ss1_is_sign, ss2_is_sign;
|
||||||
|
uint c;
|
||||||
|
|
||||||
|
ss1_is_sign = IsSign();
|
||||||
|
ss2_is_sign = ss2.IsSign();
|
||||||
|
|
||||||
|
/*
|
||||||
|
we don't have to check the carry from Abs (values will be correct
|
||||||
|
because next we're using the method Mul from the base class UInt
|
||||||
|
which is without a sign)
|
||||||
|
*/
|
||||||
|
Abs();
|
||||||
|
ss2.Abs();
|
||||||
|
|
||||||
|
c = UInt<value_size>::Mul(ss2);
|
||||||
|
c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
|
||||||
|
|
||||||
|
if( ss1_is_sign != ss2_is_sign )
|
||||||
|
SetSign();
|
||||||
|
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -688,6 +726,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts UInt<another_size> into this class
|
||||||
|
*/
|
||||||
|
template<uint argument_size>
|
||||||
|
uint FromInt(const UInt<argument_size> & p)
|
||||||
|
{
|
||||||
|
return FromUIntOrInt(p, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts the uint type into this class
|
this method converts the uint type into this class
|
||||||
*/
|
*/
|
||||||
@@ -707,6 +755,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the uint type into this class
|
||||||
|
*/
|
||||||
|
uint FromInt(uint value)
|
||||||
|
{
|
||||||
|
return FromUInt(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the default assignment operator
|
the default assignment operator
|
||||||
@@ -820,63 +876,194 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TTMATH_PLATFORM32
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts unsigned 64 bit int type to this class
|
||||||
|
***this method is created only on a 32bit platform***
|
||||||
|
*/
|
||||||
|
uint FromUInt(ulint n)
|
||||||
|
{
|
||||||
|
uint c = UInt<value_size>::FromUInt(n);
|
||||||
|
|
||||||
|
if( c )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if( value_size == 1 )
|
||||||
|
return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
|
||||||
|
|
||||||
|
if( value_size == 2 )
|
||||||
|
return ((UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts unsigned 64 bit int type to this class
|
||||||
|
***this method is created only on a 32bit platform***
|
||||||
|
*/
|
||||||
|
uint FromInt(ulint n)
|
||||||
|
{
|
||||||
|
return FromUInt(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts signed 64 bit int type to this class
|
||||||
|
***this method is created only on a 32bit platform***
|
||||||
|
*/
|
||||||
|
uint FromInt(slint n)
|
||||||
|
{
|
||||||
|
uint mask = (n < 0) ? TTMATH_UINT_MAX_VALUE : 0;
|
||||||
|
|
||||||
|
UInt<value_size>::table[0] = (uint)(ulint)n;
|
||||||
|
|
||||||
|
if( value_size == 1 )
|
||||||
|
{
|
||||||
|
if( uint(ulint(n) >> 32) != mask )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt<value_size>::table[1] = (uint)(ulint(n) >> 32);
|
||||||
|
|
||||||
|
for(uint i=2 ; i<value_size ; ++i)
|
||||||
|
UInt<value_size>::table[i] = mask;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this operator converts unsigned 64 bit int type to this class
|
||||||
|
***this operator is created only on a 32bit platform***
|
||||||
|
*/
|
||||||
|
Int<value_size> & operator=(ulint n)
|
||||||
|
{
|
||||||
|
FromUInt(n);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
a constructor for converting unsigned 64 bit int to this class
|
||||||
|
***this constructor is created only on a 32bit platform***
|
||||||
|
*/
|
||||||
|
Int(ulint n)
|
||||||
|
{
|
||||||
|
FromUInt(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this operator converts signed 64 bit int type to this class
|
||||||
|
***this operator is created only on a 32bit platform***
|
||||||
|
*/
|
||||||
|
Int<value_size> & operator=(slint n)
|
||||||
|
{
|
||||||
|
FromInt(n);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
a constructor for converting signed 64 bit int to this class
|
||||||
|
***this constructor is created only on a 32bit platform***
|
||||||
|
*/
|
||||||
|
Int(slint n)
|
||||||
|
{
|
||||||
|
FromInt(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TTMATH_PLATFORM64
|
#ifdef TTMATH_PLATFORM64
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts the signed int type to this class
|
this method converts 32 bit unsigned int type to this class
|
||||||
|
|
||||||
***this operator is created only on a 64bit platform***
|
***this operator is created only on a 64bit platform***
|
||||||
it takes one argument of 32bit
|
|
||||||
*/
|
*/
|
||||||
Int<value_size> & operator=(signed int i)
|
uint FromUInt(unsigned int i)
|
||||||
{
|
{
|
||||||
FromInt(sint(i));
|
return FromUInt(uint(i));
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting the signed int to this class
|
this method converts 32 bit unsigned int type to this class
|
||||||
|
***this operator is created only on a 64bit platform***
|
||||||
***this constructor is created only on a 64bit platform***
|
|
||||||
it takes one argument of 32bit
|
|
||||||
*/
|
*/
|
||||||
Int(signed int i)
|
uint FromInt(unsigned int i)
|
||||||
{
|
{
|
||||||
FromInt(sint(i));
|
return FromUInt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts the unsigned int type to this class
|
this method converts 32 bit signed int type to this class
|
||||||
|
***this operator is created only on a 64bit platform***
|
||||||
|
*/
|
||||||
|
uint FromInt(signed int i)
|
||||||
|
{
|
||||||
|
return FromInt(sint(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts 32 bit unsigned int type to this class
|
||||||
***this operator is created only on a 64bit platform***
|
***this operator is created only on a 64bit platform***
|
||||||
it takes one argument of 32bit
|
|
||||||
*/
|
*/
|
||||||
Int<value_size> & operator=(unsigned int i)
|
Int<value_size> & operator=(unsigned int i)
|
||||||
{
|
{
|
||||||
FromUInt(uint(i));
|
FromUInt(i);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting the unsigned int to this class
|
a constructor for converting 32 bit unsigned int to this class
|
||||||
|
|
||||||
***this constructor is created only on a 64bit platform***
|
***this constructor is created only on a 64bit platform***
|
||||||
it takes one argument of 32bit
|
|
||||||
*/
|
*/
|
||||||
Int(unsigned int i)
|
Int(unsigned int i)
|
||||||
{
|
{
|
||||||
FromUInt(uint(i));
|
FromUInt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this operator converts 32 bit signed int type to this class
|
||||||
|
***this operator is created only on a 64bit platform***
|
||||||
|
*/
|
||||||
|
Int<value_size> & operator=(signed int i)
|
||||||
|
{
|
||||||
|
FromInt(i);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
a constructor for converting 32 bit signed int to this class
|
||||||
|
***this constructor is created only on a 64bit platform***
|
||||||
|
*/
|
||||||
|
Int(signed int i)
|
||||||
|
{
|
||||||
|
FromInt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting string to this class (with the base=10)
|
a constructor for converting string to this class (with the base=10)
|
||||||
*/
|
*/
|
||||||
@@ -886,15 +1073,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
a constructor for converting string to this class (with the base=10)
|
|
||||||
*/
|
|
||||||
Int(const wchar_t * s)
|
|
||||||
{
|
|
||||||
FromString(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting a string to this class (with the base=10)
|
a constructor for converting a string to this class (with the base=10)
|
||||||
*/
|
*/
|
||||||
@@ -904,6 +1082,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
/*!
|
||||||
|
a constructor for converting string to this class (with the base=10)
|
||||||
|
*/
|
||||||
|
Int(const wchar_t * s)
|
||||||
|
{
|
||||||
|
FromString(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting a string to this class (with the base=10)
|
a constructor for converting a string to this class (with the base=10)
|
||||||
*/
|
*/
|
||||||
@@ -912,6 +1101,8 @@ public:
|
|||||||
FromString( s.c_str() );
|
FromString( s.c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a default constructor
|
a default constructor
|
||||||
@@ -943,6 +1134,175 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to uint type
|
||||||
|
can return a carry if the value is too long to store it in uint type
|
||||||
|
*/
|
||||||
|
uint ToUInt(uint & result) const
|
||||||
|
{
|
||||||
|
uint c = UInt<value_size>::ToUInt(result);
|
||||||
|
|
||||||
|
if( value_size == 1 )
|
||||||
|
return (result & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to uint type
|
||||||
|
can return a carry if the value is too long to store it in uint type
|
||||||
|
*/
|
||||||
|
uint ToInt(uint & result) const
|
||||||
|
{
|
||||||
|
return ToUInt(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to sint type
|
||||||
|
can return a carry if the value is too long to store it in sint type
|
||||||
|
*/
|
||||||
|
uint ToInt(sint & result) const
|
||||||
|
{
|
||||||
|
result = sint( UInt<value_size>::table[0] );
|
||||||
|
uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
|
||||||
|
|
||||||
|
if( (result & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for(uint i=1 ; i<value_size ; ++i)
|
||||||
|
if( UInt<value_size>::table[i] != mask )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TTMATH_PLATFORM32
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to ulint type (64 bit unsigned integer)
|
||||||
|
can return a carry if the value is too long to store it in ulint type
|
||||||
|
*** this method is created only on a 32 bit platform ***
|
||||||
|
*/
|
||||||
|
uint ToUInt(ulint & result) const
|
||||||
|
{
|
||||||
|
uint c = UInt<value_size>::ToUInt(result);
|
||||||
|
|
||||||
|
if( value_size == 1 )
|
||||||
|
return (UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
|
||||||
|
|
||||||
|
if( value_size == 2 )
|
||||||
|
return (UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to ulint type (64 bit unsigned integer)
|
||||||
|
can return a carry if the value is too long to store it in ulint type
|
||||||
|
*** this method is created only on a 32 bit platform ***
|
||||||
|
*/
|
||||||
|
uint ToInt(ulint & result) const
|
||||||
|
{
|
||||||
|
return ToUInt(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to slint type (64 bit signed integer)
|
||||||
|
can return a carry if the value is too long to store it in slint type
|
||||||
|
*** this method is created only on a 32 bit platform ***
|
||||||
|
*/
|
||||||
|
uint ToInt(slint & result) const
|
||||||
|
{
|
||||||
|
if( value_size == 1 )
|
||||||
|
{
|
||||||
|
result = slint(sint(UInt<value_size>::table[0]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint low = UInt<value_size>::table[0];
|
||||||
|
uint high = UInt<value_size>::table[1];
|
||||||
|
|
||||||
|
result = low;
|
||||||
|
result |= (ulint(high) << TTMATH_BITS_PER_UINT);
|
||||||
|
|
||||||
|
uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
|
||||||
|
|
||||||
|
if( (high & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for(uint i=2 ; i<value_size ; ++i)
|
||||||
|
if( UInt<value_size>::table[i] != mask )
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TTMATH_PLATFORM64
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to a 32 bit unsigned integer
|
||||||
|
can return a carry if the value is too long to store it in this type
|
||||||
|
*** this method is created only on a 64 bit platform ***
|
||||||
|
*/
|
||||||
|
uint ToUInt(unsigned int & result) const
|
||||||
|
{
|
||||||
|
uint c = UInt<value_size>::ToUInt(result);
|
||||||
|
|
||||||
|
if( c || IsSign() )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to a 32 bit unsigned integer
|
||||||
|
can return a carry if the value is too long to store it in this type
|
||||||
|
*** this method is created only on a 64 bit platform ***
|
||||||
|
*/
|
||||||
|
uint ToInt(unsigned int & result) const
|
||||||
|
{
|
||||||
|
return ToUInt(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to a 32 bit signed integer
|
||||||
|
can return a carry if the value is too long to store it in this type
|
||||||
|
*** this method is created only on a 64 bit platform ***
|
||||||
|
*/
|
||||||
|
uint ToInt(int & result) const
|
||||||
|
{
|
||||||
|
uint first = UInt<value_size>::table[0];
|
||||||
|
|
||||||
|
result = int(first);
|
||||||
|
uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
|
||||||
|
|
||||||
|
if( (first >> 31) != (mask >> 31) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for(uint i=1 ; i<value_size ; ++i)
|
||||||
|
if( UInt<value_size>::table[i] != mask )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -955,13 +1315,11 @@ private:
|
|||||||
{
|
{
|
||||||
Int<value_size> temp(*this);
|
Int<value_size> temp(*this);
|
||||||
temp.Abs();
|
temp.Abs();
|
||||||
|
temp.UInt<value_size>::ToStringBase(result, b, true);
|
||||||
temp.UInt<value_size>::ToString(result, b);
|
|
||||||
result.insert(result.begin(), '-');
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UInt<value_size>::ToString(result, b);
|
UInt<value_size>::ToStringBase(result, b, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -976,15 +1334,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method converts the value to a string with a base equal 'b'
|
|
||||||
*/
|
|
||||||
void ToString(std::wstring & result, uint b = 10) const
|
|
||||||
{
|
|
||||||
return ToStringBase(result, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts the value to a string with a base equal 'b'
|
this method converts the value to a string with a base equal 'b'
|
||||||
*/
|
*/
|
||||||
@@ -997,6 +1346,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to a string with a base equal 'b'
|
||||||
|
*/
|
||||||
|
void ToString(std::wstring & result, uint b = 10) const
|
||||||
|
{
|
||||||
|
return ToStringBase(result, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts the value to a string with a base equal 'b'
|
this method converts the value to a string with a base equal 'b'
|
||||||
*/
|
*/
|
||||||
@@ -1008,6 +1368,9 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -1111,16 +1474,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method converts a string into its value
|
|
||||||
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
|
|
||||||
*/
|
|
||||||
uint FromString(const std::wstring & s, uint b = 10)
|
|
||||||
{
|
|
||||||
return FromString( s.c_str(), b );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this operator converts a string into its value (with base = 10)
|
this operator converts a string into its value (with base = 10)
|
||||||
*/
|
*/
|
||||||
@@ -1132,6 +1485,19 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts a string into its value
|
||||||
|
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
|
||||||
|
*/
|
||||||
|
uint FromString(const std::wstring & s, uint b = 10)
|
||||||
|
{
|
||||||
|
return FromString( s.c_str(), b );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this operator converts a string into its value (with base = 10)
|
this operator converts a string into its value (with base = 10)
|
||||||
*/
|
*/
|
||||||
@@ -1143,6 +1509,19 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this operator converts a string into its value (with base = 10)
|
||||||
|
*/
|
||||||
|
Int<value_size> & operator=(const std::wstring & s)
|
||||||
|
{
|
||||||
|
FromString( s.c_str() );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this operator converts a string into its value (with base = 10)
|
this operator converts a string into its value (with base = 10)
|
||||||
*/
|
*/
|
||||||
@@ -1154,16 +1533,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this operator converts a string into its value (with base = 10)
|
|
||||||
*/
|
|
||||||
Int<value_size> & operator=(const std::wstring & s)
|
|
||||||
{
|
|
||||||
FromString( s.c_str() );
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
@@ -1382,11 +1751,9 @@ public:
|
|||||||
|
|
||||||
Int<value_size> & operator%=(const Int<value_size> & p2)
|
Int<value_size> & operator%=(const Int<value_size> & p2)
|
||||||
{
|
{
|
||||||
Int<value_size> temp(*this);
|
|
||||||
Int<value_size> remainder;
|
Int<value_size> remainder;
|
||||||
|
|
||||||
temp.Div(p2, remainder);
|
Div(p2, remainder);
|
||||||
|
|
||||||
operator=(remainder);
|
operator=(remainder);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@@ -1472,6 +1839,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
output to standard streams
|
output to standard streams
|
||||||
*/
|
*/
|
||||||
@@ -1480,6 +1849,8 @@ public:
|
|||||||
return OutputToStream<std::wostream, std::wstring>(s, l);
|
return OutputToStream<std::wostream, std::wstring>(s, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -1532,6 +1903,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
input from standard streams
|
input from standard streams
|
||||||
*/
|
*/
|
||||||
@@ -1539,6 +1912,8 @@ public:
|
|||||||
{
|
{
|
||||||
return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
|
return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
* Copyright (c) 2006-2010, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -75,6 +75,8 @@ static void AssignString(std::string & result, const char * str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
result = str
|
result = str
|
||||||
*/
|
*/
|
||||||
@@ -116,6 +118,8 @@ static void AssignString(std::string & result, const std::wstring & str)
|
|||||||
return AssignString(result, str.c_str());
|
return AssignString(result, str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
@@ -134,6 +138,8 @@ static void AddString(std::string & result, const char * str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
result += str
|
result += str
|
||||||
*/
|
*/
|
||||||
@@ -143,6 +149,7 @@ static void AddString(std::wstring & result, const char * str)
|
|||||||
result += *str;
|
result += *str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
* Copyright (c) 2006-2010, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -99,7 +99,7 @@ public:
|
|||||||
if 'can_be_digit' is true that means when the 'c' is a digit this
|
if 'can_be_digit' is true that means when the 'c' is a digit this
|
||||||
method returns true otherwise it returns false
|
method returns true otherwise it returns false
|
||||||
*/
|
*/
|
||||||
static bool CorrectCharacter(wchar_t c, bool can_be_digit)
|
static bool CorrectCharacter(int c, bool can_be_digit)
|
||||||
{
|
{
|
||||||
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
|
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
|
||||||
return true;
|
return true;
|
||||||
@@ -148,6 +148,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns true if such an object is defined (name exists)
|
this method returns true if such an object is defined (name exists)
|
||||||
*/
|
*/
|
||||||
@@ -163,6 +166,8 @@ public:
|
|||||||
return IsDefined(str_tmp1);
|
return IsDefined(str_tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method adds one object (variable of function) into the table
|
this method adds one object (variable of function) into the table
|
||||||
@@ -184,6 +189,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method adds one object (variable of function) into the table
|
this method adds one object (variable of function) into the table
|
||||||
*/
|
*/
|
||||||
@@ -200,6 +207,8 @@ public:
|
|||||||
return Add(str_tmp1, str_tmp2, param);
|
return Add(str_tmp1, str_tmp2, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns 'true' if the table is empty
|
this method returns 'true' if the table is empty
|
||||||
@@ -258,6 +267,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method changes the value and the number of parameters for a specific object
|
this method changes the value and the number of parameters for a specific object
|
||||||
*/
|
*/
|
||||||
@@ -274,6 +286,8 @@ public:
|
|||||||
return EditValue(str_tmp1, str_tmp2, param);
|
return EditValue(str_tmp1, str_tmp2, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method changes the name of a specific object
|
this method changes the name of a specific object
|
||||||
@@ -306,6 +320,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method changes the name of a specific object
|
this method changes the name of a specific object
|
||||||
*/
|
*/
|
||||||
@@ -322,6 +340,8 @@ public:
|
|||||||
return EditName(str_tmp1, str_tmp2);
|
return EditName(str_tmp1, str_tmp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method deletes an object
|
this method deletes an object
|
||||||
@@ -342,6 +362,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method deletes an object
|
this method deletes an object
|
||||||
*/
|
*/
|
||||||
@@ -357,6 +380,8 @@ public:
|
|||||||
return Delete(str_tmp1);
|
return Delete(str_tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method gets the value of a specific object
|
this method gets the value of a specific object
|
||||||
@@ -380,6 +405,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method gets the value of a specific object
|
this method gets the value of a specific object
|
||||||
*/
|
*/
|
||||||
@@ -397,6 +424,8 @@ public:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method gets the value of a specific object
|
this method gets the value of a specific object
|
||||||
@@ -421,6 +450,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method gets the value of a specific object
|
this method gets the value of a specific object
|
||||||
(this version is used for not copying the whole string)
|
(this version is used for not copying the whole string)
|
||||||
@@ -437,6 +468,8 @@ public:
|
|||||||
return GetValue(str_tmp1, value);
|
return GetValue(str_tmp1, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method gets the value and the number of parameters
|
this method gets the value and the number of parameters
|
||||||
@@ -463,6 +496,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method gets the value and the number of parameters
|
this method gets the value and the number of parameters
|
||||||
of a specific object
|
of a specific object
|
||||||
@@ -481,6 +516,8 @@ public:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets the value and the number of parameters
|
this method sets the value and the number of parameters
|
||||||
@@ -508,6 +545,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets the value and the number of parameters
|
this method sets the value and the number of parameters
|
||||||
of a specific object
|
of a specific object
|
||||||
@@ -527,6 +567,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns a pointer into the table
|
this method returns a pointer into the table
|
||||||
*/
|
*/
|
||||||
|
@@ -131,8 +131,8 @@ namespace ttmath
|
|||||||
for example:
|
for example:
|
||||||
"1+2;4+5"
|
"1+2;4+5"
|
||||||
the result will be on the stack as follows:
|
the result will be on the stack as follows:
|
||||||
"3"
|
stack[0].value=3
|
||||||
"9"
|
stack[1].value=9
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
class Parser
|
class Parser
|
||||||
@@ -282,9 +282,16 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
stack on which we're keeping the Items
|
stack on which we're keeping the Items
|
||||||
|
|
||||||
at the end of parsing we'll have the result on its
|
at the end of parsing we'll have the result here
|
||||||
the result don't have to be one value, it can be a list
|
the result don't have to be one value, it can be
|
||||||
of values separated by the 'semicolon item'
|
more than one if we have used a semicolon in the global space
|
||||||
|
e.g. such input string "1+2;3+4" will generate a result:
|
||||||
|
stack[0].value=3
|
||||||
|
stack[1].value=7
|
||||||
|
|
||||||
|
you should check if the stack is not empty, because if there was
|
||||||
|
a syntax error in the input string then we do not have any results
|
||||||
|
on the stack
|
||||||
*/
|
*/
|
||||||
std::vector<Item> stack;
|
std::vector<Item> stack;
|
||||||
|
|
||||||
@@ -317,8 +324,6 @@ ErrorCode error;
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
pointer to the currently reading char
|
pointer to the currently reading char
|
||||||
it's either char* or wchar_t*
|
|
||||||
|
|
||||||
when an error has occured it may be used to count the index of the wrong character
|
when an error has occured it may be used to count the index of the wrong character
|
||||||
*/
|
*/
|
||||||
const char * pstring;
|
const char * pstring;
|
||||||
@@ -1416,7 +1421,7 @@ void Frac(int sindex, int amount_of_args, ValueType & result)
|
|||||||
*/
|
*/
|
||||||
void Sprintf(char * buffer, int par)
|
void Sprintf(char * buffer, int par)
|
||||||
{
|
{
|
||||||
char buf[30]; // char, not wchar_t etc.
|
char buf[30]; // char, not wchar_t
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@@ -2708,6 +2713,8 @@ ErrorCode Parse(const std::string & str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the main method using for parsing string
|
the main method using for parsing string
|
||||||
*/
|
*/
|
||||||
@@ -2716,6 +2723,8 @@ ErrorCode Parse(const wchar_t * str)
|
|||||||
Misc::AssignString(wide_to_ansi, str);
|
Misc::AssignString(wide_to_ansi, str);
|
||||||
|
|
||||||
return Parse(wide_to_ansi.c_str());
|
return Parse(wide_to_ansi.c_str());
|
||||||
|
|
||||||
|
// !! wide_to_ansi clearing can be added here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2727,6 +2736,8 @@ ErrorCode Parse(const std::wstring & str)
|
|||||||
return Parse(str.c_str());
|
return Parse(str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns true is something was calculated
|
this method returns true is something was calculated
|
||||||
@@ -2744,6 +2755,18 @@ bool Calculated()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
initializing coefficients used when calculating the gamma (or factorial) function
|
||||||
|
this speed up the next calculations
|
||||||
|
you don't have to call this method explicitly
|
||||||
|
these coefficients will be calculated when needed
|
||||||
|
*/
|
||||||
|
void InitCGamma()
|
||||||
|
{
|
||||||
|
cgamma.InitAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2010, Tomasz Sowa
|
* Copyright (c) 2006-2012, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -56,70 +56,96 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#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
|
the version of the library
|
||||||
|
|
||||||
TTMATH_PRERELEASE_VER is either zero or one
|
TTMATH_PRERELEASE_VER is either zero or one
|
||||||
if zero that means this is the release version of the library
|
zero means that this is the release version of the library
|
||||||
|
(one means something like beta)
|
||||||
*/
|
*/
|
||||||
#define TTMATH_MAJOR_VER 0
|
#define TTMATH_MAJOR_VER 0
|
||||||
#define TTMATH_MINOR_VER 9
|
#define TTMATH_MINOR_VER 9
|
||||||
#define TTMATH_REVISION_VER 1
|
#define TTMATH_REVISION_VER 3
|
||||||
|
|
||||||
#define TTMATH_PRERELEASE_VER 0
|
#define TTMATH_PRERELEASE_VER 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
TTMATH_DEBUG
|
you can define a platform explicitly by defining either
|
||||||
this macro enables further testing during writing your code
|
TTMATH_PLATFORM32 or TTMATH_PLATFORM64 macro
|
||||||
you don't have to define it in a release mode
|
|
||||||
|
|
||||||
if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
|
|
||||||
are set as well and these macros can throw an exception if a condition in it
|
|
||||||
is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
|
|
||||||
|
|
||||||
TTMATH_RELEASE
|
|
||||||
if you are confident that your code is perfect you can define TTMATH_RELEASE
|
|
||||||
macro for example by using -D option in gcc
|
|
||||||
gcc -DTTMATH_RELEASE -o myprogram myprogram.cpp
|
|
||||||
or by defining this macro in your code before using any header files of this library
|
|
||||||
|
|
||||||
if TTMATH_RELEASE is not set then TTMATH_DEBUG is set automatically
|
|
||||||
*/
|
*/
|
||||||
#ifndef TTMATH_RELEASE
|
#if !defined TTMATH_PLATFORM32 && !defined TTMATH_PLATFORM64
|
||||||
#define TTMATH_DEBUG
|
|
||||||
|
#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
|
#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
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
|
||||||
#if !defined _M_X64 && !defined __x86_64__
|
|
||||||
|
|
||||||
/*!
|
|
||||||
we're using a 32bit platform
|
|
||||||
*/
|
|
||||||
#define TTMATH_PLATFORM32
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*!
|
|
||||||
we're using a 64bit platform
|
|
||||||
*/
|
|
||||||
#define TTMATH_PLATFORM64
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
another compilers than MS VC or GCC by default use no asm version (TTMATH_NOASM)
|
|
||||||
*/
|
|
||||||
#if !defined _MSC_VER && !defined __GNUC__
|
|
||||||
#define TTMATH_NOASM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TTMATH_PLATFORM32
|
#ifdef TTMATH_PLATFORM32
|
||||||
|
|
||||||
@@ -130,17 +156,18 @@ namespace ttmath
|
|||||||
typedef signed int sint;
|
typedef signed int sint;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this type is twice bigger than uint
|
on 32 bit platform ulint and slint will be equal 64 bits
|
||||||
(64bit on a 32bit platforms)
|
|
||||||
|
|
||||||
although C++ Standard - ANSI ISO IEC 14882:2003 doesn't define such a type (long long)
|
|
||||||
but it is defined in C99 and in upcoming C++0x /3.9.1 (2)/ and many compilers support it
|
|
||||||
|
|
||||||
this type is used in UInt::MulTwoWords and UInt::DivTwoWords when macro TTMATH_NOASM is defined
|
|
||||||
but only on a 32bit platform
|
|
||||||
*/
|
*/
|
||||||
#ifdef TTMATH_NOASM
|
#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 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
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -188,13 +215,8 @@ namespace ttmath
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
on 64bit platform we do not define ulint
|
on 64bit platforms we do not define ulint and slint
|
||||||
sizeof(long long) is 8 (64bit) but we need 128bit
|
|
||||||
|
|
||||||
on 64 bit platform (when there is defined TTMATH_NOASM macro)
|
|
||||||
methods UInt::MulTwoWords and UInt::DivTwoWords are using other algorithms than those on 32 bit
|
|
||||||
*/
|
*/
|
||||||
//typedef unsigned long long int ulint;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
how many bits there are in the uint type
|
how many bits there are in the uint type
|
||||||
@@ -371,7 +393,7 @@ namespace ttmath
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
used only in Big::ToString()
|
used only in Big::ToString()
|
||||||
if scient is false then the value will be print in the scientific mode
|
if scient is false then the value will be printed in the scientific mode
|
||||||
only if the exponent is greater than scien_from
|
only if the exponent is greater than scien_from
|
||||||
default: 15
|
default: 15
|
||||||
*/
|
*/
|
||||||
@@ -444,6 +466,13 @@ namespace ttmath
|
|||||||
uint group;
|
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
|
uint group_exp; // not implemented yet
|
||||||
@@ -463,6 +492,7 @@ namespace ttmath
|
|||||||
comma = '.';
|
comma = '.';
|
||||||
comma2 = ',';
|
comma2 = ',';
|
||||||
group = 0;
|
group = 0;
|
||||||
|
group_digits = 3;
|
||||||
group_exp = 0;
|
group_exp = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -521,26 +551,13 @@ namespace ttmath
|
|||||||
In the library is used macro TTMATH_REFERENCE_ASSERT which
|
In the library is used macro TTMATH_REFERENCE_ASSERT which
|
||||||
can throw an exception of this type
|
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
|
If you compile with gcc you can get a small benefit
|
||||||
from using method Where() (it returns std::string) with
|
from using method Where() (it returns std::string) with
|
||||||
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
|
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
|
||||||
was used)
|
was used)
|
||||||
|
|
||||||
What is the 'reference' error?
|
|
||||||
Some kind of methods use a reference as their argument to another object,
|
|
||||||
and the another object not always can be the same which is calling, e.g.
|
|
||||||
Big<1,2> foo(10);
|
|
||||||
foo.Mul(foo); // this is incorrect
|
|
||||||
above method Mul is making something more with 'this' object and
|
|
||||||
'this' cannot be passed as the argument because the result will be undefined
|
|
||||||
|
|
||||||
macro TTMATH_REFERENCE_ASSERT helps us to solve the above problem
|
|
||||||
|
|
||||||
note! some methods can use 'this' object as the argument
|
|
||||||
for example this code is correct:
|
|
||||||
UInt<2> foo(10);
|
|
||||||
foo.Add(foo);
|
|
||||||
but there are only few methods which can do that
|
|
||||||
*/
|
*/
|
||||||
class ReferenceError : public std::logic_error, public ExceptionInfo
|
class ReferenceError : public std::logic_error, public ExceptionInfo
|
||||||
{
|
{
|
||||||
@@ -596,8 +613,21 @@ namespace ttmath
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
look at the description of macros TTMATH_RELEASE and TTMATH_DEBUG
|
TTMATH_DEBUG
|
||||||
|
this macro enables further testing during writing your code
|
||||||
|
you don't have to define it in a release mode
|
||||||
|
|
||||||
|
if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
|
||||||
|
are set as well and these macros can throw an exception if a condition in it
|
||||||
|
is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
|
||||||
|
|
||||||
|
TTMATH_DEBUG is set automatically if DEBUG or _DEBUG are defined
|
||||||
*/
|
*/
|
||||||
|
#if defined DEBUG || defined _DEBUG
|
||||||
|
#define TTMATH_DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef TTMATH_DEBUG
|
#ifdef TTMATH_DEBUG
|
||||||
|
|
||||||
#if defined(__FILE__) && defined(__LINE__)
|
#if defined(__FILE__) && defined(__LINE__)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
* Copyright (c) 2006-2010, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -480,6 +480,8 @@ namespace ttmath
|
|||||||
c = new_c;
|
c = new_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c = (c != 0)? 1 : 0;
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcr2_one", c)
|
TTMATH_LOGC("UInt::Rcr2_one", c)
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
@@ -518,7 +520,7 @@ namespace ttmath
|
|||||||
c = new_c;
|
c = new_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcl2", c)
|
TTMATH_LOGC("UInt::Rcl2", (c & 1))
|
||||||
|
|
||||||
return (c & 1);
|
return (c & 1);
|
||||||
}
|
}
|
||||||
@@ -557,9 +559,11 @@ namespace ttmath
|
|||||||
c = new_c;
|
c = new_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c = (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcr2", c)
|
TTMATH_LOGC("UInt::Rcr2", c)
|
||||||
|
|
||||||
return (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
* Copyright (c) 2006-2010, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
this file is included at the end of ttmathuint.h
|
this file is included at the end of ttmathuint.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifndef __GNUC__
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifndef __GNUC__
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@@ -92,7 +92,7 @@ namespace ttmath
|
|||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
const char * UInt<value_size>::LibTypeStr()
|
const char * UInt<value_size>::LibTypeStr()
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifndef __GNUC__
|
||||||
static const char info[] = "asm_vc_64";
|
static const char info[] = "asm_vc_64";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ namespace ttmath
|
|||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
LibTypeCode UInt<value_size>::LibType()
|
LibTypeCode UInt<value_size>::LibType()
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifndef __GNUC__
|
||||||
LibTypeCode info = asm_vc_64;
|
LibTypeCode info = asm_vc_64;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -149,11 +149,7 @@ namespace ttmath
|
|||||||
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
||||||
// this algorithm doesn't require it
|
// this algorithm doesn't require it
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_adc_x64(p1,p2,b,c);
|
c = ttmath_adc_x64(p1,p2,b,c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -220,12 +216,7 @@ namespace ttmath
|
|||||||
|
|
||||||
TTMATH_ASSERT( index < value_size )
|
TTMATH_ASSERT( index < value_size )
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_addindexed_x64(p1,b,index,value);
|
c = ttmath_addindexed_x64(p1,b,index,value);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -304,12 +295,7 @@ namespace ttmath
|
|||||||
|
|
||||||
TTMATH_ASSERT( index < value_size - 1 )
|
TTMATH_ASSERT( index < value_size - 1 )
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_addindexed2_x64(p1,b,index,x1,x2);
|
c = ttmath_addindexed2_x64(p1,b,index,x1,x2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -378,12 +364,7 @@ namespace ttmath
|
|||||||
|
|
||||||
uint c;
|
uint c;
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_addvector_x64(ss1, ss2, ss1_size, ss2_size, result);
|
c = ttmath_addvector_x64(ss1, ss2, ss1_size, ss2_size, result);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -456,16 +437,10 @@ namespace ttmath
|
|||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
const uint * p2 = ss2.table;
|
const uint * p2 = ss2.table;
|
||||||
|
|
||||||
|
|
||||||
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
||||||
// this algorithm doesn't require it
|
// this algorithm doesn't require it
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_sbb_x64(p1,p2,b,c);
|
c = ttmath_sbb_x64(p1,p2,b,c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -529,12 +504,7 @@ namespace ttmath
|
|||||||
|
|
||||||
TTMATH_ASSERT( index < value_size )
|
TTMATH_ASSERT( index < value_size )
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_subindexed_x64(p1,b,index,value);
|
c = ttmath_subindexed_x64(p1,b,index,value);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -599,12 +569,7 @@ namespace ttmath
|
|||||||
|
|
||||||
uint c;
|
uint c;
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_subvector_x64(ss1, ss2, ss1_size, ss2_size, result);
|
c = ttmath_subvector_x64(ss1, ss2, ss1_size, ss2_size, result);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -682,12 +647,7 @@ namespace ttmath
|
|||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
|
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_rcl_x64(p1,b,c);
|
c = ttmath_rcl_x64(p1,b,c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -742,12 +702,7 @@ namespace ttmath
|
|||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
|
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_rcr_x64(p1,b,c);
|
c = ttmath_rcr_x64(p1,b,c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -803,12 +758,7 @@ namespace ttmath
|
|||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
|
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_rcl2_x64(p1,b,bits,c);
|
c = ttmath_rcl2_x64(p1,b,bits,c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -880,12 +830,8 @@ namespace ttmath
|
|||||||
sint b = value_size;
|
sint b = value_size;
|
||||||
uint * p1 = table;
|
uint * p1 = table;
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#ifndef __GNUC__
|
||||||
#ifdef _MSC_VER
|
|
||||||
c = ttmath_rcr2_x64(p1,b,bits,c);
|
c = ttmath_rcr2_x64(p1,b,bits,c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -950,12 +896,7 @@ namespace ttmath
|
|||||||
sint result;
|
sint result;
|
||||||
|
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
|
||||||
unsigned long nIndex = 0;
|
unsigned long nIndex = 0;
|
||||||
|
|
||||||
@@ -999,12 +940,7 @@ namespace ttmath
|
|||||||
sint result;
|
sint result;
|
||||||
|
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
|
||||||
unsigned long nIndex = 0;
|
unsigned long nIndex = 0;
|
||||||
|
|
||||||
@@ -1057,12 +993,8 @@ namespace ttmath
|
|||||||
uint old_bit;
|
uint old_bit;
|
||||||
uint v = value;
|
uint v = value;
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#ifndef __GNUC__
|
||||||
#ifdef _MSC_VER
|
|
||||||
old_bit = _bittestandset64((__int64*)&value,bit) != 0;
|
old_bit = _bittestandset64((__int64*)&value,bit) != 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1118,12 +1050,8 @@ namespace ttmath
|
|||||||
uint result1_;
|
uint result1_;
|
||||||
uint result2_;
|
uint result2_;
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#ifndef __GNUC__
|
||||||
#ifdef _MSC_VER
|
|
||||||
result1_ = _umul128(a,b,&result2_);
|
result1_ = _umul128(a,b,&result2_);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1181,12 +1109,8 @@ namespace ttmath
|
|||||||
|
|
||||||
TTMATH_ASSERT( c != 0 )
|
TTMATH_ASSERT( c != 0 )
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
||||||
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#ifndef __GNUC__
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
|
||||||
ttmath_div_x64(&a,&b,c);
|
ttmath_div_x64(&a,&b,c);
|
||||||
r_ = a;
|
r_ = a;
|
||||||
|
@@ -36,9 +36,9 @@
|
|||||||
;
|
;
|
||||||
|
|
||||||
;
|
;
|
||||||
; compile with debug info: ml64.exe /Zd /Zi ttmathuint_x86_64_msvc.asm
|
; compile with debug info: ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
|
||||||
; compile without debug info: ml64.exe ttmathuint_x86_64_msvc.asm
|
; compile without debug info: ml64.exe /c ttmathuint_x86_64_msvc.asm
|
||||||
; this create ttmathuint_x86_64_msvc.obj file which can be linked with your program
|
; this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program
|
||||||
;
|
;
|
||||||
|
|
||||||
PUBLIC ttmath_adc_x64
|
PUBLIC ttmath_adc_x64
|
||||||
|
Reference in New Issue
Block a user