initial import
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
commit
ab42f75285
|
@ -0,0 +1,4 @@
|
||||||
|
Version 0.6.2 (2007.01.10):
|
||||||
|
* New division algorithm (radix b) where b is 2^32
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
Copyright (c) 2006-2007, 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.
|
|
@ -0,0 +1,530 @@
|
||||||
|
/*
|
||||||
|
* This file is part of TTMath Mathematical Library
|
||||||
|
* and is distributed under the (new) BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2007, 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 headerfilettmathmathtt
|
||||||
|
#define headerfilettmathmathtt
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\file ttmath.h
|
||||||
|
\brief Mathematics functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ttmathbig.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace ttmath
|
||||||
|
{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the factorial from given 'x'
|
||||||
|
e.g.
|
||||||
|
Factorial(4) = 4! = 1*2*3*4
|
||||||
|
*/
|
||||||
|
template<int exp,int man>
|
||||||
|
Big<exp, man> Factorial(const Big<exp, man> & x, ErrorCode * err = 0, const volatile StopCalculating * stop = 0)
|
||||||
|
{
|
||||||
|
Big<exp, man> result;
|
||||||
|
|
||||||
|
result.SetOne();
|
||||||
|
|
||||||
|
if( x.IsSign() )
|
||||||
|
{
|
||||||
|
if( err )
|
||||||
|
*err = err_improper_argument;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !x.exponent.IsSign() && !x.exponent.IsZero() )
|
||||||
|
{
|
||||||
|
// when x>0 there's no sense to calculate the formula
|
||||||
|
// (we can't add one into the x bacause
|
||||||
|
// we don't have enough bits in our mantissa)
|
||||||
|
if( err )
|
||||||
|
*err = err_overflow;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Big<exp, man> multipler;
|
||||||
|
Big<exp, man> one;
|
||||||
|
uint carry = 0;
|
||||||
|
|
||||||
|
one = result; // =1
|
||||||
|
multipler = result; // =1
|
||||||
|
|
||||||
|
while( !carry && multipler < x )
|
||||||
|
{
|
||||||
|
if( stop && stop->WasStopSignal() )
|
||||||
|
{
|
||||||
|
if( err )
|
||||||
|
*err = err_interrupt;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
carry += multipler.Add(one);
|
||||||
|
carry += result.Mul(multipler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( err )
|
||||||
|
{
|
||||||
|
if( carry )
|
||||||
|
*err = err_overflow;
|
||||||
|
else
|
||||||
|
*err = err_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
absolute value of x
|
||||||
|
e.g. -2 = 2
|
||||||
|
2 = 2
|
||||||
|
*/
|
||||||
|
template<int exp,int man>
|
||||||
|
Big<exp, man> Abs(const Big<exp, man> & x)
|
||||||
|
{
|
||||||
|
Big<exp, man> result( x );
|
||||||
|
result.Abs();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method skips the fraction from x
|
||||||
|
e.g 2.2 = 2
|
||||||
|
2.7 = 2
|
||||||
|
-2.2 = 2
|
||||||
|
-2.7 = 2
|
||||||
|
*/
|
||||||
|
template<int exp,int man>
|
||||||
|
Big<exp, man> SkipFraction(const Big<exp, man> & x)
|
||||||
|
{
|
||||||
|
Big<exp, man> result( x );
|
||||||
|
result.SkipFraction();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method rounds to the nearest integer value
|
||||||
|
e.g 2.2 = 2
|
||||||
|
2.7 = 3
|
||||||
|
-2.2 = -2
|
||||||
|
-2.7 = -3
|
||||||
|
*/
|
||||||
|
template<int exp,int man>
|
||||||
|
Big<exp, man> Round(const Big<exp, man> & x)
|
||||||
|
{
|
||||||
|
Big<exp, man> result( x );
|
||||||
|
result.Round();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method calculates the natural logarithm (logarithm with the base 'e')
|
||||||
|
*/
|
||||||
|
template<int exp,int man>
|
||||||
|
Big<exp, man> Ln(const Big<exp, man> & x, ErrorCode * err = 0)
|
||||||
|
{
|
||||||
|
Big<exp, man> result;
|
||||||
|
|
||||||
|
uint state = result.Ln(x);
|
||||||
|
|
||||||
|
if( err )
|
||||||
|
{
|
||||||
|
switch( state )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
*err = err_ok;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
*err = err_overflow;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*err = err_improper_argument;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*err = err_internal_error;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method calculates the logarithm
|
||||||
|
*/
|
||||||
|
template<int exp,int man>
|
||||||
|
Big<exp, man> Log(const Big<exp, man> & base, const Big<exp, man> & x, ErrorCode * err = 0)
|
||||||
|
{
|
||||||
|
Big<exp, man> result;
|
||||||
|
|
||||||
|
uint state = result.Log(base,x);
|
||||||
|
|
||||||
|
if( err )
|
||||||
|
{
|
||||||
|
switch( state )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
*err = err_ok;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
*err = err_overflow;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
*err = err_improper_argument;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*err = err_internal_error;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method calculates the expression e^x
|
||||||
|
*/
|
||||||
|
template<int exp,int man>
|
||||||
|
Big<exp, man> Exp(const Big<exp, man> & x, ErrorCode * err = 0)
|
||||||
|
{
|
||||||
|
Big<exp, man> result;
|
||||||
|
|
||||||
|
uint state = result.Exp(x);
|
||||||
|
|
||||||
|
if( err )
|
||||||
|
if( state!=0 )
|
||||||
|
*err = err_overflow;
|
||||||
|
else
|
||||||
|
*err = err_ok;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* trigonometric functions
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
an auxiliary function for calculating the Sin
|
||||||
|
(you don't have to call this function)
|
||||||
|
*/
|
||||||
|
template<int exp,int man>
|
||||||
|
void PrepareSin(Big<exp,man> & x, bool & change_sign)
|
||||||
|
{
|
||||||
|
Big<exp,man> temp;
|
||||||
|
|
||||||
|
change_sign = false;
|
||||||
|
|
||||||
|
if( x.IsSign() )
|
||||||
|
{
|
||||||
|
// we're using the formula 'sin(-x) = -sin(x)'
|
||||||
|
change_sign = !change_sign;
|
||||||
|
x.ChangeSign();
|
||||||
|
}
|
||||||
|
|
||||||
|
// we're reducing the period 2*PI
|
||||||
|
// (for big values there'll always be zero)
|
||||||
|
temp.Set2Pi();
|
||||||
|
if( x > temp )
|
||||||
|
{
|
||||||
|
x.Div( temp );
|
||||||
|
x.RemainFraction();
|
||||||
|
x.Mul( temp );
|
||||||
|
}
|
||||||
|
|
||||||
|
// we're setting 'x' as being in the range of <0, 0.5PI>
|
||||||
|
|
||||||
|
temp.SetPi();
|
||||||
|
|
||||||
|
if( x > temp )
|
||||||
|
{
|
||||||
|
// x is in (pi, 2*pi>
|
||||||
|
x.Sub( temp );
|
||||||
|
change_sign = !change_sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp.Set05Pi();
|
||||||
|
|
||||||
|
if( x > temp )
|
||||||
|
{
|
||||||
|
// x is in (0.5pi, pi>
|
||||||
|
x.Sub( temp );
|
||||||
|
x = temp - x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
an auxiliary function for calculating the Sin
|
||||||
|
(you don't have to call this function)
|
||||||
|
|
||||||
|
it returns Sin(x) where 'x' is from <0, PI/2>
|
||||||
|
we're calculating the Sin with using Taylor series in zero or PI/2
|
||||||
|
(depending on which point of these two points is nearer to the 'x')
|
||||||
|
|
||||||
|
Taylor series:
|
||||||
|
sin(x) = sin(a) + cos(a)*(x-a)/(1!)
|
||||||
|
- sin(a)*((x-a)^2)/(2!) - cos(a)*((x-a)^3)/(3!)
|
||||||
|
+ sin(a)*((x-a)^4)/(4!) + ...
|
||||||
|
|
||||||
|
when a=0 it'll be:
|
||||||
|
sin(x) = (x)/(1!) - (x^3)/(3!) + (x^5)/(5!) - (x^7)/(7!) + (x^9)/(9!) ...
|
||||||
|
|
||||||
|
and when a=PI/2:
|
||||||
|
sin(x) = 1 - ((x-PI/2)^2)/(2!) + ((x-PI/2)^4)/(4!) - ((x-PI/2)^6)/(6!) ...
|
||||||
|
*/
|
||||||
|
template<int exp,int man>
|
||||||
|
Big<exp,man> Sin0pi05(const Big<exp,man> & x)
|
||||||
|
{
|
||||||
|
Big<exp,man> result;
|
||||||
|
Big<exp,man> numerator, denominator;
|
||||||
|
Big<exp,man> d_numerator, d_denominator;
|
||||||
|
Big<exp,man> one, temp, old_result;
|
||||||
|
|
||||||
|
// temp = pi/4
|
||||||
|
temp.Set05Pi();
|
||||||
|
temp.exponent.SubOne();
|
||||||
|
|
||||||
|
one.SetOne();
|
||||||
|
|
||||||
|
if( x < temp )
|
||||||
|
{
|
||||||
|
// we're using the Taylor series with a=0
|
||||||
|
result = x;
|
||||||
|
numerator = x;
|
||||||
|
denominator = one;
|
||||||
|
|
||||||
|
// d_numerator = x^2
|
||||||
|
d_numerator = x;
|
||||||
|
d_numerator.Mul(x);
|
||||||
|
|
||||||
|
d_denominator = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we're using the Taylor series with a=PI/2
|
||||||
|
result = one;
|
||||||
|
numerator = one;
|
||||||
|
denominator = one;
|
||||||
|
|
||||||
|
// d_numerator = (x-pi/2)^2
|
||||||
|
Big<exp,man> pi05;
|
||||||
|
pi05.Set05Pi();
|
||||||
|
|
||||||
|
temp = x;
|
||||||
|
temp.Sub( pi05 );
|
||||||
|
d_numerator = temp;
|
||||||
|
d_numerator.Mul( temp );
|
||||||
|
|
||||||
|
d_denominator = one;
|
||||||
|
}
|
||||||
|
|
||||||
|
int c = 0;
|
||||||
|
bool addition = false;
|
||||||
|
|
||||||
|
old_result = result;
|
||||||
|
for(int i=1 ; i<5000 ; ++i)
|
||||||
|
{
|
||||||
|
// we're starting from a second part of the formula
|
||||||
|
c += numerator. Mul( d_numerator );
|
||||||
|
c += denominator. Mul( d_denominator );
|
||||||
|
c += d_denominator.Add( one );
|
||||||
|
c += denominator. Mul( d_denominator );
|
||||||
|
c += d_denominator.Add( one );
|
||||||
|
temp = numerator;
|
||||||
|
c += temp.Div(denominator);
|
||||||
|
|
||||||
|
if( c )
|
||||||
|
// Sin is from <-1,1> and cannot make an overflow
|
||||||
|
// but the carry can be from the Taylor series
|
||||||
|
// (then we only breaks our calculations)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( addition )
|
||||||
|
result.Add( temp );
|
||||||
|
else
|
||||||
|
result.Sub( temp );
|
||||||
|
|
||||||
|
|
||||||
|
addition = !addition;
|
||||||
|
|
||||||
|
// we're testing whether the result has changed after adding
|
||||||
|
// the next part of the Taylor formula, if not we end the loop
|
||||||
|
// (it means 'x' is zero or 'x' is PI/2 or this part of the formula
|
||||||
|
// is too small)
|
||||||
|
if( result == old_result )
|
||||||
|
break;
|
||||||
|
|
||||||
|
old_result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this function calulates the Sin
|
||||||
|
*/
|
||||||
|
template<int exp,int man>
|
||||||
|
Big<exp,man> Sin(Big<exp,man> x)
|
||||||
|
{
|
||||||
|
Big<exp,man> one;
|
||||||
|
bool change_sign;
|
||||||
|
|
||||||
|
PrepareSin( x, change_sign );
|
||||||
|
Big<exp,man> result = Sin0pi05( x );
|
||||||
|
|
||||||
|
one.SetOne();
|
||||||
|
|
||||||
|
if( result > one )
|
||||||
|
result = one;
|
||||||
|
else
|
||||||
|
if( result.IsSign() )
|
||||||
|
result.SetZero();
|
||||||
|
|
||||||
|
if( change_sign )
|
||||||
|
result.ChangeSign();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this function calulates the Cos
|
||||||
|
we're using the formula cos(x) = sin(x + PI/2)
|
||||||
|
*/
|
||||||
|
template<int exp,int man>
|
||||||
|
Big<exp,man> Cos(Big<exp,man> x)
|
||||||
|
{
|
||||||
|
Big<exp,man> pi05;
|
||||||
|
pi05.Set05Pi();
|
||||||
|
|
||||||
|
x.Add( pi05 );
|
||||||
|
|
||||||
|
return Sin(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this function calulates the Tan
|
||||||
|
we're using the formula tan(x) = sin(x) / cos(x)
|
||||||
|
|
||||||
|
it takes more time than calculating the Tan directly
|
||||||
|
from for example Taylor series but should be a bit precise
|
||||||
|
because Tan receives its values from -infinity to +infinity
|
||||||
|
and when we calculate it from any series then we can make
|
||||||
|
a small mistake than calculating 'sin/cos'
|
||||||
|
*/
|
||||||
|
template<int exp,int man>
|
||||||
|
Big<exp,man> Tan(const Big<exp,man> & x, ErrorCode * err = 0)
|
||||||
|
{
|
||||||
|
Big<exp,man> result = Cos(x);
|
||||||
|
|
||||||
|
if( result.IsZero() )
|
||||||
|
{
|
||||||
|
if( err )
|
||||||
|
*err = err_improper_argument;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( err )
|
||||||
|
*err = err_ok;
|
||||||
|
|
||||||
|
return Sin(x) / result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this function calulates the CTan
|
||||||
|
we're using the formula tan(x) = cos(x) / sin(x)
|
||||||
|
|
||||||
|
(why do we make it in this way?
|
||||||
|
look at the info in Tan() function)
|
||||||
|
*/
|
||||||
|
template<int exp,int man>
|
||||||
|
Big<exp,man> CTan(const Big<exp,man> & x, ErrorCode * err = 0)
|
||||||
|
{
|
||||||
|
Big<exp,man> result = Sin(x);
|
||||||
|
|
||||||
|
if( result.IsZero() )
|
||||||
|
{
|
||||||
|
if( err )
|
||||||
|
*err = err_improper_argument;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( err )
|
||||||
|
*err = err_ok;
|
||||||
|
|
||||||
|
return Cos(x) / result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,997 @@
|
||||||
|
/*
|
||||||
|
* This file is part of TTMath Mathematical Library
|
||||||
|
* and is distributed under the (new) BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2007, 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 headerfilettmathint
|
||||||
|
#define headerfilettmathint
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\file ttmathint.h
|
||||||
|
\brief template class Int<uint>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ttmathuint.h"
|
||||||
|
|
||||||
|
namespace ttmath
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief it implements the big integer value with the sign
|
||||||
|
|
||||||
|
value_size - how many bytes specify our value (value_size = 1 -> 4 bytes -> 32 bits)
|
||||||
|
value_size = 1,2,3,4,5,6....
|
||||||
|
*/
|
||||||
|
template<uint value_size>
|
||||||
|
class Int : public UInt<value_size>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method sets the max value which this class can hold
|
||||||
|
(all bits will be one besides the last one)
|
||||||
|
*/
|
||||||
|
void SetMaxValue()
|
||||||
|
{
|
||||||
|
UInt<value_size>::SetMaxValue();
|
||||||
|
UInt<value_size>::table[value_size-1] = ~uint_the_highest_bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method sets the min value which this class can hold
|
||||||
|
(all bits will be zero besides the last one which is one)
|
||||||
|
*/
|
||||||
|
void SetMinValue()
|
||||||
|
{
|
||||||
|
UInt<value_size>::SetZero();
|
||||||
|
UInt<value_size>::table[value_size-1] = uint_the_highest_bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method sets -1 as the value
|
||||||
|
(-1 is equal the max value in an unsigned type)
|
||||||
|
*/
|
||||||
|
void SetSignOne()
|
||||||
|
{
|
||||||
|
UInt<value_size>::SetMaxValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
we change the sign of the value
|
||||||
|
|
||||||
|
if it isn't possible to change the sign this method returns 1
|
||||||
|
else return 0 and changing the sign
|
||||||
|
*/
|
||||||
|
uint ChangeSign()
|
||||||
|
{
|
||||||
|
Int<value_size> temp;
|
||||||
|
|
||||||
|
temp.SetMinValue();
|
||||||
|
|
||||||
|
/*
|
||||||
|
if the value is equal that one which has been returned from SetMinValue
|
||||||
|
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
|
||||||
|
2147483648 because the max value which can be held is 2147483647
|
||||||
|
|
||||||
|
we don't change the value and we're using this fact somewhere in some methods
|
||||||
|
(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)
|
||||||
|
*/
|
||||||
|
if( operator==(temp) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
temp.SetZero();
|
||||||
|
temp.UInt<value_size>::Sub(*this);
|
||||||
|
|
||||||
|
operator=(temp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method sets the sign
|
||||||
|
|
||||||
|
e.g. 1 -> -1
|
||||||
|
-2 -> -2
|
||||||
|
|
||||||
|
from a positive value we always make a negative value
|
||||||
|
*/
|
||||||
|
void SetSign()
|
||||||
|
{
|
||||||
|
if( IsSign() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
ChangeSign();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns true if there's the sign
|
||||||
|
|
||||||
|
(the highest bit will be converted to the bool)
|
||||||
|
*/
|
||||||
|
bool IsSign() const
|
||||||
|
{
|
||||||
|
return UInt<value_size>::IsTheHighestBitSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
it returns the absolute value
|
||||||
|
|
||||||
|
it can return carry (1) (look on ChangeSign() for details)
|
||||||
|
*/
|
||||||
|
uint Abs()
|
||||||
|
{
|
||||||
|
if( !IsSign() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return ChangeSign();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* basic mathematic functions
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method adds two value with sign and returns carry
|
||||||
|
|
||||||
|
we're using methods from the base class because values are stored with U2
|
||||||
|
we must only make the carry correction
|
||||||
|
|
||||||
|
this = p1(=this) + p2
|
||||||
|
|
||||||
|
when p1>=0 i p2>=0 carry is set when the highest bit of value is set
|
||||||
|
when p1<0 i p2<0 carry is set when the highest bit of value is clear
|
||||||
|
when p1>=0 i p2<0 carry will never be set
|
||||||
|
when p1<0 i p2>=0 carry will never be set
|
||||||
|
*/
|
||||||
|
uint Add(const Int<value_size> & ss2)
|
||||||
|
{
|
||||||
|
bool p1_is_sign = IsSign();
|
||||||
|
bool p2_is_sign = ss2.IsSign();
|
||||||
|
|
||||||
|
UInt<value_size>::Add(ss2);
|
||||||
|
|
||||||
|
if( !p1_is_sign && !p2_is_sign )
|
||||||
|
{
|
||||||
|
if( UInt<value_size>::IsTheHighestBitSet() )
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( p1_is_sign && p2_is_sign )
|
||||||
|
{
|
||||||
|
if( ! UInt<value_size>::IsTheHighestBitSet() )
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method subtracts two values with the sign
|
||||||
|
|
||||||
|
we don't use the previous Add because the method ChangeSign can
|
||||||
|
sometimes return carry
|
||||||
|
|
||||||
|
this = p1(=this) - p2
|
||||||
|
|
||||||
|
when p1>=0 i p2>=0 carry will never be set
|
||||||
|
when p1<0 i p2<0 carry will never be set
|
||||||
|
when p1>=0 i p2<0 carry is set when the highest bit of value is set
|
||||||
|
when p1<0 i p2>=0 carry is set when the highest bit of value is clear
|
||||||
|
*/
|
||||||
|
uint Sub(const Int<value_size> & ss2)
|
||||||
|
{
|
||||||
|
bool p1_is_sign = IsSign();
|
||||||
|
bool p2_is_sign = ss2.IsSign();
|
||||||
|
|
||||||
|
UInt<value_size>::Sub(ss2);
|
||||||
|
|
||||||
|
if( !p1_is_sign && p2_is_sign )
|
||||||
|
{
|
||||||
|
if( UInt<value_size>::IsTheHighestBitSet() )
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( p1_is_sign && !p2_is_sign )
|
||||||
|
{
|
||||||
|
if( ! UInt<value_size>::IsTheHighestBitSet() )
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method adds one to the value and returns carry
|
||||||
|
*/
|
||||||
|
uint AddOne()
|
||||||
|
{
|
||||||
|
Int<value_size> temp;
|
||||||
|
|
||||||
|
temp.SetOne();
|
||||||
|
|
||||||
|
return Add(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method subtracts one from the value and returns carry
|
||||||
|
*/
|
||||||
|
uint SubOne()
|
||||||
|
{
|
||||||
|
Int<value_size> temp;
|
||||||
|
|
||||||
|
temp.SetOne();
|
||||||
|
|
||||||
|
return Sub(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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;
|
||||||
|
|
||||||
|
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 result now
|
||||||
|
but if the result is with the sign then:
|
||||||
|
1. if the signs were the same that means the result is too big
|
||||||
|
(the result must be without a sign)
|
||||||
|
2. if the signs were diffrent that means if the result
|
||||||
|
is different from that one which has been returned from SetMinValue()
|
||||||
|
that is carry (result too big) but if the result is equal SetMinValue()
|
||||||
|
there'll be ok (and the next SetSign will has no effect because
|
||||||
|
the value is actually negative -- look at description of that case
|
||||||
|
in ChangeSign())
|
||||||
|
*/
|
||||||
|
if( IsSign() )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
there can be one case where signs are different and
|
||||||
|
the result will be equal the value from SetMinValue()
|
||||||
|
(there is ok situation)
|
||||||
|
*/
|
||||||
|
if( ss1_is_sign != ss2_is_sign )
|
||||||
|
{
|
||||||
|
Int<value_size> temp;
|
||||||
|
temp.SetMinValue();
|
||||||
|
|
||||||
|
if( operator!=(temp) )
|
||||||
|
/*
|
||||||
|
the result is too big
|
||||||
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
the result is too big
|
||||||
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ss1_is_sign != ss2_is_sign )
|
||||||
|
SetSign();
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
division this = this / ss2
|
||||||
|
function returns the remainder
|
||||||
|
|
||||||
|
for example: (result means this)
|
||||||
|
20 / 3 --> result: 6 remainder: 2
|
||||||
|
-20 / 3 --> result: -6 remainder: -2
|
||||||
|
20 / -3 --> result: -6 remainder: 2
|
||||||
|
-20 / -3 --> result: 6 remainder: -2
|
||||||
|
|
||||||
|
in other words: this(old) = result * this(new) + remainder
|
||||||
|
*/
|
||||||
|
Int<value_size> Div(Int<value_size> ss2)
|
||||||
|
{
|
||||||
|
bool ss1_is_sign, ss2_is_sign;
|
||||||
|
Int<value_size> remainder;
|
||||||
|
|
||||||
|
ss1_is_sign = IsSign();
|
||||||
|
ss2_is_sign = ss2.IsSign();
|
||||||
|
|
||||||
|
/*
|
||||||
|
we don't have to test the carry from Abs as well as in Mul
|
||||||
|
*/
|
||||||
|
Abs();
|
||||||
|
ss2.Abs();
|
||||||
|
|
||||||
|
remainder = UInt<value_size>::Div(ss2);
|
||||||
|
|
||||||
|
if( ss1_is_sign != ss2_is_sign )
|
||||||
|
SetSign();
|
||||||
|
|
||||||
|
if( ss1_is_sign )
|
||||||
|
remainder.SetSign();
|
||||||
|
|
||||||
|
return remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* convertion methods
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method convert an UInt<another_size> type to this class
|
||||||
|
|
||||||
|
this operation has mainly sense if the value from p
|
||||||
|
can be held in this type
|
||||||
|
|
||||||
|
it returns a carry if the value 'p' is too big
|
||||||
|
*/
|
||||||
|
template<uint argument_size>
|
||||||
|
uint FromInt(const Int<argument_size> & p)
|
||||||
|
{
|
||||||
|
uint min_size = (value_size < argument_size)? value_size : argument_size;
|
||||||
|
uint i;
|
||||||
|
|
||||||
|
for(i=0 ; i<min_size ; ++i)
|
||||||
|
UInt<value_size>::table[i] = p.table[i];
|
||||||
|
|
||||||
|
|
||||||
|
if( i < value_size )
|
||||||
|
{
|
||||||
|
uint fill = (p.table[argument_size-1] & uint_the_highest_bit)? uint_max_value : 0;
|
||||||
|
|
||||||
|
for( ; i<value_size ; ++i)
|
||||||
|
UInt<value_size>::table[i] = fill;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint test = (UInt<value_size>::table[value_size-1] & uint_the_highest_bit)? uint_max_value : 0;
|
||||||
|
|
||||||
|
for( ; i<argument_size ; ++i)
|
||||||
|
if( p.table[i] != test )
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this operator convert an UInt<another_size> type to this class
|
||||||
|
|
||||||
|
it doesn't return a carry
|
||||||
|
*/
|
||||||
|
template<uint argument_size>
|
||||||
|
Int<value_size> & operator=(const Int<argument_size> & p)
|
||||||
|
{
|
||||||
|
FromInt(p);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the default assignment operator
|
||||||
|
*/
|
||||||
|
Int<value_size> & operator=(const Int<value_size> & p)
|
||||||
|
{
|
||||||
|
FromInt(p);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method convert an int type to this class
|
||||||
|
*/
|
||||||
|
Int<value_size> & operator=(int i)
|
||||||
|
{
|
||||||
|
if(i<0)
|
||||||
|
SetSignOne();
|
||||||
|
else
|
||||||
|
UInt<value_size>::SetZero();
|
||||||
|
|
||||||
|
UInt<value_size>::table[0] = uint(i);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
constructor for converting an uint to this class
|
||||||
|
*/
|
||||||
|
Int(int i)
|
||||||
|
{
|
||||||
|
operator=(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
constructor for converting string to this class (with base=10)
|
||||||
|
*/
|
||||||
|
Int(const char * s)
|
||||||
|
{
|
||||||
|
FromString(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
constructor for converting string to this class (with base=10)
|
||||||
|
*/
|
||||||
|
Int(const std::string & s)
|
||||||
|
{
|
||||||
|
FromString( s.c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
default constructor
|
||||||
|
|
||||||
|
we don't clear table etc.
|
||||||
|
*/
|
||||||
|
Int()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the copying constructor
|
||||||
|
*/
|
||||||
|
template<uint argument_size>
|
||||||
|
Int(const Int<argument_size> & u) : UInt<value_size>::size(value_size)
|
||||||
|
{
|
||||||
|
// look that 'size' we still set as 'value_size' and not as u.value_size
|
||||||
|
|
||||||
|
operator=(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
a destructor
|
||||||
|
*/
|
||||||
|
virtual ~Int()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns the lowest value from table with the sign
|
||||||
|
|
||||||
|
we must be sure when we using this method whether the value
|
||||||
|
will hold in an int type or not (the rest value from table must be zero or -1)
|
||||||
|
*/
|
||||||
|
int ToInt() const
|
||||||
|
{
|
||||||
|
return int( UInt<value_size>::table[0] );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to a string with a base equal 'b'
|
||||||
|
*/
|
||||||
|
void ToString(std::string & result, uint b = 10) const
|
||||||
|
{
|
||||||
|
if( IsSign() )
|
||||||
|
{
|
||||||
|
Int<value_size> temp(*this);
|
||||||
|
temp.Abs();
|
||||||
|
|
||||||
|
temp.UInt<value_size>::ToString(result, b);
|
||||||
|
result.insert(result.begin(), '-');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt<value_size>::ToString(result, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts a string into its value
|
||||||
|
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
|
||||||
|
|
||||||
|
string is ended with a non-digit value, for example:
|
||||||
|
"-12" will be translated to -12
|
||||||
|
as well as:
|
||||||
|
"- 12foo" will be translated to 12 too
|
||||||
|
|
||||||
|
existing first white characters will be ommited
|
||||||
|
(between '-' and a first digit can be white characters too)
|
||||||
|
*/
|
||||||
|
uint FromString(const char * s, uint b = 10)
|
||||||
|
{
|
||||||
|
bool is_sign = false;
|
||||||
|
|
||||||
|
UInt<value_size>::SkipWhiteCharacters(s);
|
||||||
|
|
||||||
|
if( *s == '-' )
|
||||||
|
{
|
||||||
|
is_sign = true;
|
||||||
|
UInt<value_size>::SkipWhiteCharacters(++s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( *s == '+' )
|
||||||
|
{
|
||||||
|
UInt<value_size>::SkipWhiteCharacters(++s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( UInt<value_size>::FromString(s,b) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if( is_sign )
|
||||||
|
{
|
||||||
|
Int<value_size> mmin;
|
||||||
|
|
||||||
|
mmin.SetMinValue();
|
||||||
|
|
||||||
|
/*
|
||||||
|
the reference to mmin will be automatically converted to the reference
|
||||||
|
to a UInt type
|
||||||
|
(this value can be equal mmin -- look at a description in ChangeSign())
|
||||||
|
*/
|
||||||
|
if( UInt<value_size>::operator>( mmin ) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ChangeSign();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Int<value_size> mmax;
|
||||||
|
|
||||||
|
mmax.SetMaxValue();
|
||||||
|
|
||||||
|
if( UInt<value_size>::operator>( mmax ) )
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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::string & s, uint b = 10)
|
||||||
|
{
|
||||||
|
return FromString( s.c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this operator converts a string into its value (with base = 10)
|
||||||
|
*/
|
||||||
|
Int<value_size> & operator=(const char * s)
|
||||||
|
{
|
||||||
|
FromString(s);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this operator converts a string into its value (with base = 10)
|
||||||
|
*/
|
||||||
|
Int<value_size> & operator=(const std::string & s)
|
||||||
|
{
|
||||||
|
FromString( s.c_str() );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* methods for comparing
|
||||||
|
*
|
||||||
|
* operators == and != will be the same as in the base class (UInt<value_size>)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool operator<(const Int<value_size> & l) const
|
||||||
|
{
|
||||||
|
int i=value_size-1;
|
||||||
|
|
||||||
|
int a1 = int(UInt<value_size>::table[i]);
|
||||||
|
int a2 = int(l.table[i]);
|
||||||
|
|
||||||
|
if( a1 != a2 )
|
||||||
|
return a1 < a2;
|
||||||
|
|
||||||
|
|
||||||
|
// comparison as int
|
||||||
|
// if( int(UInt<value_size>::table[i]) != int(l.table[i]) )
|
||||||
|
// return int(UInt<value_size>::table[i]) < int(l.table[i]);
|
||||||
|
|
||||||
|
for(--i ; i>=0 ; --i)
|
||||||
|
{
|
||||||
|
if( UInt<value_size>::table[i] != l.table[i] )
|
||||||
|
// comparison as unsigned int
|
||||||
|
return UInt<value_size>::table[i] < l.table[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// they're equal
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator>(const Int<value_size> & l) const
|
||||||
|
{
|
||||||
|
int i=value_size-1;
|
||||||
|
|
||||||
|
|
||||||
|
int a1 = int(UInt<value_size>::table[i]);
|
||||||
|
int a2 = int(l.table[i]);
|
||||||
|
|
||||||
|
if( a1 != a2 )
|
||||||
|
return a1 > a2;
|
||||||
|
|
||||||
|
// comparison as int
|
||||||
|
// if( int(UInt<value_size>::table[i]) != int(l.table[i]) )
|
||||||
|
// return int(UInt<value_size>::table[i]) > int(l.table[i]);
|
||||||
|
|
||||||
|
for(--i ; i>=0 ; --i)
|
||||||
|
{
|
||||||
|
if( UInt<value_size>::table[i] != l.table[i] )
|
||||||
|
// comparison as unsigned int
|
||||||
|
return UInt<value_size>::table[i] > l.table[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// they're equal
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator<=(const Int<value_size> & l) const
|
||||||
|
{
|
||||||
|
int i=value_size-1;
|
||||||
|
|
||||||
|
|
||||||
|
int a1 = int(UInt<value_size>::table[i]);
|
||||||
|
int a2 = int(l.table[i]);
|
||||||
|
|
||||||
|
if( a1 != a2 )
|
||||||
|
return a1 < a2;
|
||||||
|
|
||||||
|
// comparison as int
|
||||||
|
// if( int(UInt<value_size>::table[i]) != int(l.table[i]) )
|
||||||
|
// return int(UInt<value_size>::table[i]) < int(l.table[i]);
|
||||||
|
|
||||||
|
for(--i ; i>=0 ; --i)
|
||||||
|
{
|
||||||
|
if( UInt<value_size>::table[i] != l.table[i] )
|
||||||
|
// comparison as unsigned int
|
||||||
|
return UInt<value_size>::table[i] < l.table[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// they're equal
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator>=(const Int<value_size> & l) const
|
||||||
|
{
|
||||||
|
int i=value_size-1;
|
||||||
|
|
||||||
|
|
||||||
|
int a1 = int(UInt<value_size>::table[i]);
|
||||||
|
int a2 = int(l.table[i]);
|
||||||
|
|
||||||
|
if( a1 != a2 )
|
||||||
|
return a1 > a2;
|
||||||
|
|
||||||
|
// comparison as int
|
||||||
|
// if( int(UInt<value_size>::table[i]) != int(l.table[i]) )
|
||||||
|
// return int(UInt<value_size>::table[i]) > int(l.table[i]);
|
||||||
|
|
||||||
|
for(--i ; i>=0 ; --i)
|
||||||
|
{
|
||||||
|
if( UInt<value_size>::table[i] != l.table[i] )
|
||||||
|
// comparison as unsigned int
|
||||||
|
return UInt<value_size>::table[i] > l.table[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// they're equal
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* standard mathematical operators
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
an operator for changing the sign
|
||||||
|
|
||||||
|
it's not changing 'this' but the changed value will be returned
|
||||||
|
*/
|
||||||
|
Int<value_size> operator-() const
|
||||||
|
{
|
||||||
|
Int<value_size> temp(*this);
|
||||||
|
|
||||||
|
temp.ChangeSign();
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int<value_size> operator-(const Int<value_size> & p2) const
|
||||||
|
{
|
||||||
|
Int<value_size> temp(*this);
|
||||||
|
|
||||||
|
temp.Sub(p2);
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int<value_size> & operator-=(const Int<value_size> & p2)
|
||||||
|
{
|
||||||
|
Sub(p2);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int<value_size> operator+(const Int<value_size> & p2) const
|
||||||
|
{
|
||||||
|
Int<value_size> temp(*this);
|
||||||
|
|
||||||
|
temp.Add(p2);
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int<value_size> & operator+=(const Int<value_size> & p2)
|
||||||
|
{
|
||||||
|
Add(p2);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int<value_size> operator*(const Int<value_size> & p2) const
|
||||||
|
{
|
||||||
|
Int<value_size> temp(*this);
|
||||||
|
|
||||||
|
temp.Mul(p2);
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int<value_size> & operator*=(const Int<value_size> & p2)
|
||||||
|
{
|
||||||
|
Mul(p2);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int<value_size> operator/(const Int<value_size> & p2) const
|
||||||
|
{
|
||||||
|
Int<value_size> temp(*this);
|
||||||
|
|
||||||
|
temp.Div(p2);
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int<value_size> & operator/=(const Int<value_size> & p2)
|
||||||
|
{
|
||||||
|
Div(p2);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int<value_size> operator%(const Int<value_size> & p2) const
|
||||||
|
{
|
||||||
|
Int<value_size> temp(*this);
|
||||||
|
Int<value_size> remainder = temp.Div( p2 );
|
||||||
|
|
||||||
|
return remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int<value_size> & operator%=(const Int<value_size> & p2)
|
||||||
|
{
|
||||||
|
Int<value_size> temp(*this);
|
||||||
|
Int<value_size> remainder = temp.Div( p2 );
|
||||||
|
|
||||||
|
operator=(remainder);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Prefix operator e.g ++variable
|
||||||
|
*/
|
||||||
|
UInt<value_size> & operator++()
|
||||||
|
{
|
||||||
|
AddOne();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Postfix operator e.g variable++
|
||||||
|
*/
|
||||||
|
UInt<value_size> operator++(int)
|
||||||
|
{
|
||||||
|
UInt<value_size> temp( *this );
|
||||||
|
|
||||||
|
AddOne();
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UInt<value_size> & operator--()
|
||||||
|
{
|
||||||
|
AddOne();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UInt<value_size> operator--(int)
|
||||||
|
{
|
||||||
|
UInt<value_size> temp( *this );
|
||||||
|
|
||||||
|
SubOne();
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* input/output operators for standard streams
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
friend std::ostream & operator<<(std::ostream & s, const Int<value_size> & l)
|
||||||
|
{
|
||||||
|
std::string ss;
|
||||||
|
|
||||||
|
l.ToString(ss);
|
||||||
|
s << ss;
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
friend std::istream & operator>>(std::istream & s, Int<value_size> & l)
|
||||||
|
{
|
||||||
|
std::string ss;
|
||||||
|
|
||||||
|
// char for operator>>
|
||||||
|
unsigned char z;
|
||||||
|
|
||||||
|
// operator>> omits white characters if they're set for ommiting
|
||||||
|
s >> z;
|
||||||
|
|
||||||
|
if( z=='-' || z=='+' )
|
||||||
|
{
|
||||||
|
ss += z;
|
||||||
|
s >> z; // we're reading a next character (white characters can be ommited)
|
||||||
|
}
|
||||||
|
|
||||||
|
// we're reading only digits (base=10)
|
||||||
|
while( s.good() && UInt<value_size>::CharToDigit(z, 10)>=0 )
|
||||||
|
{
|
||||||
|
ss += z;
|
||||||
|
z = s.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// we're leaving the last readed character
|
||||||
|
// (it's not belonging to the value)
|
||||||
|
s.unget();
|
||||||
|
|
||||||
|
l.FromString(ss);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* This file is part of TTMath Mathematical Library
|
||||||
|
* and is distributed under the (new) BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2007, 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
|
||||||
|
|
||||||
|
#include "ttmathtypes.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
|
namespace ttmath
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class Objects
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct ObjectValue
|
||||||
|
{
|
||||||
|
std::string value;
|
||||||
|
int param;
|
||||||
|
|
||||||
|
ObjectValue() {}
|
||||||
|
ObjectValue(const std::string & v, int p) : value(v), param(p) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<std::string, ObjectValue> Table;
|
||||||
|
typedef Table::const_iterator CIterator;
|
||||||
|
|
||||||
|
ErrorCode Add(const std::string & name, const std::string & value, int param = 0)
|
||||||
|
{
|
||||||
|
Table::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, ObjectValue(value, param)) );
|
||||||
|
|
||||||
|
return err_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Empty() const
|
||||||
|
{
|
||||||
|
return table.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
return table.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
CIterator Begin() const
|
||||||
|
{
|
||||||
|
return table.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
CIterator End() const
|
||||||
|
{
|
||||||
|
return table.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode Edit(const std::string & name, const std::string & value, int param = 0)
|
||||||
|
{
|
||||||
|
Table::iterator i = table.find(name);
|
||||||
|
|
||||||
|
if( i == table.end() )
|
||||||
|
// we don't have this variable in our table
|
||||||
|
return err_unknown_object;
|
||||||
|
|
||||||
|
i->second.value = value;
|
||||||
|
i->second.param = param;
|
||||||
|
|
||||||
|
return err_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ErrorCode Delete(const std::string & name)
|
||||||
|
{
|
||||||
|
Table::iterator i = table.find(name);
|
||||||
|
|
||||||
|
if( i == table.end() )
|
||||||
|
// we don't have this variable in our table
|
||||||
|
return err_unknown_object;
|
||||||
|
|
||||||
|
table.erase( i );
|
||||||
|
|
||||||
|
return err_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ErrorCode GetValue(const std::string & name, const char * * value) const
|
||||||
|
{
|
||||||
|
Table::const_iterator i = table.find(name);
|
||||||
|
|
||||||
|
if( i == table.end() )
|
||||||
|
{
|
||||||
|
// we don't have this variable in our table
|
||||||
|
*value = 0;
|
||||||
|
return err_unknown_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
*value = i->second.value.c_str();
|
||||||
|
|
||||||
|
return err_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode GetValueParam(const std::string & name, const char * * value, int * param) const
|
||||||
|
{
|
||||||
|
Table::const_iterator i = table.find(name);
|
||||||
|
|
||||||
|
if( i == table.end() )
|
||||||
|
{
|
||||||
|
// we don't have this variable in our table
|
||||||
|
*value = 0;
|
||||||
|
return err_unknown_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
*value = i->second.value.c_str();
|
||||||
|
*param = i->second.param;
|
||||||
|
|
||||||
|
return err_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
Table * GetTable()
|
||||||
|
{
|
||||||
|
return &table;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Table table;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,284 @@
|
||||||
|
/*
|
||||||
|
* This file is part of TTMath Mathematical Library
|
||||||
|
* and is distributed under the (new) BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2007, 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 A Documented file.
|
||||||
|
|
||||||
|
Details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the version of the library
|
||||||
|
*/
|
||||||
|
#define TTMATH_MAJOR_VER 0
|
||||||
|
#define TTMATH_MINOR_VER 6
|
||||||
|
#define TTMATH_REVISION_VER 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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 macro MATHTT_ASSERT is set as well
|
||||||
|
and MATHTT_ASSERT can throw an exception if a condition is not fulfilled
|
||||||
|
(look at the definition of MATHTT_ASSERT)
|
||||||
|
|
||||||
|
if you don't want any further testing put two characters '//' before this macro
|
||||||
|
e.g.
|
||||||
|
// #define MATHTT_DEBUG
|
||||||
|
*/
|
||||||
|
#define MATHTT_DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
32 bit integer value without a sign
|
||||||
|
(the same on 64 bits platform (amd))
|
||||||
|
*/
|
||||||
|
typedef unsigned int uint;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
how many bits there are in the uint type
|
||||||
|
*/
|
||||||
|
#define BITS_PER_UINT 32u
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the mask for the highest bit in the unsigned 32bits word (2^31)
|
||||||
|
*/
|
||||||
|
#define uint_the_highest_bit 2147483648u
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the max value of the unsigned 32bits word (2^32 - 1)
|
||||||
|
(all bits equal one)
|
||||||
|
*/
|
||||||
|
#define uint_max_value 4294967295u
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
if you define this macro that means the version one of the multiplication algorithm
|
||||||
|
will be used in the UInt class
|
||||||
|
*/
|
||||||
|
//#define UINT_MUL_VERSION_1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
if you define this macro that means the version two of the multiplication algorithm
|
||||||
|
will be used in the UInt class
|
||||||
|
|
||||||
|
this algorithm is much faster than previous
|
||||||
|
|
||||||
|
you can't use both these macros together, you must use either UINT_MUL_VERSION_1
|
||||||
|
or UINT_MUL_VERSION_2
|
||||||
|
*/
|
||||||
|
#define UINT_MUL_VERSION_2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
characters which represent the comma operator
|
||||||
|
|
||||||
|
MATHTT_COMMA_CHARACTER_1 is used in reading (parsing) and in writing
|
||||||
|
MATHTT_COMMA_CHARACTER_2 can be used in reading as an auxiliary comma character
|
||||||
|
that means you can input values for example 1.2345 and 1,2345 as well
|
||||||
|
|
||||||
|
if you don't want it just put 0 there eg.
|
||||||
|
#define MATHTT_COMMA_CHARACTER_2 0
|
||||||
|
then only MATHTT_COMMA_CHARACTER_1 will be used
|
||||||
|
|
||||||
|
don't put here any special character which is used by the parser
|
||||||
|
(for example a semicolon ';' shouldn't be here)
|
||||||
|
*/
|
||||||
|
#define MATHTT_COMMA_CHARACTER_1 '.'
|
||||||
|
#define MATHTT_COMMA_CHARACTER_2 ','
|
||||||
|
////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
//// odwrocic nazwy ma byc TTMATH
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace ttmath
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
error codes
|
||||||
|
*/
|
||||||
|
enum ErrorCode
|
||||||
|
{
|
||||||
|
err_ok = 0,
|
||||||
|
err_nothing_has_read = 1,
|
||||||
|
err_unknown_character = 2,
|
||||||
|
err_unexpected_final_bracket = 4,
|
||||||
|
err_stack_not_clear = 6,
|
||||||
|
err_unknown_variable = 8,
|
||||||
|
err_division_by_zero = 9,
|
||||||
|
err_interrupt = 10,
|
||||||
|
err_overflow = 11,
|
||||||
|
err_unknown_function = 12,
|
||||||
|
err_unexpected_semicolon_operator = 18,
|
||||||
|
err_improper_amount_of_arguments = 19,
|
||||||
|
err_improper_argument = 20,
|
||||||
|
err_unexpected_end = 21,
|
||||||
|
err_internal_error = 100,
|
||||||
|
|
||||||
|
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_this_cant_be_used = 200
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class StopCalculating
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool WasStopSignal() const volatile { return false; }
|
||||||
|
virtual ~StopCalculating(){}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// moze tutaj z runtime dziedziczyc?
|
||||||
|
//zmienic nazwe na TTMathError
|
||||||
|
class MathTTError : public std::exception
|
||||||
|
{
|
||||||
|
ErrorCode code;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MathTTError(ErrorCode c) : code(c) {}
|
||||||
|
const char* what() const throw()
|
||||||
|
{
|
||||||
|
switch( code )
|
||||||
|
{
|
||||||
|
case err_this_cant_be_used:
|
||||||
|
return "You've used 'this' somewhere in your code but you can't use it there";
|
||||||
|
// dac tu jakis lepszy komunikat w stylu
|
||||||
|
// 'uzyles referencji do samego siebie ale w tym miejscu nie mozesz tego zrobic'
|
||||||
|
default:
|
||||||
|
return ":)"; // temporary
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unnamed";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef MATHTT_DEBUG
|
||||||
|
#define MATHTT_ASSERT(expression, c) \
|
||||||
|
if( !(expression) ) throw MathTTError(c);
|
||||||
|
#else
|
||||||
|
#define MATHTT_ASSERT(expression, c)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MATHTT_THIS_ASSERT(expression) \
|
||||||
|
MATHTT_ASSERT( &expression != this, err_this_cant_be_used)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
template<class ValueType>
|
||||||
|
class ValuesHistory
|
||||||
|
{
|
||||||
|
typedef std::map<ValueType, ValueType> buffer_type;
|
||||||
|
buffer_type buffer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void AddValue(const ValueType & key, const ValueType & result)
|
||||||
|
{
|
||||||
|
buffer.insert( std::make_pair(key, result) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetValue(const ValueType & key, ValueType & result) const
|
||||||
|
{
|
||||||
|
buffer_type::iterator i = buffer.find( key );
|
||||||
|
|
||||||
|
if( i == buffer.end() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
result = *i;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint Size() const
|
||||||
|
{
|
||||||
|
return static_cast<uint>( buffer.size() );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue